Converting Color to Another in RGB style

Blitz3D Forums/Blitz3D Programming/Converting Color to Another in RGB style

Mortiis(Posted 2009) [#1]
I want to change the color of Ambient Light in realtime for example,
from red to blue. Is there an efficient way to do this? Any code or
idea is most appreciated, thanks!


Ross C(Posted 2009) [#2]
This should do the trick. The range parameter simply determines how far along the transition the color is. 0 = first colour. 1 = second colour. 0.5 = halfway in between colours... etc etc

alter_ambient() is the function to do the transition.

Arrow up and Arrow down to control transition.

Graphics3D 800,600
SetBuffer BackBuffer()

Global camera = CreateCamera()

Global sphere = CreateSphere()
PositionEntity sphere,0,0,10

Start_R = 255
Start_G = 0
Start_B = 0

Target_R = 0
Target_G = 0
Target_B = 255

range# = 0 ; number from 0 to 1

ambient_r = 0
ambient_g = 0
ambient_b = 0

AmbientLight Start_R,Start_G,Start_B

While Not KeyHit(1)

	If KeyDown(200) Then
		range = range + 0.01
		If range > 1 Then range = 1
		alter_ambient(Start_R,Start_G,Start_B,Target_R,Target_G,Target_B,range)
	ElseIf KeyDown(208) Then
		range = range - 0.01
		If range < 0 Then range = 0
		alter_ambient(Start_R,Start_G,Start_B,Target_R,Target_G,Target_B,range)
	End If
	

	UpdateWorld
	RenderWorld
	
	Flip
	
Wend
End
; sr = start red colour
; sg = start green colour
; sb = start blue colour
; tr = target red colour
; tg = target green colour
; tb = target blue colour
; range# = transition amount. 0 = 0%, 0.5 = 50%, 1 = 100% ... etc etc
Function alter_ambient(sr,sg,sb,tr,tg,tb,range#)

	Temp_R = sr - ((sr-tr)*range)
	Temp_G = sg - ((sg-tg)*range)
	Temp_B = sg - ((sg-tb)*range)
	
	AmbientLight Temp_R,Temp_G,Temp_B
	
End Function



Mortiis(Posted 2009) [#3]
Great code Ross C, thanks a lot bro!


Charrua(Posted 2009) [#4]
hi, see the second example of "3d curve library" the one called: "GG_3D_Curves_Example2.bb", at first seems to be nothing to do with colors... but shoul help you
(http://www.blitzmax.com/toolbox/toolbox.php?tool=203)
cheers
Juan


Mortiis(Posted 2009) [#5]
Hey Ross, can you provide me an example with multiple colors? Like Green to Blue, Blue to Red, Red to Purple and Purple to Green again. I tried it with the below example but it doesn't give me what I want.

Select this\ambientState
	Case "dawn"
		If this\ambientRange < 1.0
			this\ambientRange = this\ambientRange + speed
			
			alter_ambient( 20, 20, 20, 190, 180, 150, this\ambientRange )
			
			If this\ambientRange >= 1.0
				this\ambientRange = 1.0
				this\ambientState = "day"
			EndIf
		EndIf
				
	Case "day"
		If this\ambientRange > 0
			this\ambientRange = this\ambientRange - speed
			
			If this\ambientRange <= 0
				this\ambientRange = 0
				this\ambientState = "dusk"
			EndIf
				
			alter_ambient( 190, 180, 150, 220, 220, 220, this\ambientRange )
		EndIf
		
	Case "dusk"
		If this\ambientRange < 1.0
			this\ambientRange = this\ambientRange + speed
		
			If this\ambientRange >= 1.0
				this\ambientRange = 1.0
				this\ambientState = "night"
			EndIf
					
			alter_ambient( 220, 220, 220, 220, 190, 190, this\ambientRange )
		EndIf
				
	Case "night"
		If this\ambientRange > 0
			this\ambientRange = this\ambientRange - speed
			
			alter_ambient( 220, 190, 190, 20, 20, 20, this\ambientRange )
			
			If this\ambientRange <= 0
				this\ambientRange = 0
				this\ambientState = "dawn"
			EndIf
		EndIf
End Select



Stevie G(Posted 2009) [#6]
Bezier interpolation may simplify this :

http://www.blitzbasic.com/Community/posts.php?topic=76794#858953


Mortiis(Posted 2009) [#7]
Thanks Stevie but I couldn't figure out how to use that to change color in realtime and from one to another than to another and so on for 4 cycles.


Stevie G(Posted 2009) [#8]
Simple example:

Graphics3D 1024,768
SetBuffer BackBuffer()

Global camera = CreateCamera()

Global plane = CreatePlane()
RotateEntity plane, -90,0,0
PositionEntity plane, 0,0,5

Global aR, aG, aB, DayNight#

While Not KeyDown(1)

	DayNight = ( DayNight + .001 ) Mod 1.0
	COLORinterpolate( DayNight , 64,255,64, 64,64,255, 255,64,255 , 64,255,64 )
	AmbientLight aR, aG, aB
	RenderWorld()
	
	Text 0,0, ar + " "+ ag + " " + ab
	
	Flip

Wend

End


Function COLORinterpolate( t#, r1,g1,b1 , r2, g2, b2 , r3, g3, b3 , r4, g4, b4 )

	aR = r1 * (1-t)^3 + 3 * r2 * (1-t)^2 * t + 3 * r3 * (1-t) * t^2 + r4 * t^3 
	aG = g1 * (1-t)^3 + 3 * g2 * (1-t)^2 * t + 3 * g3 * (1-t) * t^2 + g4 * t^3 
	aB = b1 * (1-t)^3 + 3 * b2 * (1-t)^2 * t + 3 * b3 * (1-t) * t^2 + b4 * t^3 
	
End Function



[EDIT] Actually, you'd need a 5 pt bezier to do this

An alternative, using Ross's linear interpolation :

Graphics3D 1024,768
SetBuffer BackBuffer()

Global camera = CreateCamera()

Global plane = CreatePlane()
RotateEntity plane, -90,0,0
PositionEntity plane, 0,0,5

Global aR, aG, aB, DayNight#

While Not KeyDown(1)

	DayNight = ( DayNight + .01 ) Mod 4.0
	COLORinterpolate( DayNight , 64,255,64, 64,64,255, 255,64,64, 255,64,255 )

	AmbientLight aR, aG, aB
	RenderWorld()
	
	Text 0,0, ar + " "+ ag + " " + ab
	
	Flip

Wend

End


Function COLORinterpolate( t#, r1,g1,b1 , r2, g2, b2 , r3, g3, b3 , r4, g4, b4 )

	;get nearest integer below
	i = Floor( t )
	
	;get timestep 0 .. 1
	t# = t - i

	Select i

		Case 0
			aR = r1 + ( r2 - r1 ) * t
			aG = g1 + ( g2 - g1 ) * t
			aB = b1 + ( b2 - b1 ) * t
		Case 1
			aR = r2 + ( r3 - r2 ) * t
			aG = g2 + ( g3 - g2 ) * t
			aB = b2 + ( b3 - b2 ) * t
		Case 2
			aR = r3 + ( r4 - r3 ) * t
			aG = g3 + ( g4 - g3 ) * t
			aB = b3 + ( b4 - b3 ) * t
		Case 3
			aR = r4 + ( r1 - r4 ) * t
			aG = g4 + ( g1 - g4 ) * t
			aB = b4 + ( b1 - b4 ) * t
	End Select
	
End Function


Where you pass a float between 0 and 4 ( not including 4 as this gets set back to 0 ) and this determined the time of day and interpolates accordingly.

Stevie


Ross C(Posted 2009) [#9]
Nice alteration :o)


Mortiis(Posted 2009) [#10]
That's bloody brilliant Stevie G, you are a saviour! Thanks a lot I appreciate this!