memomem

備忘録・メモ置き場

Unity Shader 内での法線の計算

テクスチャを使用して vert でmeshを変形させたときに法線を再計算する方法

qiita.com

forum.unity.com

いくつか方法を試したが、

tangent, binormal から tex2Dlod のピクセル値を取得し法線を再計算する方法

// normalの算出

float3 tangent = v.tangent;
float3 binormal = normalize(cross(v.normal, tangent));
float4 tan = tex2Dlod (_HeightTex, float4((uv2+tangent.xy*_HeightTex_TexelSize), 0, 0));
float4 bio = tex2Dlod (_HeightTex, float4((uv2+binormal.xy*_HeightTex_TexelSize), 0, 0));
tangent.z = (tan.r-0.5) * 2 * fixTopScale * 8; // 8は法線の強調
binormal.z = (bio.r-0.5) * 2 * fixTopScale * 8;

float3 objNormal = normalize(cross(normalize(tangent), normalize(binormal)));

ピクセルのオフセット値から法線を再計算する方法

float3 normalsFromHeight(sampler2D heigthTex, float4 uv, float texelSize, float amp)
{
    float size = 4;
    float normalAmp = 10; // 法線の強調

    float a = tex2Dlod(heigthTex, uv + float4(texelSize * float2( 0, 0)*size,0,0)).x * amp * normalAmp;
    float b = tex2Dlod(heigthTex, uv + float4(texelSize * float2( 0, 1)*size,0,0)).x * amp * normalAmp;
    float c = tex2Dlod(heigthTex, uv + float4(texelSize * float2( 1, 0)*size,0,0)).x * amp * normalAmp;
    a = (a-0.5)*2;
    b = (b-0.5)*2;
    c = (c-0.5)*2;
    float3 vn = cross(normalize(float3(0, 1, b-a)), normalize(float3(1, 0, c-a)));
    return normalize(vn);
}

float3 objNormal = normalsFromHeight(_HeightTex, float4(uv2,0,0), _HeightTex_TexelSize, fixTopScale);

のどちらかが良さそう。 最初の方法が結果は自然に見える。

その他補足・メモ

// tex2Dlod( テクスチャ, float4(U値, V値, 0, w =( lod 値の指定0~7 )) float4 dWave = tex2Dlod (_HeightTex, float4(uv2, 0, 0));