[unity] 유니티 쉐이더 공부 4

2022. 2. 22. 22:20

그냥 읽고 끝내려고 했는데 한 번 따라해봐야 의의가 있지 않을까 싶음

+ 이거 따라해본 다음에는 HLSL도 공부해봐야겠당 

와 날아갔다..... ㅎㅎ 다시 써야지

Chap9.


물리기반 셰이더 구조체

struct SurfaceOutputStandard{
	fixed3 Albedo;// 물체의 기본 색상
    fixed3 Normal; //NormalMap
    fixed3 Emission;// 빛의 영향을 받지 않는 색상
    half Metalic;///재질이 금속 재질인가?
    half Smoothness;//재질이 거친가 매끈한가?
    half Occlusion;//차폐되어 어둡게 되는 강도
    half Alpha;//알파



};

 

램버트/ 블린 퐁 라이트에서 사용하는 입력 구조체

struct SurfaceOutput{
	half3 Albedo;// 물체의 기본 색상
    half3 Normal; //NormalMap
    half3 Emission;// 빛의 영향을 받지 않는 색상
    half Specular;//Specular의 넓이,수치가 높으면 하이라이트가 작아짐
    half Gloss;//Specular의 강도
    half Alpha;//알파



};

 

램버트 라이팅 만들기

가볍!

Shader "Custom/Lambert"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
     }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
   

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Lambert

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

     

        void surf (Input IN, inout SurfaceOutput o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;        
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

블린 퐁 라이팅 만들기

뭔가 좀 바뀐 것 같기도.. 하지만 Specular가 안 보여서 잘 모르겠음

Shader "Custom/BlinnPhong"
{
    Properties
    {
       
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _SpecColor("specular color",color)=(1,1,1,1)
   
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
       

        CGPROGRAM
        #pragma surface surf BlinnPhong


        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };


        void surf (Input IN, inout SurfaceOutput o)
        {
           
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
            o.Specular=0.5;
            o.Gloss=1;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

_MainTex가 없어서 그렇대

어두운 텍스쳐 넣으니까 보이네

 

_SpecColor은 예약어고 코드 내부에서 받으면 안되네 (그럴 것 같았음)

 

Chap10. 디지털 라이트 이론

디렉셔널 라이트: 직진성을 가진 조명(가볍!)

포인트 라이트: 점 모양 조명

스팟 라이트

 

이 단원은 다 학교에서 배웠던 거 or 그냥 아는 거

Part 11. Lambert 라이트 (커스텀 라이트)

여기 나오는 asset은 지금 없는 듯?

그래서 나는 다른 asset을 썼음

 

 

 

 

noambient로 엠비언트 라이트의 영향을 제거하기

 

커스텀 함수의 return값은 float4(color의 rgba를 return해야하니까)

함수의 맨 앞에 Lighting 추가하기

 

SurfaceOutput s,float3 lightDir, float atten

함수의 parameter

 lightDir// 조명 벡터가 뒤집혀있고 단위벡터인 상태

atten//감쇠

 

float4 LightingTest(SurfaceOutput s,float3 lightDir, float atten){
           float ndot1=dot(s.Normal,lightDir);
           return ndot1;
 }

단순히 조명벡터랑 노말벡터 내적하는 커스텀 라이트

 

애가 좀 무섭게 생겼지만 문제 없이 돌아간다

이것이 Lambert 라이트의 기본형!(와 쉽다)

 

max()를 이용해서 최솟값을 0으로 하는 방법이 있음

 

 

half-lambert 

기존 lambert는 음영이 너무 급격하게 변함

float4 LightingTest(SurfaceOutput s,float3 lightDir, float atten){
           float ndot1=dot(s.Normal,lightDir)*0.5+0.5;
           return ndot1;

        }

부드럽!

 

이제 attenuation이랑 Albedo 텍스쳐 적용해봐야지

float4 LightingTest(SurfaceOutput s,float3 lightDir, float atten){
           float ndot1=max(0,dot(s.Normal,lightDir));
           float4 final;
           final.rgb=ndot1*s.Albedo*_LightColor0.rgb*atten;
           final.a=s.Alpha;
           return final;

        }

Chap12. Rim 라이트

Fresnel 공식을 구현해 보기

 

dot(o.Normal,IN.viewDir)을 하면 조명 벡터 대신 뷰 벡터를 넣어 계산하는 것이기 때문에

카메라가 조명처럼 인식될 수 있다

 

  void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c=tex2D(_MainTex,IN.uv_MainTex);
            o.Emission=dot(o.Normal,IN.viewDir);
            o.Albedo=0;
            o.Alpha = c.a;
        }
  o.Emission=1-dot(o.Normal,IN.viewDir);

결과 반전시키기

흰 테두리를 조금 더 얇게 만들었으면 좋겠다

    o.Emission=pow(1-dot(o.Normal,IN.viewDir),3);

Shader "Custom/rim"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap("NormalMap",2D)="bump"{}
        _RimColor("Rimcolor",color)=(1,1,1,1)
        _RimPower("RimPower",Range(1,10))=3
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
     
        CGPROGRAM
      
        #pragma surface surf Lambert 
        
        sampler2D _MainTex;
        sampler2D _BumpMap;
        float4 _RimColor;
        float _RimPower;
        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
            float3 viewDir;
        };

      
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Normal=UnpackNormal(tex2D(_BumpMap,IN.uv_BumpMap));
            float rim=saturate(dot(o.Normal,IN.viewDir));
            o.Emission=pow(1-rim,_RimPower)*_RimColor.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

rimcolor과 rimpower를 조절할 수 있도록 property에 추가

 

텍스쳐랑 normalmap적용해서 옷도 입혀주고 복근도 생김

 

 

이걸 응용해서 홀로그램을 만들자

Shader "Custom/holo"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent"}
      
        CGPROGRAM
      
        #pragma surface surf Lambert noambient alpha:fade

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
        };

       
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
   //         o.Albedo = c.rgb;
            float rim=saturate(dot(o.Normal,IN.viewDir));
            o.Emission=float3(0,1,0);
            o.Alpha = pow(1-rim,3);
        }
        ENDCG
    }
    FallBack "Diffuse"
}

rim 라이트 연산을 알파 채널에 넣기

기존에 배웠던 걸 이용해서 간단하게 구현할 수 있었다

 

홀로그램에서 '줄무늬가 위로 올라가는' 효과를 구현해보자

float3 worldPos(세상좌표계)를 사용해보기 

우선 alpha=1, Emission=0 으로 까맣게 만들기 

코난범인같다 

worldPos중에서 y축 값만 필요하니까 rgba의  g겠구나

 

frac()는 숫자의 소수점 부분만 return하기 때문에

frac()를 사용하면 0~0.999가 반복되는 결과가 나올 것이다(천재적이다)

 

 o.Emission=frac(IN.worldPos.g);

화면상에서 움직여보면 계속 변한다

pow()를 사용해서 흰 부분을 줄여보자

 

    void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
   //         o.Albedo = c.rgb;
            float rim=saturate(dot(o.Normal,IN.viewDir));
            o.Emission=pow(frac(IN.worldPos.g-_Time.y),30);
            //float3(0,1,0);
            o.Alpha = 1;
            //pow(1-rim,3);
        }
        ENDCG
    }

시간에 따라 변하는 모습

 

이 결과물을 알파 채널에 더해주자 

   void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
   //         o.Albedo = c.rgb;
            float rim=saturate(dot(o.Normal,IN.viewDir));
            o.Emission=float3(0,1,0);
            
            o.Alpha =pow(1-rim,3)+ pow(frac(IN.worldPos.g-_Time.y),30);
            
        }

 

 

이게 되네,, 신기하다

 

 

Chap 13. Blinn-Phong 스펙큘러 커스텀라이트

와 이걸 커스텀으로 구현해보네 재밌겠당

 

기본 이론은 다 학교에서 배웠다

하프벡터와 노멀벡터를 내적하기

Shader "Custom/Customlight"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap("NormalMap",2D)="bump"{}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        
        CGPROGRAM
     
        #pragma surface surf Test noambient
        sampler2D _MainTex;
        sampler2D _BumpMap;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
           
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
            o.Albedo = c.rgb;
            o.Normal=UnpackNormal(tex2D(_BumpMap,IN.uv_BumpMap));
            o.Alpha = c.a;
        }

        float4 LightingTest(SurfaceOutput s,float3 lightDir,float3 viewDir,float atten){
      
            float4 final;
            float3 DiffColor;
            float ndotl=saturate(dot(s.Normal,lightDir));
            DiffColor=ndotl*s.Albedo*_LightColor0.rgb*atten;


            final.rgb=DiffColor.rgb;
            final.a=s.Alpha;
            return final;
        }


        ENDCG
    }
    FallBack "Diffuse"
}

DiffColor 에 Lambert연산 결과값을 저장시키고 noambient로 환경광을 껐다

사람이 좀 찰흙같네요

 

float3 H에 조명벡터와 뷰벡터의 하프벡터를 연산하여 저장한다.

 

       float3 H=normalize(lightDir+viewDir);
            float spec=saturate(dot(H,s.Normal));

spec에는 H와 N을 내적한다. 

pow()를 사용하여 스펙큘러의 넓이를 줄인다.

            spec=pow(spec,100);

이게 Blinn Phong 스펙큘러이다.

스펙큘러의 색상과 넓이를 조절하도록 응용할 수 있다.

Shader "Custom/Customlight"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap("NormalMap",2D)="bump"{}
        _SpecCol("Spec Color",color)=(1,1,1,1)
        _SpecPow("Spec Power",Range(10,200))=100
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        
        CGPROGRAM
     
        #pragma surface surf Test noambient
        sampler2D _MainTex;
        sampler2D _BumpMap;
        float4 _SpecCol;
        float _SpecPow;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
           
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
            o.Albedo = c.rgb;
            o.Normal=UnpackNormal(tex2D(_BumpMap,IN.uv_BumpMap));
            o.Alpha = c.a;
        }

        float4 LightingTest(SurfaceOutput s,float3 lightDir,float3 viewDir,float atten){
      
            float4 final;
            float3 DiffColor;
            float ndotl=saturate(dot(s.Normal,lightDir));
            DiffColor=ndotl*s.Albedo*_LightColor0.rgb*atten;

            float3 SpecColor;
            float3 H=normalize(lightDir+viewDir);
            float spec=saturate(dot(H,s.Normal));
            spec=pow(spec,_SpecPow);
            SpecColor=spec*_SpecCol.rgb;

            final.rgb=DiffColor.rgb;
            final.a=s.Alpha;
            return float4(SpecColor,1);
        }


        ENDCG
    }
    FallBack "Diffuse"
}
final.rgb=DiffColor.rgb+SpecColor.rgb;
final.a=s.Alpha;
return final;

 

Gloss 맵으로 스펙큘러 강도를 조절할 수 있다.

 

rim라이트로 스펙큘러와 비슷한 효과를 구현해보자

            float3 rimColor;
            float rim=abs(dot(viewDir,s.Normal));
            rimColor=pow(1-rim,6)*float3(0.5,0.5,0.5);

            final.rgb=DiffColor.rgb+SpecColor.rgb+rimColor.rgb;
            final.a=s.Alpha;
            return final;

rim 결과물은 항상 뷰벡터쪽으로 하이라이트가 생기는데, 이걸 스펙큘러로 이용하자

  float4 LightingTest(SurfaceOutput s,float3 lightDir,float3 viewDir,float atten){
      
            float4 final;
            float3 DiffColor;
            float ndotl=saturate(dot(s.Normal,lightDir));
            DiffColor=ndotl*s.Albedo*_LightColor0.rgb*atten;

            float3 SpecColor;
            float3 H=normalize(lightDir+viewDir);
            float spec=saturate(dot(H,s.Normal));
            spec=pow(spec,_SpecPow);
            SpecColor=spec*_SpecCol.rgb;

            float3 rimColor;
            float rim=abs(dot(viewDir,s.Normal));
            rimColor=pow(1-rim,6)*float3(0.5,0.5,0.5);

            float3 SpecColor2;
            SpecColor2=pow(rim,50)*float3(0.2,0.2,0.2);

            final.rgb=DiffColor.rgb+SpecColor.rgb+rimColor.rgb+SpecColor2.rgb;
            final.a=s.Alpha;
            return final;
        }

뭔가 좀 바뀜 (근데 캡처를 잘못했음)

 

Chap 14. NPR 렌더링

 

NPR: non-photo realistic

 

1. 외곽선이 있다

2, 음영이 끊어져있다

(물론 모든 쉘 셰이딩이 그렇지는 않겠지)

 

1. 2Pass로 그리는 법

: 두번 그려야해서 무거움

hard edge에서는 선이 끊어짐

 

 

두 번 그리는 법은 CGPROGRAM~ENDCG를 한번 더 쓰는 것

 

Shader "Custom/2pass"
{
    Properties
    {

        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
   

        CGPROGRAM
     
        #pragma surface surf Lambert

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };


        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    
    CGPROGRAM
     
        #pragma surface surf Lambert

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };


        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    
    }
    FallBack "Diffuse"
}

버텍스 쉐이더를 사용해서 오브젝트를 확장하자

       #pragma surface surf Lambert vertex:vert
Shader "Custom/2pass"
{
    Properties
    {

        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
   
    cull front

        CGPROGRAM
      
        #pragma surface surf Nolight Lambert vertex:vert noshadow noambient

        sampler2D _MainTex;

        struct Input
        {
            float4 color:COLOR;
        };

        void vert(inout appdata_full v){
        
        v.vertex.xyz=v.vertex.xyz+v.normal.xyz*0.01;
        }
        void surf (Input IN, inout SurfaceOutput o)
        {
           
        }
        float4 LightingNolight(SurfaceOutput s,float3 lightDir,float atten){
            return float4(0,0,0,1);
        }
        ENDCG
    cull back
    CGPROGRAM
     
        #pragma surface surf Lambert

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };


        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    
    }
    FallBack "Diffuse"
}

 

와 이게 되네

 

이제 두번째 패스에서 끊어지는 음영을 만들자

 

 

된건가..???

Shader "Custom/2pass"
{
    Properties
    {

        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
   
    cull front

        CGPROGRAM
      
        #pragma surface surf Nolight Lambert vertex:vert noshadow noambient

        sampler2D _MainTex;

        struct Input
        {
            float4 color:COLOR;
        };

        void vert(inout appdata_full v){
        
        v.vertex.xyz=v.vertex.xyz+v.normal.xyz*0.01;
        }
        void surf (Input IN, inout SurfaceOutput o)
        {
           
        }
        float4 LightingNolight(SurfaceOutput s,float3 lightDir,float atten){
            return float4(0,0,0,1);
        }
        ENDCG
    cull back
    CGPROGRAM
     
        #pragma surface surf Lambert toon

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };


        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }

        float4 Lightingtoon(SurfaceOutput s,float3 lightDir, float atten){
            float ndot1=dot(s.Normal,lightDir)*0.5+0.5;

           ndot1*=5;
           ndot1=ceil(ndot1)/5;
           return ndot1;
        }
        ENDCG
    
    }
    FallBack "Diffuse"
}

 

2. Fresnel 을 이용해서 외각선을 만들수도 있음

 

Diffuse Warping : 노멀과 라이트 벡터의 내적을 UV로 활용한다.

 

Chap15. Cubemap Reflection

 

리얼타임으로 반사를 구현하는 것은 무겁기 때문에 Cubemap이라는 환경 텍스쳐를 이용한다

 

 

texCUBE()를 이용하여 텍스쳐의 컬러를 만들고 이 결과값을 Emission에 저장한다.

 

Shader "Custom/reflection"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Cube ("Cubemap",Cube)=""{}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf Lambert noambient
        sampler2D _MainTex;
        samplerCUBE _Cube;

        struct Input
        {
            float2 uv_MainTex;
            float3 worldRefl;
        };



        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
            float4 re=texCUBE(_Cube,IN.worldRefl);
            o.Albedo = c.rgb;
            o.Emission=re.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

와 뭔가 반사되는 느낌이 든다

Albedo를 0으로 하면 더 확연히 보인다

여기에 NormalMap도 적용시켜보자

INTERNAL_DATA 키워드로 버텍스 노멀 데이터를 픽셀 노멀 데이터로 변환하고, 

WorldReflectionVector()를 사용해서 NormalMap이 적용된 월드 좌표계의 픽셀 노멀을 뽑아서 큐브맵의 UV로 사용한다.

 

Shader "Custom/reflection"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap("Normalmap",2D)="bump"{}
        _Cube ("Cubemap",Cube)=""{}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf Lambert noambient
        sampler2D _MainTex;
        sampler2D _BumpMap;
        samplerCUBE _Cube;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
            float3 worldRefl;
            INTERNAL_DATA
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            o.Normal=UnpackNormal(tex2D(_BumpMap,IN.uv_BumpMap));
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
            float4 re=texCUBE(_Cube,WorldReflectionVector(IN,o.Normal));

            o.Albedo = 0;
            o.Emission=re.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

노말맵이 적용된 모습

 

Chap 16. Alpha

 

z버퍼 기준으로 앞뒤 판정을 한다. 

 

불투명 오브젝트는 먼저 그린다 (순서에 상관없으니까)

반투명 오브젝트는 나중에 그린다

반투명 오브젝트끼리는 멀리있는 것부터 가까운 것까지 차례대로 그린다 

우선 quad 에 텍스쳐 넣기

 

Tags { "RenderType"="Transparent" "Queue"="Transparent" }

        CGPROGRAM
        #pragma surface surf Lambert alpha:fade

"Queue"="Transparent"

: 불투명 다음에 그린다

 

cull off 를 추가하여 양면 렌더 하기

 

방금 작성한 이 셰이더를 로봇에 적용해봤더니 뒤에 가려져야 할 오브젝트가 앞으로 찍히는 현상이 일어남

*cull off했는데도!

 

알파 블렌딩은 카메라의 위치에서 피봇점까지의 거리를 계산하기 때문에

오브젝트 사이의 크기가 극명하게 다를 때

문제가 발생하기 쉽다

 

zwrite를 off하면 앞뒤가 잘못 계산되더라도 오브젝트의 앞뒤만 바뀌는 식으로 표현된다.

 

알파테스팅: 

일반 불투명 오브젝트-> 알파테스팅->알파 블렌딩 순으로 그려짐

Shader "Custom/AlphaBlend"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Color("color",Color)=(1,1,1,1)
        _Cutoff("Alpha cutoff",Range(0,1))=0.5
    }
    SubShader
    {
        Tags { "RenderType"="TransparentCutout" "Queue"="AlphaTest"  }
      
        CGPROGRAM
        #pragma surface surf Lambert alphatest:_Cutoff
        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };


        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Legacy Shaders/Transparent/Cutout/VertexLit"
}

Chap 17.

Shader "Custom/CustomBlending"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent"}
        zwrite off
        blend SrcAlpha OneMinusSrcAlpha
        CGPROGRAM
        #pragma surface surf Lambert keepalpha

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };


        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Legacy Shaders/Transparent/VertexLit"
}

알파 블렌딩 셰이더 

zwrite off를 통해 z버퍼에 쓰는 것을 껐다

 

blend 펙터 연산 

(펙터) X Source +( 펙터)X Destination

 

Blend SrcAlpha OneMinusSrcAlpha

두장이 섞인 결과가 나옴

 

Blend SrcAlpha One

Add 모드라고 부르는 방식으로 , 폭발 효과 등에서 많이 사용한다. 

Blend One One

알파채널이 작동하지 않고 검은색만이 투명함을 결정한다

알파 채널을 절약하면서 Add를 가동시킬 수 있음

Blend DstColor Zero

두번째가 zero라서 첫번째 연산만 남게 됨

Multi 모드

DstColor SrcColor

 

'컴퓨터 > graphics' 카테고리의 다른 글

[unity] 유니티 URP 셰이더 1  (0) 2022.08.06
[unity] 유니티 쉐이더 공부 3  (0) 2021.09.08
[unity] 유니티 쉐이더 공부 2  (0) 2021.09.05
[unity] 유니티 쉐이더 공부 1  (0) 2021.09.04

BELATED ARTICLES

more