【Reading Notes】cp6-Fragment Shaders and Grab Pass

앞에 쓰다


지금까지 우리는 모두 Surface Shaders를 바탕으로 기능을 실현했다.Surface Shader의 디자인은 간단한 Shader 인코딩 실현 방법을 제공하여 예술가에게 매우 의미 있는 도구를 제공했다.Shader에 대해 더 알고 싶다면, 버텍스(정점)와 Fragment(편원) 착색기의 영역에 발을 들여놓을 때가 됐다.
본 장 내용: + 정점 착색과 편원 착색의 기본 이해 + Grab pass + Grab 착색 + 물 효과 실현, 2D 게임

소개하다.


Surface Shader에 비해 교점과 패브릭 착색기는 물리적 음영처리 기능이 적지만 더 강력한 에너지로 바뀌어 물리적 구속이 없어 비현실적인 렌더링 효과를 많이 실현할 수 있다.이 장에서는 쉐더가 물체의 변형을 시뮬레이션할 수 있도록 하는 Grab Pass를 중점적으로 다룹니다.

정점 착색기와 필름 착색기의 기본을 이해하다


vertex와 Fragment 착색기를 배우는 가장 좋은 방법은 직접 하나를 실현하는 것이다.이 소절은 간단한vertex,fragment 착색기를 실현하여 주 무늬와 색을 간단하게 읽을 수 있습니다.
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "CookbookShaders/self/grab" {
    Properties {
        _MainTex("Base (RGB) Trans(A)", 2D) = "white"{}
        _Color("Color", Color) = (1, 1, 1, 1)
    }

    SubShader{

        Pass
        {
            CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
            sampler2D _MainTex;
            float _Magnitude;
            float4 _Color;

            struct vertInput 
            {
                float4 vertex: POSITION;
                float2 texcoord: TEXCOORD0;
            };
            struct vertOutput
            {
                float4 vertex: POSITION;
                float2 texcoord: TEXCOORD0;
            };

            vertOutput vert(vertInput v)
            {
                vertOutput o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.texcoord = v.texcoord;
                return o;
            }

            half4 frag(vertOutput i):COLOR
            {
                half4 mainColor = tex2D(_MainTex, i.texcoord);
                return col * mainColor * _Color;
            }
            ENDCG
        }


    }
    FallBack "Diffuse"
}

How is works 주요 사항

  • #pragma 사전 컴파일 명령, 정점 착색 함수와 모듈 착색 함수 지정
    #pragma vertex vert
    #pragma fragment frag
  • 함수의 입력과 출력 구조를 정의하는데 여기는 의미 관련과 관련된다. 다음에
    struct vertInput
    {
    float4 vertex: POSITION;
    float2 texcoord: TEXCOORD0;
    };
    struct vertOutput
    {
    float4 vertex: POSITION;
    float2 texcoord: TEXCOORD0;
    };
  • 에 언급될 것이다.
  • 그리고 정점 함수(vert)와 블록 함수(frag)가 논리를 실행하고 마지막 색을 계산합니다.
  • vert: 정점 착색기에서 주요한 작업은 3D 대상의 로컬 좌표를 원추체로 변환하는 것이다. 여기 새 버전의 Unity는 Unity Object ToClipPos()의 내장 함수를 사용했다. 이전에는 UNITYMATRIX_MVP 내장 매크로.그 다음에 전달 무늬 좌표
  • frag: 텍스처 샘플링 및Color를 혼합하여 마지막 색을 얻습니다.


  • 어의 귀속

  • 입력 구조 언어 귀속
  • 의미
    묘사
    POSITION, SV_POSITION
    정점의 좌표, 모형 공간에서float3/float4
    NORMAL
    정점의 법방향량,float3
    TEXCOORD0 … TEXCOORDi
    무늬 좌표,float2/float3/float4
    TANGENT
    수직 매핑용 탄젠트 벡터, float4
    COLOR, COLOR0, DIFFUSE, SV_TARGET
    정점 색상 정보, float4
    COLOR1
    정점에 저장된 두 번째 색은 보통 하이라이트 색이다.float4
    + 출력 구조 의미 귀속
    의미
    묘사
    POSITION, SV_POSITION, HPOS
    정점 좌표, 카메라 좌표계 내(clip space, 범위 0-1)
    COLOR, COLOR0, COL0, COL, SV_TARGET
    주색
    COLOR1, COL1
    두 번째 색상
    TEXCOORD0…TEXCOORDi
    텍스쳐 좌표
    WPOS
    The position, in pixels, in the window(origin in the lower left corner) (잘 모름)
    비록 의미 귀속이라고 하지만 사실 구조 안에 어떤 데이터를 저장해야 하는지는 개발자가 제어할 수 있는 것이다.NORMAL의 데이터를 POSITION 의미로 충분히 저장할 수 있습니다.

    Grab Pass 사용


    4장에서는 PBR 재료에 투명 속성을 추가하여 한 재료가 어떻게 투명하게 이루어지는지 알 수 있습니다.투명도 재료는 장면에 그려질 수 있지만 장면에 그려진 것은 바꿀 수 없다.이것 또한 이런 재질이 유리나 물 아래의 무대 모양을 나타낼 수 없다는 것을 나타낸다.이러한 변형을 시뮬레이션하기 위해 Grab pass라는 새로운 기술을 소개합니다. 이것은 현재 그려진 장면에 그려진 데이터를 방문하여 사용할 수 있도록 합니다.

    Grab pass


    코드는 간단합니다. grab pass는 Unity가 정의한 특수한 pass입니다. 그는 자동으로 TextureName이라는 무늬를 만들 것입니다. 기본 이름은 입니다.GrabTexture, 다음 패스에 정의해야 접근할 수 있습니다.이 무늬에 대한 샘플링을 통해 현재 그리기 전의 내용을 얻을 수 있습니다.샘플링의 무늬 좌표를 계산하는 사고방식은 정점 좌표를 화면 좌표로 바꾸는 것이다. 여기에Unity는 우리에게 내부의 사랑 함수를 제공한다. ComputeGrabScreenPos(o.vertex).그리고 메타 셰이더의 실제 샘플링 시 매크로 UNITY 사용PROJ_COORD가 마지막 결과를 얻었는데 이 매크로는 그가 원래의 값을 되돌렸다고 볼 수 있다. 그의 정의를 보면 PSP에 따라 구분했을 뿐이라는 것을 알 수 있다.
    #if defined(SHADER_API_PSP2)
    #define UNITY_BUGGY_TEX2DPROJ4
    #define UNITY_PROJ_COORD(a) (a).xyw
    #else
    #define UNITY_PROJ_COORD(a) a
    #endif
     GrabPass{"TextureName"}

    유리 효과를 실현하다


    유리는 비교적 복잡한 재질로 대부분의 유리 재질은 완벽하지 않다. 왜냐하면 더욱 완벽해지기 위해 유리를 통해 보이는 물체가 변형되기 때문이다.사상은 정점과 편원 착색기에서 Grab pass의texture를 이용하여 UV 무늬 좌표를 약간 바꾸어 형태를 구성하는 것이다.
    구체를 통해 형변(투명하지 않아도 볼 수 있는)을 볼 수 있고 2기는 측면에서 보면 환경이 비치는 효과도 볼 수 있다.편원 착색기 코드를 통해 알 수 있듯이 우리는 법선 방향을 따라 Grab pass 무늬에 대한 샘플링을 바꾸어 보이는 변형 효과에 도달했다.
    Shader "CookbookShaders/self/grab" {
        Properties {
            _MainTex("Base (RGB) Trans(A)", 2D) = "white"{}
            _BumpMap("Noise text", 2D) = "bump" {}
            _Magnitude("Magnitude", Range(0, 1)) = 0.05
            _Color("Color", Color) = (1, 1, 1, 1)
        }
    
        SubShader{
    
            Tags{ "Queue" = "Transparent" }
    
            GrabPass
            {
                "_GrabTexture"
            }
            Pass
            {
                CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #include "UnityCG.cginc"
                sampler2D _GrabTexture;
                sampler2D _MainTex;
                sampler2D _BumpMap;
                float _Magnitude;
                float4 _Color;
    
                struct vertInput 
                {
                    float4 vertex: POSITION;
                    float2 texcoord: TEXCOORD0;
                };
                struct vertOutput
                {
                    float4 vertex: POSITION;
                    float2 texcoord: TEXCOORD0;
                    float4 uvgrab: TEXCOORD1;
                };
    
                vertOutput vert(vertInput v)
                {
                    vertOutput o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    o.texcoord = v.texcoord;
                    o.uvgrab = ComputeGrabScreenPos(o.vertex);
                    return o;
                }
    
                half4 frag(vertOutput i):COLOR
                {
                    half4 mainColor = tex2D(_MainTex, i.texcoord);
                    half4 bump = tex2D(_BumpMap, i.texcoord);
                    half2 distortion = UnpackNormal(bump).rg;
                    i.uvgrab.xy += distortion * _Magnitude;
                    fixed4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
                    return col * mainColor * _Color;
                }
                ENDCG
            }
    
    
        }
        FallBack "Diffuse"
    }
    

    실현수, 2D 게임즈


    원리와 위의 차이는 단지 소음 스티커와 인 함수를 추가하여 대형변화의 시간에 따라 변화를 실현할 뿐이다.여기는 서술이 많을 뿐이다.
    Shader "CookbookShaders/self/water" {
        Properties{
            _NoiseTex("Base (RGB) Trans(A)", 2D) = "white"{}
            _Period("Period", Range(0, 50)) = 1
            _Magnitude("Magnitude", Range(0, 1)) = 0.05
            _Color("Color", Color) = (1, 1, 1, 1)
            _Scale("Scale", Range(0, 10)) = 1
        }
    
            SubShader{
    
            Tags{ "Queue" = "Transparent" }
    
            GrabPass
            {
                "_GrabTexture"
            }
            Pass
        {
            CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #include "UnityCG.cginc"
            sampler2D _GrabTexture;
            sampler2D _NoiseTex;
            float _Period;
            float _Magnitude;
            float4 _Color;
            float _Scale;
    
            struct vertInput
            {
                float4 vertex: POSITION;
                float2 texcoord: TEXCOORD0;
                float4 uvgrab: TEXCOORD2;
            };
            struct vertOutput
            {
                float4 vertex: POSITION;
                fixed4 color : COLOR;
                float2 texcoord: TEXCOORD0;
                float4 worldPos: TEXCOORD1;
                float4 uvgrab: TEXCOORD2;
            };
    
            vertOutput vert(vertInput v)
            {
                vertOutput o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.texcoord = v.texcoord;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                o.uvgrab = ComputeGrabScreenPos(o.vertex);
                return o;
            }
    
            half4 frag(vertOutput i) :COLOR
            {
                float sinT = sin(_Time.w / _Period);
                float2 distortion = float2(tex2D(_NoiseTex, i.worldPos.xy / _Scale + float2(sinT, 0)).r - 0.5,
                                            tex2D(_NoiseTex, i.worldPos.xy / _Scale + float2(0, sinT)).r - 0.5
                    );
                i.uvgrab.xy += distortion * _Magnitude;
                fixed4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
                col *= _Color;
                return col;
            }
            ENDCG
        }
    
    
        }
            FallBack "Diffuse"
    }

    최후


    효율성에서 볼 때Grab Pass는 비교적 나쁘기 때문에 매번 렌더링을 해서 추가texture를 생성해야 한다

    좋은 웹페이지 즐겨찾기