diff --git a/src/render/opengl/OpenGLWater.cpp b/src/render/opengl/OpenGLWater.cpp index 483833d..45e835f 100644 --- a/src/render/opengl/OpenGLWater.cpp +++ b/src/render/opengl/OpenGLWater.cpp @@ -43,6 +43,9 @@ void OpenGLWater::update() Color water_color = renderer->getScenery()->getWater()->material->_rgb; 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); } diff --git a/src/render/opengl/shaders/bruneton.frag b/src/render/opengl/shaders/bruneton.frag index acefca0..ca7f142 100644 --- a/src/render/opengl/shaders/bruneton.frag +++ b/src/render/opengl/shaders/bruneton.frag @@ -209,3 +209,24 @@ vec4 applyAerialPerspective(vec4 base) 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; +} diff --git a/src/render/opengl/shaders/skybox.frag b/src/render/opengl/shaders/skybox.frag index 604677b..d2add99 100644 --- a/src/render/opengl/shaders/skybox.frag +++ b/src/render/opengl/shaders/skybox.frag @@ -1,21 +1,5 @@ void main(void) { - float yoffset = GROUND_OFFSET - waterHeight; - 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 = getSkyColor(cameraLocation, unprojected - cameraLocation); gl_FragColor = applyToneMapping(gl_FragColor); } diff --git a/src/render/opengl/shaders/water.frag b/src/render/opengl/shaders/water.frag index 83bc808..69d9efc 100644 --- a/src/render/opengl/shaders/water.frag +++ b/src/render/opengl/shaders/water.frag @@ -1,5 +1,6 @@ uniform vec4 waterColor; uniform sampler2D simplexSampler; +uniform float waterReflection; 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) { - //gl_FragColor = waterColor; - //gl_FragColor = texture2D(simplexSampler, unprojected.xz * 0.01); 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 = 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);