atmospheric rendering

Started by
7 comments, last by Dragon_Strike 16 years, 12 months ago
ive been trying to implement atmospheric scattering... ive succeded somehwat... but it still doesnt look quite right... any ideas what i might be doing wrong?


class CSUN
{
	
	public:

		CSUN()			
		{
			Turbidity = 2.0;
			ZDir = vec3(0.0,0.0,1.0);
			SunPos = vec3(1.0f,1.0f, 0.1f);
			Update();
		}
		~CSUN() {}

		vec3 SunPos;
		vec3 A, B, C, D, E;
		vec3 zenithcolor;
		vec3 ZDir; // zenithdir
		vec3 SDir; // sundir
		vec2 SunTheta;

		float Turbidity;

		void Update()
		{
			SDir = normalize(SunPos); // sundirection
			float stheta = dot(ZDir, SDir);
			SunTheta = vec2(stheta, cos(stheta)*cos(stheta));

			float T = Turbidity;
			float T2 = T * T;

			A = vec3(-0.01925 * T - 0.25922, -0.01669 * T - 0.26078, 0.17872 * T - 1.46303);
			B = vec3(-0.06651 * T + 0.00081, -0.09495 * T + 0.00921, -0.35540 * T + 0.42749);
			C = vec3(-0.00041 * T + 0.21247, -0.00792 * T + 0.21023, -0.02266 * T + 5.32505);
			D = vec3(-0.06409 * T - 0.89887, -0.04405 * T - 1.65369,  0.12064 * T - 2.57705);
			E = vec3(-0.00325 * T + 0.04517, -0.01092 * T + 0.05291, -0.06696 * T + 0.37027);	


			float suntheta = SunTheta.x;
			float suntheta2 = suntheta * suntheta;
			float suntheta3 = suntheta * suntheta2;
			
			zenithcolor.x = ( 0.00165 * suntheta3 - 0.00375 * suntheta2 + 0.00209 * suntheta + 0.00000) * T2 +
				(-0.02903 * suntheta3 + 0.06377 * suntheta2 - 0.03202 * suntheta + 0.00394) * T +
				( 0.11693 * suntheta3 - 0.21196 * suntheta2 + 0.06052 * suntheta + 0.25886);

			zenithcolor.y = ( 0.00275 * suntheta3 - 0.00610 * suntheta2 + 0.00317 * suntheta + 0.00000) * T2 +
				(-0.04214 * suntheta3 + 0.08970 * suntheta2 - 0.04153 * suntheta + 0.00516) * T +	
				( 0.15346 * suntheta3 - 0.26756 * suntheta2 + 0.06670 * suntheta + 0.26688);

			float X = (4.0 / 9.0 - T / 120.0) * (PI - 2.0 * suntheta);		
			
			zenithcolor.z = ((4.0453 * T - 4.9710) * tan(X) - 0.2155 * T + 2.4192) * 1000.0f;
		}
};

// VERTEX SHADER

#version 110

varying vec3 VertPos;

uniform vec3 A,B,C,D,E;
uniform vec3 SDir;
uniform vec3 ZDir;
uniform vec2 thetaSun;
uniform float T;
uniform vec3 zenithcolor;

vec4 GetVertexColor()
{
	vec3 Dir = normalize(gl_Vertex.xzy); // Vertex direction
	
	float theta = dot(ZDir, Dir);
	float gamma = dot(SDir, Dir);
	float cos2gamma = gamma*gamma;
		  gamma = acos(gamma);		  

	vec3 num = (1.0 + A * exp( B / theta)) *
			   (1.0 + C * exp( D * gamma) +
				E * cos2gamma);
				
	vec3 den = (1.0 + A * exp( B )) *
			   (1.0 + C * exp( D * thetaSun.x) +
				E * thetaSun.y);
				
	vec3 xyY = zenithcolor * num / den;	
	
    vec3 XYZ;
    XYZ.x = (xyY.x / xyY.y) * xyY.z;                                                                      
    XYZ.y = xyY.z;                                                                                         
    XYZ.z = ((1.0 - xyY.x - xyY.y) / xyY.y) * xyY.z;       
	
	vec3 rgb = vec3( 3.240479 * XYZ.x - 1.537150 * XYZ.y - 0.498535 * XYZ.z,
					-0.969256 * XYZ.x + 1.875991 * XYZ.y + 0.041556 * XYZ.z,
					 0.055648 * XYZ.x - 0.204043 * XYZ.y + 1.057311 * XYZ.z);
		
   		
	float expo = -(1.0 / 15000.0);
	rgb = 1.0 - exp(expo * rgb);
	
	return vec4(rgb,1.0);
	
}


void main()
{	
	gl_FrontColor = GetVertexColor();
	
	VertPos = gl_Vertex.xyz;
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;	
}





// RENDER CODE

		SkyDomeShader->use();
		SkyDomeShader->sendUniform("A", Sun.A.x, Sun.A.y, Sun.A.z);
		SkyDomeShader->sendUniform("B", Sun.B.x, Sun.B.y, Sun.B.z);
		SkyDomeShader->sendUniform("C", Sun.C.x, Sun.C.y, Sun.C.z);
		SkyDomeShader->sendUniform("D", Sun.D.x, Sun.D.y, Sun.D.z);
		SkyDomeShader->sendUniform("E", Sun.E.x, Sun.E.y, Sun.E.z);

		SkyDomeShader->sendUniform("SDir", Sun.SDir.x, Sun.SDir.y, Sun.SDir.z);
		SkyDomeShader->sendUniform("ZDir", Sun.ZDir.x, Sun.ZDir.y, Sun.ZDir.z);

		SkyDomeShader->sendUniform("thetaSun", Sun.SunTheta.x, Sun.SunTheta.y);
		SkyDomeShader->sendUniform("zenithcolor", Sun.zenithcolor.x, Sun.zenithcolor.y, Sun.zenithcolor.z);

		SkyDomeShader->sendUniform("T", Sun.Turbidity);
		
			RenderSkyDome(4096,0.2,0);
		SkyDomeShader->disable();





Image Hosted by ImageShack.us note the very white part at the bottom.. also that the color is white(blue.. eventhough i think it should have some red/yellow...
Advertisement
Strange, I implemented the same technique and it gives me good results.
There is an error that maybe can be the cause: when you calculate the numerator of the perez distribution you should divide B by cos(theta) and not by theta.
vec3 num = (1.0 + A * exp( B / cos(theta))) *
(1.0 + C * exp( D * gamma) +
E * cos2gamma);
doesnt

float theta = dot(ZDir, Dir);

alrdy give me cos(theta)?
Sorry, you're right, I didn't noticed that.

Try to exponentiate only the luminance value of the Yxy color and before converting the Yxy color to XYZ. I use 1 - exp(-0.1f * Y), and I don't multiply the luminance value for 1000.
i solved it by

float stheta = acos(dot(ZDir, SDir));

and ur way of exp

however i still have a white line at the bottom...

Do you think you could post a link to a paper that explains what you are tying to do, or perhaps give a quick explination? Some of your math looks a little weird but it's hard to decide what's wrong and what's right without knowing the theory behind the technique.
Try to subtract a small value to stheta, like 0.001, in order to avoid that stheta is PI/2; maybe at PI/2 your model returns always white.

Are you implementing 'A Practical Analytic Model for Daylight' (http://www.cs.utah.edu/vissim/papers/sunsky/)?
Quote:Original post by Ghydo
Try to subtract a small value to stheta, like 0.001, in order to avoid that stheta is PI/2; maybe at PI/2 your model returns always white.

Are you implementing 'A Practical Analytic Model for Daylight' (http://www.cs.utah.edu/vissim/papers/sunsky/)?


yes thats the one...


btw... how can i modify it to get a nice looking sun...? something like in crysis....
Quote:Original post by Ghydo
Try to subtract a small value to stheta, like 0.001, in order to avoid that stheta is PI/2; maybe at PI/2 your model returns always white.


thx.. that helped

another btw... how much "better" is Aerial Perspective against regular exp2 fog... in tearms of visual quality?

This topic is closed to new replies.

Advertisement