Lambert Lighting을 fragment에 적용해서 비교해 본다.(surface 하면서 간단한건 슬슬 tutorial에 넣어야 할듯해서...)
원문은 여기 참조 : https://docs.unity3d.com/Manual/SL-VertexFragmentShaderExamples.html
기본 구조에 대한 설명은 : https://illu.tistory.com/1197
우선 Surface code
Shader "Test/SurfaceLambert" { SubShader { half NdotL = max(0, dot(s.Normal, lightDir)); struct Input } |
일단 Surface shader에서는 ambient color와 shadow를 그리고 있으므로 fallback과 ambient color를 안받도록 했다.
원래라면 이렇게 나오는게 맞다.
샘플 라이팅 코드에서 그냥 복붙해서 공부한다면 이렇게 나올수도 있다... 알아서 고치던가 그냥 넘어가자... 1
아래는 Fragment code
Shader "Test/FragmentLambert" { Properties { _MainTex("Texture", 2D) = "white" {} } SubShader { Pass { // indicate that our pass is the "base" pass in forward rendering pipeline. It gets ambient and main directional // light direction in _WorldSpaceLightPos0 and color in _LightColor0 Tags {"LightMode"="ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag # include "UnityCG.cginc" # include "UnityLightingCommon.cginc" // for _LightColor0 struct v2f { float2 uv : TEXCOORD0; fixed4 diff : COLOR0; // diffuse lighting color float4 vertex : SV_POSITION; }; v2f vert(appdata_base v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; /* struct appdata_base { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; */ // get vertex normal in world space half3 worldNormal = UnityObjectToWorldNormal(v.normal); // dot product between normal and light direction for standard diffuse (Lambert) lighting half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz)); // factor in the light color o.diff = nl * _LightColor0; return o; } sampler2D _MainTex; fixed4 frag(v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); // multiply by lighting col *= i.diff; return col; } ENDCG } } } |
서피스 코드와 비교해보면 lightDir이 _WorldSpaceLightPos0.xyz로 바뀐것과 s.Normal을 worldNormal로 구해서 계산하는 것 정도의 차이다. (Light color는 둘다 _LightColor0 사용)
object to World space를 구하지 않고 v.normal로 노멀값을 바로 사용할 경우에는 오브젝트를 돌리면 이렇게 음영이 따라 돌아간다. 뭐 이런게 필요할때는 이렇게 써야지~
Built in shader 변수에서는 아래와 같이 정리하고 있다.
https://docs.unity3d.com/kr/current/Manual/SL-UnityShaderVariables.html
Light 파라미터는 셰이더에서 어떤 렌더링 경로가 사용되는지, 어떤 LightMode 패스 태그가 사용되는지에 따라 다른 방법으로 셰이더에 전달됩니다.
포워드 렌더링(ForwardBase 및 ForwardAdd 패스 타입):
이름 |
Type |
내용 |
_LightColor0 (Lighting.cginc) |
fixed4 |
Light Color |
_WorldSpaceLightPos0 |
float4 |
Directional lights: (world space direction, 0). Other lights: (world space position, 1) |
_LightMatrix0 (AutoLight.cginc) |
float4x4 |
world-to-light matrix. sample cookie나 감쇠 텍스쳐에 사용 |
unity_4LightPosX0 unity_4LightPosY0 unity_4LightPosZ0 |
float4 |
(ForwardBase pass only) world space positions of first four non-important point lights. |
unity_4LightAtten0 |
float4 |
(ForwardBase pass only) attenuation factors of first four non-important point lights. |
unity_LightColor |
half4[4] |
(ForwardBase pass only) colors of of first four non-important point lights. |
unity_WorldToShadow |
float4x4[4] |
World-to-shadow matrices. One matrix for spot lights, up to four for directional light cascades. 그림자 매트릭스. 스팟라이트 하나와 디렉셔널 라이트 캐스케이드를 최대 4개 지원한다. |
디퍼드 렌더링에서는 아래와 같이 지원한다.(UnityDeferredLibrary.cginc에 선언되어 있다)
이름 |
Type |
내용 |
_LightColor |
float4 |
Light color. |
_LightMatrix0 |
float4x4 |
World-to-light matrix. Used to sample cookie & attenuation textures. |
unity_WorldToShadow |
float4x4[4] |
World-to-shadow matrices. One matrix for spot lights, up to four for directional light cascades. |
자 이제 여기에 ambient color를 더해보자.
o.diff.rgb += ShadeSH9(half4(worldNormal, 1)); |
유니티는 ambient color 계산에 구면 조화(spherical harmonics)함수를 사용한다.
이에대한 자세한 설명은 고팀장님 블로그 포스팅으로 >> https://blog.naver.com/tigerjk0409/221447554201
// normal should be normalized, w=1.0 half3 ShadeSH9 (half4 normal) |
이제 Light Probe도 적용 받는다.
자 이제 그림자 패스를 추가해주자.
|
이제 잘 나온다.
하지만 self shadowing이 구현되지 않았다. 코드에 shadow를 추가해준다.
아래는 전체 코드이다.
|
최종 아웃풋.
Shader variants는 6 / 33 개.(surface는 더 쥐어짤 여지가 있긴 하다)
'Technical Report > Unity Shader' 카테고리의 다른 글
UV offset RGB divided Lightmap chromatic aberration fragment shader (0) | 2019.02.15 |
---|---|
Fragment Lambert Lit AlphaBlend (0) | 2019.02.09 |
Material Property Drawer Example (0) | 2019.02.07 |
Unity Compute Shader (0) | 2018.11.17 |
Fake FixedLight Environment (0) | 2018.08.14 |