본문으로 바로가기
반응형



Unity 내부에 define된 Lambert, BlinnPhong, Standard 이외에는 Custom Lighting Model을 사용해 보통 Shader 안에서 작성하게 된다.


inline half4 LightingUnlit(SurfaceOutput s, half3 lightDir, half atten) {

    return fixed4(s.Albedo, s.Alpha);
}

프로젝트 진행에 따라 Custom Shader가 늘어나고 중간에 Custom Lighting Model을 수정해야할 경우가 생길때 이를 Shader 마다 일일이 수정해주게 되는것도 일인데 cginc 파일을 Shader에 포함해 작성하게 되면 이런 수고를 줄일수 있다.


아래는 일반적인 Lambert Shader를 Lighting Model에 직접 작성한 Shader 예제이다.



Shader "Test/CustomLambert" {
    Properties{
        _MainTex("Texture", 2D) = "white" {}    
        }
 SubShader{
  Tags{ "RenderType" = "Opaque" }   
  CGPROGRAM           
  #pragma surface surf CustomLambert noforwardadd

 inline half4 LightingCustomLambert(SurfaceOutput s, half3 lightDir, half atten) {   
    half NdotL = max(0, dot(s.Normal, lightDir));
    half4 c;
    c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten) ;
    c.a = s.Alpha;
    return c;
  }

   
    struct Input {
        float2 uv_MainTex;         
    };

    sampler2D _MainTex; 

    void surf(Input IN, inout SurfaceOutput o) {   
        fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
        o.Albedo = c.rgb;  
    }
    ENDCG   
    }
        Fallback "Mobile/VertexLit"
}


이를 CustomLighting.cgnic파일을 하나 생성하고 아래와 같이 작성해준다.


inline half4 LightingUnlit(SurfaceOutput s, half3 lightDir, half atten) {
    return fixed4(s.Albedo, s.Alpha);

}

inline half4 LightingCustomLambert(SurfaceOutput s, half3 lightDir, half atten) {   
    half NdotL = max(0, dot(s.Normal, lightDir));
    half4 c;
    c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten) ;
    c.a = s.Alpha;
    return c;
}

inline half4 LightingWrapLambert(SurfaceOutput s, half3 lightDir, half atten) {
    half NdotL = max(0, dot(s.Normal, lightDir));
    half diff = NdotL * 0.5 + 0.5;
    half4 c;
    c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten) ;
    c.a = s.Alpha;
    return c;
}

총 3가지 Lighting model을 define했으며 이를 Shader 에서 사용하려면



Shader "Test/CustomLambert" {
    Properties{
        _MainTex("Texture", 2D) = "white" {}     
        }

    SubShader{
        Tags{ "RenderType" = "Opaque" }   
        CGPROGRAM       
  
   #include "Assets/ShaderCginc/CustomLighting.cginc"
   #pragma surface surf CustomLambert noforwardadd
       
    struct Input {
        float2 uv_MainTex;   
    };

    sampler2D _MainTex;

    void surf(Input IN, inout SurfaceOutput o) {   
        fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
        o.Albedo = c.rgb;
    }
    ENDCG   
    }
        Fallback "Mobile/VertexLit"
}



Shader folder에 같이 위치하면 ./CustomLighting.cginc 만 입력해도 되지만 경로를 분리한다면 경로를 모두 넣어주면 읽어들인다. (경로가 맞지 않는다면 오류 메세지가 뜬다)


이는 꼭 Lighting Model 뿐 아니라 Unity에 Built-in 되어있는 cginc파일을 커스텀해서 사용할때 유용하다.


이번에는 CustomDefine.cginc파일을 생성한다.


fixed3 DefineNormal(fixed4 packednormal)
{

    packednormal.x *= packednormal.w;
    fixed3 normal;

    normal.xy = packednormal.xy * 2 - 1;
    normal.z = packednormal.z;
    return normal;
}


UnpackNormal을 조금 바꿔서 이름을 바꾸어 만들어 주었다. 이를 반영해 Shader code를 작성하면


Shader "Test/CustomLambertNormal" {

    Properties{
        _MainTex("Texture", 2D) = "white" {}
        _BumpMap("Normap Map", 2D) = "white" {}
        }

    SubShader{
        Tags{ "RenderType" = "Opaque" }   
        CGPROGRAM   
   #include "Assets/ShaderCginc/CustomLighting.cginc"
   #include "Assets/ShaderCginc/CustomDefine.cginc"

   #pragma surface surf CustomLambert noforwardadd
       
    struct Input {
        float2 uv_MainTex;   
    };

    sampler2D _MainTex;
    sampler2D _BumpMap;

    void surf(Input IN, inout SurfaceOutput o) {   
        fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
        o.Albedo = c.rgb;
        o.Normal = DefineNormal(tex2D(_BumpMap, IN.uv_MainTex));           
    }
    ENDCG   
    }
        Fallback "Mobile/VertexLit"
}



반응형