Atmospheric scattering OpenGL 3.3
Posted
by
user1419305
on Stack Overflow
See other posts from Stack Overflow
or by user1419305
Published on 2012-10-13T22:50:25Z
Indexed on
2012/10/14
15:37 UTC
Read the original article
Hit count: 203
Im currently trying to convert a shader by Sean O'Neil to version 330 so i can try it out in a application im writing. Im having some issues with deprecated functions, so i replaced them, but im almost completely new to glsl, so i probably did a mistake somewhere.
Original shaders can be found here: http://www.gamedev.net/topic/592043-solved-trying-to-use-atmospheric-scattering-oneill-2004-but-get-black-sphere/
My horrible attempt at converting them:
Vertex Shader:
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
//layout(location = 1) in vec2 vertexUV;
layout(location = 2) in vec3 vertexNormal_modelspace;
uniform vec3 v3CameraPos;
uniform vec3 v3LightPos;
uniform vec3 v3InvWavelength;
uniform float fCameraHeight;
uniform float fCameraHeight2;
uniform float fOuterRadius;
uniform float fOuterRadius2;
uniform float fInnerRadius;
uniform float fInnerRadius2;
uniform float fKrESun;
uniform float fKmESun;
uniform float fKr4PI;
uniform float fKm4PI;
uniform float fScale;
uniform float fScaleDepth;
uniform float fScaleOverScaleDepth;
// passing in matrixes for transformations
uniform mat4 MVP;
uniform mat4 V;
uniform mat4 M;
const int nSamples = 4;
const float fSamples = 4.0;
out vec3 v3Direction;
out vec4 gg_FrontColor;
out vec4 gg_FrontSecondaryColor;
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(void)
{
vec3 v3Pos = vertexPosition_modelspace;
vec3 v3Ray = v3Pos - v3CameraPos;
float fFar = length(v3Ray);
v3Ray /= fFar;
vec3 v3Start = v3CameraPos;
float fHeight = length(v3Start);
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fCameraHeight));
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
float fStartOffset = fDepth*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(v3LightPos, 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;
}
gg_FrontSecondaryColor.rgb = v3FrontColor * fKmESun;
gg_FrontColor.rgb = v3FrontColor * (v3InvWavelength * fKrESun);
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
v3Direction = v3CameraPos - v3Pos;
}
Fragment Shader:
#version 330 core
uniform vec3 v3LightPos;
uniform float g;
uniform float g2;
in vec3 v3Direction;
out vec4 FragColor;
in vec4 gg_FrontColor;
in vec4 gg_FrontSecondaryColor;
void main (void)
{
float fCos = dot(v3LightPos, v3Direction) / length(v3Direction);
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
FragColor = gg_FrontColor + fMiePhase * gg_FrontSecondaryColor;
FragColor.a = FragColor.b;
}
I wrote a function to render a sphere, and im trying to render this shader onto a inverted version of it, the sphere works completely fine, with normals and all. My problem is that the sphere gets rendered all black, so the shader is not working.
This is how i'm trying to render the atmosphere inside my main rendering loop.
glUseProgram(programAtmosphere);
glBindTexture(GL_TEXTURE_2D, 0);
//######################
glUniform3f(v3CameraPos, getPlayerPos().x, getPlayerPos().y, getPlayerPos().z);
glUniform3f(v3LightPos, lightPos.x / sqrt(lightPos.x * lightPos.x + lightPos.y * lightPos.y), lightPos.y / sqrt(lightPos.x * lightPos.x + lightPos.y * lightPos.y), 0);
glUniform3f(v3InvWavelength, 1.0 / pow(0.650, 4.0), 1.0 / pow(0.570, 4.0), 1.0 / pow(0.475, 4.0));
glUniform1fARB(fCameraHeight, 1);
glUniform1fARB(fCameraHeight2, 1);
glUniform1fARB(fInnerRadius, 6350);
glUniform1fARB(fInnerRadius2, 6350 * 6350);
glUniform1fARB(fOuterRadius, 6450);
glUniform1fARB(fOuterRadius2, 6450 * 6450);
glUniform1fARB(fKrESun, 0.0025 * 20.0);
glUniform1fARB(fKmESun, 0.0015 * 20.0);
glUniform1fARB(fKr4PI, 0.0025 * 4.0 * 3.141592653);
glUniform1fARB(fKm4PI, 0.0015 * 4.0 * 3.141592653);
glUniform1fARB(fScale, 1.0 / (6450 - 6350));
glUniform1fARB(fScaleDepth, 0.25);
glUniform1fARB(fScaleOverScaleDepth, 4.0 / (6450 - 6350));
glUniform1fARB(g, -0.85);
glUniform1f(g2, -0.85 * -0.85);
// vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer[1]);
glVertexAttribPointer(
0, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// normals
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer[1]);
glVertexAttribPointer(
2, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer[1]);
glUniformMatrix4fv(ModelMatrixAT, 1, GL_FALSE, &ModelMatrix[0][0]);
glUniformMatrix4fv(ViewMatrixAT, 1, GL_FALSE, &ViewMatrix[0][0]);
glUniformMatrix4fv(ModelViewPAT, 1, GL_FALSE, &MVP[0][0]);
// Draw the triangles
glDrawElements(
GL_TRIANGLES, // mode
cubeIndices[1], // count
GL_UNSIGNED_SHORT, // type
(void*)0 // element array buffer offset
);
Any ideas?
© Stack Overflow or respective owner