diff --git a/src/basics/ColorProfile.cpp b/src/basics/ColorProfile.cpp index 25c2ff3..99af627 100644 --- a/src/basics/ColorProfile.cpp +++ b/src/basics/ColorProfile.cpp @@ -4,7 +4,7 @@ ColorProfile::ColorProfile() { - setToneMapping(TONE_MAPPING_UNCHARTED, 2.0); + setToneMapping(TONE_MAPPING_UNCHARTED, 1.6); } ColorProfile::ColorProfile(ToneMappingOperator tonemapper, double exposure) diff --git a/src/definition/Scenery.cpp b/src/definition/Scenery.cpp index 38e489e..337fea1 100644 --- a/src/definition/Scenery.cpp +++ b/src/definition/Scenery.cpp @@ -200,7 +200,7 @@ void Scenery::checkCameraAboveGround() { Vector3 camera_location = camera->getLocation(); double terrain_height = terrain->getInterpolatedHeight(camera_location.x, camera_location.z, 1, 1) + 2.0; - double water_height = terrain->getWaterHeight() + 1.0; + double water_height = terrain->getWaterHeight() + 1.5; if (camera_location.y < water_height || camera_location.y < terrain_height) { double diff = ((water_height > terrain_height) ? water_height : terrain_height) - camera_location.y; diff --git a/src/render/opengl/OpenGLRenderer.cpp b/src/render/opengl/OpenGLRenderer.cpp index d06fd5c..5a5d0f1 100644 --- a/src/render/opengl/OpenGLRenderer.cpp +++ b/src/render/opengl/OpenGLRenderer.cpp @@ -15,7 +15,8 @@ OpenGLRenderer::OpenGLRenderer(Scenery* scenery): functions = new OpenGLFunctions(); shared_state = new OpenGLSharedState(); - shared_state->set("viewDistance", 20.0); + shared_state->set("viewDistance", 300.0); + shared_state->set("exposure", 1.6); skybox = new OpenGLSkybox(this); water = new OpenGLWater(this); @@ -60,6 +61,8 @@ void OpenGLRenderer::initialize() prepare(); + disableClouds(); + skybox->initialize(); skybox->updateScenery(); diff --git a/src/render/opengl/OpenGLTerrain.cpp b/src/render/opengl/OpenGLTerrain.cpp index 1a02fc2..c251f84 100644 --- a/src/render/opengl/OpenGLTerrain.cpp +++ b/src/render/opengl/OpenGLTerrain.cpp @@ -54,6 +54,7 @@ void OpenGLTerrain::initialize() program->addVertexSource("terrain"); program->addFragmentSource("bruneton"); program->addFragmentSource("tonemapping"); + program->addFragmentSource("fadeout"); program->addFragmentSource("terrain"); // Add terrain chunks diff --git a/src/render/opengl/OpenGLWater.cpp b/src/render/opengl/OpenGLWater.cpp index 6ef79b5..7de134b 100644 --- a/src/render/opengl/OpenGLWater.cpp +++ b/src/render/opengl/OpenGLWater.cpp @@ -25,6 +25,7 @@ void OpenGLWater::initialize() program->addVertexSource("water"); program->addFragmentSource("bruneton"); program->addFragmentSource("tonemapping"); + program->addFragmentSource("fadeout"); program->addFragmentSource("water"); setVertex(0, -1.0f, 0.0f, -1.0f); diff --git a/src/render/opengl/opengl.pro b/src/render/opengl/opengl.pro index 30e51d5..889cb72 100644 --- a/src/render/opengl/opengl.pro +++ b/src/render/opengl/opengl.pro @@ -84,4 +84,5 @@ OTHER_FILES += \ shaders/bruneton.frag \ shaders/tonemapping.frag \ shaders/terrain.frag \ - shaders/terrain.vert + shaders/terrain.vert \ + shaders/fadeout.frag diff --git a/src/render/opengl/shaders/bruneton.frag b/src/render/opengl/shaders/bruneton.frag index ec61346..acefca0 100644 --- a/src/render/opengl/shaders/bruneton.frag +++ b/src/render/opengl/shaders/bruneton.frag @@ -2,7 +2,6 @@ const float GROUND_OFFSET = 0.5; const float Rg = 6360.0; const float Rt = 6420.0; const float RL = 6421.0; -const float exposure = 0.4; const float ISun = 100.0; const float AVERAGE_GROUND_REFLECTANCE = 0.1; const float HR = 8.0; @@ -90,7 +89,7 @@ vec4 _sunTransmittance(vec3 v, vec3 s, float r, float mu, float radius) { vec4 transmittance = r <= Rt ? _transmittanceWithShadow(r, mu) : vec4(1.0); /* T(x,xo) */ float d = _limit(r, mu); - radius *= (1.0 + 10.0 * d / Rt); /* Inflating due to lens effect near horizon */ + radius *= (1.0 + 25.0 * d / Rt); /* Inflating due to lens effect near horizon */ float isun = step(cos(radius * M_PI / 180.0), dot(v, s)) * ISun; /* Lsun */ transmittance.r *= isun; transmittance.g *= isun; @@ -186,3 +185,27 @@ vec3 _getInscatterColor(inout vec3 x, inout float t, vec3 v, vec3 s, out float r } return result * ISun; } + +vec4 applyAerialPerspective(vec4 base) +{ + 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); + + if (v.y == 0.0) + { + v.y = -0.000001; + } + + float r = length(x); + float mu = dot(x, v) / r; + float t = length(location - camera) * WORLD_SCALING; + + vec3 attenuation; + vec3 inscattering = _getInscatterColor(x, t, v, s, r, mu, attenuation); + + return base * vec4(attenuation, 0.0) + vec4(inscattering, 0.0); +} diff --git a/src/render/opengl/shaders/fadeout.frag b/src/render/opengl/shaders/fadeout.frag new file mode 100644 index 0000000..484b005 --- /dev/null +++ b/src/render/opengl/shaders/fadeout.frag @@ -0,0 +1,8 @@ +uniform float viewDistance; + +float distanceFadeout() +{ + vec3 camera = vec3(cameraLocation.x, 0.0, cameraLocation.z); + vec3 location = vec3(unprojected.x, 0.0, unprojected.z); + return mix(1.0, 0.0, clamp((length(location - camera) - viewDistance * 0.8) / (viewDistance * 0.2), 0.0, 1.0)); +} diff --git a/src/render/opengl/shaders/resources.qrc b/src/render/opengl/shaders/resources.qrc index d73512f..5dc91be 100644 --- a/src/render/opengl/shaders/resources.qrc +++ b/src/render/opengl/shaders/resources.qrc @@ -8,5 +8,6 @@ tonemapping.frag terrain.frag terrain.vert + fadeout.frag diff --git a/src/render/opengl/shaders/skybox.frag b/src/render/opengl/shaders/skybox.frag index cbb700b..8acc7da 100644 --- a/src/render/opengl/shaders/skybox.frag +++ b/src/render/opengl/shaders/skybox.frag @@ -15,5 +15,5 @@ void main(void) vec3 attenuation; vec3 inscattering = _getInscatterColor(x, t, v, s, r, mu, attenuation); - gl_FragColor = _toneMappingUncharted(sunTransmittance + vec4(inscattering, 0.0), 2.0); + gl_FragColor = applyToneMapping(sunTransmittance + vec4(inscattering, 0.0)); } diff --git a/src/render/opengl/shaders/terrain.frag b/src/render/opengl/shaders/terrain.frag index 4ba3625..de2f60c 100644 --- a/src/render/opengl/shaders/terrain.frag +++ b/src/render/opengl/shaders/terrain.frag @@ -1,33 +1,13 @@ uniform sampler2D groundTexture; varying vec2 texcoord; -uniform float viewDistance; void main(void) { gl_FragColor = texture2D(groundTexture, texcoord); - 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); + gl_FragColor = applyAerialPerspective(gl_FragColor); - if (v.y == 0.0) - { - v.y = -0.000001; - } + gl_FragColor = applyToneMapping(gl_FragColor); - float r = length(x); - float mu = dot(x, v) / r; - float t = length(location - camera) * WORLD_SCALING; - - vec3 attenuation; - vec3 inscattering = _getInscatterColor(x, t, v, s, r, mu, attenuation); - - gl_FragColor = gl_FragColor * vec4(attenuation, 0.0) + vec4(inscattering, 0.0); - - gl_FragColor = _toneMappingUncharted(gl_FragColor, 2.0); - - gl_FragColor.a = mix(1.0, 0.0, clamp((t - viewDistance * 0.8) / (viewDistance * 0.2), 0.0, 1.0)); + gl_FragColor.a = distanceFadeout(); } diff --git a/src/render/opengl/shaders/tonemapping.frag b/src/render/opengl/shaders/tonemapping.frag index 89f9f19..2ea09af 100644 --- a/src/render/opengl/shaders/tonemapping.frag +++ b/src/render/opengl/shaders/tonemapping.frag @@ -1,3 +1,5 @@ +uniform float exposure; + float _uncharted2Tonemap(float x) { float A = 0.15; @@ -10,7 +12,12 @@ float _uncharted2Tonemap(float x) return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F; } -vec4 _toneMappingUncharted(vec4 color, float exposure) +vec4 applyToneMapping(vec4 color) +{ + return vec4(((color * exposure) / (1.0 + color * exposure)).rgb, 1.0); +} + +/*vec4 applyToneMapping(vec4 color) { float W = 11.2; float white_scale = 1.0 / _uncharted2Tonemap(W); @@ -22,4 +29,4 @@ vec4 _toneMappingUncharted(vec4 color, float exposure) result.a = 1.0; return result; -} +}*/ diff --git a/src/render/opengl/shaders/water.frag b/src/render/opengl/shaders/water.frag index 9f5f361..06c68b6 100644 --- a/src/render/opengl/shaders/water.frag +++ b/src/render/opengl/shaders/water.frag @@ -1,32 +1,12 @@ uniform vec4 waterColor; -uniform float viewDistance; void main(void) { gl_FragColor = waterColor; - 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); + gl_FragColor = applyAerialPerspective(gl_FragColor); - if (v.y == 0.0) - { - v.y = -0.000001; - } + gl_FragColor = applyToneMapping(gl_FragColor); - float r = length(x); - float mu = dot(x, v) / r; - float t = length(location - camera) * WORLD_SCALING; - - vec3 attenuation; - vec3 inscattering = _getInscatterColor(x, t, v, s, r, mu, attenuation); - - gl_FragColor = gl_FragColor * vec4(attenuation, 0.0) + vec4(inscattering, 0.0); - - gl_FragColor = _toneMappingUncharted(gl_FragColor, 2.0); - - gl_FragColor.a = mix(1.0, 0.0, clamp((t - viewDistance * 0.8) / (viewDistance * 0.2), 0.0, 1.0)); + gl_FragColor.a = distanceFadeout(); } diff --git a/src/render/software/AtmosphereModelBruneton.cpp b/src/render/software/AtmosphereModelBruneton.cpp index a723a4d..ccaed98 100644 --- a/src/render/software/AtmosphereModelBruneton.cpp +++ b/src/render/software/AtmosphereModelBruneton.cpp @@ -934,7 +934,7 @@ static Color _sunColor(Vector3 v, Vector3 s, double r, double mu, double radius) { Color transmittance = r <= Rt ? _transmittanceWithShadow(r, mu) : COLOR_WHITE; /* T(x,xo) */ double d = _limit(r, mu); - radius *= (1.0 + 10.0 * d / Rt); /* Inflating due to lens effect near horizon */ + radius *= (1.0 + 25.0 * d / Rt); /* Inflating due to lens effect near horizon */ double isun = step(cos(radius * M_PI / 180.0), v.dotProduct(s)) * ISun; /* Lsun */ transmittance.r *= isun; transmittance.g *= isun;