Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Colour Cycling Algorythm

Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
04-04-2008 05:40
heyas;

i want to loop through rgb values so that the colour changes gradually from red to orange, yellow, etc etc through the rainbow to purple and back to red in a smooth transition.
i did a rainbow cycle once, but that was via defining each colour and changing it. i want to do step-increments this time.

that means math. :(


this is what i have; i doubt it's the 'usual' way to do things, but i thought it was pretty decent. except, of course, i only go from red, through a sort of dull red, to cyan and back. :/


float R = 1.;
float G = 0.;
float B = 0.;

integer RUP = FALSE;
integer GUP = TRUE;
integer BUP = TRUE;




default
{
state_entry()
{
llSetTimerEvent(0.5);
}

timer()
{
//--okay, cycle through r/g/b at different rates...?
//--to go through 1 0 0, .5 .5 0, 0 1 0, 0 .5 .5; etc... smoothly. oh yeah, sure.
if(RUP)
{
R = R + 0.2;
if(R >= 1.0) RUP = FALSE;
}
else
{
R = R - 0.2;
if(R <= 0.0) RUP = TRUE;
}

if(GUP)
{
G = G + 0.2;
if(G >= 1.0) GUP = FALSE;
}
else
{
G = G - 0.2;
if(G <= 0.0) GUP = TRUE;
}

if(BUP)
{
B = B + 0.2;
if(B >= 1.0) BUP = FALSE;
}
else
{
B = B - 0.2;
if(B <= 0.0) BUP = TRUE;
}

llSetColor(<R, G, B>, 0);
}

}
_____________________
Why Johnny Can't Rotate:
http://forums.secondlife.com/showthread.php?t=94705
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
04-04-2008 09:06
I suggest an affine combination. That means a relative mixing of your start and end colors. Something like:

CODE

vector START_COLOR = <1.0, 0.0, 0.0>; // Red
vector END_COLOR = <1.0, 1.0, 0.0>; // Yellow
integer STEPS = 20;
...
vector colorForStep(integer i)
{
float t = ((float)i)/STEPS;
return (1.0-t)*START_COLOR+t*END_COLOR;
}


Notice how the coefficients (1.0-t and t) of the colors being combined add to one. That means the returned value is an affine combination of the colors START_COLOR and END_COLOR.
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
04-04-2008 11:10
You should also look into HSV for colors. Search the forums, there were some posts about HSV a long time ago. I have a script or two that I can send you. IM me in world.

HSV is Hue, Saturation, Value. To cycle colors keeping the same saturation and value, you only change H.

Since SL only does RGB, you need functions that do RGB to HSV and back again.
_____________________
So many monkeys, so little Shakespeare.
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
04-04-2008 12:47
Not particularly cunning code but I think this is a rainbow. :)

CODE

// red, orange, yellow, green, blue, indigo and violet.
// R => RG => G => GB => B => BR => R

integer S = 6;
string X;
integer C;
float R = 255;
float B = 0;
float G = 0;
vector Color;

Colours()
{
if (S == 1 && G >= 255) // RG => G
{
S = 2;
X = "R";
C = -5;
}
else if (S == 2 && R <= 0) // G => GB
{
S = 3;
X = "B";
C = 5;
}
else if (S == 3 && B >= 255) // GB => B
{
S = 4;
X = "G";
C = -5;
}
else if (S == 4 && G <= 0) // B => RB
{
S = 5;
X = "R";
C = 5;
}
else if (S == 5 && R >= 255) // RB = > R
{
S = 6;
X = "B";
C = -5;
}
else if (S == 6 && B <= 0) // R => RG
{
S = 1;
X = "G";
C = 5;
}

if(X == "R") R = R + C;
else if(X == "G") G = G + C;
else if(X == "B") B = B + C;

Color = <R/255, G/255, B/255>;
//llSetColor(Color, ALL_SIDES); // faster
llSetPrimitiveParams([
PRIM_COLOR, ALL_SIDES, Color, 1.0,
PRIM_POINT_LIGHT, TRUE, Color, 1.0, 10.0, 0.75
]); // slower but prettier in the dark
}


default
{
state_entry()
{
llSetTimerEvent(0.1);
}

timer()
{
Colours();
}
}
DoteDote Edison
Thinks Too Much
Join date: 6 Jun 2004
Posts: 790
04-04-2008 16:45
Just to throw out another often overlooked option... use llSetTextureAnim() along with a rainbow ramped texture. Create the texture, something like 2 x 256 in size. Ramp through the spectrum from red to red. Call llSetTextureAnim() to set the speed of your loop. No need for constantly processing those RGB values via timer-based script.
Zena Juran
Registered User
Join date: 21 Jul 2007
Posts: 473
04-04-2008 17:44
This is how I accomplash a nice rainbow. :-)

CODE


float red = 1.0;
float green = 0.0;
float blue = 0.0;

ParticleStart()
{
llParticleSystem([
PSYS_PART_FLAGS, 291,
PSYS_SRC_PATTERN, 8,
PSYS_PART_START_ALPHA, 1.00,
PSYS_PART_END_ALPHA, 1.00,
PSYS_PART_START_COLOR, <1.00, 1.00, 1.00>,
PSYS_PART_END_COLOR,<red, green, blue>,
PSYS_PART_START_SCALE, <0.05,0.05,0.00>,
PSYS_PART_END_SCALE, <0.20,0.20,0.00>,
PSYS_PART_MAX_AGE, 0.75,
PSYS_SRC_MAX_AGE, 0.00,
PSYS_SRC_ACCEL, <0.00,0.00,0.00>,
PSYS_SRC_ANGLE_BEGIN, 0.00,
PSYS_SRC_ANGLE_END, 3.14,
PSYS_SRC_BURST_PART_COUNT, 20,
PSYS_SRC_BURST_RADIUS, 0.80,
PSYS_SRC_BURST_RATE, 0.03,
PSYS_SRC_BURST_SPEED_MIN, 0.00,
PSYS_SRC_BURST_SPEED_MAX, 0.01,
PSYS_SRC_OMEGA, <0.00,0.00,0.00>,
PSYS_SRC_TEXTURE, ""
]);

}

integer Power;

default
{
state_entry()
{
Power=TRUE;
llParticleSystem([]);
llSetTimerEvent( .5);
}

timer()
{
if (Power)
{

for ( green = 0.0; green < 1.01; green += .05)
if (Power)
{ParticleStart();}
else {llSetTimerEvent(0.0);llParticleSystem([]);}
green = 1.0;

for ( red = 1.0; red > -0.01; red -= .05)
if (Power)
{ParticleStart();}
else {llSetTimerEvent(0.0);llParticleSystem([]);}
red=0.0;

for ( blue = 0.0; blue < 1.01; blue += .05)
if (Power)
{ParticleStart();}
else {llSetTimerEvent(0.0);llParticleSystem([]);}
blue=1.0;

for ( green = 1.0; green > -0.01; green -= .05)
if (Power)
{ParticleStart();}
else {llSetTimerEvent(0.0);llParticleSystem([]);}
green = 0.0;

for ( red = 0.0; red < 1.01; red += .05)
if (Power)
{ParticleStart();}
else {llSetTimerEvent(0.0);llParticleSystem([]);}
red = 1.0;

for ( blue = 1.0; blue > -0.01; blue -= .05)
if (Power)
{ParticleStart();}
else {llSetTimerEvent(0.0);llParticleSystem([]);}
blue = 0.0;
}

else
{
llSetTimerEvent(0.0);
llParticleSystem([]);
}

}
}
Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
04-04-2008 21:23
hewee;

i use something like that for toasting marshmallows and burning logs -- going from a start colour to an end colour. but how would that work for seamless loops of colour?


pale, that works a treat.

um, but im not sure im clear what exactly its doing. what are S C and X? x is which colour parameter that is currently changing?
_____________________
Why Johnny Can't Rotate:
http://forums.secondlife.com/showthread.php?t=94705
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
04-05-2008 02:45
...wow, you expect documentation too! ;)

S is the Step we're currently on.

C is the amount by which the colour changes. So a higher value will slide through the 0-255 (or 255-0) range faster.

X is the colour (R, B, or G) we're currently changing.

S = 1: RG => G ...X = R (running from 255 to 0 in steps of C) ...remove Red to leave Green
S = 2: G => GB ...X = B (running from 0 to 255 in steps of C) ...apply Blue to Green to give Indigo
S = 3: GB => B ...X = G (running from 255 to 0 in steps of C) ...remove Green to leave Blue
S = 4: B => BR ...X = R (running from 0 to 255 in steps of C) ...apply Red to Blue to give Violet
S = 5: BR => R ...X = B (running from 255 to 0 in steps of C) ...remove Blue to leave Red
S = 6: R => RG ...X = G (running from 0 to 255 in steps of C) ...apply Green to Red to Give Yellow

I suspect my colours aren't running in 'true' rainbow order: red, orange, yellow, green, blue, indigo and violet

I have:
R => RG ...Red to Yellow
RG => G ...Yellow to Green
G => GB ...Green to Indigo
GB => B ...Indigo to Blue
B => BR ...Blue to Violet
BR => R Violet to Red

...blue and indigo are around the wrong way.


Whereas I think Isaac Newton would have:
R => RG ...Red to Yellow
RG => G ...Yellow to Green
G => B ...Green to Blue
B => GB ...Blue to Indigo
GB => BR ...Indigo to Violet
BR => R Violet to Red

...which is more difficult but then Isaac was a lot cleverer than me. :D

[My head hurts now.]
Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
04-05-2008 03:02
I usually use a variation of the script posted by Zena but I got to say the solution suggested by DoteDote sounds very interesting, and I'll definately be giving it a try next time I need to create a rainbow-type or multiple colour change effect...

From: DoteDote Edison
...use llSetTextureAnim() along with a rainbow ramped texture...
_____________________
http://wiki.secondlife.com/wiki/User:debbie_Trilling
Ollj Oh
Registered User
Join date: 28 Aug 2007
Posts: 522
04-05-2008 03:56
You want HSV to RGB conversion?
It can not be done with a simple transformation matrix, because there are different cases for different color-column-spaces.

http://alvyray.com/Papers/hsv2rgb.htm
http://www.cs.rit.edu/~ncs/color/t_convert.html
http://users.powernet.co.uk/kienzle/octave/matcompat/scripts/image/hsv2rgb.m
http://sivp.sourceforge.net/func-list-0.4.1/hsv2rgb.htm