• RuntimesUnity
  • Adding Billboard functionality to Spine-Sprite-URP.shader

spine-sprite-urp.txt
9kB
newunlitshader.txt
3kB

I wanted to add billboard functionality to an existing spine URP shader.
However, when I add this code in the middle of an existing Spine URPShader, the following happens depending on where I add it.

  1. the billboard works fine, but all existing lighting effects (normalmap, rimlighting, etc.) are not applied.
  2. no billboard is applied, it looks exactly the same as before
  3. two objects are rendered on the screen, one with billboards applied but no lights, the other with billboards applied but no lights. Both are rendered on the screen at the same time, overlapping.

I want to combine the two shaders so that the billboard is applied and the existing lighting effects are maintained at the same time.

How do I put the code in to make it work the way I want it to?

HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 3.0

            #include "UnityCG.cginc"

            struct appdata_t
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            float rayPlaneIntersection(float3 rayDir, float3 rayPos, float3 planeNormal, float3 planePos)
            {
                float denom = dot(planeNormal, rayDir);
                denom = max(denom, 0.000001); // avoid divide by zero
                float3 diff = planePos - rayPos;
                return dot(diff, planeNormal) / denom;
            }

            v2f vert(appdata_t v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);

                // Billboard mesh towards camera
                float3 vpos = mul((float3x3)unity_ObjectToWorld, v.vertex.xyz);
                float4 worldCoord = float4(unity_ObjectToWorld._m03, unity_ObjectToWorld._m13, unity_ObjectToWorld._m23, 1);
                float4 viewPos = mul(UNITY_MATRIX_V, worldCoord) + float4(vpos, 0);
                o.pos = mul(UNITY_MATRIX_P, viewPos);

                // Calculate distance to vertical billboard plane seen at this vertex's screen position
                float3 planeNormal = normalize(float3(UNITY_MATRIX_V._m20, 0.0, UNITY_MATRIX_V._m22));
                float3 planePoint = unity_ObjectToWorld._m03_m13_m23;
                float3 rayStart = _WorldSpaceCameraPos.xyz;
                float3 rayDir = -normalize(mul(UNITY_MATRIX_I_V, float4(viewPos.xyz, 1.0)).xyz - rayStart); // Convert view to world, minus camera pos
                float dist = rayPlaneIntersection(rayDir, rayStart, planeNormal, planePoint);

                // Calculate the clip space z for the vertical plane
                float4 planeOutPos = mul(UNITY_MATRIX_VP, float4(rayStart + rayDir * dist, 1.0));
                float newPosZ = planeOutPos.z / planeOutPos.w * o.pos.w;

                // Use the closest clip space z
                #if defined(UNITY_REVERSED_Z)
                o.pos.z = max(o.pos.z, newPosZ);
                #else
                o.pos.z = min(o.pos.z, newPosZ);
                #endif

                UNITY_TRANSFER_FOG(o, o.pos);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                UNITY_APPLY_FOG(i.fogCoord, col);

                return col;
            }
            ENDHLSL
  • Harald님이 이에 답장했습니다.
    Related Discussions
    ...

    Kikuhn I wanted to add billboard functionality to an existing spine URP shader.
    However, when I add this code in the middle of an existing Spine URPShader, the following happens depending on where I add it.

    How exactly did you "add this code in the middle" of existing shader code? Neither the two provided txt files nor the code section in the above posting show how you integrated it. Unfortunately it's hard to tell what you did wrong when we don't know what you actually did. Please share the shader code of the simplest Spine URP shader after you have modified it to add the billboard vertex shader code.

    Also, where do you have your billboard code from? I'm asking since it contains redundant assignment to o.pos = .. where the first line is obviously having no effect, so I question whether it is reliably working in the first place.