r/godot•
myaccounttt

Converting this Unity Shader to Godot?

Help

I'm trying to use this shader I found in the Unity forums by bgolus, but obviously, it's written in Unity's version of HLSL instead of Godot's version of GLSL. It has the exact effect I am trying to achieve, which is preventing a billboarded Sprite3D from clipping into planes behind it. I know it's possible, but I'm just having trouble converting the vertex shader to be used in Godot, and after days of research this Unity thread was the only resource I could find that would help with this problem.

Sprite 3D is right next to the wall without clipping it

This is the code he provided:

v2f vert(appdata v) {
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    o.uv = v.uv.xy;
 
    // 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 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;
}

I know billboarding by itself would look something like this:

MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],CAMERA_MATRIX[1],CAMERA_MATRIX[2],WORLD_MATRIX[3]);

But I don't know if the Unity shader even uses this approach because I can't read HLSL :/

Any ideas on what this shader code would look like Godot?

Posted May 4, 2022, 1:47 AM UTC

12
Loading comments…