[Unity] 스카이박스로 화환.

11390 단어 Unity
유니티 스카이박스 면도기로 화환을 만들어 봤어요.
스카이박스 면도기의 시선 방향은 TEXCOORD0로, 카메라 위치_WorldSpaceCameraPos를 얻을 수 있어 자체 계산 없이 바로 후광이 발사된다.

스카이박스 면도기 쓰는 법 자체는 제가 예전에 쓴 글을 참고하세요.
[Unity] 스카이박스 면도기 쓰는 법-큐타
하는 일 자체가 늘 있는 연습이기 때문에 설명하지 않는다.
Raymarching.Shader
Shader "Skybox/Raymarching"
{
    SubShader
    {
        Tags
        {
            "RenderType"="Background"
            "Queue"="Background"
            "PreviewType"="SkyBox"
        }

        Pass
        {
            ZWrite Off
            Cull Off

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

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

            struct v2f 
            {
                float4 vertex : SV_POSITION;
                float3 rayDir : TEXCOORD0;
            };

            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.rayDir = v.rayDir;
                return o;
            }

            float sphere(float3 pos, float radius)
            {
                return length(pos) - radius;
            }

            float3 repeat(float3 pos, float3 span)
            {
                return abs(fmod(pos, span)) - span * 0.5;
            }

            float getDistance(float3 pos)
            {
                return sphere(repeat(pos, 10.0), 1.0f);
            }

            float3 getNormal(float3 pos) {
                float d = 0.001;
                return normalize(float3(
                    getDistance(pos + float3(d, 0, 0)) - getDistance(pos + float3(-d, 0, 0)),
                    getDistance(pos + float3(0, d, 0)) - getDistance(pos + float3(0, -d, 0)),
                    getDistance(pos + float3(0, 0, d)) - getDistance(pos + float3(0, 0, -d))
                ));
            }

            float3 raymarch(float3 cameraPos, float3 rayDir)
            {
                float3 pos = cameraPos;
                for (int i = 0; i < 200; i++) {
                    float d = getDistance(pos);
                    pos += d * rayDir;
                    if (d < 0.001) {
                        return getNormal(pos) * 0.5 + 0.5;
                    }
                }
                return 0;
            }

            fixed4 frag (v2f i) : SV_TARGET
            {
                float3 rayDir = normalize(i.rayDir);
                return fixed4(raymarch(_WorldSpaceCameraPos, rayDir), 1.0);
            }

            ENDCG
        }
    }
}

좋은 웹페이지 즐겨찾기