From ae20a5d439379e771acdec2b484d43a11ae6f3bc Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 17 Apr 2019 09:47:33 +0200 Subject: [PATCH 1/7] Fixed crash in debugShadow.js --- libraries/render-utils/src/RenderDeferredTask.cpp | 2 +- libraries/render-utils/src/RenderShadowTask.cpp | 2 +- libraries/render-utils/src/RenderShadowTask.h | 3 ++- libraries/task/src/task/Task.h | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index ea2b05a6fa..aae3237784 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -364,7 +364,7 @@ void RenderDeferredTaskDebug::build(JobModel& task, const render::Varying& input sprintf(jobName, "DrawShadowFrustum%d", i); task.addJob(jobName, shadowFrustum, glm::vec3(0.0f, tint, 1.0f)); if (!renderShadowTaskOut.isNull()) { - const auto& shadowCascadeSceneBBoxes = renderShadowTaskOut; + const auto& shadowCascadeSceneBBoxes = renderShadowTaskOut.get(); const auto shadowBBox = shadowCascadeSceneBBoxes[ExtractFrustums::SHADOW_CASCADE0_FRUSTUM + i]; sprintf(jobName, "DrawShadowBBox%d", i); task.addJob(jobName, shadowBBox, glm::vec3(1.0f, tint, 0.0f)); diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index a261deefb8..8e6efeab9f 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -90,7 +90,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende #endif }; - render::VaryingArray cascadeSceneBBoxes; + CascadeBoxes cascadeSceneBBoxes; for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) { char jobName[64]; diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index 4dc6f3073f..82b3ebac4f 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -52,8 +52,9 @@ class RenderShadowTask { public: // There is one AABox per shadow cascade + using CascadeBoxes = render::VaryingArray; using Input = render::VaryingSet2; - using Output = render::VaryingSet2, LightStage::ShadowFramePointer>; + using Output = render::VaryingSet2; using Config = RenderShadowTaskConfig; using JobModel = render::Task::ModelIO; diff --git a/libraries/task/src/task/Task.h b/libraries/task/src/task/Task.h index 632e8a222e..b74986235e 100644 --- a/libraries/task/src/task/Task.h +++ b/libraries/task/src/task/Task.h @@ -152,6 +152,7 @@ public: template static std::shared_ptr create(const std::string& name, const Varying& input, A&&... args) { + assert(input.canCast()); return std::make_shared(name, input, std::make_shared(), std::forward(args)...); } From 5d7b149a9ec51fc750b5f4271e449105f42fc440 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 17 Apr 2019 11:12:59 +0200 Subject: [PATCH 2/7] Switched to clamped tangent for shadow slope bias --- libraries/render-utils/src/RenderShadowTask.cpp | 2 +- libraries/render-utils/src/RenderShadowTask.h | 4 ++-- libraries/render-utils/src/Shadow.slh | 15 ++++++++------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 8e6efeab9f..bf564c1c10 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -336,7 +336,7 @@ void RenderShadowSetup::setConstantBias(int cascadeIndex, float value) { } void RenderShadowSetup::setSlopeBias(int cascadeIndex, float value) { - _bias[cascadeIndex]._slope = value * value * value * 0.01f; + _bias[cascadeIndex]._slope = value * value * value * 0.001f; } void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, const Input& input, Output& output) { diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index 82b3ebac4f..1cfa786e43 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -95,8 +95,8 @@ public: float constantBias3{ 0.2f }; float slopeBias0{ 0.6f }; float slopeBias1{ 0.6f }; - float slopeBias2{ 0.7f }; - float slopeBias3{ 0.82f }; + float slopeBias2{ 0.65f }; + float slopeBias3{ 0.7f }; signals: void dirty(); diff --git a/libraries/render-utils/src/Shadow.slh b/libraries/render-utils/src/Shadow.slh index b503844554..94bec86b34 100644 --- a/libraries/render-utils/src/Shadow.slh +++ b/libraries/render-utils/src/Shadow.slh @@ -90,8 +90,8 @@ float evalShadowAttenuationPCF(int cascadeIndex, ShadowSampleOffsets offsets, ve return shadowAttenuation; } -float evalShadowCascadeAttenuation(int cascadeIndex, ShadowSampleOffsets offsets, vec4 shadowTexcoord, float oneMinusNdotL) { - float bias = getShadowFixedBias(cascadeIndex) + getShadowSlopeBias(cascadeIndex) * oneMinusNdotL; +float evalShadowCascadeAttenuation(int cascadeIndex, ShadowSampleOffsets offsets, vec4 shadowTexcoord, float slopeNdotL) { + float bias = getShadowFixedBias(cascadeIndex) + getShadowSlopeBias(cascadeIndex) * slopeNdotL; return evalShadowAttenuationPCF(cascadeIndex, offsets, shadowTexcoord, bias); } @@ -104,7 +104,8 @@ float evalShadowAttenuation(vec3 worldLightDir, vec4 worldPosition, float viewDe vec3 cascadeMix; bvec4 isPixelOnCascade; int cascadeIndex; - float oneMinusNdotL = 1.0 - clamp(dot(worldLightDir, worldNormal), 0.0, 1.0); + float NdotL = clamp(dot(worldLightDir, worldNormal), 0.0, 1.0); + float slopeNdotL = min(2.0, sqrt(1.0-NdotL*NdotL) / NdotL); for (cascadeIndex=0 ; cascadeIndex Date: Wed, 17 Apr 2019 12:35:24 +0200 Subject: [PATCH 3/7] Added opacity mask to shadow casters --- .../src/graphics/MaterialTextures.slh | 6 ++++ .../render-utils/src/MeshPartPayload.cpp | 5 +++ .../render-utils/src/RenderPipelines.cpp | 35 ++++++++++++++++++- libraries/render-utils/src/RenderPipelines.h | 1 + .../src/deformed_model_shadow.slv | 15 ++++++++ .../src/deformed_model_shadow_dq.slv | 15 ++++++++ .../render-utils/src/model_normal_map.slf | 2 +- libraries/render-utils/src/model_shadow.slf | 18 ++++++++++ libraries/render-utils/src/model_shadow.slv | 13 +++++++ 9 files changed, 108 insertions(+), 2 deletions(-) diff --git a/libraries/graphics/src/graphics/MaterialTextures.slh b/libraries/graphics/src/graphics/MaterialTextures.slh index c725aae9bb..16c7f0e211 100644 --- a/libraries/graphics/src/graphics/MaterialTextures.slh +++ b/libraries/graphics/src/graphics/MaterialTextures.slh @@ -149,6 +149,12 @@ float fetchScatteringMap(vec2 uv) { <@endfunc@> +<@func fetchMaterialAlbedoTextureCoord0(matKey, texcoord0, albedo)@> + if (getTexMapArray()._materialParams.y != 1.0 && clamp(<$texcoord0$>, vec2(0.0), vec2(1.0)) != <$texcoord0$>) { + discard; + } + vec4 <$albedo$> = fetchAlbedoMap(<$texcoord0$>); +<@endfunc@> <@func fetchMaterialTexturesCoord0(matKey, texcoord0, albedo, roughness, normal, metallic, emissive, scattering)@> if (getTexMapArray()._materialParams.y != 1.0 && clamp(<$texcoord0$>, vec2(0.0), vec2(1.0)) != <$texcoord0$>) { diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 2634784f3a..9470f11d59 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -437,6 +437,11 @@ void ModelMeshPartPayload::render(RenderArgs* args) { if (args->_renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) { RenderPipelines::bindMaterials(_drawMaterials, batch, args->_enableTexturing); args->_details._materialSwitches++; + } else { + // We might have an opacity mask so we need to bind the albedo texture and material which might hold + // the alpha mask channel + RenderPipelines::bindMaterialsOpacityMask(_drawMaterials, batch, args->_enableTexturing); + args->_details._materialSwitches++; } // Draw! diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index c4a7368f39..ba0a079c7f 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -730,6 +730,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial multiMaterial.setInitialized(); } +static gpu::TextureTablePointer defaultMaterialTextures = std::make_shared(); + void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures) { if (multiMaterial.shouldUpdate()) { updateMultiMaterial(multiMaterial); @@ -737,7 +739,6 @@ void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu: auto textureCache = DependencyManager::get(); - static gpu::TextureTablePointer defaultMaterialTextures = std::make_shared(); static std::once_flag once; std::call_once(once, [textureCache] { defaultMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, textureCache->getWhiteTexture()); @@ -763,3 +764,35 @@ void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu: batch.setResourceTextureTable(defaultMaterialTextures); } } + +static gpu::BufferView defaultMaterialSchema; + +void RenderPipelines::bindMaterialsOpacityMask(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures) { + if (multiMaterial.shouldUpdate()) { + updateMultiMaterial(multiMaterial); + } + + if (multiMaterial.getMaterialKey().isOpacityMaskMap()) { + auto textureCache = DependencyManager::get(); + + static std::once_flag once; + std::call_once(once, [textureCache] { + defaultMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, textureCache->getWhiteTexture()); + }); + + auto& schemaBuffer = multiMaterial.getSchemaBuffer(); + batch.setUniformBuffer(gr::Buffer::Material, schemaBuffer); + + if (enableTextures) { + batch.setResourceTextureTable(multiMaterial.getTextureTable()); + } else { + batch.setResourceTextureTable(defaultMaterialTextures); + } + } else { + if (defaultMaterialSchema._buffer == nullptr) { + graphics::MultiMaterial::Schema schema; + defaultMaterialSchema = gpu::BufferView(std::make_shared(sizeof(schema), (const gpu::Byte*) &schema, sizeof(schema))); + } + batch.setUniformBuffer(gr::Buffer::Material, defaultMaterialSchema); + } +} diff --git a/libraries/render-utils/src/RenderPipelines.h b/libraries/render-utils/src/RenderPipelines.h index 0f3d1160ef..4a99b21e74 100644 --- a/libraries/render-utils/src/RenderPipelines.h +++ b/libraries/render-utils/src/RenderPipelines.h @@ -18,6 +18,7 @@ public: static void bindMaterial(graphics::MaterialPointer& material, gpu::Batch& batch, bool enableTextures); static void updateMultiMaterial(graphics::MultiMaterial& multiMaterial); static void bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures); + static void bindMaterialsOpacityMask(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures); }; diff --git a/libraries/render-utils/src/deformed_model_shadow.slv b/libraries/render-utils/src/deformed_model_shadow.slv index cc6fb42f98..827fc69b32 100644 --- a/libraries/render-utils/src/deformed_model_shadow.slv +++ b/libraries/render-utils/src/deformed_model_shadow.slv @@ -18,9 +18,15 @@ <$declareMeshDeformer(_SCRIBE_NULL, _SCRIBE_NULL, 1, _SCRIBE_NULL, 1)$> <$declareMeshDeformerActivation(1, 1)$> +<@include graphics/Material.slh@> +<@include graphics/MaterialTextures.slh@> + +<$declareMaterialTexMapArrayBuffer()$> + <@include render-utils/ShaderConstants.h@> layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS; +layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01; void main(void) { vec4 deformedPosition = vec4(0.0, 0.0, 0.0, 0.0); @@ -33,5 +39,14 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, deformedPosition, gl_Position)$> <$transformModelToWorldPos(obj, deformedPosition, _positionWS)$> + + Material mat = getMaterial(); + BITFIELD matKey = getMaterialKey(mat); + _texCoord01 = vec4(0.0, 0.0, 0.0, 0.0); + // If we have an opacity mask than we need the first tex coord + if ((matKey & OPACITY_MASK_MAP_BIT) != 0) { + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$> + } } diff --git a/libraries/render-utils/src/deformed_model_shadow_dq.slv b/libraries/render-utils/src/deformed_model_shadow_dq.slv index 84b5dfb33b..646fc12ce9 100644 --- a/libraries/render-utils/src/deformed_model_shadow_dq.slv +++ b/libraries/render-utils/src/deformed_model_shadow_dq.slv @@ -18,9 +18,15 @@ <$declareMeshDeformer(_SCRIBE_NULL, _SCRIBE_NULL, 1, 1, 1)$> <$declareMeshDeformerActivation(1, 1)$> +<@include graphics/Material.slh@> +<@include graphics/MaterialTextures.slh@> + +<$declareMaterialTexMapArrayBuffer()$> + <@include render-utils/ShaderConstants.h@> layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS; +layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01; void main(void) { vec4 deformedPosition = vec4(0.0, 0.0, 0.0, 0.0); @@ -33,4 +39,13 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, deformedPosition, gl_Position)$> <$transformModelToWorldPos(obj, deformedPosition, _positionWS)$> + + Material mat = getMaterial(); + BITFIELD matKey = getMaterialKey(mat); + _texCoord01 = vec4(0.0, 0.0, 0.0, 0.0); + // If we have an opacity mask than we need the first tex coord + if ((matKey & OPACITY_MASK_MAP_BIT) != 0) { + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$> + } } diff --git a/libraries/render-utils/src/model_normal_map.slf b/libraries/render-utils/src/model_normal_map.slf index 5fbc81e35b..695fadbca8 100644 --- a/libraries/render-utils/src/model_normal_map.slf +++ b/libraries/render-utils/src/model_normal_map.slf @@ -32,7 +32,7 @@ void main(void) { <$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$> float opacity = 1.0; - <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>; + <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>; <$discardTransparent(opacity)$>; vec3 albedo = getMaterialAlbedo(mat); diff --git a/libraries/render-utils/src/model_shadow.slf b/libraries/render-utils/src/model_shadow.slf index 862fcd0cf6..956ece4923 100644 --- a/libraries/render-utils/src/model_shadow.slf +++ b/libraries/render-utils/src/model_shadow.slf @@ -9,10 +9,28 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include graphics/Material.slh@> +<@include graphics/MaterialTextures.slh@> +<@include render-utils/ShaderConstants.h@> + +<$declareMaterialTextures(ALBEDO, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL)$> + +layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01; +#define _texCoord0 _texCoord01.xy layout(location=0) out vec4 _fragColor; void main(void) { + Material mat = getMaterial(); + BITFIELD matKey = getMaterialKey(mat); + + if ((matKey & OPACITY_MASK_MAP_BIT) != 0) { + float opacity = 1.0; + <$fetchMaterialAlbedoTextureCoord0(matKey, _texCoord0, albedoTex)$> + <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>; + <$discardTransparent(opacity)$>; + } + // pass-through to set z-buffer _fragColor = vec4(1.0, 1.0, 1.0, 0.0); } diff --git a/libraries/render-utils/src/model_shadow.slv b/libraries/render-utils/src/model_shadow.slv index 8de77d7b1d..d455ea4ade 100644 --- a/libraries/render-utils/src/model_shadow.slv +++ b/libraries/render-utils/src/model_shadow.slv @@ -13,12 +13,16 @@ <@include gpu/Inputs.slh@> <@include gpu/Transform.slh@> +<@include graphics/Material.slh@> +<@include graphics/MaterialTextures.slh@> <$declareStandardTransform()$> +<$declareMaterialTexMapArrayBuffer()$> <@include render-utils/ShaderConstants.h@> layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS; +layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01; void main(void) { // standard transform @@ -26,4 +30,13 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> <$transformModelToWorldPos(obj, inPosition, _positionWS)$> + + Material mat = getMaterial(); + BITFIELD matKey = getMaterialKey(mat); + _texCoord01 = vec4(0.0, 0.0, 0.0, 0.0); + // If we have an opacity mask than we need the first tex coord + if ((matKey & OPACITY_MASK_MAP_BIT) != 0) { + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$> + } } From 3cb9c518eae445a44c9b5e49f6bd3e7cba38753a Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 18 Apr 2019 11:06:12 +0200 Subject: [PATCH 4/7] Exposed max shadow distance and a shadow bias scale parameter in graphics::Light --- libraries/graphics/src/graphics/Light.cpp | 16 +++ libraries/graphics/src/graphics/Light.h | 11 +- libraries/render-utils/src/LightStage.cpp | 105 ++++++++++-------- libraries/render-utils/src/LightStage.h | 6 +- .../render-utils/src/RenderShadowTask.cpp | 8 +- 5 files changed, 87 insertions(+), 59 deletions(-) diff --git a/libraries/graphics/src/graphics/Light.cpp b/libraries/graphics/src/graphics/Light.cpp index 76d8a6030a..8a7281880e 100755 --- a/libraries/graphics/src/graphics/Light.cpp +++ b/libraries/graphics/src/graphics/Light.cpp @@ -73,6 +73,22 @@ bool Light::getCastShadows() const { return _castShadows; } +void Light::setShadowsMaxDistance(const float maxDistance) { + _shadowsMaxDistance = std::max(0.0f, maxDistance); +} + +float Light::getShadowsMaxDistance() const { + return _shadowsMaxDistance; +} + +void Light::setShadowsBiasScale(const float scale) { + _shadowsBiasScale = std::max(0.0f, scale); +} + +float Light::getShadowsBiasScale() const { + return _shadowsBiasScale; +} + void Light::setColor(const Color& color) { _lightSchemaBuffer.edit().irradiance.color = color; updateLightRadius(); diff --git a/libraries/graphics/src/graphics/Light.h b/libraries/graphics/src/graphics/Light.h index bb9fb3e5b9..824a9138c0 100755 --- a/libraries/graphics/src/graphics/Light.h +++ b/libraries/graphics/src/graphics/Light.h @@ -106,6 +106,12 @@ public: void setCastShadows(const bool castShadows); bool getCastShadows() const; + void setShadowsMaxDistance(const float maxDistance); + float getShadowsMaxDistance() const; + + void setShadowsBiasScale(const float scale); + float getShadowsBiasScale() const; + void setOrientation(const Quat& orientation); const glm::quat& getOrientation() const { return _transform.getRotation(); } @@ -192,10 +198,11 @@ protected: Type _type { SUN }; float _spotCos { -1.0f }; // stored here to be able to reset the spot angle when turning the type spot on/off - void updateLightRadius(); - + float _shadowsMaxDistance{ 40.0f }; + float _shadowsBiasScale{ 1.0f }; bool _castShadows{ false }; + void updateLightRadius(); }; typedef std::shared_ptr< Light > LightPointer; diff --git a/libraries/render-utils/src/LightStage.cpp b/libraries/render-utils/src/LightStage.cpp index 6913949286..d35bc21526 100644 --- a/libraries/render-utils/src/LightStage.cpp +++ b/libraries/render-utils/src/LightStage.cpp @@ -120,7 +120,7 @@ float LightStage::Shadow::Cascade::computeFarDistance(const ViewFrustum& viewFru return far; } -LightStage::Shadow::Shadow(graphics::LightPointer light, float maxDistance, unsigned int cascadeCount) : +LightStage::Shadow::Shadow(graphics::LightPointer light, unsigned int cascadeCount) : _light{ light } { cascadeCount = std::min(cascadeCount, (unsigned int)SHADOW_CASCADE_MAX_COUNT); Schema schema; @@ -149,70 +149,77 @@ LightStage::Shadow::Shadow(graphics::LightPointer light, float maxDistance, unsi cascade.framebuffer->setDepthBuffer(map, depthFormat, cascadeIndex); } - setMaxDistance(maxDistance); + if (light) { + setMaxDistance(light->getShadowsMaxDistance()); + } } void LightStage::Shadow::setLight(graphics::LightPointer light) { _light = light; + if (light) { + setMaxDistance(light->getShadowsMaxDistance()); + } } - void LightStage::Shadow::setMaxDistance(float value) { - // This overlaping factor isn't really used directly for blending of shadow cascades. It - // just there to be sure the cascades do overlap. The blending width used is relative - // to the UV space and is set in the Schema with invCascadeBlendWidth. - static const auto OVERLAP_FACTOR = 1.0f / 5.0f; + value = std::max(1e-3f, value); + if (value != _maxDistance) { + // This overlaping factor isn't really used directly for blending of shadow cascades. It's + // just there to be sure the cascades do overlap. The blending width used is relative + // to the UV space and is set in the Schema with invCascadeBlendWidth. + static const auto OVERLAP_FACTOR = 1.0f / 5.0f; - _maxDistance = std::max(0.0f, value); + _maxDistance = value; - if (_cascades.size() == 1) { - _cascades.front().setMinDistance(0.0f); - _cascades.front().setMaxDistance(_maxDistance); - } else { - // Distribute the cascades along that distance - // TODO : these parameters should be exposed to the user as part of the light entity parameters, no? - static const auto LOW_MAX_DISTANCE = 2.0f; - static const auto MAX_RESOLUTION_LOSS = 0.6f; // Between 0 and 1, 0 giving tighter distributions + if (_cascades.size() == 1) { + _cascades.front().setMinDistance(0.0f); + _cascades.front().setMaxDistance(_maxDistance); + } else { + // Distribute the cascades along that distance + // TODO : these parameters should be exposed to the user as part of the light entity parameters, no? + static const auto LOW_MAX_DISTANCE = 2.0f; + static const auto MAX_RESOLUTION_LOSS = 0.6f; // Between 0 and 1, 0 giving tighter distributions - // The max cascade distance is computed by multiplying the previous cascade's max distance by a certain - // factor. There is a "user" factor that is computed from a desired max resolution loss in the shadow - // and an optimal one based on the global min and max shadow distance, all cascades considered. The final - // distance is a gradual blend between the two - const auto userDistanceScale = 1.0f / (1.0f - MAX_RESOLUTION_LOSS); - const auto optimalDistanceScale = powf(_maxDistance / LOW_MAX_DISTANCE, 1.0f / (_cascades.size() - 1)); + // The max cascade distance is computed by multiplying the previous cascade's max distance by a certain + // factor. There is a "user" factor that is computed from a desired max resolution loss in the shadow + // and an optimal one based on the global min and max shadow distance, all cascades considered. The final + // distance is a gradual blend between the two + const auto userDistanceScale = 1.0f / (1.0f - MAX_RESOLUTION_LOSS); + const auto optimalDistanceScale = powf(_maxDistance / LOW_MAX_DISTANCE, 1.0f / (_cascades.size() - 1)); - float maxCascadeUserDistance = LOW_MAX_DISTANCE; - float maxCascadeOptimalDistance = LOW_MAX_DISTANCE; - float minCascadeDistance = 0.0f; + float maxCascadeUserDistance = LOW_MAX_DISTANCE; + float maxCascadeOptimalDistance = LOW_MAX_DISTANCE; + float minCascadeDistance = 0.0f; - for (size_t cascadeIndex = 0; cascadeIndex < _cascades.size(); ++cascadeIndex) { - float blendFactor = cascadeIndex / float(_cascades.size() - 1); - float maxCascadeDistance; + for (size_t cascadeIndex = 0; cascadeIndex < _cascades.size(); ++cascadeIndex) { + float blendFactor = cascadeIndex / float(_cascades.size() - 1); + float maxCascadeDistance; - if (cascadeIndex == size_t(_cascades.size() - 1)) { - maxCascadeDistance = _maxDistance; - } else { - maxCascadeDistance = maxCascadeUserDistance + (maxCascadeOptimalDistance - maxCascadeUserDistance)*blendFactor*blendFactor; + if (cascadeIndex == size_t(_cascades.size() - 1)) { + maxCascadeDistance = _maxDistance; + } else { + maxCascadeDistance = maxCascadeUserDistance + (maxCascadeOptimalDistance - maxCascadeUserDistance)*blendFactor*blendFactor; + } + + float shadowOverlapDistance = maxCascadeDistance * OVERLAP_FACTOR; + + _cascades[cascadeIndex].setMinDistance(minCascadeDistance); + _cascades[cascadeIndex].setMaxDistance(maxCascadeDistance + shadowOverlapDistance); + + // Compute distances for next cascade + minCascadeDistance = maxCascadeDistance; + maxCascadeUserDistance = maxCascadeUserDistance * userDistanceScale; + maxCascadeOptimalDistance = maxCascadeOptimalDistance * optimalDistanceScale; + maxCascadeUserDistance = std::min(maxCascadeUserDistance, _maxDistance); } - - float shadowOverlapDistance = maxCascadeDistance * OVERLAP_FACTOR; - - _cascades[cascadeIndex].setMinDistance(minCascadeDistance); - _cascades[cascadeIndex].setMaxDistance(maxCascadeDistance + shadowOverlapDistance); - - // Compute distances for next cascade - minCascadeDistance = maxCascadeDistance; - maxCascadeUserDistance = maxCascadeUserDistance * userDistanceScale; - maxCascadeOptimalDistance = maxCascadeOptimalDistance * optimalDistanceScale; - maxCascadeUserDistance = std::min(maxCascadeUserDistance, _maxDistance); } - } - // Update the buffer - const auto& lastCascade = _cascades.back(); - auto& schema = _schemaBuffer.edit(); - schema.maxDistance = _maxDistance; - schema.invFalloffDistance = 1.0f / (OVERLAP_FACTOR*lastCascade.getMaxDistance()); + // Update the buffer + const auto& lastCascade = _cascades.back(); + auto& schema = _schemaBuffer.edit(); + schema.maxDistance = _maxDistance; + schema.invFalloffDistance = 1.0f / (OVERLAP_FACTOR*lastCascade.getMaxDistance()); + } } void LightStage::Shadow::setKeylightFrustum(const ViewFrustum& viewFrustum, diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index 1fb1754862..4da66843cc 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -74,7 +74,7 @@ public: float left, float right, float bottom, float top, float viewMaxShadowDistance) const; }; - Shadow(graphics::LightPointer light, float maxDistance, unsigned int cascadeCount = 1); + Shadow(graphics::LightPointer light, unsigned int cascadeCount = 1); void setLight(graphics::LightPointer light); @@ -104,16 +104,14 @@ public: }; protected: - using Cascades = std::vector; static const glm::mat4 _biasMatrix; graphics::LightPointer _light; - float _maxDistance; + float _maxDistance{ 0.0f }; Cascades _cascades; - UniformBufferView _schemaBuffer = nullptr; }; diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index bf564c1c10..5de89a11b5 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -34,7 +34,6 @@ #define SHADOW_FRUSTUM_NEAR 1.0f #define SHADOW_FRUSTUM_FAR 500.0f static const unsigned int SHADOW_CASCADE_COUNT{ 4 }; -static const float SHADOW_MAX_DISTANCE{ 40.0f }; using namespace render; @@ -367,7 +366,7 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c output.edit2() = _cameraFrustum; if (!_globalShadowObject) { - _globalShadowObject = std::make_shared(graphics::LightPointer(), SHADOW_MAX_DISTANCE, SHADOW_CASCADE_COUNT); + _globalShadowObject = std::make_shared(currentKeyLight, SHADOW_CASCADE_COUNT); } _globalShadowObject->setLight(currentKeyLight); @@ -378,11 +377,12 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c unsigned int cascadeIndex; // Adjust each cascade frustum + const auto biasScale = currentKeyLight->getShadowsBiasScale(); for (cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { auto& bias = _bias[cascadeIndex]; _globalShadowObject->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(), - SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR, - bias._constant, bias._slope); + SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR, + bias._constant, bias._slope * biasScale); } _shadowFrameCache->pushShadow(_globalShadowObject); From 39d03ce87a54bdc9579656efe2d814453de81fd6 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 18 Apr 2019 19:19:38 +0200 Subject: [PATCH 5/7] Removed magic number --- libraries/render-utils/src/LightStage.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/render-utils/src/LightStage.cpp b/libraries/render-utils/src/LightStage.cpp index d35bc21526..524deaaad2 100644 --- a/libraries/render-utils/src/LightStage.cpp +++ b/libraries/render-utils/src/LightStage.cpp @@ -162,7 +162,9 @@ void LightStage::Shadow::setLight(graphics::LightPointer light) { } void LightStage::Shadow::setMaxDistance(float value) { - value = std::max(1e-3f, value); + static const auto MINIMUM_MAXDISTANCE = 1e-3f; + + value = std::max(MINIMUM_MAXDISTANCE, value); if (value != _maxDistance) { // This overlaping factor isn't really used directly for blending of shadow cascades. It's // just there to be sure the cascades do overlap. The blending width used is relative From 7d412f9109299331472836edacb3d036af15b631 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Fri, 19 Apr 2019 11:03:43 +0200 Subject: [PATCH 6/7] Simplified material binding in shadow mode. Added opacity mask to shadow fade. Adjusted default bias. --- .../src/RenderableMaterialEntityItem.cpp | 8 +-- .../src/RenderableShapeEntityItem.cpp | 3 +- .../src/graphics/MaterialTextures.slh | 7 --- .../render-utils/src/MeshPartPayload.cpp | 11 +--- .../render-utils/src/RenderPipelines.cpp | 61 +++++++------------ libraries/render-utils/src/RenderPipelines.h | 6 +- libraries/render-utils/src/RenderShadowTask.h | 4 +- libraries/render-utils/src/model_shadow.slf | 10 ++- .../render-utils/src/model_shadow_fade.slf | 15 ++++- 9 files changed, 50 insertions(+), 75 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 01d1098daa..9a634a85ad 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -313,11 +313,9 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { batch.setModelTransform(renderTransform); - if (args->_renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) { - drawMaterial->setTextureTransforms(textureTransform, MaterialMappingMode::UV, true); - - // bind the material - RenderPipelines::bindMaterial(drawMaterial, batch, args->_enableTexturing); + drawMaterial->setTextureTransforms(textureTransform, MaterialMappingMode::UV, true); + // bind the material + if (RenderPipelines::bindMaterial(drawMaterial, batch, args->_renderMode, args->_enableTexturing)) { args->_details._materialSwitches++; } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index d859d4b739..2548ae5914 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -291,8 +291,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, pipeline); } } else { - if (args->_renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) { - RenderPipelines::bindMaterials(materials, batch, args->_enableTexturing); + if (RenderPipelines::bindMaterials(materials, batch, args->_renderMode, args->_enableTexturing)) { args->_details._materialSwitches++; } diff --git a/libraries/graphics/src/graphics/MaterialTextures.slh b/libraries/graphics/src/graphics/MaterialTextures.slh index 16c7f0e211..92e76e5736 100644 --- a/libraries/graphics/src/graphics/MaterialTextures.slh +++ b/libraries/graphics/src/graphics/MaterialTextures.slh @@ -149,13 +149,6 @@ float fetchScatteringMap(vec2 uv) { <@endfunc@> -<@func fetchMaterialAlbedoTextureCoord0(matKey, texcoord0, albedo)@> - if (getTexMapArray()._materialParams.y != 1.0 && clamp(<$texcoord0$>, vec2(0.0), vec2(1.0)) != <$texcoord0$>) { - discard; - } - vec4 <$albedo$> = fetchAlbedoMap(<$texcoord0$>); -<@endfunc@> - <@func fetchMaterialTexturesCoord0(matKey, texcoord0, albedo, roughness, normal, metallic, emissive, scattering)@> if (getTexMapArray()._materialParams.y != 1.0 && clamp(<$texcoord0$>, vec2(0.0), vec2(1.0)) != <$texcoord0$>) { discard; diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 9470f11d59..7be5f93a95 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -154,8 +154,7 @@ void MeshPartPayload::render(RenderArgs* args) { bindMesh(batch); // apply material properties - if (args->_renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) { - RenderPipelines::bindMaterials(_drawMaterials, batch, args->_enableTexturing); + if (RenderPipelines::bindMaterials(_drawMaterials, batch, args->_renderMode, args->_enableTexturing)) { args->_details._materialSwitches++; } @@ -434,13 +433,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) { } // apply material properties - if (args->_renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) { - RenderPipelines::bindMaterials(_drawMaterials, batch, args->_enableTexturing); - args->_details._materialSwitches++; - } else { - // We might have an opacity mask so we need to bind the albedo texture and material which might hold - // the alpha mask channel - RenderPipelines::bindMaterialsOpacityMask(_drawMaterials, batch, args->_enableTexturing); + if (RenderPipelines::bindMaterials(_drawMaterials, batch, args->_renderMode, args->_enableTexturing)) { args->_details._materialSwitches++; } diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index ba0a079c7f..cd4d787f0e 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -373,10 +373,10 @@ void initZPassPipelines(ShapePlumber& shapePlumber, gpu::StatePointer state, con gpu::Shader::createProgram(deformed_model_shadow_fade_dq), state, extraBatchSetter, itemSetter); } -void RenderPipelines::bindMaterial(graphics::MaterialPointer& material, gpu::Batch& batch, bool enableTextures) { +bool RenderPipelines::bindMaterial(graphics::MaterialPointer& material, gpu::Batch& batch, render::Args::RenderMode renderMode, bool enableTextures) { graphics::MultiMaterial multiMaterial; multiMaterial.push(graphics::MaterialLayer(material, 0)); - bindMaterials(multiMaterial, batch, enableTextures); + return bindMaterials(multiMaterial, batch, renderMode, enableTextures); } void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial) { @@ -730,17 +730,21 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial multiMaterial.setInitialized(); } -static gpu::TextureTablePointer defaultMaterialTextures = std::make_shared(); - -void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures) { +bool RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, render::Args::RenderMode renderMode, bool enableTextures) { if (multiMaterial.shouldUpdate()) { updateMultiMaterial(multiMaterial); } auto textureCache = DependencyManager::get(); + static gpu::TextureTablePointer defaultMaterialTextures = std::make_shared(); + static gpu::BufferView defaultMaterialSchema; + static std::once_flag once; std::call_once(once, [textureCache] { + graphics::MultiMaterial::Schema schema; + defaultMaterialSchema = gpu::BufferView(std::make_shared(sizeof(schema), (const gpu::Byte*) &schema, sizeof(schema))); + defaultMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, textureCache->getWhiteTexture()); defaultMaterialTextures->setTexture(gr::Texture::MaterialMetallic, textureCache->getBlackTexture()); defaultMaterialTextures->setTexture(gr::Texture::MaterialRoughness, textureCache->getWhiteTexture()); @@ -750,49 +754,26 @@ void RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu: // MaterialEmissiveLightmap has to be set later }); - auto& schemaBuffer = multiMaterial.getSchemaBuffer(); - batch.setUniformBuffer(gr::Buffer::Material, schemaBuffer); - if (enableTextures) { - batch.setResourceTextureTable(multiMaterial.getTextureTable()); - } else { - auto key = multiMaterial.getMaterialKey(); - if (key.isLightmapMap()) { - defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getBlackTexture()); - } else if (key.isEmissiveMap()) { - defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture()); - } - batch.setResourceTextureTable(defaultMaterialTextures); - } -} - -static gpu::BufferView defaultMaterialSchema; - -void RenderPipelines::bindMaterialsOpacityMask(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures) { - if (multiMaterial.shouldUpdate()) { - updateMultiMaterial(multiMaterial); - } - - if (multiMaterial.getMaterialKey().isOpacityMaskMap()) { - auto textureCache = DependencyManager::get(); - - static std::once_flag once; - std::call_once(once, [textureCache] { - defaultMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, textureCache->getWhiteTexture()); - }); - + // For shadows, we only need opacity mask information + if (renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE || multiMaterial.getMaterialKey().isOpacityMaskMap()) { auto& schemaBuffer = multiMaterial.getSchemaBuffer(); batch.setUniformBuffer(gr::Buffer::Material, schemaBuffer); - if (enableTextures) { batch.setResourceTextureTable(multiMaterial.getTextureTable()); } else { + auto key = multiMaterial.getMaterialKey(); + if (key.isLightmapMap()) { + defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getBlackTexture()); + } else if (key.isEmissiveMap()) { + defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture()); + } batch.setResourceTextureTable(defaultMaterialTextures); } + return true; } else { - if (defaultMaterialSchema._buffer == nullptr) { - graphics::MultiMaterial::Schema schema; - defaultMaterialSchema = gpu::BufferView(std::make_shared(sizeof(schema), (const gpu::Byte*) &schema, sizeof(schema))); - } + batch.setResourceTextureTable(defaultMaterialTextures); batch.setUniformBuffer(gr::Buffer::Material, defaultMaterialSchema); + return false; } } + diff --git a/libraries/render-utils/src/RenderPipelines.h b/libraries/render-utils/src/RenderPipelines.h index 4a99b21e74..5b04de08b6 100644 --- a/libraries/render-utils/src/RenderPipelines.h +++ b/libraries/render-utils/src/RenderPipelines.h @@ -12,13 +12,13 @@ #define hifi_RenderPipelines_h #include +#include class RenderPipelines { public: - static void bindMaterial(graphics::MaterialPointer& material, gpu::Batch& batch, bool enableTextures); static void updateMultiMaterial(graphics::MultiMaterial& multiMaterial); - static void bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures); - static void bindMaterialsOpacityMask(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, bool enableTextures); + static bool bindMaterial(graphics::MaterialPointer& material, gpu::Batch& batch, render::Args::RenderMode renderMode, bool enableTextures); + static bool bindMaterials(graphics::MultiMaterial& multiMaterial, gpu::Batch& batch, render::Args::RenderMode renderMode, bool enableTextures); }; diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index 1cfa786e43..ef469a7247 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -93,8 +93,8 @@ public: float constantBias1{ 0.15f }; float constantBias2{ 0.175f }; float constantBias3{ 0.2f }; - float slopeBias0{ 0.6f }; - float slopeBias1{ 0.6f }; + float slopeBias0{ 0.4f }; + float slopeBias1{ 0.45f }; float slopeBias2{ 0.65f }; float slopeBias3{ 0.7f }; diff --git a/libraries/render-utils/src/model_shadow.slf b/libraries/render-utils/src/model_shadow.slf index 956ece4923..6d8dfb7e2a 100644 --- a/libraries/render-utils/src/model_shadow.slf +++ b/libraries/render-utils/src/model_shadow.slf @@ -23,13 +23,11 @@ layout(location=0) out vec4 _fragColor; void main(void) { Material mat = getMaterial(); BITFIELD matKey = getMaterialKey(mat); + <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL)$> - if ((matKey & OPACITY_MASK_MAP_BIT) != 0) { - float opacity = 1.0; - <$fetchMaterialAlbedoTextureCoord0(matKey, _texCoord0, albedoTex)$> - <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>; - <$discardTransparent(opacity)$>; - } + float opacity = 1.0; + <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>; + <$discardTransparent(opacity)$>; // pass-through to set z-buffer _fragColor = vec4(1.0, 1.0, 1.0, 0.0); diff --git a/libraries/render-utils/src/model_shadow_fade.slf b/libraries/render-utils/src/model_shadow_fade.slf index 210b5482c8..1f94d4a0ac 100644 --- a/libraries/render-utils/src/model_shadow_fade.slf +++ b/libraries/render-utils/src/model_shadow_fade.slf @@ -9,13 +9,18 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - +<@include graphics/Material.slh@> +<@include graphics/MaterialTextures.slh@> <@include render-utils/ShaderConstants.h@> +<$declareMaterialTextures(ALBEDO, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL)$> + <@include Fade.slh@> <$declareFadeFragment()$> layout(location=RENDER_UTILS_ATTR_POSITION_WS) in vec4 _positionWS; +layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01; +#define _texCoord0 _texCoord01.xy layout(location=0) out vec4 _fragColor; @@ -24,6 +29,14 @@ void main(void) { <$fetchFadeObjectParams(fadeParams)$> applyFadeClip(fadeParams, _positionWS.xyz); + Material mat = getMaterial(); + BITFIELD matKey = getMaterialKey(mat); + <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL)$> + + float opacity = 1.0; + <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>; + <$discardTransparent(opacity)$>; + // pass-through to set z-buffer _fragColor = vec4(1.0, 1.0, 1.0, 0.0); } From 8dabcb76b8b0ea917fcbefdf71b8674cc5bca780 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 22 Apr 2019 21:30:57 +0200 Subject: [PATCH 7/7] Taking into account comments --- libraries/render-utils/src/RenderPipelines.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index cd4d787f0e..ac2eb8e475 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -755,18 +755,21 @@ bool RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu: }); // For shadows, we only need opacity mask information - if (renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE || multiMaterial.getMaterialKey().isOpacityMaskMap()) { + auto key = multiMaterial.getMaterialKey(); + if (renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE || key.isOpacityMaskMap()) { auto& schemaBuffer = multiMaterial.getSchemaBuffer(); batch.setUniformBuffer(gr::Buffer::Material, schemaBuffer); if (enableTextures) { batch.setResourceTextureTable(multiMaterial.getTextureTable()); } else { - auto key = multiMaterial.getMaterialKey(); - if (key.isLightmapMap()) { - defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getBlackTexture()); - } else if (key.isEmissiveMap()) { - defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture()); + if (renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) { + if (key.isLightmapMap()) { + defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getBlackTexture()); + } else if (key.isEmissiveMap()) { + defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture()); + } } + batch.setResourceTextureTable(defaultMaterialTextures); } return true;