[x3d-public] Calculation of normal from normalTexture.
Michalis Kamburelis
michalis.kambi at gmail.com
Sat Apr 2 22:01:33 PDT 2022
In general, as both approaches make sense ("multiply only XY" or
"multiply only Z"), for X3D it's better to just follow glTF.
As for the rationale behind glTF decision -- one reason that comes to
my mind is that in current glTF and X3D version ("multiply only XY")
- if one wants to *almost* disable normal texture, then you can use
just very small "normalScale" values.
- and "normalScale" = 0 has (expected) result that "normal map effect
is completely disabled".
Whereas in "multiply only Z" approach, "normal *= vec3(1, 1,
normalScale)", to deemphasize normal map one has to invent huge
values, as normalScale must reach infinity if you want to really make
normal XY irrelevant. And in this approach, "normalScale = 0" achieves
normals that are always orthogonal to the surface (never "coming out"
of the polygon), which I guess is less often a useful effect, or maybe
it seems less natural.
For authors, the the definition "multiply only XY" seems easier to
explain: "normalScale" allows to "emphasie" the normal map, bigger ->
more emphasized. This seems more natural, at least with such wording.
The above is just my hypothesis "why glTF did it this way". I didn't
look at any conversation archives from Khronos to actually find out
the real reasons.
Both versions seem "basically sensible to achieve the same function",
so it's just better to follow the glTF.
Regards,
Michalis
niedz., 3 kwi 2022 o 06:35 Andreas Plesch <andreasplesch at gmail.com> napisał(a):
>
> It makes sense to stay compatible with glTF but what is the reason to scale x and y instead of just only scaling z ?
>
> normal_tangent *= vec3(1.0, 1.0, castle_normalScale);
>
> It would have the same effect (just reciprocal) and is conceptually cleaner.
>
> Thanks, Andreas
>
>
>>
>>
>> In short, the spec equation is correct. Let me explain why and what is
>> the purpose of it:
>>
>> ( BTW, this is consistent with glTF material.normalTextureInfo.scale,
>> https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_material_normaltextureinfo_scale
>> ).
>>
>> 1. We deliberately multiply only XY (and not Z) components.
>> Intuitively, "normalScale" allows the normalmap effect to be:
>>
>> - more emphasized, when normalScale > 1 (larger normalScale => larger
>> XY compared to Z in tangent space => the effect of the normal map is
>> more visible, as the surface looks more "rough")
>>
>> - or deemphasized, , when normalScale < 1 (smaller normalScale => the
>> normals resemble more (0,0,1) in tangent space => normalmap effect is
>> less visible)
>>
>> Multiplying all 3 vector components by normalScale wouldn't have any
>> effect, indeed. As you say, the whole vector is normalized anyway.
>>
>> Note that this means that, regardless of the normalScale value, the
>> lighting equations *always* work with normalized vectors. Using the
>> "normalScale" doesn't make them non-normalized. This is deliberate,
>> lighting equations in general are prepared assuming that normals
>> (after all processing) are normalized.
>>
>> 2. Here's CGE/view3dscene implementation of it:
>>
>> https://github.com/castle-engine/castle-engine/blob/master/src/scene/glsl/source/bump_mapping.fs#L28
>>
>> It's just
>>
>> """
>> vec3 normal_tangent = texture2D(castle_normal_map,
>> castle_TexCoord<NormalMapTextureCoordinatesId>.st).xyz * 2.0 - vec3(1.0);
>>
>> normal_tangent *= vec3(castle_normalScale, castle_normalScale, 1.0);
>> """
>>
>> We normalize later.
>>
>> 3. I created test model for it:
>>
>> https://github.com/michaliskambi/x3d-tests/blob/master/pbr/enhanced_phong_material/bump_mapping_normalscale.x3dv
>>
>> with correct output on
>>
>> https://github.com/michaliskambi/x3d-tests/blob/master/pbr/enhanced_phong_material/bump_mapping_normalscale.png
>>
>> 4. I did just confirm it quickly looking at glTF sample viewer implementation:
>>
>> https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/master/source/Renderer/shaders/material_info.glsl#L141
>>
>> They do this (comments from me):
>>
>> """
>> #ifdef HAS_NORMAL_MAP
>>
>> info.ntex = texture(u_NormalSampler, UV).rgb * 2.0 - vec3(1.0); //
>> get normal vector from texture
>>
>> info.ntex *= vec3(u_NormalScale, u_NormalScale, 1.0); // multiply XY
>> by normalScale
>>
>> info.ntex = normalize(info.ntex); // normalize
>>
>> info.n = normalize(mat3(t, b, ng) * info.ntex); // convert from
>> tangent space to proper space (didn't check now whether this is to
>> object or eye space)
>> ...
>> """
>>
>> Regards,
>> Michalis
>>
>>
>> sob., 2 kwi 2022 o 10:06 Holger Seelig <holger.seelig at yahoo.de> napisa?(a):
>> >
>> > Looking at X3DOneSidedMaterialNode https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4-CD1/Part01/components/shape.html#X3DOneSidedMaterialNode I can find there the calculation of the normal as following:
>> >
>> > normal.xyz = normalize((textureSample(normalTexture).rgb * vec3(2,2,2) - vec3(1,1,1)) * vec3(normalScale, normalScale, 1))
>> >
>> > Think the handling of normalScale is wrong, the vector must include 3 times normalScale, not z equal 1, like so:
>> >
>> > vec3(normalScale, normalScale, normalScale)
>> >
>> > 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.
>> >
>> > Best regards,
>> > Holger.
>> >
>> > _______________________________________________
>> > x3d-public mailing list
>> > x3d-public at web3d.org
>> > http://web3d.org/mailman/listinfo/x3d-public_web3d.org
>> -------------- next part --------------
>> A non-text attachment was scrubbed...
>> Name: bump_mapping_normalscale.x3dv
>> Type: application/octet-stream
>> Size: 6485 bytes
>> Desc: not available
>> URL: <http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20220403/cdf75004/attachment.obj>
>> -------------- next part --------------
>> A non-text attachment was scrubbed...
>> Name: bump_mapping_normalscale.png
>> Type: image/png
>> Size: 382578 bytes
>> Desc: not available
>> URL: <http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20220403/cdf75004/attachment.png>
>>
>> ------------------------------
>>
>> Subject: Digest Footer
>>
>> _______________________________________________
>> x3d-public mailing list
>> x3d-public at web3d.org
>> http://web3d.org/mailman/listinfo/x3d-public_web3d.org
>>
>>
>> ------------------------------
>>
>> End of x3d-public Digest, Vol 157, Issue 4
>> ******************************************
>
> _______________________________________________
> x3d-public mailing list
> x3d-public at web3d.org
> http://web3d.org/mailman/listinfo/x3d-public_web3d.org
More information about the x3d-public
mailing list