Jump to content
  • Advertisement
Sign in to follow this  
Thex0

Atmospheric Scattering

This topic is 4583 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

Hello! I wasn't sure if I should revive this old thread, so I started this thread instead. I'm having trouble implementing the atmospheric scattering, the result is either a pitch black dome, or full white, or at best, a faint white at the suns position. I have tried several ways and techniques, but with the same result. Mostly I've been looking at Real Time Rendering of Atmospheric Scattering Effects for Flight Simulators and the ATI paper. But since nothing seems to help, I'm thinking maybe my constants are all wrong, or the scale is messed up.. Or am I missing something else? Here is the code for my cgFX.

float4x4	WorldViewProj		: VIEW_PROJECTION_MATRIX;
float3		LightDir			: LIGHTDIRECTION;
float4		SunColorIntensity	: SUNCOLORINTENSITY;
float3		EyePos				: EYEPOSITION;

float3		BR = { 0.000000650, 0.000000610, 0.000000475 }; //		: BETARAYLEIGH;
float3		BM = { 0.00000125, 0.00000125, 0.00000125 }; //			: BETAMIE;

struct VS_INPUT
{
	float4 pos				: POSITION;
	float3 vnormal			: NORMAL;
	float2 tex0				: TEXCOORD0;
};

struct VS_OUTPUT
{
	float4 pos		: POSITION;
	float4 diff		: COLOR;
};

VS_OUTPUT VS(VS_INPUT input)
{
	VS_OUTPUT output;
	
	// Transform position
	output.pos = mul(input.pos, WorldViewProj);
	
	float g = 0.3;

	float s = length(EyePos - input.pos.xyz);
	
	float3 F_ex = exp((BM + BR) * (-s));
	
	float3 v = normalize(input.pos.xyz - EyePos);
	float theta = dot(LightDir, v);
	
	// (1-g)^2 / (1+g^2 - 2g*theta)^(3/2)
	float hg = pow(1.0-g,2.0) / pow((1.0+pow(g,2.0) - 2.0*g*theta), 1.5);
	
	float3 bethaR = BR * ((3.0/(16*3.14159)) * (1 + theta*theta));
	float3 bethaM = BM * ((1.0/(4.0*3.14159)) * hg);
	
	float3 L_in = ((bethaR + bethaM) / (BR + BM)) * (1-F_ex);
	L_in *= SunColorIntensity.xyz;
	L_in *= SunColorIntensity.w;
	
	output.diff = float4(L_in,1);
	
	return output;
}

// PS
float4 PS(VS_OUTPUT input) : COLOR
{
	return input.diff;
}

technique T0
{
	pass P0
	{
		LightingEnable = false;
		DepthTestEnable = false;
		CullFaceEnable = false;
		VertexProgram = compile arbvp1 VS();
		FragmentProgram = compile arbfp1 PS() ;
	}
}


The LightDir is a normalized vector (normalize(0,2,5)), and the sun color is all white. The eye is placed at (0,10,0) and the skydome is of radius 100. Also, I've been trying to calculate the rayleigh scattering coefficient according to the formulae in the above article: BR = (8 * PI^3 * [n^2-1]^2) / (3 * N * l^4) l = (650nm, 610nm, 475nm) n = refractive index of air (= 1.0008?) N = molecular density (~2?) Now, using this yields very high values of BR because of the l^4 factor. Is this supposed to be measured in meters or in some other factor? Dividing by 0.000000650^4 seems bad to me. I would really appreciate any help :) [Edited by - Thex0 on April 5, 2006 7:27:18 PM]

Share this post


Link to post
Share on other sites
Advertisement
I can't give you details to your code, but you should implement something that allows you to change the values for BR and BM interactively (by keyboard etc.). Then, simply tune them until things look right.

g=0.3 seems a little too low. g=0.9 should be better. The effect of g is the following: If g is close to 1, you see a narrow white halo around the sun. If g is close to zero, the whole sky has a white halo.

Quote:
Original post by Thex0
BR = (8 * PI^3 * [n^2-1]^2) / (3 * N * l^4)
l = (650nm, 610nm, 475nm)
n = refractive index of air (= 1.0008?)
N = molecular density (~2?)

Now, using this yields very high values of BR because of the l^4 factor.
Is this supposed to be measured in meters or in some other factor? Dividing by 0.000000650^4 seems bad to me.


Usually, all quantities should be in meters, but you are right: 0.00000065^(-4) is quite small. But anyway, atmospheric scattering is a lot of parameter twiddling. You cannot expect the quantities that come out of the physical formulas to map 1-to-1 to RGB colors. This is because RGB colors are simple linear values, whereas actual perception of light densities is a very complicated process involving many non-linear things and other stuff. So simply tune parameters until it looks right.

Lutz

Share this post


Link to post
Share on other sites
Hello!

Thank you for your input! I actually got some colors by experimenting with the constants. So now it's a nice blue sky. However, it is blue no matter where the sun is. Do I need to change my coefficients manually depending on the sun angle? As far as I could tell the coefficients would cancel out based on the distance, but I can't get that in effect.

Also I'm wondering where the zenith angle comes in place? As far as I can tell it is not part of the equation from the ATI-paper.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!