From 420af951318945765267cc12012c573ea4559c41 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Thu, 16 Apr 2020 16:18:39 -0700 Subject: [PATCH] models support flipped normals on double sided geometry --- .../entities-renderer/src/paintStroke.slf | 6 ++++-- libraries/graphics/src/graphics/Material.slh | 1 - libraries/render-utils/src/CullFace.slh | 20 +++++++++++++++++++ libraries/render-utils/src/model.slf | 5 +++-- libraries/render-utils/src/simple.slf | 9 +++++---- .../render-utils/src/simple_procedural.slf | 3 ++- 6 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 libraries/render-utils/src/CullFace.slh diff --git a/libraries/entities-renderer/src/paintStroke.slf b/libraries/entities-renderer/src/paintStroke.slf index 3d5cc190d0..eb46be1e20 100644 --- a/libraries/entities-renderer/src/paintStroke.slf +++ b/libraries/entities-renderer/src/paintStroke.slf @@ -19,6 +19,8 @@ <@include paintStroke.slh@> <$declarePolyLineBuffers()$> +<@include CullFace.slh@> + LAYOUT(binding=0) uniform sampler2D _texture; <@if not HIFI_USE_FORWARD@> @@ -35,9 +37,9 @@ void main(void) { <@if not HIFI_USE_FORWARD@> <@if HIFI_USE_TRANSLUCENT@> - packDeferredFragmentTranslucent((2.0 * float(gl_FrontFacing) - 1.0) * _normalWS, texel.a, texel.rgb, DEFAULT_ROUGHNESS); + packDeferredFragmentTranslucent(evalFrontOrBackFaceNormal(_normalWS), texel.a, texel.rgb, DEFAULT_ROUGHNESS); <@else@> - packDeferredFragmentUnlit((2.0 * float(gl_FrontFacing) - 1.0) * _normalWS, texel.a, texel.rgb); + packDeferredFragmentUnlit(evalFrontOrBackFaceNormal(_normalWS), texel.a, texel.rgb); <@endif@> <@else@> _fragColor0 = texel; diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index 328ff4a3af..274dbc1cdd 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -13,7 +13,6 @@ <@include graphics/ShaderConstants.h@> - const int MAX_TEXCOORDS = 2; struct TexMapArray { diff --git a/libraries/render-utils/src/CullFace.slh b/libraries/render-utils/src/CullFace.slh new file mode 100644 index 0000000000..61b76bb22f --- /dev/null +++ b/libraries/render-utils/src/CullFace.slh @@ -0,0 +1,20 @@ + +<@if not CULL_FACE_SLH@> +<@def CULL_FACE_SLH@> + +// NOTE: this calculation happens once per fragment. this could be optimized by creating different shaders (via defines) +// for front, back, and double-sided. for front/back-only triangles, this will simplify to always 1 or always -1 +vec3 evalFrontOrBackFaceNormal(vec3 normal) { + return (2.0 * float(gl_FrontFacing) - 1.0) * normal; +} + +<@endif@> diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index a6cc82e335..98abc29d8c 100644 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -13,6 +13,7 @@ <@include graphics/Material.slh@> <@include graphics/MaterialTextures.slh@> <@include render-utils/ShaderConstants.h@> +<@include CullFace.slh@> <@if not HIFI_USE_SHADOW@> <@if HIFI_USE_FORWARD or HIFI_USE_TRANSLUCENT@> @@ -129,7 +130,7 @@ void main(void) { _fragColor0 = vec4(albedo * isUnlitEnabled(), opacity); <@else@> packDeferredFragmentUnlit( - normalize(_normalWS), + evalFrontOrBackFaceNormal(normalize(_normalWS)), opacity, albedo * isUnlitEnabled()); <@endif@> @@ -195,7 +196,7 @@ void main(void) { <@else@> vec3 fragNormalWS = _normalWS; <@endif@> - fragNormalWS = normalize(fragNormalWS); + fragNormalWS = evalFrontOrBackFaceNormal(normalize(fragNormalWS)); <@if HIFI_USE_FORWARD@> TransformCamera cam = getTransformCamera(); diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index 9760216682..fabe85cb4f 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -13,6 +13,7 @@ <@include gpu/Color.slh@> <@include DefaultMaterials.slh@> <@include render-utils/ShaderConstants.h@> +<@include CullFace.slh@> <@if HIFI_USE_FORWARD or HIFI_USE_TRANSLUCENT@> <@if not HIFI_USE_UNLIT@> @@ -94,7 +95,7 @@ void main(void) { 1.0, DEFAULT_OCCLUSION, fragPosition, - normalize(_normalWS) * (2.0 * float(gl_FrontFacing) - 1.0), + evalFrontOrBackFaceNormal(normalize(_normalWS)), texel.rgb, fresnel, metallic, @@ -111,7 +112,7 @@ void main(void) { 1.0, DEFAULT_OCCLUSION, fragPosition, - normalize(_normalWS) * (2.0 * float(gl_FrontFacing) - 1.0), + evalFrontOrBackFaceNormal(normalize(_normalWS)), texel.rgb, fresnel, metallic, @@ -119,7 +120,7 @@ void main(void) { texel.a); <@else@> packDeferredFragment( - normalize(_normalWS) * (2.0 * float(gl_FrontFacing) - 1.0), + evalFrontOrBackFaceNormal(normalize(_normalWS)), 1.0, texel.rgb, DEFAULT_ROUGHNESS, @@ -141,7 +142,7 @@ void main(void) { , texel.a); <@else@> packDeferredFragmentUnlit( - normalize(_normalWS) * (2.0 * float(gl_FrontFacing) - 1.0), + evalFrontOrBackFaceNormal(normalize(_normalWS)), 1.0, texel.rgb <@if HIFI_USE_FADE@> diff --git a/libraries/render-utils/src/simple_procedural.slf b/libraries/render-utils/src/simple_procedural.slf index 5b0eb62cca..cc8edbb415 100644 --- a/libraries/render-utils/src/simple_procedural.slf +++ b/libraries/render-utils/src/simple_procedural.slf @@ -24,6 +24,7 @@ <@include gpu/Transform.slh@> <$declareStandardCameraTransform()$> +<@include CullFace.slh@> <@include render-utils/ShaderConstants.h@> layout(location=RENDER_UTILS_ATTR_POSITION_MS) in vec4 _positionMS; @@ -66,7 +67,7 @@ float getProceduralFragmentWithPosition(inout ProceduralFragmentWithPosition pro #line 2030 void main(void) { - vec3 normal = normalize(_normalWS.xyz) * (2.0 * float(gl_FrontFacing) - 1.0); + vec3 normal = evalFrontOrBackFaceNormal(normalize(_normalWS.xyz)); vec3 diffuse = _color.rgb; vec3 fresnel = DEFAULT_FRESNEL; float roughness = DEFAULT_ROUGHNESS;