Jump to content
  • Advertisement
Sign in to follow this  
Dragon_Strike

atmospheric rendering

This topic is 4253 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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...

Share this post


Link to post
Share on other sites
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);

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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/)?

Share this post


Link to post
Share on other sites
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....

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!