diff --git a/libraries/gpu-gl/src/gpu/gl/GLShared.cpp b/libraries/gpu-gl/src/gpu/gl/GLShared.cpp index db64fb08d0..db930cf696 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLShared.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLShared.cpp @@ -701,7 +701,7 @@ bool compileShader(GLenum shaderDomain, const std::string& shaderSource, const s } qCWarning(gpugllogging) << "GLShader::compileShader - errors:"; qCWarning(gpugllogging) << temp; - delete[] temp; + delete[] temp; glDeleteShader(glshader); return false; diff --git a/libraries/gpu/src/gpu/Framebuffer.cpp b/libraries/gpu/src/gpu/Framebuffer.cpp index fa6a32d9e4..beb0334208 100755 --- a/libraries/gpu/src/gpu/Framebuffer.cpp +++ b/libraries/gpu/src/gpu/Framebuffer.cpp @@ -293,6 +293,17 @@ Format Framebuffer::getDepthStencilBufferFormat() const { return _depthStencilBuffer._element; } } +glm::vec4 Framebuffer::evalSubregionTexcoordTransformCoefficients(const glm::ivec2& sourceSurface, const glm::ivec2& destRegionSize, const glm::ivec2& destRegionOffset) { + float sMin = destRegionOffset.x / (float)sourceSurface.x; + float sWidth = destRegionSize.x / (float)sourceSurface.x; + float tMin = destRegionOffset.y / (float)sourceSurface.y; + float tHeight = destRegionSize.y / (float)sourceSurface.y; + return glm::vec4(sMin, tMin, sWidth, tHeight); +} + +glm::vec4 Framebuffer::evalSubregionTexcoordTransformCoefficients(const glm::ivec2& sourceSurface, const glm::ivec4& destViewport) { + return evalSubregionTexcoordTransformCoefficients(sourceSurface, glm::ivec2(destViewport.z, destViewport.w), glm::ivec2(destViewport.x, destViewport.y)); +} Transform Framebuffer::evalSubregionTexcoordTransform(const glm::ivec2& sourceSurface, const glm::ivec2& destRegionSize, const glm::ivec2& destRegionOffset) { float sMin = destRegionOffset.x / (float)sourceSurface.x; @@ -305,5 +316,5 @@ Transform Framebuffer::evalSubregionTexcoordTransform(const glm::ivec2& sourceSu return model; } Transform Framebuffer::evalSubregionTexcoordTransform(const glm::ivec2& sourceSurface, const glm::ivec4& destViewport) { - return evalSubregionTexcoordTransform(sourceSurface, glm::ivec2(destViewport.x, destViewport.y), glm::ivec2(destViewport.z, destViewport.w)); + return evalSubregionTexcoordTransform(sourceSurface, glm::ivec2(destViewport.z, destViewport.w), glm::ivec2(destViewport.x, destViewport.y)); } diff --git a/libraries/gpu/src/gpu/Framebuffer.h b/libraries/gpu/src/gpu/Framebuffer.h index 46b10fa04d..6fa6367c7d 100755 --- a/libraries/gpu/src/gpu/Framebuffer.h +++ b/libraries/gpu/src/gpu/Framebuffer.h @@ -141,6 +141,9 @@ public: Stamp getDepthStamp() const { return _depthStamp; } const std::vector& getColorStamps() const { return _colorStamps; } + static glm::vec4 evalSubregionTexcoordTransformCoefficients(const glm::ivec2& sourceSurface, const glm::ivec2& destRegionSize, const glm::ivec2& destRegionOffset = glm::ivec2(0)); + static glm::vec4 evalSubregionTexcoordTransformCoefficients(const glm::ivec2& sourceSurface, const glm::ivec4& destViewport); + static Transform evalSubregionTexcoordTransform(const glm::ivec2& sourceSurface, const glm::ivec2& destRegionSize, const glm::ivec2& destRegionOffset = glm::ivec2(0)); static Transform evalSubregionTexcoordTransform(const glm::ivec2& sourceSurface, const glm::ivec4& destViewport); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 0caee61f75..665f1c14ce 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -44,6 +44,7 @@ struct LightLocations { int radius{ -1 }; int ambientSphere{ -1 }; int lightBufferUnit{ -1 }; + int texcoordFrameTransform{ -1 }; int sphereParam{ -1 }; int coneParam{ -1 }; int deferredFrameTransformBuffer{ -1 }; @@ -190,6 +191,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo locations->radius = program->getUniforms().findLocation("radius"); locations->ambientSphere = program->getUniforms().findLocation("ambientSphere.L00"); + locations->texcoordFrameTransform = program->getUniforms().findLocation("texcoordFrameTransform"); locations->sphereParam = program->getUniforms().findLocation("sphereParam"); locations->coneParam = program->getUniforms().findLocation("coneParam"); @@ -495,6 +497,10 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c batch.setPipeline(program); } + // Adjust the texcoordTransform in the case we are rendeirng a sub region(mini mirror) + auto textureFrameTransform = gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(deferredFramebuffer->getFrameSize(), args->_viewport); + batch._glUniform4fv(locations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform)); + { // Setup the global lighting deferredLightingEffect->setupKeyLightBatch(batch, locations->lightBufferUnit, SKYBOX_MAP_UNIT); } @@ -509,7 +515,14 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c } -void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const DeferredFrameTransformPointer& frameTransform, bool points, bool spots) { +void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, + const DeferredFrameTransformPointer& frameTransform, + const DeferredFramebufferPointer& deferredFramebuffer, + const LightingModelPointer& lightingModel) { + + bool points = lightingModel->isPointLightEnabled(); + bool spots = lightingModel->isSpotLightEnabled(); + if (!points && !spots) { return; } @@ -548,6 +561,7 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, // enlarge the scales slightly to account for tesselation const float SCALE_EXPANSION = 0.05f; + auto textureFrameTransform = gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(deferredFramebuffer->getFrameSize(), monoViewport); batch.setProjectionTransform(monoProjMat); batch.setViewTransform(monoViewTransform); @@ -556,6 +570,7 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, if (points && !deferredLightingEffect->_pointLights.empty()) { // POint light pipeline batch.setPipeline(deferredLightingEffect->_pointLight); + batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform)); for (auto lightID : deferredLightingEffect->_pointLights) { auto& light = deferredLightingEffect->_allocatedLights[lightID]; @@ -588,6 +603,7 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, if (spots && !deferredLightingEffect->_spotLights.empty()) { // Spot light pipeline batch.setPipeline(deferredLightingEffect->_spotLight); + batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform)); // Spot mesh auto mesh = deferredLightingEffect->getSpotLightMesh(); @@ -686,7 +702,7 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo setupJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer, subsurfaceScatteringResource); - lightsJob.run(sceneContext, renderContext, deferredTransform, lightingModel->isPointLightEnabled(), lightingModel->isSpotLightEnabled()); + lightsJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel); cleanupJob.run(sceneContext, renderContext); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 552bd1f006..ff372aa5b4 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -146,7 +146,10 @@ class RenderDeferredLocals { public: using JobModel = render::Job::ModelI; - void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const DeferredFrameTransformPointer& frameTransform, bool points, bool spots); + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, + const DeferredFrameTransformPointer& frameTransform, + const DeferredFramebufferPointer& deferredFramebuffer, + const LightingModelPointer& lightingModel); }; diff --git a/libraries/render-utils/src/deferred_light.slv b/libraries/render-utils/src/deferred_light.slv index fa2fcf8ef9..79e8130910 100644 --- a/libraries/render-utils/src/deferred_light.slv +++ b/libraries/render-utils/src/deferred_light.slv @@ -14,6 +14,8 @@ out vec2 _texCoord0; +uniform vec4 texcoordFrameTransform; + void main(void) { const float depth = 1.0; const vec4 UNIT_QUAD[4] = vec4[4]( @@ -26,5 +28,8 @@ void main(void) { _texCoord0 = (pos.xy + 1) * 0.5; + _texCoord0 += texcoordFrameTransform.xy; + _texCoord0 *= texcoordFrameTransform.zw; + gl_Position = pos; } diff --git a/libraries/render-utils/src/deferred_light_limited.slv b/libraries/render-utils/src/deferred_light_limited.slv index 164e2a27d5..81ec882bdf 100644 --- a/libraries/render-utils/src/deferred_light_limited.slv +++ b/libraries/render-utils/src/deferred_light_limited.slv @@ -48,6 +48,7 @@ void main(void) { vec4 pos = UNIT_QUAD[gl_VertexID]; _texCoord0 = vec4((pos.xy + 1) * 0.5, 0.0, 1.0); + if (cam_isStereo()) { _texCoord0.x = 0.5 * (_texCoord0.x + cam_getStereoSide()); } diff --git a/libraries/render-utils/src/deferred_light_spot.slv b/libraries/render-utils/src/deferred_light_spot.slv index a93e944771..6ae133b7a5 100755 --- a/libraries/render-utils/src/deferred_light_spot.slv +++ b/libraries/render-utils/src/deferred_light_spot.slv @@ -19,7 +19,6 @@ <$declareStandardTransform()$> uniform vec4 coneParam; -uniform mat4 texcoordFrameTransform; out vec4 _texCoord0; @@ -51,7 +50,6 @@ void main(void) { projected.x = 0.5 * (projected.x + cam_getStereoSide()); } _texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w; - } else { const float depth = -1.0; //Draw at near plane const vec4 UNIT_QUAD[4] = vec4[4]( diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 84475be64e..150460dc9f 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -26,6 +26,7 @@ <$declareLightingPoint(supportScattering)$> +uniform vec4 texcoordFrameTransform; in vec4 _texCoord0; out vec4 _fragColor; @@ -35,6 +36,9 @@ void main(void) { // Grab the fragment data from the uv vec2 texCoord = _texCoord0.st / _texCoord0.q; + texCoord += texcoordFrameTransform.xy; + texCoord *= texcoordFrameTransform.zw; + DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord); if (frag.mode == FRAG_MODE_UNLIT) { diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index cd379af51e..0502fc2753 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -25,6 +25,7 @@ <@include LightSpot.slh@> <$declareLightingSpot(supportScattering)$> +uniform vec4 texcoordFrameTransform; in vec4 _texCoord0; out vec4 _fragColor; @@ -35,6 +36,9 @@ void main(void) { // Grab the fragment data from the uv vec2 texCoord = _texCoord0.st / _texCoord0.q; + texCoord += texcoordFrameTransform.xy; + texCoord *= texcoordFrameTransform.zw; + DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord); if (frag.mode == FRAG_MODE_UNLIT) { diff --git a/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf b/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf index 6c19982c2c..c5cb12aeb8 100644 --- a/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf +++ b/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf @@ -92,6 +92,7 @@ float getEyeDepthDiff(vec2 texcoord, vec2 delta) { +in vec2 varTexCoord0; out vec4 outFragColor; void main(void) { @@ -101,7 +102,10 @@ void main(void) { ivec4 stereoSide; ivec2 framePixelPos = getPixelPosTexcoordPosAndSide(gl_FragCoord.xy, pixelPos, texcoordPos, stereoSide); vec2 stereoSideClip = vec2(stereoSide.x, (isStereo() ? 0.5 : 1.0)); - vec2 frameTexcoordPos = sideToFrameTexcoord(stereoSideClip, texcoordPos); + + // Texcoord to fetch in the deferred texture are the exact UVs comming from vertex shader + // sideToFrameTexcoord(stereoSideClip, texcoordPos); + vec2 frameTexcoordPos = varTexCoord0; // Fetch the z under the pixel (stereo or not) float Zeye = getZEye(framePixelPos); diff --git a/libraries/render-utils/src/toneMapping.slf b/libraries/render-utils/src/toneMapping.slf new file mode 100644 index 0000000000..d6504b5bff --- /dev/null +++ b/libraries/render-utils/src/toneMapping.slf @@ -0,0 +1,59 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on Sat Oct 24 09:34:37 2015 +// +// Draw texture 0 fetched at texcoord.xy +// +// Created by Sam Gateau on 6/22/2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +struct ToneMappingParams { + vec4 _exp_2powExp_s0_s1; + ivec4 _toneCurve_s0_s1_s2; +}; + +const float INV_GAMMA_22 = 1.0 / 2.2; +const int ToneCurveNone = 0; +const int ToneCurveGamma22 = 1; +const int ToneCurveReinhard = 2; +const int ToneCurveFilmic = 3; + +uniform toneMappingParamsBuffer { + ToneMappingParams params; +}; +float getTwoPowExposure() { + return params._exp_2powExp_s0_s1.y; +} +int getToneCurve() { + return params._toneCurve_s0_s1_s2.x; +} + +uniform sampler2D colorMap; + +in vec2 varTexCoord0; +out vec4 outFragColor; + +void main(void) { + vec4 fragColorRaw = texture(colorMap, varTexCoord0); + vec3 fragColor = fragColorRaw.xyz; + + vec3 srcColor = fragColor * getTwoPowExposure(); + + int toneCurve = getToneCurve(); + vec3 tonedColor = srcColor; + if (toneCurve == ToneCurveFilmic) { + vec3 x = max(vec3(0.0), srcColor-0.004); + tonedColor = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); + } else if (toneCurve == ToneCurveReinhard) { + tonedColor = srcColor/(1.0 + srcColor); + tonedColor = pow(tonedColor, vec3(INV_GAMMA_22)); + } else if (toneCurve == ToneCurveGamma22) { + tonedColor = pow(srcColor, vec3(INV_GAMMA_22)); + } // else None toned = src + + outFragColor = vec4(tonedColor, 1.0); +}