Added skybox reflection to water shader

This commit is contained in:
Michaël Lemaire 2014-01-05 22:20:15 +01:00
parent 49b7055655
commit 33c5d89783
4 changed files with 31 additions and 21 deletions

View file

@ -43,6 +43,9 @@ void OpenGLWater::update()
Color water_color = renderer->getScenery()->getWater()->material->_rgb; Color water_color = renderer->getScenery()->getWater()->material->_rgb;
renderer->getSharedState()->set("waterColor", water_color); renderer->getSharedState()->set("waterColor", water_color);
double water_reflection = renderer->getScenery()->getWater()->reflection;
renderer->getSharedState()->set("waterReflection", water_reflection);
renderer->getSharedState()->set("simplexSampler", NoiseFunctionSimplex::getNormalTexture(), true, true); renderer->getSharedState()->set("simplexSampler", NoiseFunctionSimplex::getNormalTexture(), true, true);
} }

View file

@ -209,3 +209,24 @@ vec4 applyAerialPerspective(vec4 base)
return base * vec4(attenuation, 0.0) + vec4(inscattering, 0.0); return base * vec4(attenuation, 0.0) + vec4(inscattering, 0.0);
} }
vec4 getSkyColor(vec3 location, vec3 direction)
{
float yoffset = GROUND_OFFSET - waterHeight;
vec3 camera = vec3(location.x, max(location.y + yoffset, 0.0), location.z);
vec3 x = vec3(0.0, Rg + camera.y * WORLD_SCALING, 0.0);
vec3 v = normalize(direction);
vec3 s = normalize(sunDirection * SUN_DISTANCE_SCALED - x);
float r = length(x);
float mu = dot(x, v) / r;
float t = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rg * Rg);
vec4 sunTransmittance = _sunTransmittance(v, s, r, mu, sunRadius);
vec3 attenuation;
vec3 inscattering = _getInscatterColor(x, t, v, s, r, mu, attenuation);
vec4 result = vec4(0.01, 0.012, 0.03, 1.0); // night sky
result += sunTransmittance + vec4(inscattering, 0.0);
return result;
}

View file

@ -1,21 +1,5 @@
void main(void) void main(void)
{ {
float yoffset = GROUND_OFFSET - waterHeight; gl_FragColor = getSkyColor(cameraLocation, unprojected - cameraLocation);
vec3 camera = vec3(cameraLocation.x, max(cameraLocation.y + yoffset, 0.0), cameraLocation.z);
vec3 location = vec3(unprojected.x, max(unprojected.y + yoffset, 0.0), unprojected.z);
vec3 x = vec3(0.0, Rg + camera.y * WORLD_SCALING, 0.0);
vec3 v = normalize(location - camera);
vec3 s = normalize(sunDirection * SUN_DISTANCE_SCALED - x);
float r = length(x);
float mu = dot(x, v) / r;
float t = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rg * Rg);
vec4 sunTransmittance = _sunTransmittance(v, s, r, mu, sunRadius);
vec3 attenuation;
vec3 inscattering = _getInscatterColor(x, t, v, s, r, mu, attenuation);
gl_FragColor = vec4(0.01, 0.012, 0.03, 1.0); // night sky
gl_FragColor += sunTransmittance + vec4(inscattering, 0.0);
gl_FragColor = applyToneMapping(gl_FragColor); gl_FragColor = applyToneMapping(gl_FragColor);
} }

View file

@ -1,5 +1,6 @@
uniform vec4 waterColor; uniform vec4 waterColor;
uniform sampler2D simplexSampler; uniform sampler2D simplexSampler;
uniform float waterReflection;
vec4 applyLighting(vec3 location, vec3 normal, vec4 color, float shininess) vec4 applyLighting(vec3 location, vec3 normal, vec4 color, float shininess)
{ {
@ -24,15 +25,16 @@ vec4 applyLighting(vec3 location, vec3 normal, vec4 color, float shininess)
void main(void) void main(void)
{ {
//gl_FragColor = waterColor;
//gl_FragColor = texture2D(simplexSampler, unprojected.xz * 0.01);
vec3 normal = vec3(0.0, 0.0, 0.0); vec3 normal = vec3(0.0, 0.0, 0.0);
for (float scaling = 1.0; scaling < 50.0; scaling *= 1.5) for (float scaling = 1.0; scaling < 400.0; scaling *= 1.5)
{ {
normal += texture2D(simplexSampler, unprojected.xz * 0.01 * scaling).xyz; normal += texture2D(simplexSampler, unprojected.xz * 0.01 * scaling).xyz;
} }
normal = normalize(normal);
gl_FragColor = applyLighting(unprojected, normalize(normal), waterColor, 100.0); gl_FragColor = applyLighting(unprojected, normal, waterColor, 100.0);
gl_FragColor += getSkyColor(unprojected, reflect(unprojected - cameraLocation, normal)) * waterReflection;
gl_FragColor = applyAerialPerspective(gl_FragColor); gl_FragColor = applyAerialPerspective(gl_FragColor);