<div dir="auto">It makes sense to stay compatible with glTF but what is the reason to scale x and y instead of just only scaling z ?<div dir="auto"><br></div><div dir="auto">normal_tangent *= vec3(1.0, 1.0, castle_normalScale);</div><div dir="auto"><br></div><div dir="auto">It would have the same effect (just reciprocal) and is conceptually cleaner.</div><div dir="auto"><br></div><div dir="auto">Thanks, Andreas</div><div dir="auto"><br><div dir="auto"><br><div class="gmail_quote" dir="auto"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
<br>
In short, the spec equation is correct. Let me explain why and what is<br>
the purpose of it:<br>
<br>
( BTW, this is consistent with glTF material.normalTextureInfo.scale,<br>
<a href="https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_material_normaltextureinfo_scale" rel="noreferrer noreferrer" target="_blank">https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_material_normaltextureinfo_scale</a><br>
).<br>
<br>
1. We deliberately multiply only XY (and not Z) components.<br>
Intuitively, "normalScale" allows the normalmap effect to be:<br>
<br>
- more emphasized, when normalScale > 1 (larger normalScale => larger<br>
XY compared to Z in tangent space => the effect of the normal map is<br>
more visible, as the surface looks more "rough")<br>
<br>
- or deemphasized, , when normalScale < 1 (smaller normalScale => the<br>
normals resemble more (0,0,1) in tangent space => normalmap effect is<br>
less visible)<br>
<br>
Multiplying all 3 vector components by normalScale wouldn't have any<br>
effect, indeed. As you say, the whole vector is normalized anyway.<br>
<br>
Note that this means that, regardless of the normalScale value, the<br>
lighting equations *always* work with normalized vectors. Using the<br>
"normalScale" doesn't make them non-normalized. This is deliberate,<br>
lighting equations in general are prepared assuming that normals<br>
(after all processing) are normalized.<br>
<br>
2. Here's CGE/view3dscene implementation of it:<br>
<br>
<a href="https://github.com/castle-engine/castle-engine/blob/master/src/scene/glsl/source/bump_mapping.fs#L28" rel="noreferrer noreferrer" target="_blank">https://github.com/castle-engine/castle-engine/blob/master/src/scene/glsl/source/bump_mapping.fs#L28</a><br>
<br>
It's just<br>
<br>
"""<br>
 vec3 normal_tangent = texture2D(castle_normal_map,<br>
    castle_TexCoord<NormalMapTextureCoordinatesId>.st).xyz * 2.0 - vec3(1.0);<br>
<br>
  normal_tangent *= vec3(castle_normalScale, castle_normalScale, 1.0);<br>
"""<br>
<br>
We normalize later.<br>
<br>
3. I created test model for it:<br>
<br>
<a href="https://github.com/michaliskambi/x3d-tests/blob/master/pbr/enhanced_phong_material/bump_mapping_normalscale.x3dv" rel="noreferrer noreferrer" target="_blank">https://github.com/michaliskambi/x3d-tests/blob/master/pbr/enhanced_phong_material/bump_mapping_normalscale.x3dv</a><br>
<br>
with correct output on<br>
<br>
<a href="https://github.com/michaliskambi/x3d-tests/blob/master/pbr/enhanced_phong_material/bump_mapping_normalscale.png" rel="noreferrer noreferrer" target="_blank">https://github.com/michaliskambi/x3d-tests/blob/master/pbr/enhanced_phong_material/bump_mapping_normalscale.png</a><br>
<br>
4. I did just confirm it quickly looking at glTF sample viewer implementation:<br>
<br>
<a href="https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/master/source/Renderer/shaders/material_info.glsl#L141" rel="noreferrer noreferrer" target="_blank">https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/master/source/Renderer/shaders/material_info.glsl#L141</a><br>
<br>
They do this (comments from me):<br>
<br>
"""<br>
#ifdef HAS_NORMAL_MAP<br>
<br>
info.ntex = texture(u_NormalSampler, UV).rgb * 2.0 - vec3(1.0);  //<br>
get normal vector from texture<br>
<br>
info.ntex *= vec3(u_NormalScale, u_NormalScale, 1.0); // multiply XY<br>
by normalScale<br>
<br>
info.ntex = normalize(info.ntex); // normalize<br>
<br>
info.n = normalize(mat3(t, b, ng) * info.ntex); // convert from<br>
tangent space to proper space (didn't check now whether this is to<br>
object or eye space)<br>
...<br>
"""<br>
<br>
Regards,<br>
Michalis<br>
<br>
<br>
sob., 2 kwi 2022 o 10:06 Holger Seelig <<a href="mailto:holger.seelig@yahoo.de" target="_blank" rel="noreferrer">holger.seelig@yahoo.de</a>> napisa?(a):<br>
><br>
> Looking at X3DOneSidedMaterialNode <a href="https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4-CD1/Part01/components/shape.html#X3DOneSidedMaterialNode" rel="noreferrer noreferrer" target="_blank">https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4-CD1/Part01/components/shape.html#X3DOneSidedMaterialNode</a> I can find there the calculation of the normal as following:<br>
><br>
> <a href="http://normal.xyz" rel="noreferrer noreferrer" target="_blank">normal.xyz</a> = normalize((textureSample(normalTexture).rgb * vec3(2,2,2) - vec3(1,1,1)) * vec3(normalScale, normalScale, 1))<br>
><br>
> Think the handling of normalScale is wrong, the vector must include 3 times normalScale, not z equal 1, like so:<br>
><br>
> vec3(normalScale, normalScale, normalScale)<br>
><br>
> The second issue I notices is that the normalScale is applied before normalization, but that means that it has not effect. Normalization means multiplying the vector with a factor, so that the length of the vector is one (1), this makes the multiplication with the normalScale factor undone.<br>
><br>
> Best regards,<br>
> Holger.<br>
><br>
> _______________________________________________<br>
> x3d-public mailing list<br>
> <a href="mailto:x3d-public@web3d.org" target="_blank" rel="noreferrer">x3d-public@web3d.org</a><br>
> <a href="http://web3d.org/mailman/listinfo/x3d-public_web3d.org" rel="noreferrer noreferrer" target="_blank">http://web3d.org/mailman/listinfo/x3d-public_web3d.org</a><br>
-------------- next part --------------<br>
A non-text attachment was scrubbed...<br>
Name: bump_mapping_normalscale.x3dv<br>
Type: application/octet-stream<br>
Size: 6485 bytes<br>
Desc: not available<br>
URL: <<a href="http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20220403/cdf75004/attachment.obj" rel="noreferrer noreferrer" target="_blank">http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20220403/cdf75004/attachment.obj</a>><br>
-------------- next part --------------<br>
A non-text attachment was scrubbed...<br>
Name: bump_mapping_normalscale.png<br>
Type: image/png<br>
Size: 382578 bytes<br>
Desc: not available<br>
URL: <<a href="http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20220403/cdf75004/attachment.png" rel="noreferrer noreferrer" target="_blank">http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20220403/cdf75004/attachment.png</a>><br>
<br>
------------------------------<br>
<br>
Subject: Digest Footer<br>
<br>
_______________________________________________<br>
x3d-public mailing list<br>
<a href="mailto:x3d-public@web3d.org" target="_blank" rel="noreferrer">x3d-public@web3d.org</a><br>
<a href="http://web3d.org/mailman/listinfo/x3d-public_web3d.org" rel="noreferrer noreferrer" target="_blank">http://web3d.org/mailman/listinfo/x3d-public_web3d.org</a><br>
<br>
<br>
------------------------------<br>
<br>
End of x3d-public Digest, Vol 157, Issue 4<br>
******************************************<br>
</blockquote></div></div></div></div>