【法线贴图】
法线贴图
o.normal = UnityObjectToWorldNormal( v.normal );
o.tangent = UnityObjectToWorldDir( v.tangent.xyz );
o.btangent = cross( o.normal, o.tangent);
o.btangent *= v.tangent.w * unity_WorldTransformParams.w;
float3 tangentSpaceNormal = UnpackNormal( tex2D( _NormalTex, i.uv ) );
float3x3 mtxTangToWord_A = float3x3(
i.tangent.x,i.btangent.x,i.normal.x,
i.tangent.y,i.btangent.y,i.normal.y,
i.tangent.z,i.btangent.z,i.normal.z);
float3 N_A = mul(mtxTangToWord_A,tangentSpaceNormal);
float3x3 mtxTangToWord_B = float3x3(
i.tangent.x,i.tangent.y,i.tangent.z,
i.btangent.x,i.btangent.y,i.btangent.z,
i.normal.x,i.normal.y,i.normal.z);
float3x3 mtxTangToWord_B2 = float3x3(i.tangent,i.btangent,i.normal);
float3 N_B = mul(tangentSpaceNormal,mtxTangToWord_B);
【Shader练习-妲己】
高度图转法线图
#define heightMap iChannel0
#define heightMapResolution iChannelResolution[0]
#define normalStrength 10.0
#define textureOffset 1.0
#define pixelToTexelRatio (iResolution.xy/heightMapResolution.xy)
vec2 stdNormalMap(in vec2 uv)
{
float height = texture(heightMap, uv).r;
return -vec2(dFdx(height), dFdy(height)) * pixelToTexelRatio;
}
vec2 texNormalMap(in vec2 uv)
{
vec2 s = 1.0/heightMapResolution.xy;
float p = texture(heightMap, uv).x;
float h1 = texture(heightMap, uv + s * vec2(textureOffset,0)).x;
float v1 = texture(heightMap, uv + s * vec2(0,textureOffset)).x;
return (p - vec2(h1, v1));
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord/iResolution.xy;
float mousePosition = (iMouse.x > 0.1) ? iMouse.x : iResolution.x * 0.5;
float mouseSplit = round(mousePosition * 0.5) * 2. + 1.;
if (abs(fragCoord.x - mouseSplit) < 1.0)
{
fragColor = vec4(0.);
return;
}
vec2 normal = (fragCoord.x > mouseSplit) ? texNormalMap(uv) : stdNormalMap(uv);
normal *= normalStrength;
normal += 0.5;
fragColor = vec4(normal, 1., 1.);
}
【参考】 (opens new window)
控制法线强度
float3 tangentSpaceNormal = UnpackNormal( tex2D( _RockNormals, i.uv ) );
tangentSpaceNormal = normalize(lerp( float3(0,0,1), tangentSpaceNormal, _NormalIntensity ));