2DLookupLighting(FakeBRDF)
環境
Unity2021.2.18f1
概要
Lookupテクスチャを使用したライティングです。
以下のページの画像に対応するようにしています。 BRDF - Wakapon
Shader "Unlit/2DLookupLighting" { Properties { _NormalTex("Normal Texture", 2D) = "white" {} _Lookup("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Tags { "LightMode" = "ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; float4 tangent : TANGENT; float2 uv : TEXCOORD0; }; struct v2f { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; fixed3 TSToWS0 : TEXCOORD1; fixed3 TSToWS1 : TEXCOORD2; fixed3 TSToWS2 : TEXCOORD3; half3 viewDirWS: TEXCOORD4; half3 lightDirWS: TEXCOORD5; }; sampler2D _NormalTex; float4 _NormalTex_ST; sampler2D _Lookup; v2f vert(appdata v) { v2f o; o.positionCS = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _NormalTex); fixed3 normalWS = UnityObjectToWorldNormal(v.normal); fixed3 tangentWS = UnityObjectToWorldDir(v.tangent.xyz); fixed3 binormalWS = cross(normalWS, tangentWS) * v.tangent.w; o.TSToWS0 = fixed3(tangentWS.x, binormalWS.x, normalWS.x); o.TSToWS1 = fixed3(tangentWS.y, binormalWS.y, normalWS.y); o.TSToWS2 = fixed3(tangentWS.z, binormalWS.z, normalWS.z); o.viewDirWS = WorldSpaceViewDir(v.vertex); o.lightDirWS = WorldSpaceLightDir(v.vertex); return o; } fixed3 LightingLookup(half3 lightDir, half3 viewDir, half3 normal) { #define HALF_VEC 1 #if HALF_VEC half3 HalfDir = normalize(lightDir + viewDir); float NdotL = dot(normal, HalfDir); #else float NdotL = dot(normal, viewDir); #endif float NdotV = dot(normal, viewDir); float2 lookupUV = float2(1.0 - (NdotL * 0.5 + 0.5), 1.0 - saturate(NdotV)); fixed3 exitRadiance = tex2D(_Lookup, lookupUV).rgb; float atten = 1; return _LightColor0.rgb * (exitRadiance * atten * 2); } fixed4 frag(v2f i) : SV_Target { half3 normalTS = UnpackNormal(tex2D(_NormalTex, i.uv)); half3 normalWS; normalWS.x = dot(i.TSToWS0.xyz, normalTS); normalWS.y = dot(i.TSToWS1.xyz, normalTS); normalWS.z = dot(i.TSToWS2.xyz, normalTS); normalWS = normalize(normalWS); half3 lightDirWS = normalize(i.lightDirWS); half3 viewDirWS = normalize(i.viewDirWS); fixed3 diffuse = LightingLookup(lightDirWS, viewDirWS, normalWS); return fixed4(diffuse, 1); } ENDCG } } }
参考
Problem with BRDF Shader - Unity Forum
Writing Surface Shaders in Unity3D: BRDF Fake - YouTube
Index of /datahoarder/Walt Disney Animation Studios/BRDF Explorer