공부/Unity

[Unity] Shader URP 물 속 효과 주기 (화면 꿀렁이기)

굴러다니다니 2025. 8. 28. 15:43

물속인척 하는 shader

Shader "Hidden/UnderwaterRG_Fullscreen"
{
    Properties
    {
        _color("Tint Color", Color) = (0, 0.6, 0.8, 0.25)
        _dis("Distance", Float) = 10
        _alpha("Alpha", Range(0,1)) = 0.5
        _refraction("Refraction", Float) = 0.1
        _NormalMap("Normal Map", 2D) = "bump" {}
        _normalUV("Normal UV (xy:scale zw:scroll)", Vector) = (1,1,0.2,0.1)
    }

    SubShader
    {
        Tags { "RenderPipeline"="UniversalPipeline" "Queue"="Transparent" }
        ZWrite Off
        ZTest Always
        Cull Off
        Blend Off

        Pass
        {
            Name "UnderwaterRG_Fullscreen"
            HLSLPROGRAM
            #pragma vertex   Vert
            #pragma fragment Frag
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"

            TEXTURE2D(_CameraOpaqueTexture);
            SAMPLER(sampler_CameraOpaqueTexture);

            TEXTURE2D(_NormalMap);
            SAMPLER(sampler_NormalMap);

            float4 _color;
            float  _dis;
            float  _alpha;
            float  _refraction;
            float4 _normalUV;

            struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; };
            struct Varyings
            {
                float4 positionCS  : SV_POSITION;
                float4 positionNDC : TEXCOORD0;
                float2 uvN         : TEXCOORD1;
            };

            Varyings Vert (Attributes v)
            {
                Varyings o;
                o.positionCS  = TransformObjectToHClip(v.positionOS.xyz);
                o.positionNDC = ComputeScreenPos(o.positionCS);
                o.uvN = v.uv * _normalUV.xy + _normalUV.zw * _Time.y;
                return o;
            }

            float2 GetScreenUV(float4 ndc)
            {
                float2 uv = ndc.xy / ndc.w;
            #if UNITY_UV_STARTS_AT_TOP
                uv.y = 1.0 - uv.y;
            #endif
                return uv;
            }

            float4 Frag (Varyings i) : SV_Target
            {
                // 노멀맵 굴절
                float3 nrm = UnpackNormal(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uvN));
                float2 offset = nrm.xy * _refraction;

                // 화면 UV + 굴절
                float2 suv = GetScreenUV(i.positionNDC) + offset;

                // y축 뒤집기
                suv = float2(suv.x, 1.0 - suv.y);

                // 샘플
                float4 src = SAMPLE_TEXTURE2D(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, saturate(suv));

                // 내부 합성
                float3 tinted = lerp(src.rgb, src.rgb * _color.rgb, saturate(_alpha));
                return float4(tinted, 1);
            }
            ENDHLSL
        }
    }
}

 

저 custom shader render texture를 적용한 material을 플레인에 넣어서

카메라 앞을 가리면

전체가 물에 잠긴듯한 느낌을 낼 수 있다

 

이렇게 일렁일렁

 

 

++ normal에 이거 이미지 껴줘야됨

 

움짤 귀찮아서 캡쳐했더니 티가 안나는 느낌

쨌든 urp asset에 넣으려고 했는데 안되길래 야매로 삥땅쳤다

728x90
반응형