Search Unity

Having Trouble changing my Billboarding 2.5d Shader to A Surface Shader

Discussion in 'Shaders' started by tylerrosales, Oct 8, 2020.

  1. tylerrosales

    tylerrosales

    Joined:
    Jul 22, 2018
    Posts:
    1
    I am creating a Doom type game where the player is a sprite that is 2d in a 3d world. I am trying to change my vertex/frag shader that creates a "2.D" rotational billboarding sprite to a surface shader so I can add normals, a shadow ect. to the sprite. The current vert and frag shader works by calculating the rotation angle of the billboard and using that data to offset the uv of the tilesheet texture I made of sprites to the appropriate angled sprite so it has a 3d effect! It also animates using the columns of this tilesheet as well.
    I am TOTALLY stumped converting it to a Surface Shader appropriately. I have no errors but all I get so far is just the Tilesheet billboarding, no offsets or UV changes to the texture and I don't even know if it is using the angle data that it is being fed! ANY help would be appreciated I cannot figure this one out!
    here is the full code for the vertex shader that works really well:
    Code (CSharp):
    1. Shader "UnityCoder/Doom2"
    2. {
    3.      Properties
    4.      {
    5.          _MainTex ("Base (RGB)", 2D) = "white" {}
    6.          _Frames ("Frames (rows)", Float) = 13
    7.          _Columns ("Columns", Float) = 4
    8.          _AnimSpeed ("Animation Speed", Float) = 1
    9.               _ScaleX ("Scale X", Float) = 1.0
    10.        _ScaleY ("Scale Y", Float) = 1.0
    11.      }
    12. SubShader
    13.      {
    14.          Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True"}
    15.          ZWrite Off
    16.          Blend SrcAlpha OneMinusSrcAlpha
    17.          Pass
    18.          {
    19.              CGPROGRAM
    20.              #pragma vertex vert
    21.              #pragma fragment frag
    22.              #define PI 3.1415926535897932384626433832795
    23.              #define RAD2DEG 57.2958
    24.              #define SINGLEFRAMEANGLE (360/_Frames)
    25.              #define UVOFFSETX (1/_Frames)
    26.              #include "UnityCG.cginc"
    27.              uniform sampler2D _MainTex;
    28.              uniform float _ScaleX;
    29.           uniform float _ScaleY;
    30.              struct appdata {
    31.                  float4 vertex : POSITION;
    32.                  float4 texcoord : TEXCOORD0;
    33.              };
    34.              struct v2f {
    35.                  float4 pos : SV_POSITION;
    36.                  half2 uv : TEXCOORD0;
    37.              };
    38.                  // float4x4 _CameraToWorld;
    39.              float _Frames;
    40.              float _Columns;
    41.              float _AnimSpeed;
    42.              float2 atan2Approximation(float2 y, float2 x) // http://http.developer.nvidia.com/Cg/atan2.html
    43.              {
    44.                  float2 t0, t1, t2, t3, t4;
    45.                  t3 = abs(x);
    46.                  t1 = abs(y);
    47.                  t0 = max(t3, t1);
    48.                  t1 = min(t3, t1);
    49.                  t3 = float(1) / t0;
    50.                  t3 = t1 * t3;
    51.                  t4 = t3 * t3;
    52.                  t0 =         - float(0.013480470);
    53.                  t0 = t0 * t4 + float(0.057477314);
    54.                  t0 = t0 * t4 - float(0.121239071);
    55.                  t0 = t0 * t4 + float(0.195635925);
    56.                  t0 = t0 * t4 - float(0.332994597);
    57.                  t0 = t0 * t4 + float(0.999995630);
    58.                  t3 = t0 * t3;
    59.                  t3 = (abs(y) > abs(x)) ? float(1.570796327) - t3 : t3;
    60.                  t3 = (x < 0) ?  float(3.141592654) - t3 : t3;
    61.                  t3 = (y < 0) ? -t3 : t3;
    62.                  return t3;
    63.              }
    64.              v2f vert (appdata v)
    65.              {
    66.                  v2f o;
    67.                  o.pos = mul(UNITY_MATRIX_P,
    68.      mul(UNITY_MATRIX_MV, float4(0, 0, 0, 1)) + float4(v.vertex.x, v.vertex.y, 0, 0)* float4(_ScaleX, _ScaleY, 1.0, 1.0)) ;
    69.                
    70.                  // get direction
    71.                     float3 cameraUp = UNITY_MATRIX_IT_MV[1].xyz;
    72.                  float3 cameraForward = normalize(UNITY_MATRIX_IT_MV[2].xyz);
    73.                  float3 towardsRight = normalize(cross(cameraUp, cameraForward));
    74.                
    75.                  // get angle & current frame
    76.                     float angle = (atan2Approximation(towardsRight.z,towardsRight.x)*RAD2DEG) % 360;
    77.                  int index = angle/SINGLEFRAMEANGLE;
    78.                
    79.                     // animated frames
    80.                  float animFrame= _Columns-(1+round(_Time.y*_AnimSpeed) % _Columns);
    81.                                
    82.                  // set uv to display current frame
    83.                  o.uv = float2(v.texcoord.x*UVOFFSETX+UVOFFSETX*index,(v.texcoord.y+animFrame)/_Columns);
    84.                          
    85.                 // billboard towards camera
    86.                    float3 vpos=mul((float3x3)unity_ObjectToWorld, v.vertex.xyz);
    87.                   float4 worldCoord=float4(unity_ObjectToWorld._m03,unity_ObjectToWorld._m13,unity_ObjectToWorld._m23,1);
    88.                  float4 viewPos=mul(UNITY_MATRIX_V,worldCoord)+float4(vpos,0);
    89.                  float4 outPos=mul(UNITY_MATRIX_P,viewPos);
    90.                  return o;
    91.              }
    92.              fixed4 frag(v2f i) : SV_Target
    93.              {
    94.              return tex2D(_MainTex,i.uv);
    95.              }
    96.              ENDCG
    97.          }
    98.      }
    99. }
    and here is the part of the surface shader that i made that isnt doing anything:
    Code (CSharp):
    1.  void vert(inout appdata_full v, out Input o)
    2.          {
    3.             UNITY_INITIALIZE_OUTPUT(Input, o);
    4.             o.pos = mul(UNITY_MATRIX_P,
    5.      mul(UNITY_MATRIX_MV, float4(0, 0, 0, 1)) + float4(v.vertex.x, v.vertex.y, 0, 0)* float4(_ScaleX, _ScaleY, 1.0, 1.0)) ;
    6.  
    7.            
    8.              // get the camera basis vectors
    9.              float3 cameraUp = normalize(UNITY_MATRIX_V._m10_m11_m12);
    10.                  float3 cameraForward = -normalize(UNITY_MATRIX_V._m20_m21_m22);
    11.                  float3 towardsRight = normalize(cross(cameraUp, cameraForward));
    12.                      // get angle & current frame
    13.                      float angle = (atan2Approximation(towardsRight.z,towardsRight.x)*RAD2DEG) % 360;
    14.                  int index = angle/SINGLEFRAMEANGLE;
    15.  
    16.               // billboard towards camera
    17.                   float4x4 rotationMatrix = float4x4(towardsRight, 0,
    18.                  cameraUp, 0,
    19.                  cameraForward, 0,
    20.                  0, 0, 0, 1);
    21.              v.vertex = mul(v.vertex, rotationMatrix);
    22.              v.normal = mul(v.normal, rotationMatrix);
    23.                          // animated frames
    24.                  float animFrame= _Columns-(1+round(_Time.y*_AnimSpeed) % _Columns);
    25.                                
    26.                  // set uv to display current frame
    27.                  o.uv_MainTex = float2(v.texcoord.x*UVOFFSETX+UVOFFSETX*index,(v.texcoord.y+animFrame)/_Columns);
    28.              // undo object to world transform surface shader will apply
    29.              v.vertex.xyz = mul((float3x3)unity_WorldToObject, v.vertex.xyz);
    30.              v.normal = mul(v.normal, (float3x3)unity_ObjectToWorld);
    31.          }
    32.  
    33.          void surf (Input IN, inout SurfaceOutput o) {
    34.              // Albedo comes from a texture tinted by color
    35.              fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    36.                      o.Albedo = c.rgb;
    37.              o.Alpha = c.a;
    38.          }

    is there a different kind of code in surface shader for changing the texture coordinates to offset correctly? what am I doing wrong in the translation??