genWave Gradient Demo-TutorialSTRONGLY RECOMMEND you read up on the genWave (
viewtopic.php?f=8&t=12523 ) and genWaveViewer (
viewtopic.php?f=8&t=12522 ) threads before you attempt this demo-tutorial
Here's a method for creating a procedural gradient effect using the genWave function.
Rather than diving straight into creating an algorithm for gradients, first, let's consider what were trying to do in general terms to keep explanations simple.
Firstly, need to take into account each of the RGB colour components to make the gradient. We don't always want to start from a value of 0 for the RGB settings because this will always produce the darkest hue. A way is needed to pick any start value (within limits). Lets refer to any start value for these RGB's as colorStart. We also need to consider what the limits are for these settings (to prevent coding errors). Each RGB component is always between 0 and 255 for gE colors, these than are our minimum(0) and maximum (255) limits. This also indicates that we should avoid negative values (they fall outside of minimum 0). Let's refer to 255 as colorMax (colorMax always = 255, its a constant thing).
Still keeping things general, let's consider a color with a start value of 63. See diagram A below:-
We've used 63 of the 255 max available. Theres some FREE color space for us to play with. How do we quantify this FREE stuff? Just do some simple maths:-
FREE = colorMax - colorStart = 255 - 63 = 192. FREE stuff now has a usable value but what does it represent? Since we're creating a gradients I'd say this represents the maximum playing area for our gradient. The bit that varies in color. Let's call it colorGradMax (for color gradient Maximum). Diagram B summaries things up to now:-
Now we've got enough information to start thinking about a possible color gradient algorithm.
Lets recap. We've got our helper formula but it is not quite right yet. An actual color gradient (call it: colorGrad) would comprise a colorStart with this color gradient limit (colorGradMax) added on. So, the revised formula would look like:-
remember that: colorGradMax = colorMax - colorStart
so...
colorGrad = colorStart + colorGradMax
Another thing, way not just do away with the colorGradMax and substitue the calculation for it instead (it will be one less thing to do). 2nd revision:-
colorGrad = colorStart + (colorMax - colorStart) // colorGradMax replaced with (colorMax - colorStart)
Lets substite the 'color' text of each part with red, green and blue (except for colorMax because its a constant):-
redGrad = redStart + (colorMax - redStart)
greenGrad = greenStart + (colorMax - greenStart)
blueGrad = blueStart + (colorMax - blueStart)
we've got the maximum limit for the amount a gradient can vary for each of the red, green and blue components.
All we need now is a mechanism to vary this amount. We have it. The genWave function produces waves which are things that vary in value. The red part of the gradient would then vary by (colorMax - redStart)*genWave(...) and likewise for the other two: (colorMax - greenStart)*genWave(...), (colorMax - blueStart)*genWave(...). This does not mean you would necessarily want to apply a gradient for each of the RGB components, you might just want a gradient for the red part. For this reason we cannot hardwire the gradient formula into the color only keep it as a separate option that can be incorporated into the color definition if user wants it. Another issue is the colorMax. What if I want to create an artificial color limit so that the gradient can end prematurely before the 255 maximum limit is reached? You might not always want to end up with a bright red finish for the end of your gradient. In this case you would have to make available an adjustable maximum limit for each of the 3 RGB components (for more flexible gradient designs). Something like diagram c:-
The code might look somnething like this:-
- Code: Select all
int redMax=250;
int redStart=63;
int redGrad=redStart+(redMax-redStart)*genWave(12,...);
int greenMax=225;
int greenStart=120;
int greenGrad=greenStart+(greenMax-greenStart)*genWave(7,...);
int blueMax=147;
int blueStart=97;
int blueGrad=blueStart+(blueMax-blueStart)*genWave(24,...);
setpen(redStart, greenGrad, blueStart, 0, 1); // gradient applied to green component only
=== drawing code here =====
Note that in the code above you can apply a different genWave settings for each of the 3 RGB components for more varied gradients (as long as the genWave output selection reamins the same). You can also do stuff like 255-redGrad to reverse the red gradient component (likewise for the other 2). The same for the start colors (255-redStart).
so for each of these * below you can incorporate either, redStart, 255-redStart, redGrad, 255-redGrad (substitue Green/Blue for the other positions *2, *3).
setpen(*, *2, *3, 0, 1);
For the following stages you need to understand a bit about the genWave function, best to read up genWave Viewer Manual (thread link provided at top).
Drawing a horizontal gradient in a canvass actor.
I need to know what the gradient width and the drawing step size are so that I can use a for loop to do the job. The gradient width has to be synched up with the genWave selection range so that the two can work togather to produce a coherent result (wStep parameter of genWave syncs up with drawStep of for loop). Let's say we want a gradient that is 320px wide. If our genWave selection range parameters are wStart=0 and wEnd=320 then the gW selection range is:-
gW_Selection_range = wEnd - wStart = 320 - 0 = 320 (if wStart was 20 this would have been 300)
Our drawing step size (call it drawStep) would be:-
drawStep = gw_Selection_Range / Gradient width = 320 / 320 = 1.0
Now the 'for loop' code would look something like this:-
- Code: Select all
for(i=0; i<gradWidth; i++)
{
// gradients calculated for loop
redGrad = ..... * genWave(....,i*drawStep,....); // wStep parameter tied up with for loop's i count
greenGrad = ..... * genWave(....,i*drawStep,....);
blueGrad = ..... * genWave(....,i*drawStep,....);
// rest of draw code
}
You can play around with code for the horizontal gradients at the end of this demo-tutorial
Drawing a horizontal gradient in a canvass actor.
Here you would just transpose the gradient height for the calculations
e.g. drawStep = gw_Selection_Range / Gradient height
e.g. for loop would look something like:
- Code: Select all
for(i=0; i<gradHeight; i++)
{
// gradients calculated for loop
redGrad = ..... * genWave(....,i*drawStep,....); // wStep parameter tied up with for loop's i count
greenGrad = ..... * genWave(....,i*drawStep,....);
blueGrad = ..... * genWave(....,i*drawStep,....);
// rest of draw code
}
You can explore how the vertical gradient is drawn in the code listing for it at the bottom.
CREATE THE DEMO
1. Create a canvass actor named: gradient
2. Make a Create_Actor (Script) Event for the above canvass actor.
3. Copy/Paste the code below into the new Create_Actor Event (either the horizontal or the vertical gradient code).
(Import by saving code as a .txt file and load in gE via Script Editors File/Load option)
4. Your good to go!
Code for horizontal Gradient
- Code: Select all
// Color & gradient parameters
int redMax=255;
int redStart=63;
int redGrad=0; // leave as 0
int blueMax=255;
int blueStart=63;
int blueGrad=0; // leave as 0
int greenMax=255;
int greenStart=128;
int greenGrad=0; // leave as 0
// gradient height & width
int gradWidth=320;
int gradHeight=100;
// These are the gradient positioning x, y coords relative to canvass actors top-left corner
int gradX=10;
int gradY=10;
//These two are genWave parameters these should be the same as the genWave WAVE you've created.
double wStart=0;
double wEnd=320;
double drawStep=(wEnd-wStart)/gradWidth;
// for loop variables
double dStep=0.0;
int i=0;
//gradient draw loop
for(i=0; i<gradWidth; i++)
{
dStep=i*drawStep; // this set's up the drawing steps (synched up with genWave)
redGrad=abs(redStart+(redMax-redStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
greenGrad=abs(greenStart+(greenMax-greenStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
blueGrad=abs(blueStart+(blueMax-blueStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
// setup Gradient
setpen(255-redGrad, greenGrad, blueStart, 0, 1);
// draw gradient
moveto(i+gradX, gradY+gradHeight);
lineto(i+gradX, gradY);
}
Code for vertical gradient
- Code: Select all
// Color & gradient parameters
int redMax=255;
int redStart=63;
int redGrad=0; // leave as 0
int blueMax=255;
int blueStart=63;
int blueGrad=0; // leave as 0
int greenMax=255;
int greenStart=128;
int greenGrad=0; // leave as 0
// gradient height & width
int gradWidth=320;
int gradHeight=100;
// These are the gradient positioning x, y coords relative to canvass actors top-left corner
int gradX=10;
int gradY=10;
//These two are genWave parameters these should be the same as the genWave WAVE you've created.
double wStart=0;
double wEnd=320;
double drawStep=(wEnd-wStart)/gradHeight;
// for loop variables
double dStep=0.0;
int i=0;
//gradient draw loop
for(i=0; i<gradHeight; i++)
{
dStep=i*drawStep; // this set's up the drawing steps (synched up with genWave)
redGrad=abs(redStart+(redMax-redStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
greenGrad=abs(greenStart+(greenMax-greenStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
blueGrad=abs(blueStart+(blueMax-blueStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
// setup Gradient
setpen(255-redGrad, greenGrad, blueStart, 0, 1);
// draw gradient
moveto(gradX, gradY+gradHeight-i);
lineto(gradX+gradWidth,gradY+gradHeight-i);
}
[EDIT] Oops! Cleared up the Code tag typo was making some normal text code, sorry