Atmosphere Scattering - There something wrong

Started by
0 comments, last by Stainless 8 years, 11 months ago

For the last week or more i have been trying to implement Atmosphere scattering. (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html)

I got some problems with the skydome.

http://puu.sh/hVqkV/48c497f499.png

How i use the code:

I made a sphere inside blender with the size of 1.

So my code loads the file as an wavefront and draws it ever frame as a sphere of size around the camera.

And all what it sends is the model matrix (to keep the origin of the sphere at the camera position) and it sends the camera position but i just set it for now to (0, 0, 1)

Shader Code:

Vert:


#version 440


layout(location =0) uniform mat4 viewProjectionMatrix;

layout(location=1) uniform mat4 modelMatrix;
layout(location=2) uniform float time;
layout(location=3) uniform vec3 v3CameraPos;

layout(location=1) in vec3 v;
layout(location=2) in vec3 n;
layout(location=3) in vec2 u;

out vec3 normal;
out vec2 texUV;
out float ttime;


vec3 v3LightDir;

out vec4 c0;
out vec4 c1;
out vec4 color1;
out vec3 v3Direction;
out vec3 v3LightDirection;

vec3 v3InvWavelength =vec3(
  1.0f / pow(0.650f, 4),
  1.0f / pow(0.570f, 4),
  1.0f / pow(0.475f, 4));



float pi =3.14159265;
float km =0.0025;
float kr =0.0015;
float eSun =10;

int nSamples =2;
float fSamples =nSamples;
float fCameraHeight =10;

float fCameraHeight2 =fCameraHeight * fCameraHeight;
float fOuterRadius =1.025;
float fOuterRadius2 =fOuterRadius * fOuterRadius;

float fInnerRadius =1;
float fInnerRadius2 =fInnerRadius *fInnerRadius;
float fkrESun;

float fKrESun =kr *eSun;
float fKmESun =km *eSun;
float fKr4PI =kr *4 *pi;
float fKm4PI =km *4 *pi;

float fScaleDepth =(fOuterRadius - fInnerRadius);
float fScale = 1.0f / fScaleDepth;
float fScaleOverScaleDepth = fScale / fScaleDepth;

//The scale equation calculated by Vernier's Graphical Analysis
float scale(float fCos){
	float x = 1.0 - fCos;
	return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
}

void main(){
	v3LightDir =(viewProjectionMatrix * modelMatrix  *vec4(0, 1, 1, 1)).xyz;
	v3LightDirection =v3LightDir;
	
	gl_Position =viewProjectionMatrix * modelMatrix *vec4 (v, 1);
	
	vec3 v3Pos = gl_Position.xyz;
	vec3 v3Ray = v3Pos - v3CameraPos;
	float fFar = length(v3Ray);
	v3Ray /= fFar;
	
	vec3 v3Start = v3CameraPos;	
	float fHeight = length(v3Start);
	float fStartDepth =exp(fScaleOverScaleDepth  * (fInnerRadius - fCameraHeight));	
	float fStartAngle =dot(v3Ray, v3Start) / fHeight;
	float fStartOffset = fStartDepth*scale(fStartAngle);
	
	
	float fSampleLength =fFar / fSamples;	
	float fScaledLength =fSampleLength * fScale;	
	vec3 v3SampleRay =v3Ray * fSampleLength;	
	vec3 v3SamplePoint =v3Start + v3SampleRay * 0.5;

	vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);

	for(int i=0; i<nSamples; i++){
	    float fHeight = length(v3SamplePoint);
	    float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
	    float fLightAngle = dot(v3LightDir, v3SamplePoint) / fHeight;
	    float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
	    float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) -  scale(fCameraAngle)));

		

	    vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
	    v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
	    v3SamplePoint += v3SampleRay;

	}

	  c0.rgb = v3FrontColor * (v3InvWavelength * fKrESun);
	  c1.rgb = v3FrontColor * fKmESun;
	  v3Direction = v3CameraPos - v3Pos;
	  
}

Frag:


#version 430

in vec3 normal;
in vec2 fragCoord;

in float ttime;

uniform sampler2D tex0;

out vec4 fragColor;

in vec4 color1;
in vec4 c0;
in vec4 c1;
in vec3 v3Direction;

in vec3 v3LightDirection;

float g = -0.9;

//Mie
//g : ( -0.75, -0.999 )
//   3 * ( 1 - g^2 )               1 + c^2
//F = ----------------- * -------------------------------
//   2 * ( 2 + g^2 )     ( 1 + g^2 - 2 * g * c )^(3/2)
float phase_mie(float g, float c, float cc) {
	float gg = g * g;	
	float a = ( 1.0 - gg ) * ( 1.0 + cc );
	float b = 1.0 + gg - 2.0 * g * c;
	b *= sqrt( b );
	b *= 2.0 + gg;		
	return 1.5 * a / b;
}

//Reyleigh
//g : 0
//F = 3/4 * ( 1 + c^2 )
float phase_reyleigh(float cc) {
	return 0.75 * ( 1.0 + cc );
}

void main(){
	vec3 light =normalize(v3LightDirection);
	float fCos =dot(light, v3Direction) /length(v3Direction);
	float fCos2 =fCos *fCos;
	vec4 color =phase_reyleigh(fCos2) *c0 + phase_mie(g, fCos, fCos2) *c1;
	fragColor =color;
	color.a =color.b;
}

I don't know if i used a good model or if i don't use the code right.

I hope someone will react soon, and if there is any other information needed or any problems please tell cause this is my first post.

Advertisement

Try normalizing v3Direction in the pixel shader.

Remember that the GPU interpolates values across vertices's, so the vectors are not guaranteed to be valid when they get to the pixel shader.

This topic is closed to new replies.

Advertisement