From 4559e75f90bd2d1f70fa05f9523fc6fa8f0bfbef Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 12 Feb 2016 18:22:01 -0800 Subject: [PATCH 1/6] Trying to solve the ambient issue --- libraries/model/src/model/Light.cpp | 7 ++- libraries/model/src/model/Light.h | 11 +++-- libraries/model/src/model/Light.slh | 42 +++++++++++++++++ .../render-utils/src/DeferredGlobalLight.slh | 47 +------------------ .../src/DeferredLightingEffect.cpp | 32 +++++++++++-- .../render-utils/src/DeferredLightingEffect.h | 2 +- .../render-utils/src/RenderPipelines.cpp | 4 +- 7 files changed, 89 insertions(+), 56 deletions(-) diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index 917e3bed7e..7ab8b77f5e 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -116,5 +116,10 @@ void Light::setShowContour(float show) { editSchema()._control.w = show; } +void Light::setAmbientSphere(const gpu::SphericalHarmonics& sphere) { + editSchema()._ambientSphere = sphere; +} - +void Light::setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) { + editSchema()._ambientSphere.assignPreset(preset); +} diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index de7a846a25..96bf7fc427 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -94,10 +94,10 @@ public: void setAmbientIntensity(float intensity); float getAmbientIntensity() const { return getSchema()._ambientIntensity; } - // Spherical Harmonics storing the Ambien lighting approximation used for the Sun typed light - void setAmbientSphere(const gpu::SphericalHarmonics& sphere) { _ambientSphere = sphere; } - const gpu::SphericalHarmonics& getAmbientSphere() const { return _ambientSphere; } - void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) { _ambientSphere.assignPreset(preset); } + // Spherical Harmonics storing the Ambient lighting approximation used for the Sun typed light + void setAmbientSphere(const gpu::SphericalHarmonics& sphere); + const gpu::SphericalHarmonics& getAmbientSphere() const { return getSchema()._ambientSphere; } + void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset); // Schema to access the attribute values of the light class Schema { @@ -112,6 +112,8 @@ public: Vec4 _shadow{0.0f}; Vec4 _control{0.0f, 0.0f, 0.0f, 0.0f}; + + gpu::SphericalHarmonics _ambientSphere; }; const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; } @@ -121,7 +123,6 @@ protected: Flags _flags; UniformBufferView _schemaBuffer; Transform _transform; - gpu::SphericalHarmonics _ambientSphere; const Schema& getSchema() const { return _schemaBuffer.get(); } Schema& editSchema() { return _schemaBuffer.edit(); } diff --git a/libraries/model/src/model/Light.slh b/libraries/model/src/model/Light.slh index 708e092a0a..707e754080 100644 --- a/libraries/model/src/model/Light.slh +++ b/libraries/model/src/model/Light.slh @@ -11,6 +11,42 @@ <@if not MODEL_LIGHT_SLH@> <@def MODEL_LIGHT_SLH@> +struct SphericalHarmonics { + vec4 L00; + vec4 L1m1; + vec4 L10; + vec4 L11; + vec4 L2m2; + vec4 L2m1; + vec4 L20; + vec4 L21; + vec4 L22; +}; + +vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { + + /vec3 dir = direction.xyz; // we don;t understand why yet but we need to use z as vertical axis? + vec3 dir = direction.xyz; // we don;t understand why yet but we need to use z as vertical axis? + + const float C1 = 0.429043; + const float C2 = 0.511664; + const float C3 = 0.743125; + const float C4 = 0.886227; + const float C5 = 0.247708; + + vec4 value = C1 * sh.L22 * (dir.x * dir.x - dir.y * dir.y) + + C3 * sh.L20 * dir.z * dir.z + + C4 * sh.L00 - C5 * sh.L20 + + 2.0 * C1 * ( sh.L2m2 * dir.x * dir.y + + sh.L21 * dir.x * dir.z + + sh.L2m1 * dir.y * dir.z ) + + 2.0 * C2 * ( sh.L11 * dir.x + + sh.L1m1 * dir.y + + sh.L10 * dir.z ) ; + return value; +} + + struct Light { vec4 _position; vec4 _direction; @@ -20,6 +56,8 @@ struct Light { vec4 _shadow; vec4 _control; + + SphericalHarmonics _ambientSphere; }; vec3 getLightPosition(Light l) { return l._position.xyz; } @@ -65,6 +103,10 @@ float getLightShowContour(Light l) { return l._control.w; } +SphericalHarmonics getLightAmbientSphere(Light l) { + return l._ambientSphere; +} + <@if GPU_FEATURE_PROFILE == GPU_CORE @> uniform lightBuffer { Light light; diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 75fe187e46..71c533de24 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -26,46 +26,6 @@ vec4 evalSkyboxLight(vec3 direction, float lod) { <@endfunc@> -<@func declareSphericalHarmonics()@> -struct SphericalHarmonics { - vec4 L00; - vec4 L1m1; - vec4 L10; - vec4 L11; - vec4 L2m2; - vec4 L2m1; - vec4 L20; - vec4 L21; - vec4 L22; -}; - -vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { - - vec3 dir = direction.xzy; // we don;t understand why yet but we need to use z as vertical axis? - - const float C1 = 0.429043; - const float C2 = 0.511664; - const float C3 = 0.743125; - const float C4 = 0.886227; - const float C5 = 0.247708; - - vec4 value = C1 * sh.L22 * (dir.x * dir.x - dir.y * dir.y) + - C3 * sh.L20 * dir.z * dir.z + - C4 * sh.L00 - C5 * sh.L20 + - 2.0 * C1 * ( sh.L2m2 * dir.x * dir.y + - sh.L21 * dir.x * dir.z + - sh.L2m1 * dir.y * dir.z ) + - 2.0 * C2 * ( sh.L11 * dir.x + - sh.L1m1 * dir.y + - sh.L10 * dir.z ) ; - return value; -} - -// Need one SH -uniform SphericalHarmonics ambientSphere; - -<@endfunc@> - // Everything about light <@include model/Light.slh@> @@ -91,8 +51,6 @@ vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obsc <@func declareEvalAmbientSphereGlobalColor()@> -<$declareSphericalHarmonics()$> - vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Need the light now Light light = getLight(); @@ -102,7 +60,7 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa vec3 fragEyeDir = normalize(fragEyeVector.xyz); vec3 ambientNormal = fragNormal.xyz; - vec3 color = diffuse.rgb * evalSphericalLight(ambientSphere, ambientNormal).xyz * obscurance * getLightAmbientIntensity(light); + vec3 color = diffuse.rgb * evalSphericalLight(getLightAmbientSphere(light), ambientNormal).xyz * obscurance * getLightAmbientIntensity(light); vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); @@ -115,7 +73,6 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa <@func declareEvalSkyboxGlobalColor()@> <$declareSkyboxMap()$> -<$declareSphericalHarmonics()$> vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Need the light now @@ -125,7 +82,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - vec3 color = diffuse.rgb * evalSphericalLight(ambientSphere, fragNormal).xyz * obscurance * getLightAmbientIntensity(light); + vec3 color = diffuse.rgb * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light); vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 003c309740..b82dd81e68 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -343,6 +343,8 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo } { // Setup the global lighting + setupKeyLightBatch(batch, locations->lightBufferUnit, SKYBOX_MAP_UNIT); + /* auto globalLight = _allocatedLights[_globalLights.front()]; if (locations->ambientSphere >= 0) { @@ -361,7 +363,7 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo if (locations->lightBufferUnit >= 0) { batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer()); - } + }*/ } @@ -511,10 +513,29 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo } } -void DeferredLightingEffect::setupBatch(gpu::Batch& batch, int lightBufferUnit) { +void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int skyboxCubemapUnit) { PerformanceTimer perfTimer("DLE->setupBatch()"); auto globalLight = _allocatedLights[_globalLights.front()]; - batch.setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer()); + + if (lightBufferUnit >= 0) { + batch.setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer()); + } + + bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); + + /* if (ambientSphereBufferUnit >= 0) { + gpu::SphericalHarmonics sh = globalLight->getAmbientSphere(); + if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) { + sh = (*_skybox->getCubemap()->getIrradiance()); + } + for (int i =0; i = 0)) { + batch.setResourceTexture(skyboxCubemapUnit, _skybox->getCubemap()); + } } static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) { @@ -593,6 +614,11 @@ void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const gl void DeferredLightingEffect::setGlobalSkybox(const model::SkyboxPointer& skybox) { _skybox = skybox; + auto light = _allocatedLights.front(); + + if (_skybox && _skybox->getCubemap() && _skybox->getCubemap()->isDefined() && _skybox->getCubemap()->getIrradiance()) { + light->setAmbientSphere( (*_skybox->getCubemap()->getIrradiance()) ); + } } model::MeshPointer DeferredLightingEffect::getSpotLightMesh() { diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 6ef5794d95..8cb4bbba8f 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -46,7 +46,7 @@ public: void prepare(RenderArgs* args); void render(const render::RenderContextPointer& renderContext); - void setupBatch(gpu::Batch& batch, int lightBufferUnit); + void setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int skyboxCubemapUnit); // update global lighting void setAmbientLightMode(int preset); diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index fce9ce1c28..0954c7ef83 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -96,7 +96,9 @@ void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) { batchSetter(pipeline, batch); // Set the light if (pipeline.locations->lightBufferUnit >= 0) { - DependencyManager::get()->setupBatch(batch, pipeline.locations->lightBufferUnit); + DependencyManager::get()->setupKeyLightBatch(batch, + pipeline.locations->lightBufferUnit, + -1); } } From 0a6ceb67adf2d2cd156ca5e32400d939421c65ed Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 15 Feb 2016 12:01:28 -0800 Subject: [PATCH 2/6] Fixing a typo --- libraries/model/src/model/Light.slh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model/src/model/Light.slh b/libraries/model/src/model/Light.slh index 707e754080..4a95b55bed 100644 --- a/libraries/model/src/model/Light.slh +++ b/libraries/model/src/model/Light.slh @@ -25,7 +25,7 @@ struct SphericalHarmonics { vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { - /vec3 dir = direction.xyz; // we don;t understand why yet but we need to use z as vertical axis? + vec3 dir = direction.xyz; // we don;t understand why yet but we need to use z as vertical axis? vec3 dir = direction.xyz; // we don;t understand why yet but we need to use z as vertical axis? const float C1 = 0.429043; From e149daa49be0ce06d87847a292fe553c73c7cf9b Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 15 Feb 2016 13:27:28 -0800 Subject: [PATCH 3/6] Cleaning the Light.slh --- libraries/model/src/model/Light.slh | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/model/src/model/Light.slh b/libraries/model/src/model/Light.slh index 4a95b55bed..d743da81b7 100644 --- a/libraries/model/src/model/Light.slh +++ b/libraries/model/src/model/Light.slh @@ -26,7 +26,6 @@ struct SphericalHarmonics { vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { vec3 dir = direction.xyz; // we don;t understand why yet but we need to use z as vertical axis? - vec3 dir = direction.xyz; // we don;t understand why yet but we need to use z as vertical axis? const float C1 = 0.429043; const float C2 = 0.511664; From b9d14b74ee26f055b9a4953eefbe800f9c900f26 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 15 Feb 2016 17:27:28 -0800 Subject: [PATCH 4/6] Adding the GLobalKeyLighting to transparents, the ambient lighting --- .../render-utils/src/model_translucent.slf | 33 ++++++------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/libraries/render-utils/src/model_translucent.slf b/libraries/render-utils/src/model_translucent.slf index c6f745ed0f..481cb942b3 100755 --- a/libraries/render-utils/src/model_translucent.slf +++ b/libraries/render-utils/src/model_translucent.slf @@ -5,7 +5,7 @@ // model_translucent.frag // fragment shader // -// Created by Andrzej Kapolka on 9/19/14. +// Created by Sam Gateau on 2/15/2016. // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -14,31 +14,13 @@ <@include model/Material.slh@> -<@include DeferredLighting.slh@> -<@include model/Light.slh@> +<@include DeferredGlobalLight.slh@> +<$declareEvalAmbientSphereGlobalColor()$> <@include gpu/Transform.slh@> <$declareStandardCameraTransform()$> -vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss, float opacity) { - // Need the light now - Light light = getLight(); - TransformCamera cam = getTransformCamera(); - vec3 fragNormal; - <$transformEyeToWorldDir(cam, normal, fragNormal)$> - vec3 fragEyeVectorView = normalize(-position); - vec3 fragEyeDir; - <$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$> - - vec3 color = opacity * diffuse.rgb * getLightColor(light) * getLightAmbientIntensity(light); - - vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); - - color += vec3(diffuse * shading.w * opacity + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light); - - return vec4(color, opacity); -} uniform sampler2D diffuseMap; @@ -61,11 +43,16 @@ void main(void) { float fragGloss = getMaterialShininess(mat) / 128; float fragOpacity = getMaterialOpacity(mat) * diffuse.a * _alpha; - _fragColor = evalGlobalColor(1.0, + TransformCamera cam = getTransformCamera(); + + _fragColor = vec4(evalAmbientSphereGlobalColor( + cam._viewInverse, + 1.0, + 1.0, fragPosition, fragNormal, fragDiffuse, fragSpecular, - fragGloss, + fragGloss), fragOpacity); } From a740f4a6de14dc02b0a9c688c6f59eae5f0741e1 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 15 Feb 2016 17:41:20 -0800 Subject: [PATCH 5/6] Removing unecessary code --- .../src/DeferredLightingEffect.cpp | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 7abf801436..e39c3f5de2 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -345,27 +345,6 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo { // Setup the global lighting setupKeyLightBatch(batch, locations->lightBufferUnit, SKYBOX_MAP_UNIT); - /* - 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(SKYBOX_MAP_UNIT, _skybox->getCubemap()); - } - - if (locations->lightBufferUnit >= 0) { - batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer()); - }*/ - } { @@ -523,17 +502,6 @@ void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBuff } bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); - - /* if (ambientSphereBufferUnit >= 0) { - gpu::SphericalHarmonics sh = globalLight->getAmbientSphere(); - if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) { - sh = (*_skybox->getCubemap()->getIrradiance()); - } - for (int i =0; i = 0)) { batch.setResourceTexture(skyboxCubemapUnit, _skybox->getCubemap()); } From 4c82e0b2b18ccbabb2e842f647d15a6cea7ef481 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 15 Feb 2016 17:44:40 -0800 Subject: [PATCH 6/6] Removing dead comment --- libraries/model/src/model/Light.slh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model/src/model/Light.slh b/libraries/model/src/model/Light.slh index d743da81b7..6529da1b61 100644 --- a/libraries/model/src/model/Light.slh +++ b/libraries/model/src/model/Light.slh @@ -25,7 +25,7 @@ struct SphericalHarmonics { vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { - vec3 dir = direction.xyz; // we don;t understand why yet but we need to use z as vertical axis? + vec3 dir = direction.xyz; const float C1 = 0.429043; const float C2 = 0.511664;