본문 바로가기
Shader

빌보드(Billboard)를 만들어 봅시다 3부. 마무리해 봅시다 / HLSL버전

by 대마왕J 2024. 7. 28.

이제 오브젝트 스페이스의 이동과 회전을 만들어 봅시다 . 노드에서는 아주 쉽습니다. 

걍 오브젝트 노드가 따로 있어서... 
포지션과 스케일이 있으므로 이걸 이용하면 됩니다. 

요렇게 말이죠 . 스케일은 곱해주고 이동은 더해주면 됩니다. 
(Q :월드 공간이라면서 거기에 오브젝트 공간 이동 더해주면 되나요?
A : 아니 사실 OS 공간인데 우리가 억지로 월드공간으로 정해버린거라서 상관없어요)

그러면 이제 이동과 스케일까지 다 적용되면서 빌보드도 적용됩니다. 셰이더만 언릿으로 해주면 완벽. 

 

 

HLSL 버전도 없으면 서운하겠죠? 

개념은 동일합니다. 똑같이 짜주면 되어요
주석에 써 놨고 연산순서도 노드랑 똑같이 해 봤습니다 (굳이)

Shader "BillboardHLSL1"
{
    SubShader
    {
        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalRenderPipeline" }
        cull off

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"            

            struct Attributes
            {
                float4 positionOS   : POSITION;                 
            };

            struct Varyings
            {
                float4 positionHCS  : SV_POSITION;
            };
            
            Varyings vert(Attributes IN)
            {
                Varyings OUT;
                
                // 오브젝트의 스케일과 이동 구하기///////////////////////////////////////  
                //objectToWorld 메트릭스 가져오기. 이게 UNITY_MATRIX_M 이다.  
                float4x4 objectToWorld = GetObjectToWorldMatrix();
                //오브젝트 스케일 구하기. 사실z 는 필요없지만 혼자 안해주면 외로울까봐
                float3 scaleOS = float3(length(GetObjectToWorldMatrix()._m00_m10_m20), 
                                        length(GetObjectToWorldMatrix()._m01_m11_m21),
                                        length(GetObjectToWorldMatrix()._m02_m12_m22));
                //오브젝트 이동 구하기
                float3 moveOS = GetAbsolutePositionWS(UNITY_MATRIX_M._m03_m13_m23);

                // 빌보드 시작하기 /////////////////////////////////////////////////////
                IN.positionOS.rg *= scaleOS.xy;//스케일 곱하기
                //viewINV 를 OS 포지션에 곱해줘서 늘 카메라를 바라보게 만듭니다. 그리고 이러면 월드공간이 됨
                float4 Billboard = mul(UNITY_MATRIX_I_V, float4(IN.positionOS.rgb,0));
                Billboard.rgb += moveOS; //이동 더해주기
                //월드공간을 다시 오브젝트 공간으로 돌려줍니다
                float3 positionOS = TransformWorldToObject(Billboard.rgb);

                OUT.positionHCS = TransformObjectToHClip(positionOS);
                return OUT;
            }

            half4 frag() : SV_Target
            {
                return float4(1,0,0,1);
            }
            ENDHLSL
        }
    }
}

이러면 잘됩니다. 잇힝. 
박스로 시작해서 문제이긴 한데 쿼드로 시작하면 더 좋아지겠죠. 

이거 선택 외각선도 빌보드에 맞게 어떻게 하는 법 있던데 어떻게 하더라.. 

반응형

댓글