Unity/UnityShader
[HLSL]NormalTexture To WorldNormal
멍산
2023. 10. 16. 00:23
Shader "Example/NormalTexture"
{
Properties
{
_NormalMap("NormalMap",2D) = "bump"{}
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
float3 normalWS : TEXCOORD1;
float3 tangentWS : TEXCOORD2;
float3 bitangentWS : TEXCOORD3;
};
TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
CBUFFER_START(UnityPerMaterial)
float4 _NormalMap_ST;
CBUFFER_END
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.uv = IN.uv;
OUT.normal = IN.normal;
OUT.normalWS = TransformObjectToWorldNormal(IN.normal);
OUT.tangentWS = TransformObjectToWorldDir(IN.tangent.xyz);
OUT.bitangentWS = cross(OUT.normalWS, OUT.tangentWS) * IN.tangent.w * unity_WorldTransformParams.w;
return OUT;
}
half3 TangentNormalToWorldNormal(half3 TangentNormal, half3 T, half3 B, half3 N)
{
float3x3 TBN = float3x3(T, B, N);
TBN = transpose(TBN);
return mul(TBN, TangentNormal);
}
half4 frag(Varyings IN) : SV_Target
{
float4 nT = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(IN.uv, _NormalMap));
nT.rgb = UnpackNormal(nT);
float3 N = TangentNormalToWorldNormal(nT.rgb, IN.tangentWS, IN.bitangentWS, IN.normalWS);
return half4(N,1);
}
ENDHLSL
}
}
}
*Sample Texture 2D의 Type을 Normal 로 할 경우 Normal Unpack 과정을 생략할 수 있습니다.
*ShaderGraph Transform 노드
https://docs.unity3d.com/Packages/com.unity.shadergraph@12.1/manual/Transform-Node.html