From 5edcc38eba32ae82d16be429b4de1fb374ed3552 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Thu, 18 May 2017 01:06:59 -0700 Subject: [PATCH] Polishing the scope shaders --- libraries/model/src/model/Skybox.h | 4 ++ libraries/render-utils/src/ZoneRenderer.cpp | 58 ++++++++++--------- libraries/render-utils/src/ZoneRenderer.h | 5 +- libraries/render-utils/src/zone_draw.slh | 37 ++++++++++++ .../render-utils/src/zone_drawAmbient.slf | 25 ++------ .../render-utils/src/zone_drawKeyLight.slf | 46 +++++++-------- .../render-utils/src/zone_drawSkybox.slf | 48 +++++++-------- 7 files changed, 122 insertions(+), 101 deletions(-) create mode 100644 libraries/render-utils/src/zone_draw.slh diff --git a/libraries/model/src/model/Skybox.h b/libraries/model/src/model/Skybox.h index d7d95fbe9e..90896fd8c6 100755 --- a/libraries/model/src/model/Skybox.h +++ b/libraries/model/src/model/Skybox.h @@ -25,6 +25,8 @@ typedef glm::vec3 Color; class Skybox { public: + typedef gpu::BufferView UniformBufferView; + Skybox(); Skybox& operator= (const Skybox& skybox); virtual ~Skybox() {}; @@ -43,6 +45,8 @@ public: static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox); + const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; } + protected: static const int SKYBOX_SKYMAP_SLOT { 0 }; static const int SKYBOX_CONSTANTS_SLOT { 0 }; diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 2ae18ffb1f..57cb4ecdaa 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -62,21 +62,21 @@ void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() { if (!_keyLightPipeline) { - auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS(); - auto ps = gpu::Shader::createPixel(std::string(zone_drawKeyLight_frag)); - gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS(); + auto ps = gpu::Shader::createPixel(std::string(zone_drawKeyLight_frag)); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); - gpu::Shader::BindingSet slotBindings; - slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER)); - slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), ZONE_KEYLIGHT_BUFFER)); + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), ZONE_KEYLIGHT_BUFFER)); - gpu::Shader::makeProgram(*program, slotBindings); + gpu::Shader::makeProgram(*program, slotBindings); - gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); - _keyLightPipeline = gpu::Pipeline::create(program, state); - } + state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + _keyLightPipeline = gpu::Pipeline::create(program, state); + } return _keyLightPipeline; } @@ -109,7 +109,8 @@ const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() { gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER)); slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), ZONE_SKYBOX_MAP)); - + slotBindings.insert(gpu::Shader::Binding(std::string("skyboxBuffer"), ZONE_SKYBOX_BUFFER)); + gpu::Shader::makeProgram(*program, slotBindings); gpu::StatePointer state = gpu::StatePointer(new gpu::State()); @@ -126,13 +127,13 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I auto deferredTransform = inputs; auto lightStage = DependencyManager::get()->getLightStage(); - model::LightPointer keyLight; - if (lightStage && lightStage->_currentFrame._sunLights.size()) { - keyLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front()); - } - else { - keyLight = DependencyManager::get()->getGlobalLight(); - } + model::LightPointer keyLight; + if (lightStage && lightStage->_currentFrame._sunLights.size()) { + keyLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front()); + } + else { + keyLight = DependencyManager::get()->getGlobalLight(); + } model::LightPointer keyAmbiLight; if (lightStage && lightStage->_currentFrame._ambientLights.size()) { @@ -163,17 +164,17 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I batch.setUniformBuffer(ZONE_DEFERRED_TRANSFORM_BUFFER, deferredTransform->getFrameTransformBuffer()); - batch.setPipeline(getKeyLightPipeline()); - model.setTranslation(glm::vec3(-4.0, -3.0, -10.0)); - batch.setModelTransform(model); - if (keyLight) { - batch.setUniformBuffer(ZONE_KEYLIGHT_BUFFER, keyLight->getLightSchemaBuffer()); - } - batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.setPipeline(getKeyLightPipeline()); + model.setTranslation(glm::vec3(-4.0, -3.0, -10.0)); + batch.setModelTransform(model); + if (keyLight) { + batch.setUniformBuffer(ZONE_KEYLIGHT_BUFFER, keyLight->getLightSchemaBuffer()); + } + batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setPipeline(getAmbientPipeline()); - model.setTranslation(glm::vec3(-4.0, 0.0, -10.0)); - batch.setModelTransform(model); + model.setTranslation(glm::vec3(-4.0, 0.0, -10.0)); + batch.setModelTransform(model); if (keyAmbiLight) { batch.setUniformBuffer(ZONE_AMBIENT_BUFFER, keyAmbiLight->getAmbientSchemaBuffer()); @@ -188,6 +189,7 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I batch.setModelTransform(model); if (skybox) { batch.setResourceTexture(ZONE_SKYBOX_MAP, skybox->getCubemap()); + batch.setUniformBuffer(ZONE_SKYBOX_BUFFER, skybox->getSchemaBuffer()); } batch.draw(gpu::TRIANGLE_STRIP, 4); diff --git a/libraries/render-utils/src/ZoneRenderer.h b/libraries/render-utils/src/ZoneRenderer.h index 10eaa67d31..40f9db2995 100644 --- a/libraries/render-utils/src/ZoneRenderer.h +++ b/libraries/render-utils/src/ZoneRenderer.h @@ -65,9 +65,10 @@ protected: enum Slots { ZONE_DEFERRED_TRANSFORM_BUFFER = 0, - ZONE_KEYLIGHT_BUFFER, - ZONE_AMBIENT_BUFFER, + ZONE_KEYLIGHT_BUFFER, + ZONE_AMBIENT_BUFFER, ZONE_AMBIENT_MAP, + ZONE_SKYBOX_BUFFER, ZONE_SKYBOX_MAP, }; diff --git a/libraries/render-utils/src/zone_draw.slh b/libraries/render-utils/src/zone_draw.slh new file mode 100644 index 0000000000..2cc8fc99f2 --- /dev/null +++ b/libraries/render-utils/src/zone_draw.slh @@ -0,0 +1,37 @@ + +// Generated on <$_SCRIBE_DATE$> +// +// Created by Sam Gateau on 5/17/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include DeferredTransform.slh@> +<$declareDeferredFrameTransform()$> + +<@func evalGlobeWidget()@> + const float SCOPE_RADIUS = 1.0; + const float SCOPE_RADIUS2 = SCOPE_RADIUS * SCOPE_RADIUS; + const float EDGE_HALFWIDTH = 0.025; + const float EDGE_HALFWIDTH2 = EDGE_HALFWIDTH * EDGE_HALFWIDTH; + const float OUT_RADIUS = SCOPE_RADIUS + EDGE_HALFWIDTH; + + vec2 sphereUV = (varTexCoord0.xy * 2.0 - vec2(1.0)) * OUT_RADIUS; + float sphereR2 = dot(sphereUV.xy, sphereUV.xy); + if (sphereR2 > OUT_RADIUS * OUT_RADIUS) { + discard; + } + float sphereR = sqrt(sphereR2); + + float edgeFalloff = (SCOPE_RADIUS - sphereR) / (EDGE_HALFWIDTH); + float edgeFalloff2 = min(1.0, edgeFalloff * edgeFalloff); + + vec4 base = vec4(0.0, 0.0, 0.0, 1.0 - edgeFalloff2); + if (sphereR2 > SCOPE_RADIUS2) { + _fragColor = base; + return; + } +<@endfunc@> + diff --git a/libraries/render-utils/src/zone_drawAmbient.slf b/libraries/render-utils/src/zone_drawAmbient.slf index f14bed5c03..f104e5be44 100644 --- a/libraries/render-utils/src/zone_drawAmbient.slf +++ b/libraries/render-utils/src/zone_drawAmbient.slf @@ -8,9 +8,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -<@include DeferredTransform.slh@> -<$declareDeferredFrameTransform()$> +<@include zone_draw.slh@> <@include model/Light.slh@> @@ -26,20 +24,8 @@ out vec4 _fragColor; void main(void) { - const float INNER_RADIUS = 1.0; - const float INNER_RADIUS2 = INNER_RADIUS * INNER_RADIUS; - const float OUTER_RADIUS = 1.05; - const float OUTER_RADIUS2 = OUTER_RADIUS * OUTER_RADIUS; - vec2 sphereUV = (varTexCoord0.xy * 2.0 - vec2(1.0)) * OUTER_RADIUS; - float sphereR2 = dot(sphereUV.xy, sphereUV.xy); - if (sphereR2 > OUTER_RADIUS * OUTER_RADIUS) { - discard; - } - if (sphereR2 > INNER_RADIUS2) { - float falloff = (sphereR2 - OUTER_RADIUS2) / (OUTER_RADIUS2 - INNER_RADIUS2); - _fragColor = vec4(0.0, 0.0, 0.0, falloff * falloff); - return; - } + <$evalGlobeWidget()$> + vec3 spherePos = normalize(vec3(sphereUV, sqrt(1.0 - sphereR2))); @@ -58,10 +44,11 @@ void main(void) { // vec3 ambient = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), fragNormal).xyz; // _fragColor = vec4( 0.5 * (fragNormal + vec3(1.0)), 1.0); - vec3 ambient = (sphereUV.x > 0 ? ambientMap : ambientSH); + vec3 color = (sphereUV.x > 0 ? ambientMap : ambientSH); + color = color * 1.0 - base.w + base.xyz * base.w; const float INV_GAMMA_22 = 1.0 / 2.2; - _fragColor = vec4(pow(ambient, vec3(INV_GAMMA_22)), 1.0); + _fragColor = vec4(pow(color, vec3(INV_GAMMA_22)), 1.0); } diff --git a/libraries/render-utils/src/zone_drawKeyLight.slf b/libraries/render-utils/src/zone_drawKeyLight.slf index 5165d5139d..dcfdd20c6a 100644 --- a/libraries/render-utils/src/zone_drawKeyLight.slf +++ b/libraries/render-utils/src/zone_drawKeyLight.slf @@ -8,9 +8,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -<@include DeferredTransform.slh@> -<$declareDeferredFrameTransform()$> +<@include zone_draw.slh@> <@include model/Light.slh@> @@ -25,33 +23,31 @@ out vec4 _fragColor; void main(void) { - const float INNER_RADIUS = 1.0; - const float INNER_RADIUS2 = INNER_RADIUS * INNER_RADIUS; - const float OUTER_RADIUS = 1.05; - const float OUTER_RADIUS2 = OUTER_RADIUS * OUTER_RADIUS; - vec2 sphereUV = (varTexCoord0.xy * 2.0 - vec2(1.0)) * OUTER_RADIUS; - float sphereR2 = dot(sphereUV.xy, sphereUV.xy); - if (sphereR2 > OUTER_RADIUS * OUTER_RADIUS) { - discard; - } - if (sphereR2 > INNER_RADIUS2) { - float falloff = (sphereR2 - OUTER_RADIUS2) / (OUTER_RADIUS2 - INNER_RADIUS2); - _fragColor = vec4(0.0, 0.0, 0.0, falloff * falloff); - return; - } - vec3 spherePos = normalize(vec3(sphereUV, sqrt(1.0 - sphereR2))); - - - vec3 fragNormal = vec3(getViewInverse() * vec4(spherePos, 0.0)); - + <$evalGlobeWidget()$> Light light = getLight(); - - vec3 lightDirection = getLightDirection(light); + vec3 lightDirection = getLightDirection(light); vec3 lightIrradiance = getLightIrradiance(light); + vec3 color = vec3(0.0); + + const float INOUT_RATIO = 0.4; + const float SUN_THRESHOLD = 0.99; - vec3 color = lightIrradiance; + vec3 outSpherePos = normalize(vec3(sphereUV, -sqrt(1.0 - sphereR2))); + vec3 outNormal = vec3(getViewInverse() * vec4(outSpherePos, 0.0)); + float val = step(SUN_THRESHOLD, dot(-lightDirection, outNormal)); + color = lightIrradiance * vec3(val); + + if (sphereR2 < INOUT_RATIO * INOUT_RATIO * SCOPE_RADIUS2) { + vec2 inSphereUV = sphereUV / INOUT_RATIO; + vec3 inSpherePos = normalize(vec3(inSphereUV, sqrt(1.0 - dot(inSphereUV.xy, inSphereUV.xy)))); + vec3 inNormal = vec3(getViewInverse() * vec4(inSpherePos, 0.0)); + + color += lightIrradiance * vec3(dot(-lightDirection, inNormal)); + } + + color = color * 1.0 - base.w + base.xyz * base.w; const float INV_GAMMA_22 = 1.0 / 2.2; _fragColor = vec4(pow(color, vec3(INV_GAMMA_22)), 1.0); } diff --git a/libraries/render-utils/src/zone_drawSkybox.slf b/libraries/render-utils/src/zone_drawSkybox.slf index 77b144379b..fd6976365e 100644 --- a/libraries/render-utils/src/zone_drawSkybox.slf +++ b/libraries/render-utils/src/zone_drawSkybox.slf @@ -8,47 +8,41 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include zone_draw.slh@> -<@include DeferredTransform.slh@> -<$declareDeferredFrameTransform()$> - -// declareSkyboxMap uniform samplerCube skyboxMap; -vec4 evalSkyboxLight(vec3 direction, float lod) { - // textureQueryLevels is not available until #430, so we require explicit lod - // float mipmapLevel = lod * textureQueryLevels(skyboxMap); - return textureLod(skyboxMap, direction, lod); -} +struct Skybox { + vec4 color; +}; + +uniform skyboxBuffer { + Skybox skybox; +}; in vec2 varTexCoord0; out vec4 _fragColor; void main(void) { + <$evalGlobeWidget()$> - const float INNER_RADIUS = 1.0; - const float INNER_RADIUS2 = INNER_RADIUS * INNER_RADIUS; - const float OUTER_RADIUS = 1.05; - const float OUTER_RADIUS2 = OUTER_RADIUS * OUTER_RADIUS; - vec2 sphereUV = (varTexCoord0.xy * 2.0 - vec2(1.0)) * OUTER_RADIUS; - float sphereR2 = dot(sphereUV.xy, sphereUV.xy); - if (sphereR2 > OUTER_RADIUS * OUTER_RADIUS) { - discard; - } - if (sphereR2 > INNER_RADIUS2) { - float falloff = (sphereR2 - OUTER_RADIUS2) / (OUTER_RADIUS2 - INNER_RADIUS2); - _fragColor = vec4(0.0, 0.0, 0.0, falloff * falloff); - return; - } vec3 spherePos = normalize(vec3(sphereUV, -sqrt(1.0 - sphereR2))); - vec3 fragNormal = vec3(getViewInverse() * vec4(spherePos, 0.0)); + vec3 direction = vec3(getViewInverse() * vec4(spherePos, 0.0)); - float lod = 0; - vec3 ambient = evalSkyboxLight(fragNormal, lod).xyz; + vec3 color = skybox.color.rgb; + // blend is only set if there is a cubemap + if (skybox.color.a > 0.0) { + color = texture(skyboxMap, direction).rgb; + if (skybox.color.a < 1.0) { + color *= skybox.color.rgb; + } + } + + color = color * 1.0 - base.w + base.xyz * base.w; const float INV_GAMMA_22 = 1.0 / 2.2; - _fragColor = vec4(pow(ambient, vec3(INV_GAMMA_22)), 1.0); + _fragColor = vec4(pow(color, vec3(INV_GAMMA_22)), 1.0); }