[Reading Notes] CP5-Vertex Functions(착색기 정점 처리)

앞에 쓰다


Shader는 주로 3D 대상의 빛이 비치는 실제 상황을 모의하는 데 사용되지만, 뿐만 아니라, 그는 Objects가 어떻게 보이는지 정의할 뿐만 아니라, Objects의 모양도 완전히 재정의할 수 있다.
이 섹션에서는 + Surface Shader에서 정점 색상 액세스 + Surface Shader에서 정점 애니메이션 + 압출로 모델 변형 + 눈 + 부피 폭발 효과 구현

간단한 소개


1장에서 첫 번째 shader를 생성하여 3D 모델이 삼각면의 집합체가 아니라는 것을 설명했다.각 정점에는 자신을 더 잘 과장하기 위해 추가 데이터가 포함되어 있다.이 데이터를 어떻게 접근하는지 탐색하고, 우리 shader에서 사용할 것입니다.

Surface Shader를 통한 정점 색상 액세스


먼저 알아야 할 것은 하나의 정점 함수가 정점 자체에 대한 정보를 되돌릴 수 있고 우리가 제어할 수 있다는 것이다.우리는 정점의 법방향량 (하나의float3값), 정점의 위치 (float3)를 수신할 수 있고, 너는 안에 색을 저장할 수 있다 (float4).정점 색상을 저장하는 방법과 정점 색상을 사용하는 방법을 보여 줍니다.
4
  • vert 함수의 반환 구조를 정의해야 합니다. struct Input {float2 uv MainTex;float2 vertColor;}

  • 4
  • 입력에서 정점 색상을 가져오고 struct appdatafull { float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; float4 texcoord1 : TEXCOORD1; float4 texcoord2 : TEXCOORD2; float4 texcoord3 : TEXCOORD3; fixed4 color : COLOR; UNITY_VERTEX_INPUT_INSTANCE_ID };

  • 위에는 Unity에 내장된 완전한 정점 구조입니다. color 필드에서 역정점 색을 가져올 것입니다. 그래서 정점 함수는 대략 이렇게 생겼습니다.
    void vert(inout appdata_full v, out Input o)
    {
        o.verColor = v.color;
    }
    

    4
  • Surface에서 4
  • 마지막으로surf에서 색을 최종 처리하면 우리가 원하는 효과에 도달합니다
    void surf(Input IN, inout SurfaceOutput o)
    {
        o.Albedo = IN.vertColor.rgb * _MainTint.rgb; //         
    }
    

    더.


    우리가vertcolor의 네 번째 필드를 사용할 수 있습니다. 왜냐하면 우리가 정의한 구조는float4 형식의 값이기 때문입니다.이것은 우리가 정점의 알파를 전달할 수 있다는 것을 의미한다.너는 이 필드를 이용하여 대상의 디스플레이를 최적화할 수 있다. 실제로 네 번째 필드의 의미는 개발자 스스로 완전히 제어할 수 있다. 예를 들어 알파, 투명도를 추가하고, 마스크를 제공하여 무늬를 혼합할 수 있다.
    Unity5에서는 DirectX11을 사용하여 저희 shader를 컴파일할 수 있지만, 유닛이 컴파일을 통과하지 못하더라도 알림을 주지 않을 것입니다.vert에 한 줄의 코드만 추가해야 합니다.
    void vert(inout appdata_full v, out Input o)
    {
        UNITY_INITALIZE_OUTPUT(Input, o);
        o.vertColor = v.color;
    }
    

    교점 이동(Surface Shader)


    여기서 착색기 프로그램은 mesh 정점의 y값을 수정하여 CG에 내장된sin 함수를 통해 파도 효과를 시뮬레이션합니다.Unity 내장 변수를 통해Time으로 변화를 주도록 하겠습니다.
    Shader "CookbookShaders/self/vertexAni" {
        Properties
        {
            _MainTex("Base (RGB)", 2D) = "white"{}
            _tintAmount("Tint Amount", Range(0,1)) = 0.5
            _ColorA("ColorA", Color) = (1, 1, 1, 1)
            _ColorB("ColorB", Color) = (1, 1, 1, 1)
            _Speed("Wave speed", Range(0.1, 80)) = 5
            _Frequency("Wave Frequency", Range(0, 5)) = 2
            _Amplitude("Wave Amplitude", Range(-1, 1)) = 1
        }
    
            SubShader
            {
                Tags {"RenderType" = "Opaque"}
                LOD 200
    
                CGPROGRAM
    
        #pragma surface surf Lambert vertex:vert
    
                sampler2D _MainTex;
                float4 _ColorA;
                float4 _ColorB;
                float _tintAmount;
                float _Speed;
                float _Frequency;
                float _Amplitude;
                float _OffsetVal;
    
                struct Input
                {
                    float2 uv_MainTex;
                    float3 vertColor;
                };
    
                void vert(inout appdata_full v, out Input o)
                {
                    float time = _Time * _Speed;
                    float waveValueA = sin(time + v.vertex.x * _Frequency) * _Amplitude;
                    v.vertex.xyz = float3(v.vertex.x, v.vertex.y + waveValueA, v.vertex.z);
                    o.vertColor = float3(waveValueA, waveValueA, waveValueA);
                    o.uv_MainTex = v.texcoord;
                }
    
                void surf(Input IN, inout SurfaceOutput o)
    
                {
                    half4 c = tex2D(_MainTex, IN.uv_MainTex);
                    float3 tintColor = lerp(_ColorA, _ColorB, IN.vertColor).rgb;
                    o.Albedo = c.rgb * (tintColor * _tintAmount);
                    o.Alpha = c.a;
                }
            ENDCG
        }
        FallBack "Diffuse"
    }
    

    Extruding(압출? 수정?)너의 모형


    게임을 제작하는 과정에서 가장 큰 문제는 중복성이다. 중복된 창설 내용은 시간을 많이 소모한다. 예를 들어 수천 수만의 적을 상대하면 그들은 모두 똑같아질 것이다.여기에 비교적 낮은 대가로 당신의 모델이 서로 다른 표현을 하고 있다는 것을 소개합니다. shader를 통해 모델의 기하학적 데이터를 수정하는 것을 Normal extrusion이라고 합니다.통통하고 마른 모형을 만들 수 있다.
    주요 사상은 모델을 우리가 원하는 방향으로 변형시키는 것이다.여기의 Shader에서 우리는 모형의 법선 방향을 따라 정점의 위치를 변화시킨다
    void vert(inout appdata_full v)
    {
        float3 N = normalize(v.normal);
        v.vertex.xyz += N * _Amount;
    }

    변형에 대해 더 많은 제어를 하려면 변형 방향을 포함하는 Extrusion map을 추가하여 위치가 밖으로 변화하고 안으로 변화하는 것을 제어할 수 있다. 주의해야 할 것은texture에 저장된 데이터(0,1) 범위의 경우 그를 (-1,1)로 전환시켜야 한다.
    sampler2D _ExtrusionTex;
    void vert(inout appdata_full v) {
    float4 tex = tex2Dlod (_ExtrusionTex, float4(v.texcoord.xy,0,0));
        float extrusion = tex.r * 2 - 1;
        v.vertex.xyz += v.normal * _Amount * extrusion;
    }

    눈, 모형 표면


    눈의 시뮬레이션 게임도 도전이다. 대량의 게임은 눈의 무늬 스티커를 간단하게 사용한다.이 소절은 눈의 효과에 도달하면 산더만 사용한다는 것을 소개한다.

    부피 폭발 실현


    게임 예술은 실제 효과와 효율 사이에서 똑똑한 선택을 해야 하는데 이것은 장면의 폭발 효과에도 마찬가지다.폭발은 많은 게임의 핵심 부분에 나타나고 폭발의 물리 시뮬레이션은 종종 현대 컴퓨터의 연산 능력을 능가한다.많은 게임에서 입자 특수효과를 사용하여 이런 효과를 하는데 폭발이 발생할 때 많은 화염, 스모그 등 입자를 실례화하여 효과를 내야 한다. 불행하게도 이것은 진실하지 않고 항상 반점이 있다.이 소절은 2D 무늬로 시뮬레이션하지 않고 3D 대상을 직접 펼치는 기술을 소개할 것이다.
    착색기의 핵심은 잡음 스티커(Perlin noise)를 사용하여 3D 대상의 정점을 바꾸고sin 함수를 사용하여 시간 차원의 변화를 제어하는 것이다.두 번째 부분은surf 함수에서 Nosetex를 사용하여 무작위 색을 사용합니다.색상을 잘라냅니다. RampTex는 색상의 그라데이션 맵입니다.
    Shader "CookbookShaders/self/explosion" {
        Properties {
            _RampTex("Color Ramp", 2D) = "white"{}
            _RampOffset("Ramp offset", Range(-0.5, 0.5)) = 0
            _NoiseTex("Noise Tex", 2D) = "gray" {}
            _Period("Period", Range(0, 1)) = 0.5
            _Amount("_Amount", Range(0, 1.0)) = 0.1
            _ClipRange("ClipRange", Range(0, 1)) = 1
        }
        SubShader {
            Tags { "RenderType"="Opaque" }
            LOD 200
    
            CGPROGRAM
            #pragma surface surf Lambert vertex:vert nolightmap
    
            // Use shader model 3.0 target, to get nicer looking lighting
            //#pragma target 3.0
    
            sampler2D _RampTex;
            half _RampOffset;
            sampler2D _NoiseTex;
            float _Period;
            half _Amount;
            half _ClipRange;
    
            struct Input {
                float2 uv_NoiseTex;
            };
    
            void vert(inout appdata_full v)
            {
                float3 disp = tex2Dlod(_NoiseTex, float4(v.texcoord.xy, 0, 0));
                float time = sin(_Time[3] * _Period + disp.r * 10);
                v.vertex.xyz += normalize(v.normal) * disp.r * _Amount * time;
            }
    
            void surf (Input IN, inout SurfaceOutput o) 
            {
                float3 noise = tex2D(_NoiseTex, IN.uv_NoiseTex);
                float n = saturate(noise.r + _RampOffset);
                clip(_ClipRange - n);
                half4 c = tex2D(_RampTex, float2(n, 0.5));
                o.Albedo = c.rgb;
                o.Emission = c.rgb * c.a;
            }
            ENDCG
        }
        FallBack "Diffuse"
    }
    

    좋은 웹페이지 즐겨찾기