Skip to content

Bug in normal hex tile material node #663

@sava41

Description

@sava41

Description

Not sure where to report this but the normal hex tiling shader has incorrect logic for rotating normals. Here is an example normal map. See how the shading directions on the shapes are all different:

Image

Here is the same scene with the shader fixed by editing /isaacsim/kit/mdl/core/mdl/nvidia/core_definitions.mdl

Image

Here is the diff:

2433c2431,2432
<     // transform to geometry normals
---
>     // transform to geometry normals using derivative-based blending
>     // (Heitz & Neyret, JCGT 2022 "Practical Real-Time Hex-Tiling")
2436a2436,2438
> 
>     float3 tu = state::texture_tangent_u(0);
>     float3 tv = state::texture_tangent_v(0);
2438,2446d2439
<     float3 tu1 = state::texture_tangent_u(0) * tile_data.tangent_rot_mat1 * strength;
<     float3 tu2 = state::texture_tangent_u(0) * tile_data.tangent_rot_mat2 * strength;
<     float3 tu3 = state::texture_tangent_u(0) * tile_data.tangent_rot_mat3 * strength;
<     float3 tv1 = state::texture_tangent_v(0) * tile_data.tangent_rot_mat1 * strength;
<     float3 tv2 = state::texture_tangent_v(0) * tile_data.tangent_rot_mat2 * strength;
<     float3 tv3 = state::texture_tangent_v(0) * tile_data.tangent_rot_mat3 * strength;
<     float3 n1 = math::normalize(tu1 * nm1.x + tv1 * nm1.y + sn * nm1.z);
<     float3 n2 = math::normalize(tu2 * nm2.x + tv2 * nm2.y + sn * nm2.z);
<     float3 n3 = math::normalize(tu3 * nm3.x + tv3 * nm3.y + sn * nm3.z);
2448c2441,2469
<     // belnd weights
---
>     // Extract per-tile rotation cos/sin from the correctly-computed tu_i vectors:
>     //   tu_i = tu * tangent_rot_mat_i = cos(rrr_i)*tu - sin(rrr_i)*tv
>     //   cos_i =  dot(tu, tu_i)
>     //   sin_i = -dot(tv, tu_i)
>     float3 tu1 = tu * tile_data.tangent_rot_mat1;
>     float3 tu2 = tu * tile_data.tangent_rot_mat2;
>     float3 tu3 = tu * tile_data.tangent_rot_mat3;
>     float cos1 = math::dot(tu, tu1);  float sin1 = -math::dot(tv, tu1);
>     float cos2 = math::dot(tu, tu2);  float sin2 = -math::dot(tv, tu2);
>     float cos3 = math::dot(tu, tu3);  float sin3 = -math::dot(tv, tu3);
> 
>     // Convert each tile's tangent-space normal to a 2D height-field derivative
>     // in the tile's rotated UV frame: d = -nm.xy / nm.z
>     // Clamp the denominator to avoid division by zero (TspaceNormalToDerivative).
>     float eps = 1.0 / 128.0;
>     float denom1 = math::max(nm1.z, eps * math::max(math::abs(nm1.x), math::abs(nm1.y)));
>     float denom2 = math::max(nm2.z, eps * math::max(math::abs(nm2.x), math::abs(nm2.y)));
>     float denom3 = math::max(nm3.z, eps * math::max(math::abs(nm3.x), math::abs(nm3.y)));
>     float2 d1 = float2(-nm1.x / denom1, -nm1.y / denom1);
>     float2 d2 = float2(-nm2.x / denom2, -nm2.y / denom2);
>     float2 d3 = float2(-nm3.x / denom3, -nm3.y / denom3);
> 
>     // Rotate each derivative from the tile's rotated frame back to the original
>     // UV frame using the inverse rotation R(-rrr_i) = [[cos, sin], [-sin, cos]].
>     float2 d1r = float2( cos1 * d1.x + sin1 * d1.y, -sin1 * d1.x + cos1 * d1.y);
>     float2 d2r = float2( cos2 * d2.x + sin2 * d2.y, -sin2 * d2.x + cos2 * d2.y);
>     float2 d3r = float2( cos3 * d3.x + sin3 * d3.y, -sin3 * d3.x + cos3 * d3.y);
> 
>     // blend weights
2461,2462c2482,2485
<     // blend
<     float3 out_normal = gradient_blend_3_normals(n1, w.x, n2, w.y, n3, w.z);
---
>     // Blend derivatives linearly in derivative space (correct per JCGT paper),
>     // then reconstruct the world-space normal: n = normalize(-d.x*tu - d.y*tv + sn)
>     float2 d_blend = w.x * d1r + w.y * d2r + w.z * d3r;
>     float3 out_normal = math::normalize(-tu * d_blend.x * strength - tv * d_blend.y * strength + sn);

Not sure if/where I can submit the fix because I believe this comes from proprietary nvidia materials repository?

Isaac Sim version

5.1.0

Operating System (OS)

Ubuntu 24.04

GPU Name

RTX 4070

GPU Driver and CUDA versions

Driver 580.159.03, CUDA 13.0

Logs

No response

Additional information

edited file:
core_definitions.mdl.txt

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions