Files
2025-05-07 15:07:44 +08:00

122 lines
4.0 KiB
HLSL

// Shapes © Freya Holmér - https://twitter.com/FreyaHolmer/
// Website & Documentation - https://acegikmo.com/shapes/
#include "UnityCG.cginc"
#include "../Shapes.cginc"
#pragma target 3.0
UNITY_INSTANCING_BUFFER_START(Props)
PROP_DEF( half4, _Color)
PROP_DEF( half4, _ColorB)
PROP_DEF( half4, _ColorC)
PROP_DEF( half4, _ColorD)
PROP_DEF( float3, _A)
PROP_DEF( float3, _B)
PROP_DEF( float3, _C)
PROP_DEF( float3, _D)
UNITY_INSTANCING_BUFFER_END(Props)
struct VertexInput {
float4 vertex : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VertexOutput {
float4 pos : SV_POSITION;
#if QUAD_INTERPOLATION_QUALITY == 0
half4 color : TEXCOORD0;
#elif QUAD_INTERPOLATION_QUALITY == 1
half2 uv : TEXCOORD2;
#elif QUAD_INTERPOLATION_QUALITY == 2
half2 localPos : TEXCOORD1;
#elif QUAD_INTERPOLATION_QUALITY == 3
half2 localPos : TEXCOORD1;
half4 posAB : TEXCOORD2;
half4 posCD : TEXCOORD3;
#endif
UNITY_FOG_COORDS(4)
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
half2 PlanarProject( half3 pos3D, half3 dirX, half3 dirY ){
return half2( dot( pos3D, dirX ), dot( pos3D, dirY ) );
}
VertexOutput vert (VertexInput v) {
UNITY_SETUP_INSTANCE_ID(v);
VertexOutput o = (VertexOutput)0;
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
float3 A = PROP(_A);
float3 B = PROP(_B);
float3 C = PROP(_C);
float3 D = PROP(_D);
v.vertex.xyz = A * v.color.r + B * v.color.g + C * v.color.b + D * v.color.a;
#if QUAD_INTERPOLATION_QUALITY == 0
// per-vertex version, which doesn't do a real bilinear version
half4 colorA = PROP(_Color);
half4 colorB = PROP(_ColorB);
half4 colorC = PROP(_ColorC);
half4 colorD = PROP(_ColorD);
o.color = colorA * v.color.r + colorB * v.color.g + colorC * v.color.b + colorD * v.color.a;
#elif QUAD_INTERPOLATION_QUALITY == 1
o.uv = v.uv * 0.5 + 0.5;
#elif QUAD_INTERPOLATION_QUALITY == 2
o.localPos = v.vertex.xy; // assume 2D coordinates only
#elif QUAD_INTERPOLATION_QUALITY == 3
// construct best fit plane from average face normals
half3 ab = B - A;
half3 ac = C - A;
half3 ad = D - A;
half3 normalA = normalize(cross( ab, ac ));
half3 normalB = normalize(cross( ab, ac ));
half3 normal = normalize(normalA + normalB);
half3 tangent = normalize(ab);
half3 bitangent = cross( normal, tangent );
// project all coordinates
o.posAB.xy = PlanarProject( A, tangent, bitangent );
o.posAB.zw = PlanarProject( B, tangent, bitangent );
o.posCD.xy = PlanarProject( C, tangent, bitangent );
o.posCD.zw = PlanarProject( D, tangent, bitangent );
o.localPos = PlanarProject( v.vertex, tangent, bitangent );
#endif
o.pos = UnityObjectToClipPos( v.vertex );
UNITY_TRANSFER_FOG(o,o.pos);
return o;
}
FRAG_OUTPUT_V4 frag( VertexOutput i ) : SV_Target {
UNITY_SETUP_INSTANCE_ID(i);
#if QUAD_INTERPOLATION_QUALITY == 0
return ShapesOutput( i.color, 1 );
#else
#if QUAD_INTERPOLATION_QUALITY == 1
half2 uv = i.uv;
#elif QUAD_INTERPOLATION_QUALITY == 2
float3 A = PROP(_A);
float3 B = PROP(_B);
float3 C = PROP(_C);
float3 D = PROP(_D);
half2 uv = InvBilinear( i.localPos.xy, A.xy, B.xy, C.xy, D.xy );
#elif QUAD_INTERPOLATION_QUALITY == 3
half2 uv = InvBilinear( i.localPos.xy, i.posAB.xy, i.posAB.zw, i.posCD.xy, i.posCD.zw );
#endif
half4 colorA = PROP(_Color);
half4 colorB = PROP(_ColorB);
half4 colorC = PROP(_ColorC);
half4 colorD = PROP(_ColorD);
half4 left = lerp(colorA, colorB, uv.y );
half4 right = lerp(colorD, colorC, uv.y );
half4 color = lerp( left, right, uv.x );
return SHAPES_OUTPUT( color, 1, i );
#endif
}