Shader 파트 20 기하학적 면도기로 다각형을 조합하는 작업은 거의 없어요.

25560 단어 Unityshadertech

쉐더를 할 시간이 얼마 안 남았어요.


하마터면 Shader를 할 뻔했다.쉐더를 할 시간이 많지 않을 것 같아서요.
100부까지 열심히 하겠습니다.10년이 걸려도 돼요.
100편의 글을 배웠다면 초보자라도 이해할 수 있을 것 같아요.
이렇게 하는 거야.
※ 초보자는 필기 레벨로 기록
기술 보도로는 도움이 안 될 것 같습니다.

미리 준비하다


아래 참조
Shader 파트 1Unite 2017 애니메이션을 볼 때가 많지 않아요. (기초지식~종이 스크레이퍼로 색깔 바꾸기)

데모


과거 문장의 내용을 조합하다.
[연결된 과거 글]
Shader의 16번째 부분을 기하학적 음영으로 법선 방향으로 다각형을 움직일 때가 많지 않아요.
Shader의 17번째 부분을 기하학적 면도기로 다각형의 크기를 바꿀 때가 많지 않아요.
Shader의 18번째 부분을 기하학적 면도기로 다각형마다 색깔을 바꿀 때가 많지 않아요.
Shader의 19번째 부분을 커버로 다각형을 회전시킬 차이는 거의 없다
다음 시위는 실패판이다.

희망하는 행동은 다음과 같다.
• 각 다각형 즉석 회전
・즉석에서 각 다각형의 비율 변경
• 교점을 움직여도 색상은 변하지 않는다
다음은 순조롭게 진행된 시위 행진이다.
회전, 확장은 원하는 대로 각 다각형의 중심에서 진행되며 색깔도 이동에 따라 달라진다.

Shader 샘플


Shader "Custom/GeometryTest"
{
    Properties
    {
        _ScaleFactor ("Scale Factor", Range(0,1.0)) = 0.5
        _PositionFactor("Position Factor", Range(0,1.0)) = 0.5
        _RotationFactor ("Rotation Factor", Range(0,1.0)) = 0.5
    }
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }
        
        //両面描画
        Cull Off

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma geometry geom
            #pragma fragment frag

            #include "UnityCG.cginc"

            float _PositionFactor;
            float _RotationFactor;
            float _ScaleFactor;

            struct appdata
            {
                float4 vertex : POSITION;
                float3 localPos : TEXCOORD0;
            };

            //頂点シェーダー
            appdata vert(appdata v)
            {
                appdata o;
                o.localPos = v.vertex.xyz; //ジオメトリーシェーダーで頂点を動かす前に"描画しようとしているピクセル"のローカル座標を保持しておく
                return v;
            }

            struct g2f
            {
                float4 vertex : SV_POSITION;
                fixed4 color : COLOR;
            };

            //回転させる
            //pは回転させたい座標 angleは回転させる角度 axisはどの軸を元に回転させるか 
            float3 rotate(float3 p, float angle, float3 axis)
            {
                float3 a = normalize(axis);
                float s = sin(angle);
                float c = cos(angle);
                float r = 1.0 - c;
                float3x3 m = float3x3(
                    a.x * a.x * r + c, a.y * a.x * r + a.z * s, a.z * a.x * r - a.y * s,
                    a.x * a.y * r - a.z * s, a.y * a.y * r + c, a.z * a.y * r + a.x * s,
                    a.x * a.z * r + a.y * s, a.y * a.z * r - a.x * s, a.z * a.z * r + c
                );

                return mul(m, p);
            }

            //ランダムな値を返す
            float rand(float2 co)
            {
                return frac(sin(dot(co.xy, float2(12.9898, 78.233))) * 43758.5453);
            }

            // ジオメトリシェーダー
            [maxvertexcount(3)]
            void geom(triangle appdata input[3], uint pid : SV_PrimitiveID,inout TriangleStream<g2f> stream)
            {
                // 法線を計算
                float3 vec1 = input[1].vertex - input[0].vertex;
                float3 vec2 = input[2].vertex - input[0].vertex;
                float3 normal = normalize(cross(vec1, vec2));

                //1枚のポリゴンの中心
                float3 center = (input[0].vertex + input[1].vertex + input[2].vertex) / 3;
                float random = 2.0 * rand(center.xy) - 0.5;
                float3 r3 = random.xxx;
              
                [unroll]
                for (int i = 0; i < 3; i++)
                {
                    appdata v = input[i];
                    g2f o;
                    //移動に利用する位置ベクトルを保持
                    // float3 currentPos = normal * _PositionFactor * abs(r3); //負の値は法線と逆方向に移動してしまうので絶対値利用
                    // //法線ベクトルに沿って頂点を移動
                    // v.vertex.xyz += currentPos;
                    // //回転させる
                    // v.vertex.xyz = currentPos + center + rotate(v.vertex.xyz - center - currentPos, (pid + _Time.y) * _RotationFactor, r3);
                    // //中心を起点にスケールを変える
                    // v.vertex.xyz = currentPos + center + (v.vertex.xyz - center - currentPos) * (1.0 - _ScaleFactor);

                    //こっちの方がすっきり 順番を変えただけ
                    v.vertex.xyz = center + rotate(v.vertex.xyz - center, (pid + _Time.y) * _RotationFactor, r3);
                    v.vertex.xyz = center + (v.vertex.xyz - center) * (1.0 - _ScaleFactor);
                    v.vertex.xyz += normal * _PositionFactor * abs(r3);
                    
                    // NGパターン
                    // v.vertex.xyz += normal * _PositionFactor * abs(r3);
                    // v.vertex.xyz = center + rotate(v.vertex.xyz - center, (pid + _Time.y) * _RotationFactor, r3);
                    // v.vertex.xyz = center + (v.vertex.xyz - center) * (1.0 - _ScaleFactor);
                    
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    //ランダムな値
                    //シード値にワールド座標を利用すると移動するたびに色が変わってやかましいのでローカル座標を利用
                    float r = rand(v.localPos.xy);
                    float g = rand(v.localPos.xz);
                    float b = rand(v.localPos.yz);
                    
                    // NGパターン
                    // float r = rand(v.vertex.xy);
                    // float g = rand(v.vertex.xz);
                    // float b = rand(v.vertex.yz);
                    o.color = fixed4(r,g,b,1);
                    stream.Append(o);
                }
            }

            //フラグメントシェーダー
            fixed4 frag(g2f i) : SV_Target
            {
                return i.color;
            }
            ENDCG
        }
    }
}

움직일 때마다 변하는 색깔.


색깔이 바뀔 때마다.
자신이 정의한 랜덤값rand関数을 되돌려준 이유는 세계 좌표를 그에게 건네주었기 때문이다.
세계 좌표가 정점의 이동에 따라 변화하는 것은 당연한 것이다.
따라서 교점 스크레이퍼로 로컬 좌표를 한 번 유지하십시오rand関数의 씨앗 값.

중심을 원점으로 이동하지 않는 다각형


다각형의 정점을 이동한 후 회전 및 비례자 변경
중심을 원점으로 한 동작이 파산했다.
이유는 간단합니다. 이후 처리는 교점을 이동하기 전의 다각형의 중심을 참조합니다.
그래서あらかじめ移動に利用した位置ベクトルを保持しておく 또는
만약ポリゴンの頂点の移動の処理を最後に行う희망대로 다각형의 중심을 원점으로 옮겼다.

참조 링크


형상 성형 시작하기
다음은 HoloLens에서 사용하는 Near Clip 표현에 대한 설명입니다.
[Unity] Gemoetry Shader에서 3D 모형이 사라진 출처를 소개합니다[그림자가 있음]

좋은 웹페이지 즐겨찾기