From cf1f5b8771fe829fe025078aa1bc778d36f7cd49 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 11 Sep 2015 15:25:33 -0700 Subject: [PATCH 01/11] Work in progress --- libraries/render-utils/src/DeferredBuffer.slh | 1 + libraries/render-utils/src/spot_light.slf | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index b9112def10..85fdac5d22 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -70,4 +70,5 @@ DeferredFragment unpackDeferredFragment(vec2 texcoord) { return frag; } + <@endif@> diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index 6510ee612c..8ee48c4f30 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -21,8 +21,12 @@ // Everything about light <@include model/Light.slh@> +<@include gpu/Transform.slh@> + +<$declareStandardTransform()$> + // The view Matrix -uniform mat4 invViewMat; +//uniform mat4 invViewMat; in vec4 _texCoord0; out vec4 _fragColor; @@ -38,6 +42,10 @@ void main(void) { discard; } + // Need the camera inv view mat + TransformCamera cam = getTransformCamera(); + mat4 invViewMat = cam._viewInverse; + // Need the light now Light light = getLight(); @@ -86,5 +94,8 @@ void main(void) { _fragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); } } + + + _fragColor = vec4(frag.position.xyz, 1); } From 6c63dc044425b188cedf9f3d4552a635a58e3c43 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 14 Sep 2015 12:28:33 -0700 Subject: [PATCH 02/11] work in progress --- .../src/DeferredLightingEffect.cpp | 8 ++++++++ .../render-utils/src/DeferredLightingEffect.h | 20 ++++++++++++++++++- libraries/render-utils/src/spot_light.slf | 10 +--------- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index a785a5d2ec..c9297bb3d3 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -245,6 +245,12 @@ gpu::FramebufferPointer _copyFBO; void DeferredLightingEffect::render(RenderArgs* args) { gpu::Batch batch; + // Allocate the parameters buffer used by all the deferred shaders + if (!_parametersBuffer._buffer) { + Parameters parameters[2]; + _parametersBuffer = gpu::BufferView(std::make_shared(2 * sizeof(Parameters), (const gpu::Byte*) ¶meters)); + } + // Framebuffer copy operations cannot function as multipass stereo operations. batch.enableStereo(false); @@ -270,6 +276,8 @@ void DeferredLightingEffect::render(RenderArgs* args) { batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture()); + + float sMin = args->_viewport.x / (float)framebufferSize.width(); float sWidth = args->_viewport.z / (float)framebufferSize.width(); float tMin = args->_viewport.y / (float)framebufferSize.height(); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 2fe56732cb..dd57117481 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -77,7 +77,7 @@ public: void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; } void setGlobalSkybox(const model::SkyboxPointer& skybox); - + private: DeferredLightingEffect() {} virtual ~DeferredLightingEffect() { } @@ -169,6 +169,24 @@ private: int _ambientLightMode = 0; model::AtmospherePointer _atmosphere; model::SkyboxPointer _skybox; + + // Class describing the uniform buffer with all the parameters common to the deferred shaders + class Parameters { + public: + + float nearVal{ 1.0f }; + float depthScale{ 1.0f }; + glm::vec2 spare0; // 2 spare scalars here + glm::vec2 depthTexCoordOffset{ 0.0f }; + glm::vec2 depthTexCoordScale{ 1.0f }; + + Parameters() {} + }; + typedef gpu::BufferView UniformBufferView; + UniformBufferView _parametersBuffer; + + const UniformBufferView& getParametersBuffer() const { return _parametersBuffer; } + }; class SimpleProgramKey { diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index 8ee48c4f30..3195e5af0d 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -21,12 +21,9 @@ // Everything about light <@include model/Light.slh@> -<@include gpu/Transform.slh@> - -<$declareStandardTransform()$> // The view Matrix -//uniform mat4 invViewMat; +uniform mat4 invViewMat; in vec4 _texCoord0; out vec4 _fragColor; @@ -42,10 +39,6 @@ void main(void) { discard; } - // Need the camera inv view mat - TransformCamera cam = getTransformCamera(); - mat4 invViewMat = cam._viewInverse; - // Need the light now Light light = getLight(); @@ -96,6 +89,5 @@ void main(void) { } - _fragColor = vec4(frag.position.xyz, 1); } From 00688172dd469f6afa6db40ac1c043194421cd15 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 14 Sep 2015 15:49:05 -0700 Subject: [PATCH 03/11] work in progress, gathering th eindvidual parameters of the deferred pass into a single UBO that is bound once for all the deferred lighting passes --- .../stereo/StereoDisplayPlugin.cpp | 4 +- libraries/render-utils/src/DeferredBuffer.slh | 45 +++++++--- .../render-utils/src/DeferredGlobalLight.slh | 10 +-- .../render-utils/src/DeferredLighting.slh | 11 +++ .../src/DeferredLightingEffect.cpp | 87 +++++++++---------- .../render-utils/src/DeferredLightingEffect.h | 12 +-- .../src/directional_ambient_light.slf | 5 +- ...onal_ambient_light_cascaded_shadow_map.slf | 5 +- .../directional_ambient_light_shadow_map.slf | 5 +- .../render-utils/src/directional_light.slf | 5 +- .../directional_light_cascaded_shadow_map.slf | 5 +- .../src/directional_light_shadow_map.slf | 5 +- .../src/directional_skybox_light.slf | 5 +- ...ional_skybox_light_cascaded_shadow_map.slf | 5 +- .../directional_skybox_light_shadow_map.slf | 5 +- libraries/render-utils/src/point_light.slf | 6 +- libraries/render-utils/src/spot_light.slf | 6 +- 17 files changed, 139 insertions(+), 87 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index ae3c1f29e2..d8b20ffdc0 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -73,14 +73,14 @@ void StereoDisplayPlugin::activate() { [this](bool clicked) { updateScreen(); }, true, checked, "Screens"); _screenActions[i] = action; } - CONTAINER->setFullscreen(qApp->primaryScreen()); + // CONTAINER->setFullscreen(qApp->primaryScreen()); WindowOpenGLDisplayPlugin::activate(); } void StereoDisplayPlugin::updateScreen() { for (uint32_t i = 0; i < _screenActions.size(); ++i) { if (_screenActions[i]->isChecked()) { - CONTAINER->setFullscreen(qApp->screens().at(i)); + // CONTAINER->setFullscreen(qApp->screens().at(i)); break; } } diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index ee889a1a93..5598f3ca3d 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -25,17 +25,34 @@ uniform sampler2D specularMap; // the depth texture uniform sampler2D depthMap; -// the distance to the near clip plane -uniform float near; -// scale factor for depth: (far - near) / far -uniform float depthScale; +struct DeferredTransform { + // the distance to the near clip plane + // scale factor for depth: (far - near) / far + vec4 nearVal_depthScale_spareAB; + // offset for depth texture coordinates + // scale for depth texture coordinates + vec4 depthTexCoordOffset_scale; -// offset for depth texture coordinates -uniform vec2 depthTexCoordOffset; + mat4 viewInverse; +}; + +layout(std140) uniform deferredTransformBuffer { + DeferredTransform _deferredTransform; +}; +DeferredTransform getDeferredTransform() { + return _deferredTransform; +} -// scale for depth texture coordinates -uniform vec2 depthTexCoordScale; +vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) { + vec2 nearVal_depthScale = deferredTransform.nearVal_depthScale_spareAB.xy; + vec2 depthTexCoordOffset = deferredTransform.depthTexCoordOffset_scale.xy; + vec2 depthTexCoordScale = deferredTransform.depthTexCoordOffset_scale.zw; + + // compute the view space position using the depth + float z = nearVal_depthScale.x / (depthVal * nearVal_depthScale.y - 1.0); + return vec4((depthTexCoordOffset + texcoord * depthTexCoordScale) * z, z, 1.0); +} struct DeferredFragment { float depthVal; @@ -51,6 +68,9 @@ struct DeferredFragment { }; DeferredFragment unpackDeferredFragment(vec2 texcoord) { + + DeferredTransform deferredTransform = getDeferredTransform(); + DeferredFragment frag; frag.depthVal = texture(depthMap, texcoord).r; frag.normalVal = texture(normalMap, texcoord); @@ -63,10 +83,13 @@ DeferredFragment unpackDeferredFragment(vec2 texcoord) { } texcoord.x *= 2.0; } - // compute the view space position using the depth - float z = near / (frag.depthVal * depthScale - 1.0); - frag.position = vec4((depthTexCoordOffset + texcoord * depthTexCoordScale) * z, z, 1.0); + frag.position = evalEyePositionFromZ(deferredTransform, frag.depthVal, texcoord); + + // compute the view space position using the depth + /* float z = near / (frag.depthVal * depthScale - 1.0); + frag.position = vec4((depthTexCoordOffset + texcoord * depthTexCoordScale) * z, z, 1.0); + */ // Unpack the normal from the map frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0)); diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index fe8e74361a..a04d76541c 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -62,10 +62,8 @@ uniform SphericalHarmonics ambientSphere; // Everything about light <@include model/Light.slh@> -// The view Matrix -uniform mat4 invViewMat; -vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { +vec3 evalAmbienGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Need the light now Light light = getLight(); @@ -82,7 +80,7 @@ vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, return color; } -vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { +vec3 evalAmbienSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Need the light now Light light = getLight(); @@ -100,7 +98,7 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no return color; } -vec3 evalSkyboxGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { +vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Need the light now Light light = getLight(); @@ -117,7 +115,7 @@ vec3 evalSkyboxGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, return color; } -vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) { +vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) { Light light = getLight(); diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index bb37a9e3e8..888742bb18 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -11,6 +11,8 @@ <@if not DEFERRED_LIGHTING_SLH@> <@def DEFERRED_LIGHTING_SLH@> + +<@func declareEvalPBRShading()@> // Frag Shading returns the diffuse amount as W and the specular rgb as xyz vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) { // Diffuse Lighting @@ -33,6 +35,9 @@ vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 sp return vec4(reflect, diffuse); } +<@endfunc@> + +<@func declareEvalBlinnRShading()@> vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) { // Diffuse Lighting @@ -49,6 +54,12 @@ vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 return vec4(reflect, diffuse); } +<@endfunc@> + + +<$declareEvalPBRShading()$> + + vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) { /*if (gl_FragCoord.x > 1000) { diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index a122b12141..6cb9196dc3 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -53,18 +53,14 @@ static const std::string glowIntensityShaderHandle = "glowIntensity"; struct LightLocations { int shadowDistances; int shadowScale; - int nearLocation; - int depthScale; - int depthTexCoordOffset; - int depthTexCoordScale; int radius; int ambientSphere; int lightBufferUnit; int atmosphereBufferUnit; - int invViewMat; int texcoordMat; int coneParam; int stereo; + int deferredTransformBuffer; }; static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations); @@ -278,9 +274,9 @@ void DeferredLightingEffect::render(RenderArgs* args) { gpu::Batch batch; // Allocate the parameters buffer used by all the deferred shaders - if (!_parametersBuffer._buffer) { - Parameters parameters[2]; - _parametersBuffer = gpu::BufferView(std::make_shared(2 * sizeof(Parameters), (const gpu::Byte*) ¶meters)); + if (!_deferredTransformBuffer._buffer) { + DeferredTransform parameters[2]; + _deferredTransformBuffer = gpu::BufferView(std::make_shared(2 * sizeof(DeferredTransform), (const gpu::Byte*) ¶meters)); } // Framebuffer copy operations cannot function as multipass stereo operations. @@ -318,8 +314,29 @@ void DeferredLightingEffect::render(RenderArgs* args) { bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); // Fetch the ViewMatrix; - glm::mat4 invViewMat; - invViewMat = args->_viewFrustum->getView(); + // glm::mat4 invViewMat; + // invViewMat = args->_viewFrustum->getView(); + + auto viewFrustum = args->_viewFrustum; + { + float left, right, bottom, top, nearVal, farVal; + glm::vec4 nearClipPlane, farClipPlane; + viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); + float depthScale = (farVal - nearVal) / farVal; + float nearScale = -1.0f / nearVal; + float depthTexCoordScaleS = (right - left) * nearScale / sWidth; + float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; + float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; + float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; + + auto leftParameters = _deferredTransformBuffer.edit(0); + leftParameters.nearVal = nearVal; + leftParameters.depthScale = depthScale; + leftParameters.depthTexCoordOffset = glm::vec2(depthTexCoordOffsetS, depthTexCoordOffsetT); + leftParameters.depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT); + leftParameters.viewInverse = viewFrustum->getView(); + } + batch.setUniformBuffer(DEFERRED_TRANSFORM_BUFFER_SLOT, _deferredTransformBuffer); auto& program = _directionalLight; LightLocationsPtr locations = _directionalLightLocations; @@ -395,25 +412,9 @@ void DeferredLightingEffect::render(RenderArgs* args) { if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) { batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer()); } - batch._glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat)); + // batch._glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat)); } - float left, right, bottom, top, nearVal, farVal; - glm::vec4 nearClipPlane, farClipPlane; - args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - - batch._glUniform1f(locations->nearLocation, nearVal); - - float depthScale = (farVal - nearVal) / farVal; - batch._glUniform1f(locations->depthScale, depthScale); - - float nearScale = -1.0f / nearVal; - float depthTexCoordScaleS = (right - left) * nearScale / sWidth; - float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; - float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; - float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; - batch._glUniform2f(locations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); - batch._glUniform2f(locations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); bool stereo = args->_context->isStereo(); batch._glUniform1f(locations->stereo, stereo ? 1 : 0); @@ -469,18 +470,15 @@ void DeferredLightingEffect::render(RenderArgs* args) { if (!_pointLights.empty()) { batch.setPipeline(_pointLight); - batch._glUniform1f(_pointLightLocations->nearLocation, nearVal); - batch._glUniform1f(_pointLightLocations->depthScale, depthScale); - batch._glUniform2f(_pointLightLocations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); - batch._glUniform2f(_pointLightLocations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); - - batch._glUniformMatrix4fv(_pointLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat)); + + // batch._glUniformMatrix4fv(_pointLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat)); batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); for (auto lightID : _pointLights) { auto& light = _allocatedLights[lightID]; - // IN DEBUG: light->setShowContour(true); + // IN DEBUG: + light->setShowContour(true); if (_pointLightLocations->lightBufferUnit >= 0) { batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer()); } @@ -517,18 +515,15 @@ void DeferredLightingEffect::render(RenderArgs* args) { if (!_spotLights.empty()) { batch.setPipeline(_spotLight); - batch._glUniform1f(_spotLightLocations->nearLocation, nearVal); - batch._glUniform1f(_spotLightLocations->depthScale, depthScale); - batch._glUniform2f(_spotLightLocations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); - batch._glUniform2f(_spotLightLocations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); - - batch._glUniformMatrix4fv(_spotLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat)); + + // batch._glUniformMatrix4fv(_spotLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat)); batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); for (auto lightID : _spotLights) { auto light = _allocatedLights[lightID]; - // IN DEBUG: light->setShowContour(true); + // IN DEBUG: + light->setShowContour(true); batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer()); @@ -656,23 +651,23 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo const int ATMOSPHERE_GPU_SLOT = 4; slotBindings.insert(gpu::Shader::Binding(std::string("atmosphereBufferUnit"), ATMOSPHERE_GPU_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("deferredTransformBuffer"), DeferredLightingEffect::DEFERRED_TRANSFORM_BUFFER_SLOT)); + gpu::Shader::makeProgram(*program, slotBindings); locations->stereo = program->getUniforms().findLocation("stereoMode"); locations->shadowDistances = program->getUniforms().findLocation("shadowDistances"); locations->shadowScale = program->getUniforms().findLocation("shadowScale"); - locations->nearLocation = program->getUniforms().findLocation("near"); - locations->depthScale = program->getUniforms().findLocation("depthScale"); - locations->depthTexCoordOffset = program->getUniforms().findLocation("depthTexCoordOffset"); - locations->depthTexCoordScale = program->getUniforms().findLocation("depthTexCoordScale"); + locations->radius = program->getUniforms().findLocation("radius"); locations->ambientSphere = program->getUniforms().findLocation("ambientSphere.L00"); - locations->invViewMat = program->getUniforms().findLocation("invViewMat"); + locations->texcoordMat = program->getUniforms().findLocation("texcoordMat"); locations->coneParam = program->getUniforms().findLocation("coneParam"); locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer"); locations->atmosphereBufferUnit = program->getBuffers().findLocation("atmosphereBufferUnit"); + locations->deferredTransformBuffer = program->getBuffers().findLocation("deferredTransformBuffer"); auto state = std::make_shared(); if (lightVolume) { diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 5d7830c1ab..87ef8b4a40 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -32,6 +32,7 @@ class DeferredLightingEffect : public Dependency { public: static const int NORMAL_FITTING_MAP_SLOT = 10; + static const int DEFERRED_TRANSFORM_BUFFER_SLOT = 7; void init(AbstractViewStateInterface* viewState); @@ -153,7 +154,7 @@ private: model::SkyboxPointer _skybox; // Class describing the uniform buffer with all the parameters common to the deferred shaders - class Parameters { + class DeferredTransform { public: float nearVal{ 1.0f }; @@ -162,13 +163,12 @@ private: glm::vec2 depthTexCoordOffset{ 0.0f }; glm::vec2 depthTexCoordScale{ 1.0f }; - Parameters() {} + glm::mat4 viewInverse; + + DeferredTransform() {} }; typedef gpu::BufferView UniformBufferView; - UniformBufferView _parametersBuffer; - - const UniformBufferView& getParametersBuffer() const { return _parametersBuffer; } - + UniformBufferView _deferredTransformBuffer; }; class SimpleProgramKey { diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index 10de6a1101..9b10bb2eea 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -27,6 +27,7 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { vec3 color = evalLightmappedColor( + getDeferredTransform().viewInverse, 1.0, frag.normal, frag.diffuse, @@ -34,7 +35,9 @@ void main(void) { _fragColor = vec4(color, 1.0); } else { - vec3 color = evalAmbienSphereGlobalColor(1.0, + vec3 color = evalAmbienSphereGlobalColor( + getDeferredTransform().viewInverse, + 1.0, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf index ff8e6aa91c..ab8361e2dc 100755 --- a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf @@ -33,13 +33,16 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { _fragColor = vec4(evalLightmappedColor( + getDeferredTransform().viewInverse, shadowAttenuation, frag.normal, frag.diffuse, frag.specularVal.xyz), 1.0); } else { - vec3 color = evalAmbienSphereGlobalColor(shadowAttenuation, + vec3 color = evalAmbienSphereGlobalColor( + getDeferredTransform().viewInverse, + shadowAttenuation, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf index d446d4edb2..1d6db7f30f 100755 --- a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf @@ -33,13 +33,16 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { _fragColor = vec4(evalLightmappedColor( + getDeferredTransform().viewInverse, shadowAttenuation, frag.normal, frag.diffuse, frag.specularVal.xyz), 1.0); } else { - vec3 color = evalAmbienSphereGlobalColor(shadowAttenuation, + vec3 color = evalAmbienSphereGlobalColor( + getDeferredTransform().viewInverse, + shadowAttenuation, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_light.slf b/libraries/render-utils/src/directional_light.slf index 2e0334406e..5a350f77da 100644 --- a/libraries/render-utils/src/directional_light.slf +++ b/libraries/render-utils/src/directional_light.slf @@ -26,13 +26,16 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { _fragColor = vec4( evalLightmappedColor( + getDeferredTransform().viewInverse, 1.0, frag.normal, frag.diffuse, frag.specularVal.xyz), 1.0); } else { - vec3 color = evalAmbienGlobalColor(1.0, + vec3 color = evalAmbienGlobalColor( + getDeferredTransform().viewInverse, + 1.0, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf index bfc42db9bc..d34cb08956 100644 --- a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf @@ -33,13 +33,16 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { _fragColor = vec4(evalLightmappedColor( + getDeferredTransform().viewInverse, shadowAttenuation, frag.normal, frag.diffuse, frag.specularVal.xyz), 1.0); } else { - vec3 color = evalAmbienGlobalColor(shadowAttenuation, + vec3 color = evalAmbienGlobalColor( + getDeferredTransform().viewInverse, + shadowAttenuation, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_light_shadow_map.slf b/libraries/render-utils/src/directional_light_shadow_map.slf index 951aeab122..ab1fb4cd69 100644 --- a/libraries/render-utils/src/directional_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_shadow_map.slf @@ -33,13 +33,16 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { _fragColor = vec4(evalLightmappedColor( + getDeferredTransform().viewInverse, shadowAttenuation, frag.normal, frag.diffuse, frag.specularVal.xyz), 1.0); } else { - vec3 color = evalAmbienGlobalColor(shadowAttenuation, + vec3 color = evalAmbienGlobalColor( + getDeferredTransform().viewInverse, + shadowAttenuation, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_skybox_light.slf b/libraries/render-utils/src/directional_skybox_light.slf index cd95369395..c6fcb10f38 100755 --- a/libraries/render-utils/src/directional_skybox_light.slf +++ b/libraries/render-utils/src/directional_skybox_light.slf @@ -27,6 +27,7 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { vec3 color = evalLightmappedColor( + getDeferredTransform().viewInverse, 1.0, frag.normal, frag.diffuse, @@ -34,7 +35,9 @@ void main(void) { _fragColor = vec4(color, 1.0); } else { - vec3 color = evalSkyboxGlobalColor(1.0, + vec3 color = evalSkyboxGlobalColor( + getDeferredTransform().viewInverse, + 1.0, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf index 171d3fa996..81fb37ea10 100755 --- a/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf @@ -33,13 +33,16 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { _fragColor = vec4(evalLightmappedColor( + getDeferredTransform().viewInverse, shadowAttenuation, frag.normal, frag.diffuse, frag.specularVal.xyz), 1.0); } else { - vec3 color = evalSkyboxGlobalColor(shadowAttenuation, + vec3 color = evalSkyboxGlobalColor( + getDeferredTransform().viewInverse, + shadowAttenuation, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_skybox_light_shadow_map.slf b/libraries/render-utils/src/directional_skybox_light_shadow_map.slf index aa4206bce9..70d0f75025 100755 --- a/libraries/render-utils/src/directional_skybox_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_skybox_light_shadow_map.slf @@ -33,13 +33,16 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { _fragColor = vec4(evalLightmappedColor( + getDeferredTransform().viewInverse, shadowAttenuation, frag.normal, frag.diffuse, frag.specularVal.xyz), 1.0); } else { - vec3 color = evalSkyboxGlobalColor(shadowAttenuation, + vec3 color = evalSkyboxGlobalColor( + getDeferredTransform().viewInverse, + shadowAttenuation, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 528e6e9d96..0731c36ea0 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -21,8 +21,6 @@ // Everything about light <@include model/Light.slh@> -// The view Matrix -uniform mat4 invViewMat; in vec4 _texCoord0; out vec4 _fragColor; @@ -31,7 +29,9 @@ void main(void) { // Grab the fragment data from the uv vec2 texCoord = _texCoord0.st / _texCoord0.q; DeferredFragment frag = unpackDeferredFragment(texCoord); - + + mat4 invViewMat = getDeferredTransform().viewInverse; + // Kill if in front of the light volume float depth = frag.depthVal; if (depth < gl_FragCoord.z) { diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index 3195e5af0d..6fb8f64dc4 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -21,10 +21,6 @@ // Everything about light <@include model/Light.slh@> - -// The view Matrix -uniform mat4 invViewMat; - in vec4 _texCoord0; out vec4 _fragColor; @@ -33,6 +29,8 @@ void main(void) { vec2 texCoord = _texCoord0.st / _texCoord0.q; DeferredFragment frag = unpackDeferredFragment(texCoord); + mat4 invViewMat = getDeferredTransform().viewInverse; + // Kill if in front of the light volume float depth = frag.depthVal; if (depth < gl_FragCoord.z) { From 45dc5be53d57db45655736dcaa4486ba8c226303 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 14 Sep 2015 17:48:15 -0700 Subject: [PATCH 04/11] DeferredTransform buffer working for the deferred rendering in mono --- libraries/render-utils/src/DeferredBuffer.slh | 8 +++-- .../src/DeferredLightingEffect.cpp | 32 ++++++++----------- .../render-utils/src/DeferredLightingEffect.h | 6 ++-- .../src/directional_skybox_light.slf | 5 +-- libraries/render-utils/src/spot_light.slf | 8 +++-- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index 5598f3ca3d..0b829a2938 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -27,14 +27,16 @@ uniform sampler2D depthMap; struct DeferredTransform { + mat4 view; + mat4 viewInverse; + // the distance to the near clip plane // scale factor for depth: (far - near) / far vec4 nearVal_depthScale_spareAB; // offset for depth texture coordinates // scale for depth texture coordinates vec4 depthTexCoordOffset_scale; - - mat4 viewInverse; + }; layout(std140) uniform deferredTransformBuffer { @@ -67,7 +69,7 @@ struct DeferredFragment { float gloss; }; -DeferredFragment unpackDeferredFragment(vec2 texcoord) { +DeferredFragment unpackDeferredFragment( vec2 texcoord) { DeferredTransform deferredTransform = getDeferredTransform(); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 6cb9196dc3..1ded7e218d 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -275,8 +275,8 @@ void DeferredLightingEffect::render(RenderArgs* args) { // Allocate the parameters buffer used by all the deferred shaders if (!_deferredTransformBuffer._buffer) { - DeferredTransform parameters[2]; - _deferredTransformBuffer = gpu::BufferView(std::make_shared(2 * sizeof(DeferredTransform), (const gpu::Byte*) ¶meters)); + DeferredTransform parameters/*[2]*/; + _deferredTransformBuffer = gpu::BufferView(std::make_shared(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters)); } // Framebuffer copy operations cannot function as multipass stereo operations. @@ -313,10 +313,6 @@ void DeferredLightingEffect::render(RenderArgs* args) { bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); - // Fetch the ViewMatrix; - // glm::mat4 invViewMat; - // invViewMat = args->_viewFrustum->getView(); - auto viewFrustum = args->_viewFrustum; { float left, right, bottom, top, nearVal, farVal; @@ -329,14 +325,21 @@ void DeferredLightingEffect::render(RenderArgs* args) { float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; - auto leftParameters = _deferredTransformBuffer.edit(0); + Transform viewTransform; + viewFrustum->evalViewTransform(viewTransform); + + DeferredTransform leftParameters; + viewTransform.getInverseMatrix(leftParameters._view); + viewTransform.getMatrix(leftParameters._viewInverse); leftParameters.nearVal = nearVal; leftParameters.depthScale = depthScale; leftParameters.depthTexCoordOffset = glm::vec2(depthTexCoordOffsetS, depthTexCoordOffsetT); leftParameters.depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT); - leftParameters.viewInverse = viewFrustum->getView(); + + _deferredTransformBuffer._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &leftParameters); } - batch.setUniformBuffer(DEFERRED_TRANSFORM_BUFFER_SLOT, _deferredTransformBuffer); + + batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer); auto& program = _directionalLight; LightLocationsPtr locations = _directionalLightLocations; @@ -412,7 +415,6 @@ void DeferredLightingEffect::render(RenderArgs* args) { if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) { batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer()); } - // batch._glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat)); } bool stereo = args->_context->isStereo(); @@ -471,14 +473,11 @@ void DeferredLightingEffect::render(RenderArgs* args) { if (!_pointLights.empty()) { batch.setPipeline(_pointLight); - // batch._glUniformMatrix4fv(_pointLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat)); - batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); for (auto lightID : _pointLights) { auto& light = _allocatedLights[lightID]; - // IN DEBUG: - light->setShowContour(true); + // IN DEBUG: light->setShowContour(true); if (_pointLightLocations->lightBufferUnit >= 0) { batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer()); } @@ -516,14 +515,11 @@ void DeferredLightingEffect::render(RenderArgs* args) { if (!_spotLights.empty()) { batch.setPipeline(_spotLight); - // batch._glUniformMatrix4fv(_spotLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat)); - batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); for (auto lightID : _spotLights) { auto light = _allocatedLights[lightID]; - // IN DEBUG: - light->setShowContour(true); + // IN DEBUG: light->setShowContour(true); batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer()); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 87ef8b4a40..e8b40b06ad 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -32,7 +32,7 @@ class DeferredLightingEffect : public Dependency { public: static const int NORMAL_FITTING_MAP_SLOT = 10; - static const int DEFERRED_TRANSFORM_BUFFER_SLOT = 7; + static const int DEFERRED_TRANSFORM_BUFFER_SLOT = 2; void init(AbstractViewStateInterface* viewState); @@ -157,13 +157,15 @@ private: class DeferredTransform { public: + glm::mat4 _view; + glm::mat4 _viewInverse; + float nearVal{ 1.0f }; float depthScale{ 1.0f }; glm::vec2 spare0; // 2 spare scalars here glm::vec2 depthTexCoordOffset{ 0.0f }; glm::vec2 depthTexCoordScale{ 1.0f }; - glm::mat4 viewInverse; DeferredTransform() {} }; diff --git a/libraries/render-utils/src/directional_skybox_light.slf b/libraries/render-utils/src/directional_skybox_light.slf index c6fcb10f38..5819e13e50 100755 --- a/libraries/render-utils/src/directional_skybox_light.slf +++ b/libraries/render-utils/src/directional_skybox_light.slf @@ -21,13 +21,14 @@ in vec2 _texCoord0; out vec4 _fragColor; void main(void) { + DeferredTransform deferredTransform = getDeferredTransform(); DeferredFragment frag = unpackDeferredFragment(_texCoord0); // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { vec3 color = evalLightmappedColor( - getDeferredTransform().viewInverse, + deferredTransform.viewInverse, 1.0, frag.normal, frag.diffuse, @@ -36,7 +37,7 @@ void main(void) { _fragColor = vec4(color, 1.0); } else { vec3 color = evalSkyboxGlobalColor( - getDeferredTransform().viewInverse, + deferredTransform.viewInverse, 1.0, frag.position.xyz, frag.normal, diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index 6fb8f64dc4..a329602f82 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -25,11 +25,12 @@ in vec4 _texCoord0; out vec4 _fragColor; void main(void) { + DeferredTransform deferredTransform = getDeferredTransform(); // Grab the fragment data from the uv vec2 texCoord = _texCoord0.st / _texCoord0.q; DeferredFragment frag = unpackDeferredFragment(texCoord); - mat4 invViewMat = getDeferredTransform().viewInverse; + mat4 invViewMat = deferredTransform.viewInverse; // Kill if in front of the light volume float depth = frag.depthVal; @@ -44,6 +45,9 @@ void main(void) { vec4 fragPos = invViewMat * frag.position; vec3 fragLightVec = getLightPosition(light) - fragPos.xyz; + _fragColor = vec4(frag.position.xyz, 0.0); + // return; + // Kill if too far from the light center if (dot(fragLightVec, fragLightVec) > getLightSquareRadius(light)) { discard; @@ -85,7 +89,5 @@ void main(void) { _fragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); } } - - } From 400f90aea4428f2774dce08496ebab81e1c29331 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 15 Sep 2015 08:34:46 -0700 Subject: [PATCH 05/11] Introducing a stereo loop that should do the right thing but doesn't yet --- libraries/gpu/src/gpu/Context.cpp | 9 + libraries/gpu/src/gpu/Context.h | 14 + libraries/render-utils/src/DeferredBuffer.slh | 21 +- .../src/DeferredLightingEffect.cpp | 545 ++++++++++-------- .../render-utils/src/DeferredLightingEffect.h | 8 +- .../src/directional_ambient_light.slf | 11 +- libraries/render-utils/src/spot_light.slf | 9 +- 7 files changed, 357 insertions(+), 260 deletions(-) diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp index 36fa9dccad..e1dc94fcd7 100644 --- a/libraries/gpu/src/gpu/Context.cpp +++ b/libraries/gpu/src/gpu/Context.cpp @@ -56,6 +56,15 @@ void Context::setStereoViews(const mat4 eyeViews[2]) { _backend->setStereoViews(eyeViews); } +void Context::getStereoProjections(mat4* eyeProjections) const { + _backend->getStereoProjections(eyeProjections); +} + +void Context::getStereoViews(mat4* eyeViews) const { + _backend->getStereoViews(eyeViews); +} + + void Context::syncCache() { PROFILE_RANGE(__FUNCTION__); _backend->syncCache(); diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index bda4110921..e0d6c08af6 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -61,6 +61,18 @@ public: } } + void getStereoProjections(mat4* eyeProjections) const { + for (int i = 0; i < 2; ++i) { + eyeProjections[i] = _stereo._eyeProjections[i]; + } + } + + void getStereoViews(mat4* eyeViews) const { + for (int i = 0; i < 2; ++i) { + eyeViews[i] = _stereo._eyeViews[i]; + } + } + virtual void syncCache() = 0; virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0; @@ -176,6 +188,8 @@ public: bool isStereo(); void setStereoProjections(const mat4 eyeProjections[2]); void setStereoViews(const mat4 eyeViews[2]); + void getStereoProjections(mat4* eyeProjections) const; + void getStereoViews(mat4* eyeViews) const; void syncCache(); // Downloading the Framebuffer is a synchronous action that is not efficient. diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index 0b829a2938..32cf064e6e 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -11,7 +11,6 @@ <@if not DEFERRED_BUFFER_SLH@> <@def DEFERRED_BUFFER_SLH@> -uniform bool stereoMode = false; // the diffuse texture uniform sampler2D diffuseMap; @@ -27,12 +26,13 @@ uniform sampler2D depthMap; struct DeferredTransform { - mat4 view; + mat4 viewInverse; // the distance to the near clip plane // scale factor for depth: (far - near) / far - vec4 nearVal_depthScale_spareAB; + // stereoMode + vec4 nearVal_depthScale_stereoMode_spare0; // offset for depth texture coordinates // scale for depth texture coordinates vec4 depthTexCoordOffset_scale; @@ -46,8 +46,15 @@ DeferredTransform getDeferredTransform() { return _deferredTransform; } +bool getStereoMode(DeferredTransform deferredTransform) { + return (deferredTransform.nearVal_depthScale_stereoMode_spare0.z != 0.0); +} +float getStereoSide(DeferredTransform deferredTransform) { + return (deferredTransform.nearVal_depthScale_stereoMode_spare0.z); +} + vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) { - vec2 nearVal_depthScale = deferredTransform.nearVal_depthScale_spareAB.xy; + vec2 nearVal_depthScale = deferredTransform.nearVal_depthScale_stereoMode_spare0.xy; vec2 depthTexCoordOffset = deferredTransform.depthTexCoordOffset_scale.xy; vec2 depthTexCoordScale = deferredTransform.depthTexCoordOffset_scale.zw; @@ -79,7 +86,7 @@ DeferredFragment unpackDeferredFragment( vec2 texcoord) { frag.diffuseVal = texture(diffuseMap, texcoord); frag.specularVal = texture(specularMap, texcoord); - if (stereoMode) { + if (getStereoMode(deferredTransform)) { if (texcoord.x > 0.5) { texcoord.x -= 0.5; } @@ -88,10 +95,6 @@ DeferredFragment unpackDeferredFragment( vec2 texcoord) { frag.position = evalEyePositionFromZ(deferredTransform, frag.depthVal, texcoord); - // compute the view space position using the depth - /* float z = near / (frag.depthVal * depthScale - 1.0); - frag.position = vec4((depthTexCoordOffset + texcoord * depthTexCoordScale) * z, z, 1.0); - */ // Unpack the normal from the map frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0)); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 1ded7e218d..10da54fc75 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -59,7 +59,6 @@ struct LightLocations { int atmosphereBufferUnit; int texcoordMat; int coneParam; - int stereo; int deferredTransformBuffer; }; @@ -274,9 +273,10 @@ void DeferredLightingEffect::render(RenderArgs* args) { gpu::Batch batch; // Allocate the parameters buffer used by all the deferred shaders - if (!_deferredTransformBuffer._buffer) { - DeferredTransform parameters/*[2]*/; - _deferredTransformBuffer = gpu::BufferView(std::make_shared(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters)); + if (!_deferredTransformBuffer[0]._buffer) { + DeferredTransform parameters; + _deferredTransformBuffer[0] = gpu::BufferView(std::make_shared(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters)); + _deferredTransformBuffer[1] = gpu::BufferView(std::make_shared(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters)); } // Framebuffer copy operations cannot function as multipass stereo operations. @@ -297,11 +297,8 @@ void DeferredLightingEffect::render(RenderArgs* args) { batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true); batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture()); - batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture()); - batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture()); - batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture()); @@ -314,270 +311,329 @@ void DeferredLightingEffect::render(RenderArgs* args) { bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); auto viewFrustum = args->_viewFrustum; - { - float left, right, bottom, top, nearVal, farVal; - glm::vec4 nearClipPlane, farClipPlane; - viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - float depthScale = (farVal - nearVal) / farVal; - float nearScale = -1.0f / nearVal; - float depthTexCoordScaleS = (right - left) * nearScale / sWidth; - float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; - float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; - float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; - Transform viewTransform; - viewFrustum->evalViewTransform(viewTransform); + float left, right, bottom, top, nearVal, farVal; + glm::vec4 nearClipPlane, farClipPlane; + viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); + float depthScale = (farVal - nearVal) / farVal; + float nearScale = -1.0f / nearVal; + float depthTexCoordScaleS = (right - left) * nearScale / sWidth; + float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; + float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; + float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; - DeferredTransform leftParameters; - viewTransform.getInverseMatrix(leftParameters._view); - viewTransform.getMatrix(leftParameters._viewInverse); - leftParameters.nearVal = nearVal; - leftParameters.depthScale = depthScale; - leftParameters.depthTexCoordOffset = glm::vec2(depthTexCoordOffsetS, depthTexCoordOffsetT); - leftParameters.depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT); + mat4 monoProjMat; + viewFrustum->evalProjectionMatrix(monoProjMat); + Transform monoViewTransform; + viewFrustum->evalViewTransform(monoViewTransform); - _deferredTransformBuffer._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &leftParameters); - } + bool isStereo = args->_context->isStereo(); + int numPasses = 1; - batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer); + mat4 projMats[2]; + Transform viewTransforms[2]; + vec4 viewports[2]; + vec2 screenBottomLeftCorners[2]; + vec2 screenTopRightCorners[2]; - auto& program = _directionalLight; - LightLocationsPtr locations = _directionalLightLocations; + DeferredTransform deferredTransforms[2]; - // FIXME: Note: we've removed the menu items to enable shadows, so this will always be false for now. - // When we add back shadow support, this old approach may likely be removed and completely replaced - // but I've left it in for now. - bool shadowsEnabled = false; - bool cascadeShadowsEnabled = false; - - if (shadowsEnabled) { - batch.setResourceTexture(4, framebufferCache->getShadowFramebuffer()->getDepthStencilBuffer()); - - program = _directionalLightShadowMap; - locations = _directionalLightShadowMapLocations; - if (cascadeShadowsEnabled) { - program = _directionalLightCascadedShadowMap; - locations = _directionalLightCascadedShadowMapLocations; - if (useSkyboxCubemap) { - program = _directionalSkyboxLightCascadedShadowMap; - locations = _directionalSkyboxLightCascadedShadowMapLocations; - } else if (_ambientLightMode > -1) { - program = _directionalAmbientSphereLightCascadedShadowMap; - locations = _directionalAmbientSphereLightCascadedShadowMapLocations; - } - batch.setPipeline(program); - batch._glUniform3fv(locations->shadowDistances, 1, (const float*) &_viewState->getShadowDistances()); - - } else { - if (useSkyboxCubemap) { - program = _directionalSkyboxLightShadowMap; - locations = _directionalSkyboxLightShadowMapLocations; - } else if (_ambientLightMode > -1) { - program = _directionalAmbientSphereLightShadowMap; - locations = _directionalAmbientSphereLightShadowMapLocations; - } - batch.setPipeline(program); + if (isStereo) { + numPasses = 2; + + mat4 eyeViews[2]; + args->_context->getStereoProjections(projMats); + args->_context->getStereoViews(eyeViews); + + glm::mat4 monoViewMat; + monoViewTransform.getMatrix(monoViewMat); + + float halfWidth = 0.5 * sWidth; + + for (int i = 0; i < numPasses; i++) { + + auto sideViewMat = eyeViews[i] * monoViewMat; + + viewTransforms[i].evalFromRawMatrix(sideViewMat); + + deferredTransforms[i]._viewInverse = sideViewMat; + deferredTransforms[i].nearVal = nearVal; + deferredTransforms[i].depthScale = depthScale; + deferredTransforms[i].isStereo = (i == 0 ? -1.0f : 1.0f); + deferredTransforms[i].depthTexCoordOffset = glm::vec2(depthTexCoordOffsetS, depthTexCoordOffsetT); + deferredTransforms[i].depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT); + + + viewports[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); + screenBottomLeftCorners[i] = glm::vec2(-1.0f + i * 1.0f, -1.0f); + screenTopRightCorners[i] = glm::vec2(i * 1.0f, 1.0f); } - batch._glUniform1f(locations->shadowScale, 1.0f / framebufferCache->getShadowFramebuffer()->getWidth()); - } else { - if (useSkyboxCubemap) { - program = _directionalSkyboxLight; - locations = _directionalSkyboxLightLocations; - } else if (_ambientLightMode > -1) { - program = _directionalAmbientSphereLight; - locations = _directionalAmbientSphereLightLocations; - } - batch.setPipeline(program); + projMats[0] = monoProjMat; + + viewTransforms[0] = monoViewTransform; + + viewTransforms[0].getMatrix(deferredTransforms[0]._viewInverse); + + deferredTransforms[0].nearVal = nearVal; + deferredTransforms[0].depthScale = depthScale; + deferredTransforms[0].isStereo = 0.0f; + deferredTransforms[0].depthTexCoordOffset = glm::vec2(depthTexCoordOffsetS, depthTexCoordOffsetT); + deferredTransforms[0].depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT); + + + viewports[0] = glm::vec4(sMin, tMin, sWidth, tHeight); + screenBottomLeftCorners[0] = glm::vec2(-1.0f, -1.0f); + screenTopRightCorners[0] = glm::vec2(1.0f, 1.0f); } - { // Setup the global lighting - auto globalLight = _allocatedLights[_globalLights.front()]; - - if (locations->ambientSphere >= 0) { - gpu::SphericalHarmonics sh = globalLight->getAmbientSphere(); - if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) { - sh = (*_skybox->getCubemap()->getIrradiance()); - } - for (int i =0; i ambientSphere + i, 1, (const float*) (&sh) + i * 4); - } - } - - if (useSkyboxCubemap) { - batch.setResourceTexture(5, _skybox->getCubemap()); - } + auto eyePoint = viewFrustum->getPosition(); + float nearRadius = glm::distance(eyePoint, viewFrustum->getNearTopLeft()); - if (locations->lightBufferUnit >= 0) { - batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer()); - } - - if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) { - batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer()); - } - } - bool stereo = args->_context->isStereo(); - batch._glUniform1f(locations->stereo, stereo ? 1 : 0); + for (int side = 0; side < numPasses; side++) { - { - Transform model; - model.setTranslation(glm::vec3(sMin, tMin, 0.0)); - model.setScale(glm::vec3(sWidth, tHeight, 1.0)); - batch.setModelTransform(model); + _deferredTransformBuffer[side]._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &deferredTransforms[side]); - batch.setProjectionTransform(glm::mat4()); - batch.setViewTransform(Transform()); + batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer[side]); - glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); - glm::vec2 topLeft(-1.0f, -1.0f); + + /* glm::vec2 topLeft(-1.0f, -1.0f); glm::vec2 bottomRight(1.0f, 1.0f); glm::vec2 texCoordTopLeft(sMin, tMin); - glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight); + glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight);*/ + glm::vec2 topLeft = screenBottomLeftCorners[side]; + glm::vec2 bottomRight = screenTopRightCorners[side]; + glm::vec2 texCoordTopLeft(viewports[side].x, viewports[side].y); + glm::vec2 texCoordBottomRight(viewports[side].x + viewports[side].z, viewports[side].y + viewports[side].w); - DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); - } + // First Global directional light and ambient pass + auto& program = _directionalLight; + LightLocationsPtr locations = _directionalLightLocations; - if (useSkyboxCubemap) { - batch.setResourceTexture(5, nullptr); - } - - if (shadowsEnabled) { - batch.setResourceTexture(4, nullptr); - } - - glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); - glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); - auto texcoordMat = glm::mat4(); - texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); - texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); - texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f); - texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); - - // enlarge the scales slightly to account for tesselation - const float SCALE_EXPANSION = 0.05f; - - auto eyePoint = args->_viewFrustum->getPosition(); - float nearRadius = glm::distance(eyePoint, args->_viewFrustum->getNearTopLeft()); - - auto geometryCache = DependencyManager::get(); + // FIXME: Note: we've removed the menu items to enable shadows, so this will always be false for now. + // When we add back shadow support, this old approach may likely be removed and completely replaced + // but I've left it in for now. + /* bool shadowsEnabled = false; + bool cascadeShadowsEnabled = false; - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); + if (shadowsEnabled) { + batch.setResourceTexture(4, framebufferCache->getShadowFramebuffer()->getDepthStencilBuffer()); + + program = _directionalLightShadowMap; + locations = _directionalLightShadowMapLocations; + if (cascadeShadowsEnabled) { + program = _directionalLightCascadedShadowMap; + locations = _directionalLightCascadedShadowMapLocations; + if (useSkyboxCubemap) { + program = _directionalSkyboxLightCascadedShadowMap; + locations = _directionalSkyboxLightCascadedShadowMapLocations; + } else if (_ambientLightMode > -1) { + program = _directionalAmbientSphereLightCascadedShadowMap; + locations = _directionalAmbientSphereLightCascadedShadowMapLocations; + } + batch.setPipeline(program); + batch._glUniform3fv(locations->shadowDistances, 1, (const float*) &_viewState->getShadowDistances()); + + } else { + if (useSkyboxCubemap) { + program = _directionalSkyboxLightShadowMap; + locations = _directionalSkyboxLightShadowMapLocations; + } else if (_ambientLightMode > -1) { + program = _directionalAmbientSphereLightShadowMap; + locations = _directionalAmbientSphereLightShadowMapLocations; + } + batch.setPipeline(program); + } + batch._glUniform1f(locations->shadowScale, 1.0f / framebufferCache->getShadowFramebuffer()->getWidth()); + + } else*/ { + if (useSkyboxCubemap) { + program = _directionalSkyboxLight; + locations = _directionalSkyboxLightLocations; + } else if (_ambientLightMode > -1) { + program = _directionalAmbientSphereLight; + locations = _directionalAmbientSphereLightLocations; + } + batch.setPipeline(program); + } - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - - if (!_pointLights.empty()) { - batch.setPipeline(_pointLight); - - batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); - - for (auto lightID : _pointLights) { - auto& light = _allocatedLights[lightID]; - // IN DEBUG: light->setShowContour(true); - if (_pointLightLocations->lightBufferUnit >= 0) { - batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer()); + { // Setup the global lighting + auto globalLight = _allocatedLights[_globalLights.front()]; + + if (locations->ambientSphere >= 0) { + gpu::SphericalHarmonics sh = globalLight->getAmbientSphere(); + if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) { + sh = (*_skybox->getCubemap()->getIrradiance()); + } + for (int i =0; i ambientSphere + i, 1, (const float*) (&sh) + i * 4); + } + } + + if (useSkyboxCubemap) { + batch.setResourceTexture(5, _skybox->getCubemap()); } - float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); - // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume, - // we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working... - if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) { - Transform model; - model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f)); - batch.setModelTransform(model); - batch.setViewTransform(Transform()); - batch.setProjectionTransform(glm::mat4()); - - glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); - glm::vec2 topLeft(-1.0f, -1.0f); - glm::vec2 bottomRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(sMin, tMin); - glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight); - - DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); - - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - } else { - Transform model; - model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z)); - batch.setModelTransform(model); - geometryCache->renderSphere(batch, expandedRadius, 32, 32, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); + if (locations->lightBufferUnit >= 0) { + batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer()); + } + + if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) { + batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer()); } } - _pointLights.clear(); - } - - if (!_spotLights.empty()) { - batch.setPipeline(_spotLight); - batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); + { + Transform model; + model.setTranslation(glm::vec3(sMin, tMin, 0.0)); + model.setScale(glm::vec3(sWidth, tHeight, 1.0)); + batch.setModelTransform(model); - for (auto lightID : _spotLights) { - auto light = _allocatedLights[lightID]; - // IN DEBUG: light->setShowContour(true); + batch.setProjectionTransform(glm::mat4()); + batch.setViewTransform(Transform()); - batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer()); - - auto eyeLightPos = eyePoint - light->getPosition(); - auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection()); - - const float TANGENT_LENGTH_SCALE = 0.666f; - glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f); - - float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); - // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume, - // we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working... - if ((eyeHalfPlaneDistance > -nearRadius) && - (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) { - coneParam.w = 0.0f; - batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam)); - - Transform model; - model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f)); - batch.setModelTransform(model); - batch.setViewTransform(Transform()); - batch.setProjectionTransform(glm::mat4()); - - glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); - glm::vec2 topLeft(-1.0f, -1.0f); - glm::vec2 bottomRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(sMin, tMin); - glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight); - - DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); - - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - } else { - coneParam.w = 1.0f; - batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam)); - - Transform model; - model.setTranslation(light->getPosition()); - model.postRotate(light->getOrientation()); - model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius)); - - batch.setModelTransform(model); - auto mesh = getSpotLightMesh(); - - - batch.setIndexBuffer(mesh->getIndexBuffer()); - batch.setInputBuffer(0, mesh->getVertexBuffer()); - batch.setInputFormat(mesh->getVertexFormat()); - - auto& part = mesh->getPartBuffer().get(); - - batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex); - } + glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); + /* glm::vec2 topLeft = screenBottomLeftCorners[side]; // = glm::vec2(-1.0f, -1.0f); + glm::vec2 bottomRight = screenTopRightCorners[side]; //=(1.0f, 1.0f); + glm::vec2 texCoordTopLeft(sMin, tMin); + glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight); + */ + DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); + } + + if (useSkyboxCubemap) { + batch.setResourceTexture(5, nullptr); + } + + /* if (shadowsEnabled) { + batch.setResourceTexture(4, nullptr); + }*/ + + glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); + glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); + auto texcoordMat = glm::mat4(); + texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); + texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); + texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f); + texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + + // enlarge the scales slightly to account for tesselation + const float SCALE_EXPANSION = 0.05f; + + auto geometryCache = DependencyManager::get(); + + batch.setProjectionTransform(projMats[side]); + batch.setViewTransform(viewTransforms[side]); + + if (!_pointLights.empty()) { + batch.setPipeline(_pointLight); + + batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); + + for (auto lightID : _pointLights) { + auto& light = _allocatedLights[lightID]; + // IN DEBUG: light->setShowContour(true); + if (_pointLightLocations->lightBufferUnit >= 0) { + batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer()); + } + + float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); + // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume, + // we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working... + if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) { + Transform model; + model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f)); + batch.setModelTransform(model); + batch.setViewTransform(Transform()); + batch.setProjectionTransform(glm::mat4()); + + glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); + /* glm::vec2 topLeft(-1.0f, -1.0f); + glm::vec2 bottomRight(1.0f, 1.0f); + glm::vec2 texCoordTopLeft(sMin, tMin); + glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight); +*/ + DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); + + batch.setProjectionTransform(projMats[side]); + batch.setViewTransform(viewTransforms[side]); + } else { + Transform model; + model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z)); + batch.setModelTransform(model); + geometryCache->renderSphere(batch, expandedRadius, 32, 32, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); + } + } + // _pointLights.clear(); } - _spotLights.clear(); - } + if (!_spotLights.empty()) { + batch.setPipeline(_spotLight); + + batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); + + for (auto lightID : _spotLights) { + auto light = _allocatedLights[lightID]; + // IN DEBUG: light->setShowContour(true); + + batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer()); + + auto eyeLightPos = eyePoint - light->getPosition(); + auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection()); + + const float TANGENT_LENGTH_SCALE = 0.666f; + glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f); + + float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); + // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume, + // we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working... + if ((eyeHalfPlaneDistance > -nearRadius) && + (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) { + coneParam.w = 0.0f; + batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam)); + + Transform model; + model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f)); + batch.setModelTransform(model); + batch.setViewTransform(Transform()); + batch.setProjectionTransform(glm::mat4()); + + glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); + /* glm::vec2 topLeft(-1.0f, -1.0f); + glm::vec2 bottomRight(1.0f, 1.0f); + glm::vec2 texCoordTopLeft(sMin, tMin); + glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight); +*/ + DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); + + batch.setProjectionTransform( projMats[side]); + batch.setViewTransform(viewTransforms[side]); + } else { + coneParam.w = 1.0f; + batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam)); + + Transform model; + model.setTranslation(light->getPosition()); + model.postRotate(light->getOrientation()); + model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius)); + + batch.setModelTransform(model); + auto mesh = getSpotLightMesh(); + + batch.setIndexBuffer(mesh->getIndexBuffer()); + batch.setInputBuffer(0, mesh->getVertexBuffer()); + batch.setInputFormat(mesh->getVertexFormat()); + + auto& part = mesh->getPartBuffer().get(); + + batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex); + } + } + // _spotLights.clear(); + } + } + // Probably not necessary in the long run because the gpu layer would unbound this texture if used as render target batch.setResourceTexture(0, nullptr); batch.setResourceTexture(1, nullptr); @@ -587,6 +643,12 @@ void DeferredLightingEffect::render(RenderArgs* args) { args->_context->render(batch); // End of the Lighting pass + if (!_pointLights.empty()) { + _pointLights.clear(); + } + if (!_spotLights.empty()) { + _spotLights.clear(); + } } @@ -651,7 +713,6 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo gpu::Shader::makeProgram(*program, slotBindings); - locations->stereo = program->getUniforms().findLocation("stereoMode"); locations->shadowDistances = program->getUniforms().findLocation("shadowDistances"); locations->shadowScale = program->getUniforms().findLocation("shadowScale"); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index e8b40b06ad..de0448a51d 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -156,13 +156,13 @@ private: // Class describing the uniform buffer with all the parameters common to the deferred shaders class DeferredTransform { public: - - glm::mat4 _view; + glm::mat4 _viewInverse; float nearVal{ 1.0f }; float depthScale{ 1.0f }; - glm::vec2 spare0; // 2 spare scalars here + float isStereo{ 0.f }; + float spare0; // spare scalar here glm::vec2 depthTexCoordOffset{ 0.0f }; glm::vec2 depthTexCoordScale{ 1.0f }; @@ -170,7 +170,7 @@ private: DeferredTransform() {} }; typedef gpu::BufferView UniformBufferView; - UniformBufferView _deferredTransformBuffer; + UniformBufferView _deferredTransformBuffer[2]; }; class SimpleProgramKey { diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index 9b10bb2eea..bb485c77d8 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -21,13 +21,14 @@ in vec2 _texCoord0; out vec4 _fragColor; void main(void) { + DeferredTransform deferredTransform = getDeferredTransform(); DeferredFragment frag = unpackDeferredFragment(_texCoord0); // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { vec3 color = evalLightmappedColor( - getDeferredTransform().viewInverse, + deferredTransform.viewInverse, 1.0, frag.normal, frag.diffuse, @@ -36,7 +37,7 @@ void main(void) { _fragColor = vec4(color, 1.0); } else { vec3 color = evalAmbienSphereGlobalColor( - getDeferredTransform().viewInverse, + deferredTransform.viewInverse, 1.0, frag.position.xyz, frag.normal, @@ -46,4 +47,10 @@ void main(void) { _fragColor = vec4(color, frag.normalVal.a); } + +/* if (getStereoMode(deferredTransform)) { + float side = getStereoSide(deferredTransform); + _fragColor = vec4(-side, 0.0, side, 1.0); + } +*/ } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index a329602f82..d8949183d6 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -45,9 +45,6 @@ void main(void) { vec4 fragPos = invViewMat * frag.position; vec3 fragLightVec = getLightPosition(light) - fragPos.xyz; - _fragColor = vec4(frag.position.xyz, 0.0); - // return; - // Kill if too far from the light center if (dot(fragLightVec, fragLightVec) > getLightSquareRadius(light)) { discard; @@ -89,5 +86,11 @@ void main(void) { _fragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); } } + + + if (getStereoMode(deferredTransform)) { + float side = getStereoSide(deferredTransform); + _fragColor = vec4(-side, 0.0, side, 1.0); + } } From dc8756e4659eed24d593522bb7176fc2f4e9bc9c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 15 Sep 2015 14:40:23 -0700 Subject: [PATCH 06/11] Need to pull master, just updated all the deferred shaders to use scribe func declare blocks to avoid long shaders... didn;t validate the current clip to eye position evaluation --- libraries/render-utils/src/DeferredBuffer.slh | 11 +++ .../render-utils/src/DeferredGlobalLight.slh | 24 +++++- .../src/DeferredLightingEffect.cpp | 85 +++++++++++++------ .../render-utils/src/DeferredLightingEffect.h | 1 + libraries/render-utils/src/Shadow.slh | 3 +- .../src/directional_ambient_light.slf | 3 + ...onal_ambient_light_cascaded_shadow_map.slf | 3 + .../directional_ambient_light_shadow_map.slf | 2 + .../render-utils/src/directional_light.slf | 3 + .../directional_light_cascaded_shadow_map.slf | 3 + .../src/directional_light_shadow_map.slf | 3 + .../src/directional_skybox_light.slf | 16 +++- ...ional_skybox_light_cascaded_shadow_map.slf | 3 + .../directional_skybox_light_shadow_map.slf | 3 + libraries/render-utils/src/point_light.slf | 12 ++- libraries/render-utils/src/spot_light.slf | 6 +- 16 files changed, 149 insertions(+), 32 deletions(-) diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index 32cf064e6e..ff6cfc175e 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -27,6 +27,7 @@ uniform sampler2D depthMap; struct DeferredTransform { + mat4 projection; mat4 viewInverse; // the distance to the near clip plane @@ -54,12 +55,22 @@ float getStereoSide(DeferredTransform deferredTransform) { } vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) { + vec3 nPos = vec3(texcoord.xy * 2.0f - 1.0f, depthVal * 2.0f - 1.0f); + + float Ze = -deferredTransform.projection[3][2] / (nPos.z + deferredTransform.projection[2][2]); + float Xe = (nPos.x - Ze * deferredTransform.projection[2][0] - deferredTransform.projection[3][0]) / deferredTransform.projection[0][0]; + float Ye = (nPos.y - Ze * deferredTransform.projection[2][1] - deferredTransform.projection[3][1]) / deferredTransform.projection[1][1]; + vec2 nearVal_depthScale = deferredTransform.nearVal_depthScale_stereoMode_spare0.xy; vec2 depthTexCoordOffset = deferredTransform.depthTexCoordOffset_scale.xy; vec2 depthTexCoordScale = deferredTransform.depthTexCoordOffset_scale.zw; // compute the view space position using the depth float z = nearVal_depthScale.x / (depthVal * nearVal_depthScale.y - 1.0); + if (texcoord.x > 0.0f) { + z = Ze; + return vec4(Xe, Ye, Ze, 1.0f); + } return vec4((depthTexCoordOffset + texcoord * depthTexCoordScale) * z, z, 1.0); } diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index a04d76541c..e3ea1287d9 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -13,6 +13,8 @@ <@include DeferredLighting.slh@> +<@func declareSkyboxMap()@> + uniform samplerCube skyboxMap; vec4 evalSkyboxLight(vec3 direction, float lod) { @@ -22,6 +24,9 @@ vec4 evalSkyboxLight(vec3 direction, float lod) { return skytexel; } +<@endfunc@> + +<@func declareSphericalHarmonics()@> struct SphericalHarmonics { vec4 L00; vec4 L1m1; @@ -59,10 +64,12 @@ vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { // Need one SH uniform SphericalHarmonics ambientSphere; +<@endfunc@> + // Everything about light <@include model/Light.slh@> - +<@func declareEvalAmbientGlobalColor()@> vec3 evalAmbienGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Need the light now @@ -80,6 +87,12 @@ vec3 evalAmbienGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 positi return color; } +<@endfunc@> + +<@func declareEvalAmbientSphereGlobalColor()@> + +<$declareSphericalHarmonics()$> + vec3 evalAmbienSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Need the light now Light light = getLight(); @@ -97,6 +110,12 @@ vec3 evalAmbienSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 return color; } +<@endfunc@> + +<@func declareEvalSkyboxGlobalColor()@> + +<$declareSkyboxMap()$> +<$declareSphericalHarmonics()$> vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Need the light now @@ -114,7 +133,9 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 positi return color; } +<@endfunc@> +<@func declareEvalLightmappedColor()@> vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) { Light light = getLight(); @@ -139,5 +160,6 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, vec3 normal, return diffuse * (ambientLight + diffuseLight); } +<@endfunc@> <@endif@> diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 10da54fc75..05649d883f 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -308,8 +308,10 @@ void DeferredLightingEffect::render(RenderArgs* args) { float tMin = args->_viewport.y / (float)framebufferSize.height(); float tHeight = args->_viewport.w / (float)framebufferSize.height(); - bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); + auto monoViewport = args->_viewport; + + // The view furstum is the mono frustum base auto viewFrustum = args->_viewFrustum; float left, right, bottom, top, nearVal, farVal; @@ -322,19 +324,27 @@ void DeferredLightingEffect::render(RenderArgs* args) { float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; + // Eval the mono projection mat4 monoProjMat; viewFrustum->evalProjectionMatrix(monoProjMat); + + // The mono view transform Transform monoViewTransform; viewFrustum->evalViewTransform(monoViewTransform); + // THe mono view matrix coming from the mono view transform + glm::mat4 monoViewMat; + monoViewTransform.getMatrix(monoViewMat); + bool isStereo = args->_context->isStereo(); int numPasses = 1; mat4 projMats[2]; - Transform viewTransforms[2]; - vec4 viewports[2]; + ivec4 viewports[2]; + vec4 clipQuad[2]; vec2 screenBottomLeftCorners[2]; vec2 screenTopRightCorners[2]; + vec4 fetchTexcoordRects[2]; DeferredTransform deferredTransforms[2]; @@ -345,18 +355,25 @@ void DeferredLightingEffect::render(RenderArgs* args) { args->_context->getStereoProjections(projMats); args->_context->getStereoViews(eyeViews); - glm::mat4 monoViewMat; - monoViewTransform.getMatrix(monoViewMat); + float halfWidth = 0.5 * sWidth; for (int i = 0; i < numPasses; i++) { + // In stereo, the 2 sides are layout side by side in the mono viewport and their width is half + int sideWidth = monoViewport.z * 0.5; + viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w); auto sideViewMat = eyeViews[i] * monoViewMat; - viewTransforms[i].evalFromRawMatrix(sideViewMat); - deferredTransforms[i]._viewInverse = sideViewMat; + + projMats[i] = projMats[i] * eyeViews[i]; + + deferredTransforms[i]._projection = projMats[i]; + + deferredTransforms[i]._viewInverse = monoViewMat; + deferredTransforms[i].nearVal = nearVal; deferredTransforms[i].depthScale = depthScale; deferredTransforms[i].isStereo = (i == 0 ? -1.0f : 1.0f); @@ -364,16 +381,22 @@ void DeferredLightingEffect::render(RenderArgs* args) { deferredTransforms[i].depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT); - viewports[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); + clipQuad[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); screenBottomLeftCorners[i] = glm::vec2(-1.0f + i * 1.0f, -1.0f); screenTopRightCorners[i] = glm::vec2(i * 1.0f, 1.0f); + + fetchTexcoordRects[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); + } } else { + + viewports[0] = monoViewport; + projMats[0] = monoProjMat; - viewTransforms[0] = monoViewTransform; + deferredTransforms[0]._projection = monoProjMat; - viewTransforms[0].getMatrix(deferredTransforms[0]._viewInverse); + deferredTransforms[0]._viewInverse = monoViewMat; deferredTransforms[0].nearVal = nearVal; deferredTransforms[0].depthScale = depthScale; @@ -382,9 +405,11 @@ void DeferredLightingEffect::render(RenderArgs* args) { deferredTransforms[0].depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT); - viewports[0] = glm::vec4(sMin, tMin, sWidth, tHeight); + clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight); screenBottomLeftCorners[0] = glm::vec2(-1.0f, -1.0f); screenTopRightCorners[0] = glm::vec2(1.0f, 1.0f); + + fetchTexcoordRects[0] = glm::vec4(sMin, tMin, sWidth, tHeight); } auto eyePoint = viewFrustum->getPosition(); @@ -392,22 +417,30 @@ void DeferredLightingEffect::render(RenderArgs* args) { for (int side = 0; side < numPasses; side++) { + // Render in this side's viewport + batch.setViewportTransform(viewports[side]); + batch.setStateScissorRect(viewports[side]); + // Sync and Bind the correct DeferredTransform ubo _deferredTransformBuffer[side]._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &deferredTransforms[side]); - batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer[side]); - /* glm::vec2 topLeft(-1.0f, -1.0f); + + glm::vec2 topLeft(-1.0f, -1.0f); glm::vec2 bottomRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(sMin, tMin); + /* glm::vec2 texCoordTopLeft(sMin, tMin); glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight);*/ - glm::vec2 topLeft = screenBottomLeftCorners[side]; - glm::vec2 bottomRight = screenTopRightCorners[side]; - glm::vec2 texCoordTopLeft(viewports[side].x, viewports[side].y); - glm::vec2 texCoordBottomRight(viewports[side].x + viewports[side].z, viewports[side].y + viewports[side].w); + /* glm::vec2 topLeft = screenBottomLeftCorners[side]; + glm::vec2 bottomRight = screenTopRightCorners[side];*/ + glm::vec2 texCoordTopLeft(clipQuad[side].x, clipQuad[side].y); + glm::vec2 texCoordBottomRight(clipQuad[side].x + clipQuad[side].z, clipQuad[side].y + clipQuad[side].w); + + // First Global directional light and ambient pass + bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); + auto& program = _directionalLight; LightLocationsPtr locations = _directionalLightLocations; @@ -485,11 +518,13 @@ void DeferredLightingEffect::render(RenderArgs* args) { } { - Transform model; + /* Transform model; model.setTranslation(glm::vec3(sMin, tMin, 0.0)); model.setScale(glm::vec3(sWidth, tHeight, 1.0)); batch.setModelTransform(model); + */ + batch.setModelTransform(Transform()); batch.setProjectionTransform(glm::mat4()); batch.setViewTransform(Transform()); @@ -510,11 +545,11 @@ void DeferredLightingEffect::render(RenderArgs* args) { batch.setResourceTexture(4, nullptr); }*/ - glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); - glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); auto texcoordMat = glm::mat4(); - texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); + /* texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); + */ texcoordMat[0] = glm::vec4(fetchTexcoordRects[side].z / 2.0f, 0.0f, 0.0f, fetchTexcoordRects[side].x + fetchTexcoordRects[side].z / 2.0f); + texcoordMat[1] = glm::vec4(0.0f, fetchTexcoordRects[side].w / 2.0f, 0.0f, fetchTexcoordRects[side].y + fetchTexcoordRects[side].w / 2.0f); texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f); texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); @@ -524,7 +559,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { auto geometryCache = DependencyManager::get(); batch.setProjectionTransform(projMats[side]); - batch.setViewTransform(viewTransforms[side]); + batch.setViewTransform(monoViewTransform); if (!_pointLights.empty()) { batch.setPipeline(_pointLight); @@ -557,7 +592,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); batch.setProjectionTransform(projMats[side]); - batch.setViewTransform(viewTransforms[side]); + batch.setViewTransform(monoViewTransform); } else { Transform model; model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z)); @@ -608,7 +643,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); batch.setProjectionTransform( projMats[side]); - batch.setViewTransform(viewTransforms[side]); + batch.setViewTransform(monoViewTransform); } else { coneParam.w = 1.0f; batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam)); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index de0448a51d..db02a4e771 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -157,6 +157,7 @@ private: class DeferredTransform { public: + glm::mat4 _projection; glm::mat4 _viewInverse; float nearVal{ 1.0f }; diff --git a/libraries/render-utils/src/Shadow.slh b/libraries/render-utils/src/Shadow.slh index decb434177..525abf60b7 100755 --- a/libraries/render-utils/src/Shadow.slh +++ b/libraries/render-utils/src/Shadow.slh @@ -111,7 +111,7 @@ float evalShadowAttenuation(vec4 shadowTexcoord) { return evalShadowAttenuationBasic(shadowTexcoord); } - + <@endif@> diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index bb485c77d8..8dfd0488ac 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientSphereGlobalColor()$> + in vec2 _texCoord0; out vec4 _fragColor; diff --git a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf index ab8361e2dc..8ca272a9c3 100755 --- a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientSphereGlobalColor()$> + // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf index 1d6db7f30f..ef92e1d493 100755 --- a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf @@ -16,6 +16,8 @@ <@include DeferredBuffer.slh@> <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientSphereGlobalColor()$> // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/directional_light.slf b/libraries/render-utils/src/directional_light.slf index 5a350f77da..07ee126bd6 100644 --- a/libraries/render-utils/src/directional_light.slf +++ b/libraries/render-utils/src/directional_light.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientGlobalColor()$> + in vec2 _texCoord0; out vec4 _fragColor; diff --git a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf index d34cb08956..a580653cb0 100644 --- a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientGlobalColor()$> + // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/directional_light_shadow_map.slf b/libraries/render-utils/src/directional_light_shadow_map.slf index ab1fb4cd69..4e0f9db360 100644 --- a/libraries/render-utils/src/directional_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_shadow_map.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientGlobalColor()$> + // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/directional_skybox_light.slf b/libraries/render-utils/src/directional_skybox_light.slf index 5819e13e50..21ea28a681 100755 --- a/libraries/render-utils/src/directional_skybox_light.slf +++ b/libraries/render-utils/src/directional_skybox_light.slf @@ -3,20 +3,23 @@ // Generated on <$_SCRIBE_DATE$> // // directional_light.frag -// fragment shader + // Everything about deferred buffer <@include DeferredBuffer.slh@> <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalSkyboxGlobalColor()$> + in vec2 _texCoord0; out vec4 _fragColor; @@ -47,4 +50,13 @@ void main(void) { _fragColor = vec4(color, frag.normalVal.a); } + + // Debug Stereo + if (getStereoMode(deferredTransform)) { + float side = getStereoSide(deferredTransform); + // _fragColor = vec4(-side, 0.0, side, 1.0); + //_fragColor = vec4(_texCoord0, 0.0, 1.0); + // _fragColor = vec4(frag.position.xyz, 1.0); + + } } diff --git a/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf index 81fb37ea10..c1fe501434 100755 --- a/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalSkyboxGlobalColor()$> + // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/directional_skybox_light_shadow_map.slf b/libraries/render-utils/src/directional_skybox_light_shadow_map.slf index 70d0f75025..df3dbc64c4 100755 --- a/libraries/render-utils/src/directional_skybox_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_skybox_light_shadow_map.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalSkyboxGlobalColor()$> + // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 0731c36ea0..e2818754bb 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -26,11 +26,13 @@ in vec4 _texCoord0; out vec4 _fragColor; void main(void) { + DeferredTransform deferredTransform = getDeferredTransform(); + // Grab the fragment data from the uv vec2 texCoord = _texCoord0.st / _texCoord0.q; DeferredFragment frag = unpackDeferredFragment(texCoord); - mat4 invViewMat = getDeferredTransform().viewInverse; + mat4 invViewMat = deferredTransform.viewInverse; // Kill if in front of the light volume float depth = frag.depthVal; @@ -75,4 +77,12 @@ void main(void) { _fragColor = vec4(edgeCoord * edgeCoord * getLightShowContour(light) * getLightColor(light), 0.0); } } + + // Debug Stereo + if (getStereoMode(deferredTransform)) { + float side = getStereoSide(deferredTransform); + // _fragColor = vec4(-side, 0.0, side, 1.0); + // _fragColor = vec4(texCoord, 0.0, 1.0); + _fragColor = vec4(frag.position.xyz, 1.0); + } } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index d8949183d6..23cde97eef 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -87,10 +87,12 @@ void main(void) { } } - + // Debug Stereo if (getStereoMode(deferredTransform)) { float side = getStereoSide(deferredTransform); - _fragColor = vec4(-side, 0.0, side, 1.0); + // _fragColor = vec4(-side, 0.0, side, 1.0); + // _fragColor = vec4(texCoord, 0.0, 1.0); + _fragColor = vec4(frag.position.xyz, 1.0); } } From 7b8e11e01ce4b38002719713844f5d4970872e5f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 15 Sep 2015 15:22:45 -0700 Subject: [PATCH 07/11] Debugging, looking good, no ready for final lighting --- libraries/render-utils/src/DeferredBuffer.slh | 19 +++++-------------- libraries/render-utils/src/point_light.slf | 2 +- libraries/render-utils/src/spot_light.slf | 2 +- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index ff6cfc175e..3a1cf7a881 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -57,21 +57,12 @@ float getStereoSide(DeferredTransform deferredTransform) { vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) { vec3 nPos = vec3(texcoord.xy * 2.0f - 1.0f, depthVal * 2.0f - 1.0f); - float Ze = -deferredTransform.projection[3][2] / (nPos.z + deferredTransform.projection[2][2]); - float Xe = (nPos.x - Ze * deferredTransform.projection[2][0] - deferredTransform.projection[3][0]) / deferredTransform.projection[0][0]; - float Ye = (nPos.y - Ze * deferredTransform.projection[2][1] - deferredTransform.projection[3][1]) / deferredTransform.projection[1][1]; - - vec2 nearVal_depthScale = deferredTransform.nearVal_depthScale_stereoMode_spare0.xy; - vec2 depthTexCoordOffset = deferredTransform.depthTexCoordOffset_scale.xy; - vec2 depthTexCoordScale = deferredTransform.depthTexCoordOffset_scale.zw; - // compute the view space position using the depth - float z = nearVal_depthScale.x / (depthVal * nearVal_depthScale.y - 1.0); - if (texcoord.x > 0.0f) { - z = Ze; - return vec4(Xe, Ye, Ze, 1.0f); - } - return vec4((depthTexCoordOffset + texcoord * depthTexCoordScale) * z, z, 1.0); + // basically manually pick the proj matrix components to do the inverse + float Ze = -deferredTransform.projection[3][2] / (nPos.z + deferredTransform.projection[2][2]); + float Xe = (-Ze * nPos.x - Ze * deferredTransform.projection[2][0] - deferredTransform.projection[3][0]) / deferredTransform.projection[0][0]; + float Ye = (-Ze * nPos.y - Ze * deferredTransform.projection[2][1] - deferredTransform.projection[3][1]) / deferredTransform.projection[1][1]; + return vec4(Xe, Ye, Ze, 1.0f); } struct DeferredFragment { diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index e2818754bb..478b1982e5 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -83,6 +83,6 @@ void main(void) { float side = getStereoSide(deferredTransform); // _fragColor = vec4(-side, 0.0, side, 1.0); // _fragColor = vec4(texCoord, 0.0, 1.0); - _fragColor = vec4(frag.position.xyz, 1.0); + // _fragColor = vec4(frag.position.xyz, 1.0); } } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index 23cde97eef..46242d8e11 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -92,7 +92,7 @@ void main(void) { float side = getStereoSide(deferredTransform); // _fragColor = vec4(-side, 0.0, side, 1.0); // _fragColor = vec4(texCoord, 0.0, 1.0); - _fragColor = vec4(frag.position.xyz, 1.0); + // _fragColor = vec4(frag.position.xyz, 1.0); } } From f00e3829f1b6c6c7b1493f798f6cc7d0a7e2861c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 15 Sep 2015 16:54:04 -0700 Subject: [PATCH 08/11] Cleaning for PR --- libraries/render-utils/src/DeferredBuffer.slh | 22 +- .../src/DeferredLightingEffect.cpp | 227 +++++------------- .../render-utils/src/DeferredLightingEffect.h | 15 +- .../src/directional_ambient_light.slf | 25 +- ...onal_ambient_light_cascaded_shadow_map.slf | 24 +- .../directional_ambient_light_shadow_map.slf | 24 +- .../render-utils/src/directional_light.slf | 26 +- .../directional_light_cascaded_shadow_map.slf | 14 +- .../src/directional_light_shadow_map.slf | 27 ++- .../src/directional_skybox_light.slf | 27 +-- ...ional_skybox_light_cascaded_shadow_map.slf | 34 +-- .../directional_skybox_light_shadow_map.slf | 25 +- libraries/render-utils/src/point_light.slf | 10 +- libraries/render-utils/src/spot_light.slf | 11 +- 14 files changed, 183 insertions(+), 328 deletions(-) diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index 3a1cf7a881..e3d9593936 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -25,19 +25,11 @@ uniform sampler2D specularMap; uniform sampler2D depthMap; -struct DeferredTransform { - +struct DeferredTransform { mat4 projection; mat4 viewInverse; - // the distance to the near clip plane - // scale factor for depth: (far - near) / far - // stereoMode - vec4 nearVal_depthScale_stereoMode_spare0; - // offset for depth texture coordinates - // scale for depth texture coordinates - vec4 depthTexCoordOffset_scale; - + vec4 stereoSide_spareABC; }; layout(std140) uniform deferredTransformBuffer { @@ -48,10 +40,10 @@ DeferredTransform getDeferredTransform() { } bool getStereoMode(DeferredTransform deferredTransform) { - return (deferredTransform.nearVal_depthScale_stereoMode_spare0.z != 0.0); + return (deferredTransform.stereoSide_spareABC.x != 0.0); } float getStereoSide(DeferredTransform deferredTransform) { - return (deferredTransform.nearVal_depthScale_stereoMode_spare0.z); + return (deferredTransform.stereoSide_spareABC.x); } vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) { @@ -78,10 +70,7 @@ struct DeferredFragment { float gloss; }; -DeferredFragment unpackDeferredFragment( vec2 texcoord) { - - DeferredTransform deferredTransform = getDeferredTransform(); - +DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec2 texcoord) { DeferredFragment frag; frag.depthVal = texture(depthMap, texcoord).r; frag.normalVal = texture(normalMap, texcoord); @@ -94,7 +83,6 @@ DeferredFragment unpackDeferredFragment( vec2 texcoord) { } texcoord.x *= 2.0; } - frag.position = evalEyePositionFromZ(deferredTransform, frag.depthVal, texcoord); // Unpack the normal from the map diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 05649d883f..55fe4d9ca9 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -291,43 +291,31 @@ void DeferredLightingEffect::render(RenderArgs* args) { _copyFBO = framebufferCache->getFramebuffer(); batch.setFramebuffer(_copyFBO); + // Clearing it batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true); - + + // BInd the G-Buffer surfaces batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture()); batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture()); batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture()); batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture()); - - + // THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport) + auto monoViewport = args->_viewport; float sMin = args->_viewport.x / (float)framebufferSize.width(); float sWidth = args->_viewport.z / (float)framebufferSize.width(); float tMin = args->_viewport.y / (float)framebufferSize.height(); float tHeight = args->_viewport.w / (float)framebufferSize.height(); - auto monoViewport = args->_viewport; - - - // The view furstum is the mono frustum base + // The view frustum is the mono frustum base auto viewFrustum = args->_viewFrustum; - float left, right, bottom, top, nearVal, farVal; - glm::vec4 nearClipPlane, farClipPlane; - viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - float depthScale = (farVal - nearVal) / farVal; - float nearScale = -1.0f / nearVal; - float depthTexCoordScaleS = (right - left) * nearScale / sWidth; - float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; - float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; - float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; - // Eval the mono projection mat4 monoProjMat; viewFrustum->evalProjectionMatrix(monoProjMat); - + // The mono view transform Transform monoViewTransform; viewFrustum->evalViewTransform(monoViewTransform); @@ -336,6 +324,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { glm::mat4 monoViewMat; monoViewTransform.getMatrix(monoViewMat); + // Running in stero ? bool isStereo = args->_context->isStereo(); int numPasses = 1; @@ -347,6 +336,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { vec4 fetchTexcoordRects[2]; DeferredTransform deferredTransforms[2]; + auto geometryCache = DependencyManager::get(); if (isStereo) { numPasses = 2; @@ -355,8 +345,6 @@ void DeferredLightingEffect::render(RenderArgs* args) { args->_context->getStereoProjections(projMats); args->_context->getStereoViews(eyeViews); - - float halfWidth = 0.5 * sWidth; for (int i = 0; i < numPasses; i++) { @@ -364,47 +352,28 @@ void DeferredLightingEffect::render(RenderArgs* args) { int sideWidth = monoViewport.z * 0.5; viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w); - auto sideViewMat = eyeViews[i] * monoViewMat; - - - + // Combine the side projection with the side View offset (the view matrix is same for all side) projMats[i] = projMats[i] * eyeViews[i]; - deferredTransforms[i]._projection = projMats[i]; - - deferredTransforms[i]._viewInverse = monoViewMat; - - deferredTransforms[i].nearVal = nearVal; - deferredTransforms[i].depthScale = depthScale; - deferredTransforms[i].isStereo = (i == 0 ? -1.0f : 1.0f); - deferredTransforms[i].depthTexCoordOffset = glm::vec2(depthTexCoordOffsetS, depthTexCoordOffsetT); - deferredTransforms[i].depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT); - + deferredTransforms[i].projection = projMats[i]; + deferredTransforms[i].viewInverse = monoViewMat; + deferredTransforms[i].stereoSide = (i == 0 ? -1.0f : 1.0f); clipQuad[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); screenBottomLeftCorners[i] = glm::vec2(-1.0f + i * 1.0f, -1.0f); screenTopRightCorners[i] = glm::vec2(i * 1.0f, 1.0f); fetchTexcoordRects[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); - } } else { viewports[0] = monoViewport; - projMats[0] = monoProjMat; - deferredTransforms[0]._projection = monoProjMat; + deferredTransforms[0].projection = monoProjMat; + deferredTransforms[0].viewInverse = monoViewMat; + deferredTransforms[0].stereoSide = 0.0f; - deferredTransforms[0]._viewInverse = monoViewMat; - - deferredTransforms[0].nearVal = nearVal; - deferredTransforms[0].depthScale = depthScale; - deferredTransforms[0].isStereo = 0.0f; - deferredTransforms[0].depthTexCoordOffset = glm::vec2(depthTexCoordOffsetS, depthTexCoordOffsetT); - deferredTransforms[0].depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT); - - clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight); screenBottomLeftCorners[0] = glm::vec2(-1.0f, -1.0f); screenTopRightCorners[0] = glm::vec2(1.0f, 1.0f); @@ -425,126 +394,71 @@ void DeferredLightingEffect::render(RenderArgs* args) { _deferredTransformBuffer[side]._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &deferredTransforms[side]); batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer[side]); - - glm::vec2 topLeft(-1.0f, -1.0f); glm::vec2 bottomRight(1.0f, 1.0f); - /* glm::vec2 texCoordTopLeft(sMin, tMin); - glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight);*/ - /* glm::vec2 topLeft = screenBottomLeftCorners[side]; - glm::vec2 bottomRight = screenTopRightCorners[side];*/ glm::vec2 texCoordTopLeft(clipQuad[side].x, clipQuad[side].y); glm::vec2 texCoordBottomRight(clipQuad[side].x + clipQuad[side].z, clipQuad[side].y + clipQuad[side].w); - - // First Global directional light and ambient pass - bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); + { + bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); - auto& program = _directionalLight; - LightLocationsPtr locations = _directionalLightLocations; + auto& program = _directionalLight; + LightLocationsPtr locations = _directionalLightLocations; - // FIXME: Note: we've removed the menu items to enable shadows, so this will always be false for now. - // When we add back shadow support, this old approach may likely be removed and completely replaced - // but I've left it in for now. - /* bool shadowsEnabled = false; - bool cascadeShadowsEnabled = false; - - if (shadowsEnabled) { - batch.setResourceTexture(4, framebufferCache->getShadowFramebuffer()->getDepthStencilBuffer()); - - program = _directionalLightShadowMap; - locations = _directionalLightShadowMapLocations; - if (cascadeShadowsEnabled) { - program = _directionalLightCascadedShadowMap; - locations = _directionalLightCascadedShadowMapLocations; + // TODO: At some point bring back the shadows... + // Setup the global directional pass pipeline + { if (useSkyboxCubemap) { - program = _directionalSkyboxLightCascadedShadowMap; - locations = _directionalSkyboxLightCascadedShadowMapLocations; - } else if (_ambientLightMode > -1) { - program = _directionalAmbientSphereLightCascadedShadowMap; - locations = _directionalAmbientSphereLightCascadedShadowMapLocations; - } - batch.setPipeline(program); - batch._glUniform3fv(locations->shadowDistances, 1, (const float*) &_viewState->getShadowDistances()); - - } else { - if (useSkyboxCubemap) { - program = _directionalSkyboxLightShadowMap; - locations = _directionalSkyboxLightShadowMapLocations; - } else if (_ambientLightMode > -1) { - program = _directionalAmbientSphereLightShadowMap; - locations = _directionalAmbientSphereLightShadowMapLocations; - } - batch.setPipeline(program); - } - batch._glUniform1f(locations->shadowScale, 1.0f / framebufferCache->getShadowFramebuffer()->getWidth()); - - } else*/ { - if (useSkyboxCubemap) { program = _directionalSkyboxLight; locations = _directionalSkyboxLightLocations; - } else if (_ambientLightMode > -1) { - program = _directionalAmbientSphereLight; - locations = _directionalAmbientSphereLightLocations; - } - batch.setPipeline(program); - } - - { // Setup the global lighting - auto globalLight = _allocatedLights[_globalLights.front()]; - - if (locations->ambientSphere >= 0) { - gpu::SphericalHarmonics sh = globalLight->getAmbientSphere(); - if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) { - sh = (*_skybox->getCubemap()->getIrradiance()); + } else if (_ambientLightMode > -1) { + program = _directionalAmbientSphereLight; + locations = _directionalAmbientSphereLightLocations; } - for (int i =0; i ambientSphere + i, 1, (const float*) (&sh) + i * 4); - } - } - - if (useSkyboxCubemap) { - batch.setResourceTexture(5, _skybox->getCubemap()); + batch.setPipeline(program); } - if (locations->lightBufferUnit >= 0) { - batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer()); - } + { // Setup the global lighting + auto globalLight = _allocatedLights[_globalLights.front()]; + + if (locations->ambientSphere >= 0) { + gpu::SphericalHarmonics sh = globalLight->getAmbientSphere(); + if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) { + sh = (*_skybox->getCubemap()->getIrradiance()); + } + for (int i =0; i ambientSphere + i, 1, (const float*) (&sh) + i * 4); + } + } + + if (useSkyboxCubemap) { + batch.setResourceTexture(5, _skybox->getCubemap()); + } + + if (locations->lightBufferUnit >= 0) { + batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer()); + } - if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) { - batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer()); + if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) { + batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer()); + } + } + + { + batch.setModelTransform(Transform()); + batch.setProjectionTransform(glm::mat4()); + batch.setViewTransform(Transform()); + + glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); + geometryCache->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); + } + + if (useSkyboxCubemap) { + batch.setResourceTexture(5, nullptr); } } - { - /* Transform model; - model.setTranslation(glm::vec3(sMin, tMin, 0.0)); - model.setScale(glm::vec3(sWidth, tHeight, 1.0)); - batch.setModelTransform(model); - */ - - batch.setModelTransform(Transform()); - batch.setProjectionTransform(glm::mat4()); - batch.setViewTransform(Transform()); - - glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); - /* glm::vec2 topLeft = screenBottomLeftCorners[side]; // = glm::vec2(-1.0f, -1.0f); - glm::vec2 bottomRight = screenTopRightCorners[side]; //=(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(sMin, tMin); - glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight); - */ - DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); - } - - if (useSkyboxCubemap) { - batch.setResourceTexture(5, nullptr); - } - - /* if (shadowsEnabled) { - batch.setResourceTexture(4, nullptr); - }*/ - auto texcoordMat = glm::mat4(); /* texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); @@ -556,11 +470,11 @@ void DeferredLightingEffect::render(RenderArgs* args) { // enlarge the scales slightly to account for tesselation const float SCALE_EXPANSION = 0.05f; - auto geometryCache = DependencyManager::get(); batch.setProjectionTransform(projMats[side]); batch.setViewTransform(monoViewTransform); + // Splat Point lights if (!_pointLights.empty()) { batch.setPipeline(_pointLight); @@ -584,11 +498,6 @@ void DeferredLightingEffect::render(RenderArgs* args) { batch.setProjectionTransform(glm::mat4()); glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); - /* glm::vec2 topLeft(-1.0f, -1.0f); - glm::vec2 bottomRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(sMin, tMin); - glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight); -*/ DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); batch.setProjectionTransform(projMats[side]); @@ -600,9 +509,9 @@ void DeferredLightingEffect::render(RenderArgs* args) { geometryCache->renderSphere(batch, expandedRadius, 32, 32, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); } } - // _pointLights.clear(); } + // Splat spot lights if (!_spotLights.empty()) { batch.setPipeline(_spotLight); @@ -635,11 +544,6 @@ void DeferredLightingEffect::render(RenderArgs* args) { batch.setProjectionTransform(glm::mat4()); glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); - /* glm::vec2 topLeft(-1.0f, -1.0f); - glm::vec2 bottomRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(sMin, tMin); - glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight); -*/ DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); batch.setProjectionTransform( projMats[side]); @@ -665,7 +569,6 @@ void DeferredLightingEffect::render(RenderArgs* args) { batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex); } } - // _spotLights.clear(); } } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index db02a4e771..ea6f2f0ce0 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -156,17 +156,10 @@ private: // Class describing the uniform buffer with all the parameters common to the deferred shaders class DeferredTransform { public: - - glm::mat4 _projection; - glm::mat4 _viewInverse; - - float nearVal{ 1.0f }; - float depthScale{ 1.0f }; - float isStereo{ 0.f }; - float spare0; // spare scalar here - glm::vec2 depthTexCoordOffset{ 0.0f }; - glm::vec2 depthTexCoordScale{ 1.0f }; - + glm::mat4 projection; + glm::mat4 viewInverse; + float stereoSide{ 0.f }; + float spareA, spareB, spareC; DeferredTransform() {} }; diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index 8dfd0488ac..52ecc71a14 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -25,8 +25,7 @@ out vec4 _fragColor; void main(void) { DeferredTransform deferredTransform = getDeferredTransform(); - DeferredFragment frag = unpackDeferredFragment(_texCoord0); - + DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { @@ -36,24 +35,16 @@ void main(void) { frag.normal, frag.diffuse, frag.specularVal.xyz); - _fragColor = vec4(color, 1.0); } else { vec3 color = evalAmbienSphereGlobalColor( - deferredTransform.viewInverse, - 1.0, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); - + deferredTransform.viewInverse, + 1.0, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); _fragColor = vec4(color, frag.normalVal.a); } - -/* if (getStereoMode(deferredTransform)) { - float side = getStereoSide(deferredTransform); - _fragColor = vec4(-side, 0.0, side, 1.0); - } -*/ } diff --git a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf index 8ca272a9c3..8b0212636e 100755 --- a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf @@ -27,7 +27,8 @@ in vec2 _texCoord0; out vec4 _fragColor; void main(void) { - DeferredFragment frag = unpackDeferredFragment(_texCoord0); + DeferredTransform deferredTransform = getDeferredTransform(); + DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); // Eval shadow Texcoord and then Attenuation vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position); @@ -35,23 +36,22 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - _fragColor = vec4(evalLightmappedColor( - getDeferredTransform().viewInverse, + vec3 color = evalLightmappedColor( + deferredTransform.viewInverse, shadowAttenuation, frag.normal, frag.diffuse, - frag.specularVal.xyz), - 1.0); + frag.specularVal.xyz); + _fragColor = vec4(color, 1.0); } else { vec3 color = evalAmbienSphereGlobalColor( - getDeferredTransform().viewInverse, + deferredTransform.viewInverse, shadowAttenuation, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); - + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); _fragColor = vec4(color, frag.normalVal.a); } } diff --git a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf index ef92e1d493..2dee8bf9b9 100755 --- a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf @@ -26,7 +26,8 @@ in vec2 _texCoord0; out vec4 _fragColor; void main(void) { - DeferredFragment frag = unpackDeferredFragment(_texCoord0); + DeferredTransform deferredTransform = getDeferredTransform(); + DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); // Eval shadow Texcoord and then Attenuation vec4 shadowTexcoord = evalShadowTexcoord(frag.position); @@ -34,23 +35,22 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - _fragColor = vec4(evalLightmappedColor( - getDeferredTransform().viewInverse, + vec3 color = evalLightmappedColor( + deferredTransform.viewInverse, shadowAttenuation, frag.normal, frag.diffuse, - frag.specularVal.xyz), - 1.0); + frag.specularVal.xyz); + _fragColor = vec4(color, 1.0); } else { vec3 color = evalAmbienSphereGlobalColor( - getDeferredTransform().viewInverse, + deferredTransform.viewInverse, shadowAttenuation, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); - + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); _fragColor = vec4(color, frag.normalVal.a); } } diff --git a/libraries/render-utils/src/directional_light.slf b/libraries/render-utils/src/directional_light.slf index 07ee126bd6..22b0157762 100644 --- a/libraries/render-utils/src/directional_light.slf +++ b/libraries/render-utils/src/directional_light.slf @@ -24,27 +24,27 @@ in vec2 _texCoord0; out vec4 _fragColor; void main(void) { - DeferredFragment frag = unpackDeferredFragment(_texCoord0); + DeferredTransform deferredTransform = getDeferredTransform(); + DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - _fragColor = vec4( evalLightmappedColor( - getDeferredTransform().viewInverse, + vec3 color = evalLightmappedColor( + deferredTransform.viewInverse, 1.0, frag.normal, frag.diffuse, - frag.specularVal.xyz), - 1.0); + frag.specularVal.xyz); + _fragColor = vec4(color, 1.0); } else { vec3 color = evalAmbienGlobalColor( - getDeferredTransform().viewInverse, - 1.0, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); - + deferredTransform.viewInverse, + 1.0, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); _fragColor = vec4(color, frag.normalVal.a); } } diff --git a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf index a580653cb0..4abe8e2e9d 100644 --- a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf @@ -27,7 +27,9 @@ in vec2 _texCoord0; out vec4 _fragColor; void main(void) { - DeferredFragment frag = unpackDeferredFragment(_texCoord0); + DeferredTransform deferredTransform = getDeferredTransform(); + DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); + // Eval shadow Texcoord and then Attenuation vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position); @@ -35,16 +37,16 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - _fragColor = vec4(evalLightmappedColor( - getDeferredTransform().viewInverse, + vec3 color = evalLightmappedColor( + deferredTransform.viewInverse, shadowAttenuation, frag.normal, frag.diffuse, - frag.specularVal.xyz), - 1.0); + frag.specularVal.xyz); + _fragColor = vec4(color, 1.0); } else { vec3 color = evalAmbienGlobalColor( - getDeferredTransform().viewInverse, + deferredTransform.viewInverse, shadowAttenuation, frag.position.xyz, frag.normal, diff --git a/libraries/render-utils/src/directional_light_shadow_map.slf b/libraries/render-utils/src/directional_light_shadow_map.slf index 4e0f9db360..b3362a2040 100644 --- a/libraries/render-utils/src/directional_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_shadow_map.slf @@ -27,7 +27,8 @@ in vec2 _texCoord0; out vec4 _fragColor; void main(void) { - DeferredFragment frag = unpackDeferredFragment(_texCoord0); + DeferredTransform deferredTransform = getDeferredTransform(); + DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); // Eval shadow Texcoord and then Attenuation vec4 shadowTexcoord = evalShadowTexcoord(frag.position); @@ -35,22 +36,22 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - _fragColor = vec4(evalLightmappedColor( - getDeferredTransform().viewInverse, + vec3 color = evalLightmappedColor( + deferredTransform.viewInverse, shadowAttenuation, frag.normal, frag.diffuse, - frag.specularVal.xyz), - 1.0); + frag.specularVal.xyz); + _fragColor = vec4(color, 1.0); } else { - vec3 color = evalAmbienGlobalColor( - getDeferredTransform().viewInverse, - shadowAttenuation, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); + vec3 color = evalAmbienGlobalColor( + deferredTransform.viewInverse, + shadowAttenuation, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); _fragColor = vec4(color, frag.normalVal.a); } diff --git a/libraries/render-utils/src/directional_skybox_light.slf b/libraries/render-utils/src/directional_skybox_light.slf index 21ea28a681..ca3efef047 100755 --- a/libraries/render-utils/src/directional_skybox_light.slf +++ b/libraries/render-utils/src/directional_skybox_light.slf @@ -25,8 +25,7 @@ out vec4 _fragColor; void main(void) { DeferredTransform deferredTransform = getDeferredTransform(); - DeferredFragment frag = unpackDeferredFragment(_texCoord0); - + DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { @@ -36,27 +35,17 @@ void main(void) { frag.normal, frag.diffuse, frag.specularVal.xyz); - _fragColor = vec4(color, 1.0); } else { vec3 color = evalSkyboxGlobalColor( - deferredTransform.viewInverse, - 1.0, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); + deferredTransform.viewInverse, + 1.0, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); _fragColor = vec4(color, frag.normalVal.a); } - - // Debug Stereo - if (getStereoMode(deferredTransform)) { - float side = getStereoSide(deferredTransform); - // _fragColor = vec4(-side, 0.0, side, 1.0); - //_fragColor = vec4(_texCoord0, 0.0, 1.0); - // _fragColor = vec4(frag.position.xyz, 1.0); - - } } diff --git a/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf index c1fe501434..3c09bf62b6 100755 --- a/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf @@ -27,7 +27,8 @@ in vec2 _texCoord0; out vec4 _fragColor; void main(void) { - DeferredFragment frag = unpackDeferredFragment(_texCoord0); + DeferredTransform deferredTransform = getDeferredTransform(); + DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); // Eval shadow Texcoord and then Attenuation vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position); @@ -35,22 +36,23 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - _fragColor = vec4(evalLightmappedColor( - getDeferredTransform().viewInverse, - shadowAttenuation, - frag.normal, - frag.diffuse, - frag.specularVal.xyz), - 1.0); + vec3 color = evalLightmappedColor( + deferredTransform.viewInverse, + shadowAttenuation, + frag.normal, + frag.diffuse, + frag.specularVal.xyz); + + _fragColor = vec4(color, 1.0); } else { - vec3 color = evalSkyboxGlobalColor( - getDeferredTransform().viewInverse, - shadowAttenuation, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); + vec3 color = evalSkyboxGlobalColor( + deferredTransform.viewInverse, + shadowAttenuation, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); _fragColor = vec4(color, frag.normalVal.a); } diff --git a/libraries/render-utils/src/directional_skybox_light_shadow_map.slf b/libraries/render-utils/src/directional_skybox_light_shadow_map.slf index df3dbc64c4..632270476b 100755 --- a/libraries/render-utils/src/directional_skybox_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_skybox_light_shadow_map.slf @@ -27,7 +27,8 @@ in vec2 _texCoord0; out vec4 _fragColor; void main(void) { - DeferredFragment frag = unpackDeferredFragment(_texCoord0); + DeferredTransform deferredTransform = getDeferredTransform(); + DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); // Eval shadow Texcoord and then Attenuation vec4 shadowTexcoord = evalShadowTexcoord(frag.position); @@ -35,22 +36,22 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - _fragColor = vec4(evalLightmappedColor( - getDeferredTransform().viewInverse, + vec3 color = evalLightmappedColor( + deferredTransform.viewInverse, shadowAttenuation, frag.normal, frag.diffuse, - frag.specularVal.xyz), - 1.0); + frag.specularVal.xyz); + _fragColor = vec4(color, 1.0); } else { vec3 color = evalSkyboxGlobalColor( - getDeferredTransform().viewInverse, - shadowAttenuation, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); + deferredTransform.viewInverse, + shadowAttenuation, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); _fragColor = vec4(color, frag.normalVal.a); } diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 478b1982e5..e9045e18c5 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -30,7 +30,7 @@ void main(void) { // Grab the fragment data from the uv vec2 texCoord = _texCoord0.st / _texCoord0.q; - DeferredFragment frag = unpackDeferredFragment(texCoord); + DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord); mat4 invViewMat = deferredTransform.viewInverse; @@ -77,12 +77,4 @@ void main(void) { _fragColor = vec4(edgeCoord * edgeCoord * getLightShowContour(light) * getLightColor(light), 0.0); } } - - // Debug Stereo - if (getStereoMode(deferredTransform)) { - float side = getStereoSide(deferredTransform); - // _fragColor = vec4(-side, 0.0, side, 1.0); - // _fragColor = vec4(texCoord, 0.0, 1.0); - // _fragColor = vec4(frag.position.xyz, 1.0); - } } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index 46242d8e11..73b081260e 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -26,9 +26,10 @@ out vec4 _fragColor; void main(void) { DeferredTransform deferredTransform = getDeferredTransform(); + // Grab the fragment data from the uv vec2 texCoord = _texCoord0.st / _texCoord0.q; - DeferredFragment frag = unpackDeferredFragment(texCoord); + DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord); mat4 invViewMat = deferredTransform.viewInverse; @@ -86,13 +87,5 @@ void main(void) { _fragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); } } - - // Debug Stereo - if (getStereoMode(deferredTransform)) { - float side = getStereoSide(deferredTransform); - // _fragColor = vec4(-side, 0.0, side, 1.0); - // _fragColor = vec4(texCoord, 0.0, 1.0); - // _fragColor = vec4(frag.position.xyz, 1.0); - } } From 8ab96fe9072a4884ff243c0ad68e2a0bbfbc376f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 15 Sep 2015 17:02:30 -0700 Subject: [PATCH 09/11] Bringin back full screen for stereo mode --- .../src/display-plugins/stereo/StereoDisplayPlugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index d8b20ffdc0..ae3c1f29e2 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -73,14 +73,14 @@ void StereoDisplayPlugin::activate() { [this](bool clicked) { updateScreen(); }, true, checked, "Screens"); _screenActions[i] = action; } - // CONTAINER->setFullscreen(qApp->primaryScreen()); + CONTAINER->setFullscreen(qApp->primaryScreen()); WindowOpenGLDisplayPlugin::activate(); } void StereoDisplayPlugin::updateScreen() { for (uint32_t i = 0; i < _screenActions.size(); ++i) { if (_screenActions[i]->isChecked()) { - // CONTAINER->setFullscreen(qApp->screens().at(i)); + CONTAINER->setFullscreen(qApp->screens().at(i)); break; } } From 5410bc0945145772d9101cc4fbc45d89ad2d2d36 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 15 Sep 2015 17:48:55 -0700 Subject: [PATCH 10/11] FIx the review comment and trying to fix the simple stereo display plugin projection and eye view matrix --- .../stereo/StereoDisplayPlugin.cpp | 29 ++++++++++++------- libraries/render-utils/src/DeferredBuffer.slh | 2 +- .../src/DeferredLightingEffect.cpp | 2 +- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index ae3c1f29e2..77906d1857 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -29,33 +29,40 @@ bool StereoDisplayPlugin::isSupported() const { // FIXME make this into a setting that can be adjusted const float DEFAULT_IPD = 0.064f; -const float HALF_DEFAULT_IPD = DEFAULT_IPD / 2.0f; + +// Default physical display width (50cm) +const float DEFAULT_SCREEN_WIDTH = 0.5f; + +// Default separation = ipd / screenWidth +const float DEFAULT_SEPARATION = DEFAULT_IPD / DEFAULT_SCREEN_WIDTH; + +// Default convergence depth: where is the screen plane in the virtual space (which depth) +const float DEFAULT_CONVERGENCE = 0.5f; glm::mat4 StereoDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseProjection) const { // Refer to http://www.nvidia.com/content/gtc-2010/pdfs/2010_gtc2010.pdf on creating // stereo projection matrices. Do NOT use "toe-in", use translation. + // Updated version: http://developer.download.nvidia.com/assets/gamedev/docs/Siggraph2011-Stereoscopy_From_XY_to_Z-SG.pdf if (eye == Mono) { // FIXME provide a combined matrix, needed for proper culling return baseProjection; } - float nearZ = DEFAULT_NEAR_CLIP; // near clipping plane - float screenZ = 0.25f; // screen projection plane - // FIXME verify this is the right calculation - float frustumshift = HALF_DEFAULT_IPD * nearZ / screenZ; + float frustumshift = DEFAULT_SEPARATION; if (eye == Right) { frustumshift = -frustumshift; } - return glm::translate(baseProjection, vec3(frustumshift, 0, 0)); + + + auto eyeProjection = baseProjection; + eyeProjection[2][0] += frustumshift; + eyeProjection[3][0] += frustumshift * DEFAULT_CONVERGENCE; // include the eye offset here + return eyeProjection; } glm::mat4 StereoDisplayPlugin::getEyePose(Eye eye) const { - float modelviewShift = HALF_DEFAULT_IPD; - if (eye == Left) { - modelviewShift = -modelviewShift; - } - return glm::translate(mat4(), vec3(modelviewShift, 0, 0)); + return mat4(); } std::vector _screenActions; diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index e3d9593936..89b8b26a4f 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -40,7 +40,7 @@ DeferredTransform getDeferredTransform() { } bool getStereoMode(DeferredTransform deferredTransform) { - return (deferredTransform.stereoSide_spareABC.x != 0.0); + return (deferredTransform.stereoSide_spareABC.x != 0.0); } float getStereoSide(DeferredTransform deferredTransform) { return (deferredTransform.stereoSide_spareABC.x); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 55fe4d9ca9..213ce8eed5 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -349,7 +349,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { for (int i = 0; i < numPasses; i++) { // In stereo, the 2 sides are layout side by side in the mono viewport and their width is half - int sideWidth = monoViewport.z * 0.5; + int sideWidth = monoViewport.z >> 1; viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w); // Combine the side projection with the side View offset (the view matrix is same for all side) From 80d25a68b639b1d93867635f642ab90b53b6228d Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 15 Sep 2015 18:05:15 -0700 Subject: [PATCH 11/11] Bringing back the eyeView per side to the deferred transform stack --- .../render-utils/src/DeferredLightingEffect.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 213ce8eed5..0ec8b4ad24 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -329,6 +329,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { int numPasses = 1; mat4 projMats[2]; + Transform viewTransforms[2]; ivec4 viewports[2]; vec4 clipQuad[2]; vec2 screenBottomLeftCorners[2]; @@ -352,11 +353,12 @@ void DeferredLightingEffect::render(RenderArgs* args) { int sideWidth = monoViewport.z >> 1; viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w); - // Combine the side projection with the side View offset (the view matrix is same for all side) - projMats[i] = projMats[i] * eyeViews[i]; - deferredTransforms[i].projection = projMats[i]; - deferredTransforms[i].viewInverse = monoViewMat; + + auto sideViewMat = eyeViews[i] * monoViewMat; + viewTransforms[i].evalFromRawMatrix(sideViewMat); + deferredTransforms[i].viewInverse = sideViewMat; + deferredTransforms[i].stereoSide = (i == 0 ? -1.0f : 1.0f); clipQuad[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); @@ -472,7 +474,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { batch.setProjectionTransform(projMats[side]); - batch.setViewTransform(monoViewTransform); + batch.setViewTransform(viewTransforms[side]); // Splat Point lights if (!_pointLights.empty()) { @@ -501,7 +503,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); batch.setProjectionTransform(projMats[side]); - batch.setViewTransform(monoViewTransform); + batch.setViewTransform(viewTransforms[side]); } else { Transform model; model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z)); @@ -547,7 +549,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); batch.setProjectionTransform( projMats[side]); - batch.setViewTransform(monoViewTransform); + batch.setViewTransform(viewTransforms[side]); } else { coneParam.w = 1.0f; batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));