How to make a Sun (physical)

Started by
21 comments, last by scope 13 years, 11 months ago
can you post the code of your pixel shader?
Advertisement
There you go...

struct SkydomeVSOutput{	float4 Position		: POSITION;	float2 TexCoord		: TEXCOORD0;	float3 UPosition	: TEXCOORD1;};struct SkydomePSOutput{	float4 Color	: COLOR0;};SkydomeVSOutput SkydomeVS(float4 inPos : POSITION, float2 inTexCoord : TEXCOORD0){	SkydomeVSOutput output = (SkydomeVSOutput)0;		float4x4 ViewProjection = mul(xView, xProj);	float4x4 WorldViewProjection = mul(xWorld, ViewProjection);	output.Position = mul(inPos, WorldViewProjection);	inTexCoord.x /= 1.6;	output.TexCoord = inTexCoord;	output.UPosition = inPos;			return output;}SkydomePSOutput SkydomePS(float2 inTexCoord : TEXCOORD0, float3 inUPos : TEXCOORD1){	SkydomePSOutput output = (SkydomePSOutput)0;		output.Color = ambientColor * ambientIntensity;	float3 finalSunPosition = float3(0.0f, 0.0f, 0.0f);	float3 SunPosNoon = float3(1.0f, 1.0f, 0.0f);	float3 SunPosSundown = float3(0.0f, 0.0f, 1.0f);	float3 SunPosNight = float3(0.0f, 0.0f, 0.0f);	float3 SunPosSunrise = float3(0.0f, 0.0f, -1.0f);	if(xDaytimeNoon)	{		finalSunPosition += lerp(SunPosNoon, SunPosSundown, xTime);	}	if(xDaytimeSundown)	{	//finalSunPosition = SunPosNight;		finalSunPosition += lerp(SunPosSundown, SunPosNight, xTime);	}	if(xDaytimeNight)	{		finalSunPosition += lerp(SunPosNight, SunPosSunrise, xTime);	}	if(xDaytimeSunrise)	{		finalSunPosition += lerp(SunPosSunrise, SunPosNoon, xTime);	}	// Calculating Sun	float3 normal = normalize(inUPos);	float3 sun = normalize(finalSunPosition);	float SunDot = dot(sun, normal);	vector sunVec = 0.5f * pow( max(0, SunDot), 300.0f );	float4 noon = float4(tex2D(SkydomeNoonTextureSampler, inTexCoord) + float4(0.1, 0.1, 0.1, 0));	float4 sundown = float4(tex2D(SkydomeSundownTextureSampler, inTexCoord) + float4(0.6, 0.15, 0.15, 0));	float4 night = float4(tex2D(SkydomeNightTextureSampler, inTexCoord) + float4(0, 0, 0.3, 0) + float4(-0.2, -0.2, -0.2, 0));		if(xDaytimeNoon)	{		output.Color += lerp(noon, sundown, xTime);		output.Color += sunVec;	}			if(xDaytimeSundown)	{		output.Color += lerp(sundown, night, xTime);		output.Color += sunVec;	}	if(xDaytimeNight)	{		output.Color += lerp(night, sundown, xTime);		output.Color += sunVec;	}	if(xDaytimeSunrise)	{		output.Color += lerp(sundown, noon, xTime);		output.Color += sunVec;	}	return output;}technique Skydome{	pass Pass0	{		VertexShader = compile vs_2_0 SkydomeVS();		PixelShader = compile ps_2_0 SkydomePS();				// Render States		ZWriteEnable = false;		FillMode = Solid;	}}
hmm this has a lot of conditions in it, i don't know if thats good in a pixel shader performance wise.

i think it's better to compute the sun position on the cpu (for example by rotating it around an axis as i showed you) and use a simple variable that represents the current time of day in the range of 0 (midnight) to 1 (noon) to blend those textures.

for example like this:

float4 night = float4(tex2D(SkydomeNightTextureSampler, inTexCoord));night *= 1.0f - saturate(time_of_day * 1.5);


this would make your night texture fade out and disappear at around 1/3 of the day. no lerps needed.


But back to your question, if you multiply "sunVec" with some color value, you don't get the desired results?

	if(xDaytimeNoon)    output.Color += lerp(noon, sundown, xTime);	if(xDaytimeSundown) output.Color += lerp(sundown, night, xTime);	if(xDaytimeNight)   output.Color += lerp(night, sundown, xTime);	if(xDaytimeSunrise) output.Color += lerp(sundown, noon, xTime);	output.Color += sunVec * float4(1.0, 0, 0, 1.0f); //somecolor


(you can actually render the sun at night too because it's on the other side of the "earth" just like in real life :-))

Oh, btw you can define "sunVec" just as a float3 or float4. it said "vector" because i pasted that from some old sloppy code :)

This topic is closed to new replies.

Advertisement