반응형
URP Shader Training 중급에서 사용할 example.
maskmap이랑 몇가지는 그냥 임의 커스텀(참고용). 이거저거 잡다하게 붙인...
Shader "LightingExample/BlinnPhong" { Properties { [Header(URP BlinnPhong Lighting)] [Space(20)] _TintColor ("Tint Color", color) = (1,1,1,1) _BaseMap("Albedo(RGB)", 2D) = "white" {} [Normal]_BumpMap("Normal texture", 2D) = "white" {} _MaskMap("Occlusion(G), Glossness(A)", 2D) = "white" {} [Space(20)][Header(Control slide bar)] _SpecColor("Specular Color", color) = (1,1,1,1) _Specular("Specular Intensity", Range(0, 10)) = 1 _Glossness("Glossness", Range(0.1, 50)) = 1 _OcclusionInten("Occlusion Intensity", Range(0,1)) = 1 _EnviIntensity("Environment Lighting", Range(0,1)) = 1 } SubShader { Tags { "RenderPipeline"="UniversalPipeline" "RenderType"="Opaque" "Queue"="Geometry" } Pass { Name "Universal Forward" Tags {"LightMode" = "UniversalForward"} HLSLPROGRAM #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma vertex vert #pragma fragment frag #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" struct VertexInput { float4 vertex : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; float4 tangent : TANGENT; }; struct VertexOutput { float4 vertex : SV_POSITION; float3 normalWS : NORMAL; float2 uv : TEXCOORD0; float3 tangentWS : TEXCOORD1; float3 bitangentWS : TEXCOORD2; float3 viewDir : TEXCOORD3; }; float4 _BaseMap_ST; Texture2D _BaseMap, _BumpMap, _MaskMap; SamplerState sampler_BaseMap; float _Specular, _Glossness, _OcclusionInten, _EnviIntensity; half4 _TintColor, _SpecColor; VertexOutput vert(VertexInput v) { VertexOutput o; o.vertex = TransformObjectToHClip(v.vertex.xyz); o.normalWS = TransformObjectToWorldNormal(v.normal.xyz); o.tangentWS = TransformObjectToWorldDir(v.tangent.xyz); o.bitangentWS = cross(o.normalWS, o.tangentWS) * v.tangent.w * unity_WorldTransformParams.w; o.viewDir = _WorldSpaceCameraPos.xyz - TransformObjectToWorld(v.vertex.xyz); o.uv = v.uv.xy * _BaseMap_ST.xy + _BaseMap_ST.zw; return o; } //DX5기준으로 Legacy에서의 unpack normal을 그대로 사용. R/5bit, G/6bit, B/5bit, A/8bit를 R>G, G>A로 사용-사람의 눈이 녹색의 변화에 민감하기에 G가 1bit더 크다. mobile에서는 채널 변환 없이 *2.0 - 1.0으로 그냥 계산하게 된다. //URP에서 unpack normal처리는 "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 에서 확인할 수 있다. inline half3 UnpackNormal(half4 packednormal) { half3 normal; normal.xy = packednormal.wy * 2 - 1; normal.z = sqrt(1 - normal.x * normal.x - normal.y * normal.y); return normal; } inline half3 TangentNormalToWorldNormal(half3 TangnetNormal, half3 T, half3 B, half3 N) { float3x3 TBN = float3x3(T, B, N); TBN = transpose(TBN); return mul(TBN, TangnetNormal); } half4 frag(VertexOutput i) : SV_Target { float3 lightDir = _MainLightPosition.xyz; float3 lightColor = _MainLightColor.rgb; float3 viewDir = normalize(i.viewDir); half4 color = _BaseMap.Sample(sampler_BaseMap, i.uv) * _TintColor; half4 mask = _MaskMap.Sample(sampler_BaseMap, i.uv); half3 bump = UnpackNormal(_BumpMap.Sample(sampler_BaseMap, i.uv)) ; float3 worldNormal = TangentNormalToWorldNormal(bump, i.tangentWS, i.bitangentWS, i.normalWS); float NdotL = saturate(dot(worldNormal, lightDir)); float3 hv = SafeNormalize(lightDir + viewDir); // https://github.com/Unity-Technologies/Graphics/blob/master/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl float NdotH = saturate(dot(hv, normalize(worldNormal))); //Occlusion 처리는 임의로 계산한것이기 때문에 무시한다. float specular = pow(NdotH, _Glossness * mask.a) * _Specular + mask.g * _OcclusionInten; half3 ambient = SampleSH(i.normalWS); //ambient color처리는임의로 계산한 내용. blinnphong 수식에서는 무시한다. color.rgb = color.rgb * NdotL * lightColor * specular * _SpecColor.rgb + ambient * (1.0 - NdotL) * _EnviIntensity; return color; } ENDHLSL } } } |
반응형
'Technical Report > Unity Shader' 카테고리의 다른 글
URP Realtime Shadow color control (2) | 2022.01.22 |
---|---|
URP BlinnPhong Default Character Shader (0) | 2021.07.14 |
URP Shader coding guide Basic term (3) | 2021.05.01 |
2D Signed Distance Field Basics (0) | 2021.02.10 |
Shader Graph Custom Shader function (0) | 2020.02.15 |