Hey guys!
I am trying to modify Unitys default sprite shader to achieve a curved effect. Basically, I want to decrease the Y-position of vertices by the square distance from the camera along the X-axis.
I found this curved world shader that helped me get started. Here is the main part of the functionality in that shader, slightly modified so that it curves based on the X-axis rather than Z:
// This is where the curvature is applied
void vert( inout appdata_full v)
{
// Transform the vertex coordinates from model space into world space
float4 vv = mul( _Object2World, v.vertex );
// Now adjust the coordinates to be relative to the camera position
vv.xyz -= _WorldSpaceCameraPos.xyz;
// Reduce the y coordinate (i.e. lower the "height") of each vertex based
// on the square of the distance from the camera in the z axis, multiplied
// by the chosen curvature factor
vv = float4( 0.0f, (vv.x * vv.x) * - _Curvature, 0.0f, 0.0f );
// Now apply the offset back to the vertices in model space
v.vertex += mul(_World2Object, vv);
}
So in the sprite shader I a have tried this:
v2f vert(appdata_full IN)
{
v2f OUT;
float4 vv = mul(UNITY_MATRIX_MVP, IN.vertex);
vv.xyz -= _WorldSpaceCameraPos.xyz;
vv = float4( 0.0f, (vv.x * vv.x) * - _Curvature, 0.0f, 0.0f );
vv += mul(_World2Object, vv);
OUT.vertex = vv;
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap (OUT.vertex);
#endif
return OUT;
}
I am very new to this, and I don’t really understand what UNITY_MATRIX_MVP is. I have tried to replace it with _Object2World but that didn’t help. Obviously I am doing something very wrong, because the sprite disappears.
If someone could point me in the right direction I would really appreciate it! I guess I need a better understanding of the math involved here.
Full modified sprite shader below.
Shader "Sprites/Curved"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
_Curvature ("Curvature", Float) = 0.001
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
fixed4 _Color;
uniform float _Curvature;
v2f vert(appdata_full IN)
{
v2f OUT;
float4 vv = mul(UNITY_MATRIX_MVP, IN.vertex);
vv.xyz -= _WorldSpaceCameraPos.xyz;
vv = float4( 0.0f, (vv.x * vv.x) * - _Curvature, 0.0f, 0.0f );
vv += mul(_World2Object, vv);
OUT.vertex = vv;
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap (OUT.vertex);
#endif
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;
c.rgb *= c.a;
return c;
}
ENDCG
}
}
}