diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 52185f2545..1841b967ef 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -72,11 +73,12 @@ namespace { GL_COLOR_ATTACHMENT2, }; - constexpr std::array UniformNames = { + constexpr std::array UniformNames = { "nLightSources", "lightDirectionsViewSpace", "lightIntensities", "modelViewTransform", "normalTransform", "projectionTransform", "performShading", "ambientIntensity", "diffuseIntensity", - "specularIntensity", "performManualDepthTest", "gBufferDepthTexture" + "specularIntensity", "performManualDepthTest", "gBufferDepthTexture", + "viewport", "resolution" }; constexpr std::array UniformOpacityNames = { @@ -812,7 +814,7 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) { glClearBufferfv(GL_COLOR, 1, glm::value_ptr(glm::vec4(0.f, 0.f, 0.f, 0.f))); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - // Use a manuel depth test to make the models aware of the rest of the envierment + // Use a manuel depth test to make the models aware of the rest of the scene _program->setUniform( _uniformCache.performManualDepthTest, _enableDepthTest @@ -831,6 +833,23 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) { gBufferDepthTextureUnit ); + // Will also need the resolution and viewport to get a texture coordinate for the + // G-buffer depth texture + _program->setUniform( + _uniformCache.resolution, + glm::vec2(global::windowDelegate->currentDrawBufferResolution()) + ); + + GLint vp[4] = { 0 }; + global::renderEngine->openglStateCache().viewport(vp); + glm::ivec4 viewport = glm::ivec4(vp[0], vp[1], vp[2], vp[3]); + _program->setUniform( + _uniformCache.viewport, + static_cast(viewport[0]), + static_cast(viewport[1]), + static_cast(viewport[2]), + static_cast(viewport[3]) + ); // Render Pass 1 // Render all parts of the model into the new framebuffer without opacity diff --git a/modules/base/rendering/renderablemodel.h b/modules/base/rendering/renderablemodel.h index eafd558810..a65e669a74 100644 --- a/modules/base/rendering/renderablemodel.h +++ b/modules/base/rendering/renderablemodel.h @@ -105,7 +105,8 @@ private: UniformCache(nLightSources, lightDirectionsViewSpace, lightIntensities, modelViewTransform, normalTransform, projectionTransform, performShading, ambientIntensity, diffuseIntensity, - specularIntensity, performManualDepthTest, gBufferDepthTexture) _uniformCache; + specularIntensity, performManualDepthTest, gBufferDepthTexture, + viewport, resolution) _uniformCache; std::vector> _lightSources; diff --git a/modules/base/shaders/model_fs.glsl b/modules/base/shaders/model_fs.glsl index cfe1b02702..cf11ee634b 100644 --- a/modules/base/shaders/model_fs.glsl +++ b/modules/base/shaders/model_fs.glsl @@ -25,7 +25,6 @@ #include "fragment.glsl" in vec2 vs_st; -in vec2 vs_viewportPixelCoord; in vec3 vs_normalViewSpace; in vec4 vs_positionCameraSpace; in float vs_screenSpaceDepth; @@ -51,6 +50,9 @@ uniform float lightIntensities[8]; uniform bool performManualDepthTest = false; uniform sampler2D gBufferDepthTexture; +uniform vec4 viewport; +uniform vec2 resolution; + Fragment getFragment() { Fragment frag; frag.depth = vs_screenSpaceDepth; @@ -60,9 +62,27 @@ Fragment getFragment() { frag.color.a = 1.0; if (performManualDepthTest) { + // gl_FragCoord.x goes from 0 to resolution.x and gl_FragCoord.y goes from 0 to + // resolution.y, need to normalize it + vec2 texCoord = gl_FragCoord.xy; + texCoord.x = texCoord.x / resolution.x; + texCoord.y = texCoord.y / resolution.y; + + // Modify the texCoord based on the Viewport and Resolution. This modification is + // necessary in case of side-by-side stereo as we only want to access the part of the + // feeding texture that we are currently responsible for. Otherwise we would map the + // entire feeding texture into our half of the result texture, leading to a doubling + // of the "missing" half. If you don't believe me, load a configuration file with the + // side_by_side stereo mode enabled, disable FXAA, and remove this modification. + // The same calculation is done in the FXAA shader, the HDR resolving and the + // atmosphere shader + vec2 st = texCoord; + st.x = st.x / (resolution.x / viewport[2]) + (viewport[0] / resolution.x); + st.y = st.y / (resolution.y / viewport[3]) + (viewport[1] / resolution.y); + // Manual depth test float gBufferDepth = - denormalizeFloat(texture(gBufferDepthTexture, vs_viewportPixelCoord).x); + denormalizeFloat(texture(gBufferDepthTexture, st).x); if (vs_screenSpaceDepth > gBufferDepth) { frag.color = vec4(0.0); frag.depth = gBufferDepth; diff --git a/modules/base/shaders/model_vs.glsl b/modules/base/shaders/model_vs.glsl index d100ed7c7d..c6a049cae8 100644 --- a/modules/base/shaders/model_vs.glsl +++ b/modules/base/shaders/model_vs.glsl @@ -32,7 +32,6 @@ layout(location = 2) in vec3 in_normal; layout(location = 3) in vec3 in_tangent; out vec2 vs_st; -out vec2 vs_viewportPixelCoord; out vec3 vs_normalViewSpace; out float vs_screenSpaceDepth; out vec4 vs_positionCameraSpace; @@ -68,9 +67,4 @@ void main() { vec3 B = normalize(cross(N, T)); vs_TBN = mat3(T, B, N); - - // Figure out the fragment's position in the viewport - vec3 ndc = gl_Position.xyz / gl_Position.w; // perspective divide/normalize - vec2 viewportCoord = ndc.xy * 0.5 + 0.5; // ndc is -1 to 1 in GL. scale for 0 to 1 - vs_viewportPixelCoord = viewportCoord; }