250403

凡愚·2025년 4월 3일

개발 일지

목록 보기
130/350

✅ What I did today


  • Project BCA
  • Udemy Course : Unity Shader
  • Project Katana


🎮 Project BCA




🎞️ Udemy Course : Unity Shader


Basic Lambert

    SubShader
    {
        Pass
        {
            Tags {"LightMode"="ForwardBase"}

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "UnityLightingCommon.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                fixed4 diff : COLOR0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            // 램버트 모델로 빛 세기 계산
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord;
                half3 worldNormal = UnityObjectToWorldNormal(v.normal); // 노말을 월드 좌표계로 변환
                half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz)); // 광원 방향과 노말의 내적
                o.diff = nl * _LightColor0; // 광원 색상과 내적값을 곱하여 diffuse 색상 계산
                return o;
            }
            // 텍스쳐랑 빛 세기 곱하기
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                col *= i.diff;
                return col;
            }
            ENDCG
        }
    }

Cast shadow

램버트에 패스 추가

        Pass
        {
            Tags {"LightMode"="ShadowCaster"}

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_shadowcaster
            #include "UnityCG.cginc"

            struct appdata {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f {
                V2F_SHADOW_CASTER;
            };

            v2f vert(appdata v)
            {
                v2f o;
                TRANSFER_SHADOW_CASTER_NORMALOFFSET(o); // 그림자 데이터 생성
                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                SHADOW_CASTER_FRAGMENT(i); // 그림자 받았다면 색상 변환
            }
            ENDCG
        }

함수 호출로 유니티가 그림자 대신 계산해줌

Receive shadow

        Pass
        {
            Tags {"LightMode"="ForwardBase"}

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // directional light와 실시간 그림자만 고려하겠다는 뜻
            #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlighmap novertexlight
            #include "UnityCG.cginc"
            #include "UnityLightingCommon.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                fixed4 diff : COLOR0;
                // vertex에서 post로 바꾼 이유 : TRANSFER_SHADOW()가 vertex가 아닌 pos를 찾기 때문
                float4 pos : SV_POSITION; 
                SHADOW_COORDS(1) // 그림자 좌표들을 계산
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            // 램버트 모델로 빛 세기 계산
            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord;
                half3 worldNormal = UnityObjectToWorldNormal(v.normal);
                half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz)); 
                o.diff = nl * _LightColor0; 
                TRANSFER_SHADOW(o); // 그림자를 월드 좌표계에서 frag를 위한 좌표계로 변환

                return o;
            }
            // 텍스쳐랑 빛 세기 곱하기
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                fixed shadow = SHADOW_ATTENUATION(i); // 그림자 세기 계산
                col *= i.diff * shadow;
                return col;
            }
            ENDCG
        }


🎮 Project Katana


클릭하던 와중에 방향을 크게 틀거나 이리저리 움직여도 힘이 가해져서 어색한 문제

클릭 프레임과 그 다음 프레임의 차이를 기준으로 하려고 했는데 인식을 잘 못함
버퍼를 둬서 프레임 방향벡터 모은 후에 그걸로 기준 벡터 적용하려고 했는데 로직이 너무 어지러워짐
상태 패턴 쓰려고 했더니 상태가 공통으로 쓰는 변수가 너무 많아서 계속 매니저에 함수나 변수 추가해야할 것 같아서 뭔가 이상함 상태 패턴의 이점이 격감되는 것 같음
gpt는 Context 데이터 구조를 만드는 걸 추천 (공통 부분 코드를 나눌 수 있다는 것 외에 나아지는 거 없다)
차라리 판정 로직 계획을 수정하여 '지금까지 그었던 벡터들 총합'을 저장해놓고 비교하는게 더 간단할듯. 패턴 다 제거.

    void Update()
    {
        if (isClicking)
        {

            if (Input.GetMouseButtonUp(0)) isClicking = false;

            Vector2 deltaPos = (Vector2)Input.mousePosition - lastFramePos;
            slideVecSum += deltaPos;

            float angle = Mathf.Abs(Vector2.SignedAngle(slideVecSum, deltaPos));
            if (angle > 45) isClicking = false;

            player.GetComponent<Rigidbody2D>().AddForce(deltaPos * power);
            lastFramePos = (Vector2)Input.mousePosition;
        }
        else if (Input.GetMouseButtonDown(0) && IsPlayer())
        {
            isClicking = true;
            slideVecSum = Vector2.zero;
            lastFramePos = Input.mousePosition;
        }
    }



0개의 댓글