Unity/그래픽스프로그래밍

0507 _ 큐브맵 만들어서, 물체에 월드 노멀, 리플렉션 적용시기키

minquu 2021. 5. 7. 18:11
반응형

큐브맵 // HDRI 네모난 큐브 형식이라고 되어있다고 보면됌
Environment 중 하나 

----

 

텍스쳐 한 장을 받는 쉐이더 스크립터를 만들어준다.

램버트 라이팅 세팅으로

 

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

        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"
}

 

 

----

 

큐브맵을 받을수 있는 프로퍼티를 뚫는다 .

 

 

큐브맵을 받는 형식은 Cube로 

 

윈도우 - 렌더링 - 라이팅 세팅에 넣어야한다.

 

 

먼저

 

 

메터리얼에 큐브맵을 넣어준다.

 

 

메터리얼을 스카이박스메터리얼에 넣어준다.

★ 책에서 나온게 버전업 되면서 바뀌었다.

우리가 만든 메테리얼을 넣는게 아니라 검색해서 넣어야한다.

 

우리가 만든 메테리얼은 로봇에다가 넣을 것 이기 때문에

 

로봇 켈리 넣고,

메터리얼 넣고

 

 

sky박스가 반사되도록 만들것이다.

 

 

Input 에 

 

 

 

월드 리플렉션이 있음 이걸 사용

 

이걸 똑같이 안쓰면 하드한 리플렉션 공식을 넣어야함

 

 

texCUBE (엔디비아 CG 용어)를 사용해서 이미지를 넣어야한다.

 

 

texCUBE(큐브텍스트 이미지 , 월드 리플렉션) = float4 로 반한

 

 

이미지션에 넣어서 테스트 하기 

 

Shader "Custom/Test"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Cube ("CubeMap", Cube) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Lambert

        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 ref =  texCUBE(_Cube, IN.worldRefl);
            o.Albedo = c.rgb;
            o.Emission = ref.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

 

 

 

반사되는걸 확인 가능

 

이미션에 넣는 이유, 밝고 어두움을 반사하는데 빛을 넣는다고 밝아 지는게 아니기 때문에 (거울 예제)

 

지금은 흰색인 이유는 알베도에 흰색에 있고, 이미션에도 있어서 1이 넘어서 그럼

 

// 알베도랑 이미션을 같이 쓰면 밝아진다.

 

그래서 알베도를 0으로 만들고, 이미션에 반사된 값을 출력해보자 

 

 

---

 

노멀을 넣으면 오류가 생긴다 .

 

 

 

 

이터널 데이터를 써줘야한다

 

 

이터널 데이터를 써주지 않으면

 

★ 월드 리플렉션이랑 월드 노멀을 같이 쓸수가 없다.

 

인풋에 넣어주고

 

 

 

노멀을 넣으면 월드 노멀을 넣ㅇ어줘야한다

 

 

 

노멀에 해당하는 반사벡터를 얻을려면 WorldReflctionVector 써줘야함

노멀을 먼저 쓰고 그걸 받아서 써주는 것이다 ! 

            float4 ref =  texCUBE(_Cube, WorldReflectionVector(IN, o.Normal));

 

 

 

----

Shader "Custom/Test"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Normal ("Normal (RGB)", 2D) = "white" {}
        _Cube ("CubeMap", Cube) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Lambert

        sampler2D _MainTex;
        samplerCUBE _Cube;
        sampler2D _Normal;
        struct Input
        {
            float2 uv_MainTex;
            float3 worldRefl;
            float2 uv_Normal;
            INTERNAL_DATA
        };

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

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

 

 

 

 

 

----

 

총 과정 

 


메터리얼 하나 받는 쉐이더 작성
기본 Lambert 라이트 모델 적용
큐브맵을 받게 프로퍼티 작성
타입을 Cube
변수선언시 타입을 samplerCUBE로
Input 구조체에 worldRefl 정의
texCUBE 함수를 사용해 큐브맵 적용 (_Cube, IN.worldRefl)
결과값이 re 값을 확인(Emission에서)
범프 텍스쳐 넣을 수 있게 속성정의
노멀이 적용된 반사벡터를 구하기 위해서 WorldReflectionVector함수 사용
결과 확인 (Emission)

반응형