mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-07-28 05:27:53 -05:00
fix(tangent): binarize tangent.w to ±1 to prevent NaNs and artifacts
Unity’s Mesh.RecalculateTangents() sometimes generates triangles whose three vertices disagree on tangent.w (+1 vs –1). The mixed values are linearly interpolated in the fragment shader; at the midpoint w≈0, bitangent normalization hits a divide-by-zero, producing NaNs and visible glitches (notably on Android GPUs).
This commit is contained in:
parent
027e57fe26
commit
d7a2ddf9dc
|
|
@ -58,7 +58,11 @@ inline half3x3 MToon_GetTangentToWorld(const half3 normalWS, const half4 tangent
|
|||
const half3 normalizedNormalWS = normalize(normalWS);
|
||||
const half3 normalizedTangentWS = normalize(tangentWS.xyz);
|
||||
|
||||
const half3 normalizedBitangentWS = normalize(tangentWS.w * cross(normalizedNormalWS, normalizedTangentWS));
|
||||
// NOTE: tangent Sign は本来、+1 か -1 の値が望まれる。そしてこれは通常、三角形内ですべておなじ値である。
|
||||
// しかし Unity 純正の Mesh.RecalculateTangents() を呼び出すと、頂点ごとに異なる tangent Sign を持つ三角形が生まれることがある。
|
||||
// その場合 interpolate されて 0 となり、ゼロ除算と NaN が発生し、Android 環境等でビジュアルアーティファクトが出る場合があるため、二値化する。
|
||||
const half tangentSign = tangentWS.w > 0 ? 1.0 : -1.0;
|
||||
const half3 normalizedBitangentWS = normalize(tangentSign * cross(normalizedNormalWS, normalizedTangentWS));
|
||||
|
||||
return half3x3(normalizedTangentWS, normalizedBitangentWS, normalizedNormalWS);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user