250417

lililllilillll·2025년 4월 16일

개발 일지

목록 보기
144/350

✅ What I did today


  • The Book of Shader
  • Prototyping :: P001 : Day 2


📖 The Book of Shader


원래는 cpu로 그래픽 작업 했는데 글카 나오면서 마이크로프로세서로 병렬처리하는 방법 생겨났다
opengl이 맨 처음 만들어진 그래픽 api였다
directx가 shader라는거 만들었다
opengl하고 directx하고 싸웠는데 opengl이 이전 기능 제거 안 하고 기능 추가 제대로 안 해서 밀릴뻔했는데 요즘(이 글 쓴 때가 언제인진 모르겠지만)은 다시 좋아졌다



💡 Prototyping :: P001 : Day 2


Phase A : Implementing

  • Character Controller는 자식의 collider나 추가 collider를 무시하고 자신의 캡슐 콜라이더만 신경쓴다.
  • Rigidbody 이동이나 회전은 MovePosition()으로 움직여도 FixedUpdate()에서 호출해야 한다
  • 벽뚫을 방지하려면 MovePosition() 류는 쓰면 안된다. raycast로 벽뚫 방지하던가.
  • LayerMask.NameToLayer()는 생성자나 필드 초기화 구문에서 사용할 수 없다
  • raycast를 위해 layerMask 사용할 때 ~를 붙여줘야 무시하는 마스크가 된다

한 것

  • outline shader 개선
  • level 1, 2 완성
  • 2d, 3d 움직임 스크립트 분리
  • rigidbody 기반 이동 완성 : 벽뚫기 문제 발생하여 character controller로 변경할 예정
Shader "URP/FullscreenOutline_DepthNormal"
{
    Properties
    {
        _OutlineColor    ("Outline Color", Color)        = (0,0,0,1)
        _Thickness       ("Outline Thickness(px)", Range(1,6)) = 1
        _DepthThreshold  ("Depth Δ",  Range(0,0.02))     = 0.002
        _NormalThreshold ("Normal Δ", Range(0,1))        = 0.15
    }

    SubShader
    {
        Tags { "RenderPipeline" = "UniversalRenderPipeline" }
        Pass
        {
            Name "FullscreenPass"  Tags{ "LightMode"="UniversalRenderer" }

            HLSLPROGRAM
            #pragma vertex FullscreenVert
            #pragma fragment frag
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            // 핵심 버퍼
            TEXTURE2D_X(_BlitTexture);         SAMPLER(sampler_BlitTexture);
            TEXTURE2D(_CameraDepthTexture);    SAMPLER(sampler_CameraDepthTexture);
            TEXTURE2D(_CameraNormalsTexture);  SAMPLER(sampler_CameraNormalsTexture);

            // 머티리얼 프로퍼티
            float4 _OutlineColor;
            float  _Thickness;
            float  _DepthThreshold;
            float  _NormalThreshold;

            struct Varyings { float4 positionCS : SV_POSITION; };

            Varyings FullscreenVert (uint id : SV_VertexID)
            {
                Varyings o;
                o.positionCS = GetFullScreenTriangleVertexPosition(id);
                return o;
            }

            // depth to linear eye‑space
            float LinearEye (float raw) { return Linear01Depth(raw, _ZBufferParams); }

            float4 frag (Varyings i) : SV_Target
            {
                float2 uv    = i.positionCS.xy / _ScreenParams.xy;
                float2 texel = _Thickness / _ScreenParams.xy;

                // 기준 픽셀 깊이·노멀
                float  depthCenter   = LinearEye(SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, uv).r);
                float3 normalCenter  = normalize(SAMPLE_TEXTURE2D(_CameraNormalsTexture, sampler_CameraNormalsTexture, uv).rgb * 2 - 1);

                // 최대 변화량 저장 변수 (ASCII 이름!)
                float  maxDepthDelta   = 0.0;
                float  maxNormalDelta  = 0.0;

                [unroll] for (int y = -1; y <= 1; ++y)
                {
                    [unroll] for (int x = -1; x <= 1; ++x)
                    {
                        if (x == 0 && y == 0) continue;
                        float2 offset = float2(x, y) * texel;

                        float  d = LinearEye(SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, uv + offset).r);
                        float3 n = normalize(SAMPLE_TEXTURE2D(_CameraNormalsTexture, sampler_CameraNormalsTexture, uv + offset).rgb * 2 - 1);

                        maxDepthDelta  = max(maxDepthDelta,  abs(d - depthCenter));
                        maxNormalDelta = max(maxNormalDelta, 1 - dot(n, normalCenter)); // 각도 차
                    }
                }

                bool isEdge =
                    (maxDepthDelta  > _DepthThreshold) ||
                    (maxNormalDelta > _NormalThreshold);

                float4 src = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_BlitTexture, uv);
                return isEdge ? _OutlineColor : src;
            }
            ENDHLSL
        }
    }
}

배경을 무시하지 않고 외곽선만 따도록 변경.
o1이 딴소리하던거 o3한테 물었더니 한 번에 해결해줌.
이게 맞나 싶긴 한데 일단 해결했으니 ok.



profile
너 정말 **핵심**을 찔렀어

0개의 댓글