From 3fc711dba298c78a87b84198ed8c2cd58f106c20 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 17 Apr 2019 12:35:24 +0200 Subject: [PATCH] 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)$> + } }