<@include gpu/Config.slh@> <$VERSION_HEADER$> // <$_SCRIBE_FILENAME$> // Generated on <$_SCRIBE_DATE$> // // Created by Andrzej Kapolka on 5/6/14. // Copyright 2014 High Fidelity, Inc. // Copyright 2024 Overte e.V. // // 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@> <@include CullFace.slh@> <@if HIFI_USE_MTOON@> <@if HIFI_USE_SHADOW@> <$declareMToonMaterialTextures(ALBEDO)$> <@if HIFI_USE_MIRROR@> TEXTURE(GRAPHICS_TEXTURE_MATERIAL_MIRROR, sampler2D, mirrorMap); <@endif@> <@else@> <@if HIFI_USE_NORMALMAP@> <$declareMToonMaterialTextures(ALBEDO, NORMAL, SHADE, EMISSIVE, SHADING_SHIFT, MATCAP, RIM, UV_ANIMATION_MASK)$> <@else@> <$declareMToonMaterialTextures(ALBEDO, _SCRIBE_NULL, SHADE, EMISSIVE, SHADING_SHIFT, MATCAP, RIM, UV_ANIMATION_MASK)$> <@endif@> <@endif@> <@else@> <@if HIFI_USE_SHADOW or HIFI_USE_UNLIT@> <$declareMaterialTextures(ALBEDO)$> <@if HIFI_USE_MIRROR@> TEXTURE(GRAPHICS_TEXTURE_MATERIAL_MIRROR, sampler2D, mirrorMap); <@endif@> <@else@> <@if not HIFI_USE_LIGHTMAP@> <@if HIFI_USE_TRANSLUCENT@> <@if HIFI_USE_NORMALMAP@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION)$> <@else@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC, EMISSIVE, OCCLUSION)$> <@endif@> <@else@> <@if HIFI_USE_NORMALMAP@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION, SCATTERING)$> <@else@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC, EMISSIVE, OCCLUSION, SCATTERING)$> <@endif@> <@endif@> <@else@> <@if HIFI_USE_NORMALMAP@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC)$> <@else@> <$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, METALLIC)$> <@endif@> <$declareMaterialLightmap()$> <@endif@> <@endif@> <@endif@> <@if HIFI_USE_TRIPLANAR@> struct TriplanarParams { vec4 scale; }; UNIFORM_BUFFER(GRAPHICS_BUFFER_TRIPLANAR_SCALE, triplanarParamsBuffer) { TriplanarParams triplanarParams; }; <@endif@> <@if HIFI_USE_SPLATMAP@> <$declareMaterialSplatMap()$> <@endif@> <@if not HIFI_USE_SHADOW@> <@if HIFI_USE_MTOON@> <@include DefaultMaterials.slh@> <@include GlobalLight.slh@> <@if HIFI_USE_FORWARD or HIFI_USE_TRANSLUCENT@> <$declareEvalGlobalLightingAlphaBlendedMToon(1)$> <@else@> <$declareEvalGlobalLightingAlphaBlendedMToon(_SCRIBE_NULL)$> <@endif@> <@include gpu/Transform.slh@> <$declareStandardCameraTransform()$> <@if HIFI_USE_FORWARD@> <@include LightLocal.slh@> <@endif@> <@elif HIFI_USE_FORWARD or HIFI_USE_TRANSLUCENT@> <@include DefaultMaterials.slh@> <@include GlobalLight.slh@> <@if HIFI_USE_LIGHTMAP@> <$declareEvalLightmappedColor()$> <@else@> <@include LightLocal.slh@> <$declareEvalGlobalLightingAlphaBlended()$> <@endif@> <@include gpu/Transform.slh@> <$declareStandardCameraTransform()$> <@endif@> <@if HIFI_USE_FORWARD@> OUTPUT(0, vec4, _fragColor0); <@else@> <@include DeferredBufferWrite.slh@> <@endif@> <@else@> <@if HIFI_USE_MIRROR@> <@if HIFI_USE_FORWARD@> OUTPUT(0, vec4, _fragColor0); <@else@> <@include DeferredBufferWrite.slh@> <@endif@> <@else@> OUTPUT(0, vec4, _fragColor0); <@endif@> <@endif@> <@include LightingModel.slh@> <@if HIFI_USE_FADE@> <@include Fade.slh@> <$declareFadeFragment()$> <@endif@> <@if HIFI_USE_NORMALMAP and HIFI_USE_TRIPLANAR@> <@include gpu/Transform.slh@> <$declareStandardObjectTransform()$> <@endif@> INPUT(RENDER_UTILS_ATTR_POSITION_WS, vec4, _positionWS); INPUT(RENDER_UTILS_ATTR_TEXCOORD01, vec4, _texCoord01[NUM_LAYERS]); #define _texCoords mat2[NUM_LAYERS]( \ mat2(_texCoord01[0].xy, _texCoord01[0].zw) \ <@if HIFI_USE_LAYERS2 or HIFI_USE_LAYERS3@> , mat2(_texCoord01[1].xy, _texCoord01[1].zw) \ <@endif@> <@if HIFI_USE_LAYERS3@> , mat2(_texCoord01[2].xy, _texCoord01[2].zw) \ <@endif@> ) <@if not HIFI_USE_SHADOW@> INPUT(RENDER_UTILS_ATTR_POSITION_ES, vec4, _positionES); INPUT(RENDER_UTILS_ATTR_NORMAL_WS, vec3, _normalWS); <@if not HIFI_USE_MTOON@> INPUT(RENDER_UTILS_ATTR_COLOR, vec4, _color); <@endif@> INPUT(RENDER_UTILS_ATTR_PREV_POSITION_CS, vec4, _prevPositionCS); <@if not HIFI_USE_TRIPLANAR@> <@if HIFI_USE_NORMALMAP@> INPUT(RENDER_UTILS_ATTR_TANGENT_WS, vec3, _tangentWS); <@endif@> <@endif@> <@endif@> <@if HIFI_USE_TRIPLANAR@> INPUT(RENDER_UTILS_ATTR_POSITION_MS, vec3, _positionMS); INPUT(RENDER_UTILS_ATTR_NORMAL_MS, vec3, _normalMS); <@endif@> void main(void) { <@if HIFI_USE_FADE@> <@if not HIFI_USE_SHADOW@> vec3 fadeEmissive; FadeObjectParams fadeParams; <$fetchFadeObjectParams(fadeParams)$> applyFade(fadeParams, _positionWS.xyz, fadeEmissive); <@else@> FadeObjectParams fadeParams; <$fetchFadeObjectParams(fadeParams)$> applyFadeClip(fadeParams, _positionWS.xyz); <@endif@> <@endif@> <@if not HIFI_USE_SHADOW@> vec3 normalWS = normalize(_normalWS); <@endif@> Material mats[NUM_LAYERS]; BITFIELD matKeys[NUM_LAYERS]; for (int layer = 0; layer < NUM_LAYERS; layer++) { Material mat = getMaterial(layer); mats[layer] = mat; matKeys[layer] = getMaterialKey(mat); } <@if HIFI_USE_SHADOW or HIFI_USE_UNLIT@> <@if not HIFI_USE_SHADOW@> vec3 albedo = vec3(0.0); <@endif@> float opacity = 0.0; <@if not HIFI_USE_TRIPLANAR@> <@if HIFI_USE_SPLATMAP@> vec3 layerBlend = fetchSplatMap(0, _texCoords[0]); // splatMap is only stored in the first material <@endif@> for (int layer = NUM_LAYERS - 1; layer >= 0; layer--) { <@if not HIFI_USE_MTOON@> <$fetchMaterialTextures(layer, matKeys[layer], _texCoords[layer], albedoTex, opacityCutoffTex)$> <@else@> <$fetchMToonMaterialTextures(layer, matKeys[layer], _texCoords[layer], albedoTex, opacityCutoffTex)$> <@endif@> <@else@> vec3 triplanarScale = triplanarParams.scale.xyz; <@if not HIFI_USE_MTOON@> <$fetchMaterialTexturesTriplanar(layerBlend, matKeys, _positionMS, _normalMS, _SCRIBE_NULL, _texCoord01, triplanarScale, albedoTex)$> <@else@> <$fetchMToonMaterialTexturesTriplanar(layerBlend, matKeys, _positionMS, _normalMS, _SCRIBE_NULL, _texCoord01, triplanarScale, albedoTex)$> <@endif@> float opacityCutoffTex = 1.0; <@if HIFI_USE_LAYERS3@> const int layerIndices[3] = int[3](0, 1, 2); <@elif HIFI_USE_LAYERS2@> const int layerIndices[3] = int[3](1, 0, 1); <@else@> const int layerIndices[3] = int[3](0, 0, 0); <@endif@> for (int i = 0; i < 3; i++) { int layer = layerIndices[i]; <@endif@> <@if not HIFI_USE_SHADOW@> vec3 albedoLayer = getMaterialAlbedo(mats[layer]); <$evalMaterialAlbedo(albedoTex, albedoLayer, matKeys[layer], albedoLayer)$> <@endif@> float cutoff = getMaterialOpacityCutoff(mats[layer]); <@if HIFI_USE_TRANSLUCENT@> float opacityLayer = getMaterialOpacity(mats[layer]); <$evalMaterialOpacity(albedoTex.a, cutoff, opacityLayer, matKeys[layer], opacityLayer)$> <@else@> float opacityLayer = 1.0; <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacityLayer, matKeys[layer], opacityLayer)$> <@endif@> opacityLayer *= opacityCutoffTex; <@if HIFI_USE_TRIPLANAR or HIFI_USE_SPLATMAP@> <@if HIFI_USE_TRIPLANAR@> float magnitude = layerBlend[i]; <@else@> float magnitude = layerBlend[layer]; <@endif@> <@if not HIFI_USE_SHADOW@> albedo += albedoLayer * magnitude; <@endif@> opacity += opacityLayer * magnitude; <@else@> if (layer == NUM_LAYERS - 1) { <@if not HIFI_USE_SHADOW@> albedo = albedoLayer; <@endif@> opacity = opacityLayer; } else { <@if not HIFI_USE_SHADOW@> albedo = mix(albedo, albedoLayer, opacityLayer); <@endif@> <$evalLayeredOpacity(opacity, opacityLayer, opacity)$> } <@endif@> } <@if HIFI_USE_TRANSLUCENT@> <@if not HIFI_USE_MTOON@> opacity *= _color.a; <@endif@> <$discardInvisible(opacity)$> <@else@> <$discardTransparent(opacity)$> <@endif@> <@if not HIFI_USE_SHADOW@> <@if not HIFI_USE_MTOON@> albedo *= _color.rgb; <@endif@> <@if HIFI_USE_FADE@> albedo += fadeEmissive; <@endif@> <@endif@> <@if HIFI_USE_MIRROR@> vec3 mirrorColor = texelFetch(mirrorMap, ivec2(gl_FragCoord.xy), 0).rgb; <@if HIFI_USE_FORWARD@> _fragColor0 = vec4(mirrorColor, 1.0); <@else@> // Mirrors have AA disabled packDeferredFragmentUnlit(vec4(0.0, 0.0, 0.0, 1.0), vec3(1.0, 0.0, 0.0), 1.0, mirrorColor); <@endif@> <@elif HIFI_USE_SHADOW@> _fragColor0 = vec4(1.0); <@elif HIFI_USE_FORWARD@> _fragColor0 = vec4(albedo * isUnlitEnabled(), opacity); <@elif HIFI_USE_TRANSLUCENT@> packDeferredFragmentTranslucentUnlit( opacity, albedo * isUnlitEnabled()); <@else@> packDeferredFragmentUnlit( _prevPositionCS, evalFrontOrBackFaceNormal(normalWS), opacity, albedo * isUnlitEnabled()); <@endif@> <@elif HIFI_USE_MTOON@> float time = getMaterialTime(mats[0]); // time is only stored in the first material vec3 albedo = vec3(0.0); float opacity = 0.0; vec3 emissive = vec3(0.0); vec3 fragNormalWS = vec3(0.0); vec3 shade = vec3(0.0); float shadingShift = 0.0; float shadingToony = 0.0; vec3 matcap = vec3(0.0); vec3 parametricRim = vec3(0.0); float parametricRimFresnelPower = 0.0; float parametricRimLift = 0.0; vec3 rimTex = vec3(0.0); float rimLightingMix = 0.0; <@if not HIFI_USE_TRIPLANAR@> <@if HIFI_USE_SPLATMAP@> vec3 layerBlend = fetchSplatMap(0, _texCoords[0]); // splatMap is only stored in the first material <@endif@> for (int layer = NUM_LAYERS - 1; layer >= 0; layer--) { vec3 uvScrollSpeed = getMaterialUVScrollSpeed(mats[layer]); <@if HIFI_USE_NORMALMAP@> <$fetchMToonMaterialTextures(layer, matKeys[layer], _texCoords[layer], albedoTex, opacityCutoffTex, normalTex, shadeTex, emissiveTex, shadingShiftTex, rimTexLayer, uvScrollSpeed, time)$> <@else@> <$fetchMToonMaterialTextures(layer, matKeys[layer], _texCoords[layer], albedoTex, opacityCutoffTex, _SCRIBE_NULL, shadeTex, emissiveTex, shadingShiftTex, rimTexLayer, uvScrollSpeed, time)$> <@endif@> <@else@> vec3 triplanarScale = triplanarParams.scale.xyz; vec3 uvScrollSpeed = getMaterialUVScrollSpeed(mats[0]); <@if HIFI_USE_NORMALMAP@> <$fetchMToonMaterialTexturesTriplanar(layerBlend, matKeys, _positionMS, _normalMS, normalWS, _texCoord01, triplanarScale, albedoTex, normalTex, shadeTex, emissiveTex, shadingShiftTex, rimTexLayer, uvScrollSpeed, time)$> <@else@> <$fetchMToonMaterialTexturesTriplanar(layerBlend, matKeys, _positionMS, _normalMS, _SCRIBE_NULL, _texCoord01, triplanarScale, albedoTex, _SCRIBE_NULL, shadeTex, emissiveTex, shadingShiftTex, rimTexLayer, uvScrollSpeed, time)$> <@endif@> float opacityCutoffTex = 1.0; <@if HIFI_USE_LAYERS3@> const int layerIndices[3] = int[3](0, 1, 2); <@elif HIFI_USE_LAYERS2@> const int layerIndices[3] = int[3](1, 0, 1); <@else@> const int layerIndices[3] = int[3](0, 0, 0); <@endif@> for (int i = 0; i < 3; i++) { int layer = layerIndices[i]; <@endif@> vec3 albedoLayer = getMaterialAlbedo(mats[layer]); <$evalMaterialAlbedo(albedoTex, albedoLayer, matKeys[layer], albedoLayer)$> float cutoff = getMaterialOpacityCutoff(mats[layer]); <@if HIFI_USE_TRANSLUCENT@> float opacityLayer = getMaterialOpacity(mats[layer]); <$evalMaterialOpacity(albedoTex.a, cutoff, opacityLayer, matKeys[layer], opacityLayer)$> <@else@> float opacityLayer = 1.0; <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacityLayer, matKeys[layer], opacityLayer)$> <@endif@> opacityLayer *= opacityCutoffTex; vec3 emissiveLayer = getMaterialEmissive(mats[layer]); <$evalMaterialEmissive(emissiveTex, emissiveLayer, matKeys[layer], emissiveLayer)$> <@if HIFI_USE_NORMALMAP@> vec3 fragNormalWSLayer; <@if not HIFI_USE_TRIPLANAR@> <$evalMaterialNormalLOD(_positionES, normalTex, normalWS, _tangentWS, fragNormalWSLayer)$> <@else@> <$evalMaterialNormalLODTriplanar(_positionES, normalTex, normalWS, fragNormalWSLayer)$> <@endif@> <@else@> vec3 fragNormalWSLayer = normalWS; <@endif@> fragNormalWSLayer = evalFrontOrBackFaceNormal(fragNormalWSLayer); vec3 shadeLayer = getMaterialShade(mats[layer]); <$evalMaterialShade(shadeTex, shadeLayer, matKeys[layer], shadeLayer)$> float shadingShiftLayer = getMaterialShadingShift(mats[layer]); <$evalMaterialShadingShift(shadingShiftTex, shadingShiftLayer, matKeys[layer], shadingShiftLayer)$> float shadingToonyLayer = getMaterialShadingToony(mats[layer]); vec3 matcapLayer = getMaterialMatcap(mats[layer]); vec3 parametricRimLayer = getMaterialParametricRim(mats[layer]); float parametricRimFresnelPowerLayer = getMaterialParametricRimFresnelPower(mats[layer]); float parametricRimLiftLayer = getMaterialParametricRimLift(mats[layer]); float rimLightingMixLayer = getMaterialRimLightingMix(mats[layer]); <@if HIFI_USE_TRIPLANAR or HIFI_USE_SPLATMAP@> <@if HIFI_USE_TRIPLANAR@> float magnitude = layerBlend[i]; <@else@> float magnitude = layerBlend[layer]; <@endif@> albedo += albedoLayer * magnitude; opacity += opacityLayer * magnitude; emissive += emissiveLayer * magnitude; fragNormalWS += fragNormalWSLayer * magnitude; shade += shadeLayer * magnitude; shadingShift += shadingShiftLayer * magnitude; shadingToony += shadingToonyLayer * magnitude; parametricRim += parametricRimLayer * magnitude; parametricRimFresnelPower += parametricRimFresnelPowerLayer * magnitude; parametricRimLift += parametricRimLiftLayer * magnitude; rimTex += rimTexLayer * magnitude; rimLightingMix += rimLightingMixLayer * magnitude; <@else@> if (layer == NUM_LAYERS - 1) { albedo = albedoLayer; opacity = opacityLayer; emissive = emissiveLayer; fragNormalWS = fragNormalWSLayer; shade = shadeLayer; shadingShift = shadingShiftLayer; shadingToony = shadingToonyLayer; parametricRim = parametricRimLayer; parametricRimFresnelPower = parametricRimFresnelPowerLayer; parametricRimLift = parametricRimLiftLayer; rimTex = rimTexLayer; rimLightingMix = rimLightingMixLayer; } else { albedo = mix(albedo, albedoLayer, opacityLayer); <$evalLayeredOpacity(opacity, opacityLayer, opacity)$> emissive = mix(emissive, emissiveLayer, opacityLayer); fragNormalWS = mix(fragNormalWS, fragNormalWSLayer, opacityLayer); shade = mix(shade, shadeLayer, opacityLayer); shadingShift = mix(shadingShift, shadingShiftLayer, opacityLayer); shadingToony = mix(shadingToony, shadingToonyLayer, opacityLayer); parametricRim = mix(parametricRim, parametricRimLayer, opacityLayer); parametricRimFresnelPower = mix(parametricRimFresnelPower, parametricRimFresnelPowerLayer, opacityLayer); parametricRimLift = mix(parametricRimLift, parametricRimLiftLayer, opacityLayer); rimTex = mix(rimTex, rimTexLayer, opacityLayer); rimLightingMix = mix(rimLightingMix, rimLightingMixLayer, opacityLayer); } <@endif@> } fragNormalWS = normalize(fragNormalWS); <@if HIFI_USE_TRANSLUCENT@> <$discardInvisible(opacity)$> <@else@> <$discardTransparent(opacity)$> <@endif@> TransformCamera cam = getTransformCamera(); float metallic = DEFAULT_METALLIC; vec3 fresnel = getFresnelF0(metallic, albedo); vec4 color = vec4(evalGlobalLightingAlphaBlendedMToon( cam._viewInverse, 1.0, _positionES.xyz, fragNormalWS, albedo, fresnel, metallic, emissive, DEFAULT_ROUGHNESS, opacity, shade, shadingShift, shadingToony, matcap, parametricRim, parametricRimFresnelPower, parametricRimLift, rimTex, rimLightingMix, matKeys[0]), opacity); <@if HIFI_USE_FORWARD@> vec3 fragPositionWS = _positionWS.xyz; vec3 fragToEyeWS = cam._viewInverse[3].xyz - fragPositionWS; vec3 fragToEyeDirWS = normalize(fragToEyeWS); SurfaceData surfaceWS = initSurfaceData(DEFAULT_ROUGHNESS, fragNormalWS, fragToEyeDirWS); vec4 localLighting = vec4(0.0); <$fetchClusterInfo(_positionWS)$> if (hasLocalLights(numLights, clusterPos, dims)) { localLighting = evalLocalLighting(cluster, numLights, fragPositionWS, surfaceWS, metallic, fresnel, albedo, 0.0, vec4(0), vec4(0), opacity); } color.rgb += localLighting.rgb; _fragColor0 = isUnlitEnabled() * vec4(color.rgb <@if HIFI_USE_FADE@> + fadeEmissive <@endif@> , color.a); <@elif HIFI_USE_TRANSLUCENT@> packDeferredFragmentTranslucentUnlit( color.a, color.rgb <@if HIFI_USE_FADE@> + fadeEmissive <@endif@> ); <@else@> packDeferredFragmentUnlit( _prevPositionCS, fragNormalWS, 1.0, color.rgb <@if HIFI_USE_FADE@> + fadeEmissive <@endif@> ); <@endif@> <@else@> vec3 albedo = vec3(0.0); float opacity = 0.0; vec3 fragNormalWS = vec3(0.0); float roughness = 0.0; float metallic = 0.0; <@if not HIFI_USE_LIGHTMAP@> vec3 emissive = vec3(0.0); float occlusion = 0.0; <@if not HIFI_USE_TRANSLUCENT@> float scattering = 0.0; <@endif@> <@else@> vec3 lightmap = vec3(0.0); <@endif@> <@if not HIFI_USE_TRIPLANAR@> <@if HIFI_USE_SPLATMAP@> vec3 layerBlend = fetchSplatMap(0, _texCoords[0]); // splatMap is only stored in the first material <@endif@> for (int layer = NUM_LAYERS - 1; layer >= 0; layer--) { <@if not HIFI_USE_LIGHTMAP@> <@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@> <$fetchMaterialTextures(layer, matKeys[layer], _texCoords[layer], albedoTex, opacityCutoffTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$> <@elif HIFI_USE_NORMALMAP@> <$fetchMaterialTextures(layer, matKeys[layer], _texCoords[layer], albedoTex, opacityCutoffTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex, occlusionTex)$> <@elif HIFI_USE_TRANSLUCENT@> <$fetchMaterialTextures(layer, matKeys[layer], _texCoords[layer], albedoTex, opacityCutoffTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$> <@else@> <$fetchMaterialTextures(layer, matKeys[layer], _texCoords[layer], albedoTex, opacityCutoffTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex, occlusionTex)$> <@endif@> <@else@> <@if HIFI_USE_NORMALMAP@> <$fetchMaterialTextures(layer, matKeys[layer], _texCoords[layer], albedoTex, opacityCutoffTex, roughnessTex, normalTex, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmapTex)$> <@else@> <$fetchMaterialTextures(layer, matKeys[layer], _texCoords[layer], albedoTex, opacityCutoffTex, roughnessTex, _SCRIBE_NULL, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmapTex)$> <@endif@> <@endif@> <@else@> vec3 triplanarScale = triplanarParams.scale.xyz; <@if not HIFI_USE_LIGHTMAP@> <@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@> <$fetchMaterialTexturesTriplanar(layerBlend, matKeys, _positionMS, _normalMS, normalWS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$> <@elif HIFI_USE_NORMALMAP@> <$fetchMaterialTexturesTriplanar(layerBlend, matKeys, _positionMS, _normalMS, normalWS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex, occlusionTex)$> <@elif HIFI_USE_TRANSLUCENT@> <$fetchMaterialTexturesTriplanar(layerBlend, matKeys, _positionMS, _normalMS, _SCRIBE_NULL, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$> <@else@> <$fetchMaterialTexturesTriplanar(layerBlend, matKeys, _positionMS, _normalMS, _SCRIBE_NULL, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex, occlusionTex)$> <@endif@> <@else@> <@if HIFI_USE_NORMALMAP@> <$fetchMaterialTexturesTriplanar(layerBlend, matKeys, _positionMS, _normalMS, normalWS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmapTex)$> <@else@> <$fetchMaterialTexturesTriplanar(layerBlend, matKeys, _positionMS, _normalMS, _SCRIBE_NULL, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmapTex)$> <@endif@> <@endif@> float opacityCutoffTex = 1.0; <@if HIFI_USE_LAYERS3@> const int layerIndices[3] = int[3](0, 1, 2); <@elif HIFI_USE_LAYERS2@> const int layerIndices[3] = int[3](1, 0, 1); <@else@> const int layerIndices[3] = int[3](0, 0, 0); <@endif@> for (int i = 0; i < 3; i++) { int layer = layerIndices[i]; <@endif@> vec3 albedoLayer = getMaterialAlbedo(mats[layer]); <$evalMaterialAlbedo(albedoTex, albedoLayer, matKeys[layer], albedoLayer)$> float cutoff = getMaterialOpacityCutoff(mats[layer]); <@if HIFI_USE_TRANSLUCENT@> float opacityLayer = getMaterialOpacity(mats[layer]); <$evalMaterialOpacity(albedoTex.a, cutoff, opacityLayer, matKeys[layer], opacityLayer)$> <@else@> float opacityLayer = 1.0; <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacityLayer, matKeys[layer], opacityLayer)$> <@endif@> opacityLayer *= opacityCutoffTex; float roughnessLayer = getMaterialRoughness(mats[layer]); <$evalMaterialRoughness(roughnessTex, roughnessLayer, matKeys[layer], roughnessLayer)$> float metallicLayer = getMaterialMetallic(mats[layer]); <$evalMaterialMetallic(metallicTex, metallicLayer, matKeys[layer], metallicLayer)$> <@if not HIFI_USE_LIGHTMAP@> vec3 emissiveLayer = getMaterialEmissive(mats[layer]); <$evalMaterialEmissive(emissiveTex, emissiveLayer, matKeys[layer], emissiveLayer)$> float occlusionLayer = DEFAULT_OCCLUSION; <$evalMaterialOcclusion(occlusionTex, matKeys[layer], occlusionLayer)$> <@if not HIFI_USE_TRANSLUCENT@> float scatteringLayer = getMaterialScattering(mats[layer]); <$evalMaterialScattering(scatteringTex, scatteringLayer, matKeys[layer], scatteringLayer)$> <@endif@> <@endif@> <@if HIFI_USE_NORMALMAP@> vec3 fragNormalWSLayer; <@if not HIFI_USE_TRIPLANAR@> <$evalMaterialNormalLOD(_positionES, normalTex, normalWS, _tangentWS, fragNormalWSLayer)$> <@else@> <$evalMaterialNormalLODTriplanar(_positionES, normalTex, normalWS, fragNormalWSLayer)$> <@endif@> <@else@> vec3 fragNormalWSLayer = normalWS; <@endif@> fragNormalWSLayer = evalFrontOrBackFaceNormal(fragNormalWSLayer); <@if HIFI_USE_TRIPLANAR or HIFI_USE_SPLATMAP@> <@if HIFI_USE_TRIPLANAR@> float magnitude = layerBlend[i]; <@else@> float magnitude = layerBlend[layer]; <@endif@> albedo += albedoLayer * magnitude; opacity += opacityLayer * magnitude; fragNormalWS += fragNormalWSLayer * magnitude; roughness += roughnessLayer * magnitude; metallic += metallicLayer * magnitude; <@if not HIFI_USE_LIGHTMAP@> emissive += emissiveLayer * magnitude; occlusion += occlusionLayer * magnitude; <@if not HIFI_USE_TRANSLUCENT@> scattering += scatteringLayer * magnitude; <@endif@> <@else@> lightmap += lightmapTex * magnitude; <@endif@> <@else@> if (layer == NUM_LAYERS - 1) { albedo = albedoLayer; opacity = opacityLayer; fragNormalWS = fragNormalWSLayer; roughness = roughnessLayer; metallic = metallicLayer; <@if not HIFI_USE_LIGHTMAP@> emissive = emissiveLayer; occlusion = occlusionLayer; <@if not HIFI_USE_TRANSLUCENT@> scattering = scatteringLayer; <@endif@> <@else@> lightmap = lightmapTex; <@endif@> } else { albedo = mix(albedo, albedoLayer, opacityLayer); <$evalLayeredOpacity(opacity, opacityLayer, opacity)$> fragNormalWS = mix(fragNormalWS, fragNormalWSLayer, opacityLayer); roughness = mix(roughness, roughnessLayer, opacityLayer); metallic = mix(metallic, metallicLayer, opacityLayer); <@if not HIFI_USE_LIGHTMAP@> emissive = mix(emissive, emissiveLayer, opacityLayer); occlusion = mix(occlusion, occlusionLayer, opacityLayer); <@if not HIFI_USE_TRANSLUCENT@> scattering = mix(scattering, scatteringLayer, opacityLayer); <@endif@> <@else@> lightmap = mix(lightmap, lightmapTex, opacityLayer); <@endif@> } <@endif@> } albedo *= _color.rgb; fragNormalWS = normalize(fragNormalWS); <@if HIFI_USE_TRANSLUCENT@> opacity *= _color.a; <$discardInvisible(opacity)$> <@else@> <$discardTransparent(opacity)$> <@endif@> <@if HIFI_USE_FORWARD@> TransformCamera cam = getTransformCamera(); vec3 fresnel = getFresnelF0(metallic, albedo); <@if not HIFI_USE_LIGHTMAP@> vec3 fragPositionWS = _positionWS.xyz; vec3 fragToEyeWS = cam._viewInverse[3].xyz - fragPositionWS; vec3 fragToEyeDirWS = normalize(fragToEyeWS); SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragToEyeDirWS); vec4 localLighting = vec4(0.0); <$fetchClusterInfo(_positionWS)$> if (hasLocalLights(numLights, clusterPos, dims)) { localLighting = evalLocalLighting(cluster, numLights, fragPositionWS, surfaceWS, metallic, fresnel, albedo, 0.0, vec4(0), vec4(0), opacity); } _fragColor0 = vec4(evalGlobalLightingAlphaBlended( cam._viewInverse, 1.0, occlusion, _positionES.xyz, fragNormalWS, albedo, fresnel, metallic, emissive <@if HIFI_USE_FADE@> + fadeEmissive <@endif@> , surfaceWS, opacity, localLighting.rgb), opacity); <@else@> _fragColor0 = vec4(evalLightmappedColor( cam._viewInverse, 1.0, DEFAULT_OCCLUSION, fragNormalWS, albedo, lightmap), opacity); <@endif@> <@else@> <@if not HIFI_USE_TRANSLUCENT@> <@if not HIFI_USE_LIGHTMAP@> packDeferredFragment( _prevPositionCS, fragNormalWS, opacity, albedo, roughness, metallic, emissive <@if HIFI_USE_FADE@> + fadeEmissive <@endif@> , occlusion, scattering); <@else@> packDeferredFragmentLightmap( _prevPositionCS, fragNormalWS, opacity, albedo, roughness, metallic, lightmap <@if HIFI_USE_FADE@> + fadeEmissive <@endif@> ); <@endif@> <@else@> TransformCamera cam = getTransformCamera(); <@if not HIFI_USE_LIGHTMAP@> vec3 fresnel = getFresnelF0(metallic, albedo); vec3 fragPositionWS = _positionWS.xyz; vec3 fragToEyeWS = cam._viewInverse[3].xyz - fragPositionWS; vec3 fragToEyeDirWS = normalize(fragToEyeWS); SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragToEyeDirWS); vec4 localLighting = vec4(0.0); <$fetchClusterInfo(_positionWS)$> if (hasLocalLights(numLights, clusterPos, dims)) { localLighting = evalLocalLighting(cluster, numLights, fragPositionWS, surfaceWS, metallic, fresnel, albedo, 0.0, vec4(0), vec4(0), opacity); } vec4 outColor = vec4(evalGlobalLightingAlphaBlended( cam._viewInverse, 1.0, occlusion, _positionES.xyz, fragNormalWS, albedo, fresnel, metallic, emissive <@if HIFI_USE_FADE@> + fadeEmissive <@endif@> , surfaceWS, opacity, localLighting.rgb), opacity); packDeferredFragmentTranslucentUnlit(outColor.a, outColor.rgb); <@else@> vec4 outColor = vec4(evalLightmappedColor( cam._viewInverse, 1.0, DEFAULT_OCCLUSION, fragNormalWS, albedo, lightmap), opacity); packDeferredFragmentLightmap(_prevPositionCS, fragNormalWS, outColor.a, outColor.rgb, roughness, metallic, outColor.rgb); <@endif@> <@endif@> <@endif@> <@endif@> }