Merge pull request #1656 from HifiExperiments/triplanarNormals
Some checks failed
Master API-docs CI Build and Deploy / Build and deploy API-docs (push) Has been cancelled
Master Doxygen CI Build and Deploy / Build and deploy Doxygen documentation (push) Has been cancelled

fix triplanar normal mapping with non-uniform scale
This commit is contained in:
ksuprynowicz 2025-07-01 22:49:02 +02:00 committed by GitHub
commit 587bec6b95
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 40 additions and 25 deletions

View file

@ -335,6 +335,15 @@ TransformObject getTransformObject() {
}
<@endfunc@>
<@func transformModelToWorldDirNoScale(objectTransform, modelDir, worldDir)@>
{ // transformModelToWorldDir
vec3 mr0 = normalize(vec3(<$objectTransform$>._modelInverse[0].x, <$objectTransform$>._modelInverse[1].x, <$objectTransform$>._modelInverse[2].x));
vec3 mr1 = normalize(vec3(<$objectTransform$>._modelInverse[0].y, <$objectTransform$>._modelInverse[1].y, <$objectTransform$>._modelInverse[2].y));
vec3 mr2 = normalize(vec3(<$objectTransform$>._modelInverse[0].z, <$objectTransform$>._modelInverse[1].z, <$objectTransform$>._modelInverse[2].z));
<$worldDir$> = vec3(dot(mr0, <$modelDir$>), dot(mr1, <$modelDir$>), dot(mr2, <$modelDir$>));
}
<@endfunc@>
<@func transformModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@>
{ // transformModelToEyeDir
vec3 mr0 = vec3(<$objectTransform$>._modelInverse[0].x, <$objectTransform$>._modelInverse[1].x, <$objectTransform$>._modelInverse[2].x);

View file

@ -38,7 +38,7 @@
{
// attenuate the normal map divergence from the mesh normal based on distance
// The attenuation range [30,100] meters from the eye is arbitrary for now
<$normal$> = mix(<$fetchedNormal$>, <$interpolatedNormal$>, smoothstep(30.0, 100.0, (-<$fragPosES$>).z));
<$normal$> = normalize(mix(<$fetchedNormal$>, <$interpolatedNormal$>, smoothstep(30.0, 100.0, (-<$fragPosES$>).z)));
}
<@endfunc@>
@ -391,7 +391,7 @@ vec3 fetchLightMap(int layer, mat2 uvs) {
<@if HIFI_USE_TRIPLANAR@>
<@func fetchMaterialTexturesTriplanar(matKeys, positionMS, normalMS, texCoords, triplanarScale, albedo, roughness, normal, metallic, emissive, scattering, occlusion, lightmap)@>
<@func fetchMaterialTexturesTriplanar(matKeys, positionMS, normalMS, normalWS, texCoords, triplanarScale, albedo, roughness, normal, metallic, emissive, scattering, occlusion, lightmap)@>
vec3 inPosition = (<$positionMS$> - vec3(0.5)) / <$triplanarScale$>.xyz;
vec3 normalMS = normalize(<$normalMS$>);
@ -559,10 +559,11 @@ vec3 fetchLightMap(int layer, mat2 uvs) {
float <$roughness$> = <$roughness$>Triplanar;
<@endif@>
<@if normal@>
vec3 <$normal$> = normalize(<$normal$>Triplanar + normalMS.xyz);
vec3 <$normal$> = <$normal$>Triplanar;
{
TransformObject obj = getTransformObject();
<$transformModelToWorldDir(obj, $normal$, $normal$)$>
<$transformModelToWorldDirNoScale(obj, $normal$, $normal$)$>
<$normal$> = normalize(<$normal$> + normalWS);
}
<@endif@>
<@if metallic@>
@ -900,7 +901,7 @@ float fetchUVAnimationMaskMap(int layer, mat2 uvs) {
<@if HIFI_USE_TRIPLANAR@>
<@func fetchMToonMaterialTexturesTriplanar(matKeys, positionMS, normalMS, texCoords, triplanarScale, albedo, normal, shade, emissive, shadingShift, rim, uvScrollSpeed, time)@>
<@func fetchMToonMaterialTexturesTriplanar(matKeys, positionMS, normalMS, normalWS, texCoords, triplanarScale, albedo, normal, shade, emissive, shadingShift, rim, uvScrollSpeed, time)@>
vec3 inPosition = (<$positionMS$> - vec3(0.5)) / <$triplanarScale$>.xyz;
vec3 normalMS = normalize(<$normalMS$>);
@ -1041,10 +1042,11 @@ float fetchUVAnimationMaskMap(int layer, mat2 uvs) {
vec4 <$albedo$> = <$albedo$>Triplanar;
<@endif@>
<@if normal@>
vec3 <$normal$> = normalize(<$normal$>Triplanar + normalMS.xyz);
vec3 <$normal$> = <$normal$>Triplanar;
{
TransformObject obj = getTransformObject();
<$transformModelToWorldDir(obj, $normal$, $normal$)$>
<$transformModelToWorldDirNoScale(obj, $normal$, $normal$)$>
<$normal$> = normalize(<$normal$> + normalWS);
}
<@endif@>
<@if shade@>

View file

@ -171,6 +171,10 @@ void main(void) {
<@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++) {
@ -188,9 +192,9 @@ void main(void) {
<@else@>
vec3 triplanarScale = triplanarParams.scale.xyz;
<@if not HIFI_USE_MTOON@>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _SCRIBE_NULL, _texCoord01, triplanarScale, albedoTex)$>
<@else@>
<$fetchMToonMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex)$>
<$fetchMToonMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _SCRIBE_NULL, _texCoord01, triplanarScale, albedoTex)$>
<@endif@>
<@endif@>
@ -234,13 +238,13 @@ void main(void) {
<@elif HIFI_USE_TRANSLUCENT@>
packDeferredFragmentTranslucentUnlit(
_prevPositionCS,
evalFrontOrBackFaceNormal(normalize(_normalWS)),
evalFrontOrBackFaceNormal(normalWS),
opacity,
albedo * isUnlitEnabled());
<@else@>
packDeferredFragmentUnlit(
_prevPositionCS,
evalFrontOrBackFaceNormal(normalize(_normalWS)),
evalFrontOrBackFaceNormal(normalWS),
opacity,
albedo * isUnlitEnabled());
<@endif@>
@ -273,14 +277,14 @@ void main(void) {
<@if HIFI_USE_NORMALMAP@>
vec3 fragNormalWS;
<@if not HIFI_USE_TRIPLANAR@>
<$evalMaterialNormalLOD(_positionES, normalTex, _normalWS, _tangentWS, fragNormalWS)$>
<$evalMaterialNormalLOD(_positionES, normalTex, normalWS, _tangentWS, fragNormalWS)$>
<@else@>
<$evalMaterialNormalLODTriplanar(_positionES, normalTex, _normalWS, fragNormalWS)$>
<$evalMaterialNormalLODTriplanar(_positionES, normalTex, normalWS, fragNormalWS)$>
<@endif@>
<@else@>
vec3 fragNormalWS = _normalWS;
vec3 fragNormalWS = normalWS;
<@endif@>
fragNormalWS = evalFrontOrBackFaceNormal(normalize(fragNormalWS));
fragNormalWS = evalFrontOrBackFaceNormal(fragNormalWS);
vec3 shade = getMaterialShade(mats[0]);
<$evalMaterialShade(shadeTex, shade, matKeys[0], shade)$>;
@ -349,19 +353,19 @@ void main(void) {
vec3 triplanarScale = triplanarParams.scale.xyz;
<@if not HIFI_USE_LIGHTMAP@>
<@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, normalWS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<@elif HIFI_USE_NORMALMAP@>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, normalWS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<@elif HIFI_USE_TRANSLUCENT@>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _SCRIBE_NULL, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<@else@>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _SCRIBE_NULL, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<@endif@>
<@else@>
<@if HIFI_USE_NORMALMAP@>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, normalWS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<@else@>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _SCRIBE_NULL, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<@endif@>
<@endif@>
<@endif@>
@ -403,14 +407,14 @@ void main(void) {
<@if HIFI_USE_NORMALMAP@>
vec3 fragNormalWS;
<@if not HIFI_USE_TRIPLANAR@>
<$evalMaterialNormalLOD(_positionES, normalTex, _normalWS, _tangentWS, fragNormalWS)$>
<$evalMaterialNormalLOD(_positionES, normalTex, normalWS, _tangentWS, fragNormalWS)$>
<@else@>
<$evalMaterialNormalLODTriplanar(_positionES, normalTex, _normalWS, fragNormalWS)$>
<$evalMaterialNormalLODTriplanar(_positionES, normalTex, normalWS, fragNormalWS)$>
<@endif@>
<@else@>
vec3 fragNormalWS = _normalWS;
vec3 fragNormalWS = normalWS;
<@endif@>
fragNormalWS = evalFrontOrBackFaceNormal(normalize(fragNormalWS));
fragNormalWS = evalFrontOrBackFaceNormal(fragNormalWS);
<@if HIFI_USE_FORWARD@>
TransformCamera cam = getTransformCamera();