Aetheria/Assets/Shaders/Terrain/MyTessellation.cginc
Reinier Vens 7561c09edc Unity 6 Upgrade + Solid Gravity Surface
Upgraded Unity version to 6000.1.10f1
Rewrote gravity surface shader to use shader environment vars for placement + various compatibility fixes
2025-07-10 21:05:54 +01:00

163 lines
No EOL
4.3 KiB
HLSL

#if !defined(TESSELLATION_INCLUDED)
#define TESSELLATION_INCLUDED
float _TessellationUniform;
float _TessellationEdgeLength;
struct TessellationControlPoint {
float4 vertex : INTERNALTESSPOS;
float3 normal : NORMAL;
#if TESSELLATION_TANGENT
float4 tangent : TANGENT;
#endif
float2 uv : TEXCOORD0;
#if TESSELLATION_UV1
float2 uv1 : TEXCOORD1;
#endif
#if TESSELLATION_UV2
float2 uv2 : TEXCOORD2;
#endif
};
struct TessellationFactors {
float edge[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
TessellationControlPoint MyTessellationVertexProgram (VertexData v) {
TessellationControlPoint p;
p.vertex = v.vertex;
p.normal = v.normal;
#if TESSELLATION_TANGENT
p.tangent = v.tangent;
#endif
p.uv = v.uv;
#if TESSELLATION_UV1
p.uv1 = v.uv1;
#endif
#if TESSELLATION_UV2
p.uv2 = v.uv2;
#endif
return p;
}
bool TriangleIsBelowClipPlane (
float3 p0, float3 p1, float3 p2, int planeIndex, float bias
) {
float4 plane = unity_CameraWorldClipPlanes[planeIndex];
return
dot(float4(p0, 1), plane) < bias &&
dot(float4(p1, 1), plane) < bias &&
dot(float4(p2, 1), plane) < bias;
}
bool TriangleIsCulled (float3 p0, float3 p1, float3 p2, float bias) {
return
TriangleIsBelowClipPlane(p0, p1, p2, 0, bias) ||
TriangleIsBelowClipPlane(p0, p1, p2, 1, bias) ||
TriangleIsBelowClipPlane(p0, p1, p2, 2, bias) ||
TriangleIsBelowClipPlane(p0, p1, p2, 3, bias);
}
float TessellationEdgeFactor (float3 p0, float3 p1) {
#if defined(_TESSELLATION_EDGE)
float edgeLength = distance(p0, p1);
float3 edgeCenter = (p0 + p1) * 0.5;
float viewDistance = distance(edgeCenter, _WorldSpaceCameraPos);
return edgeLength * _ScreenParams.y /
(_TessellationEdgeLength * viewDistance);
#else
return _TessellationUniform;
#endif
}
#if !defined(MY_LIGHTING_INCLUDED)
uniform float3 _GridTransform;
#endif
float TessellationEdgeFactor (float2 p0, float2 p1) {
#if defined(_TESSELLATION_EDGE)
float edgeLength = distance(p0, p1);
float2 edgeCenter = (p0 + p1) * 0.5;
float viewDistance = distance(edgeCenter, _WorldSpaceCameraPos.xz);
return edgeLength * _ScreenParams.y /
(_TessellationEdgeLength * viewDistance);
#else
return _TessellationUniform;
#endif
}
TessellationFactors MyPatchConstantFunction (
InputPatch<TessellationControlPoint, 3> patch
) {
//float3 p0 = mul(unity_ObjectToWorld, patch[0].vertex).xyz;
//float3 p1 = mul(unity_ObjectToWorld, patch[1].vertex).xyz;
//float3 p2 = mul(unity_ObjectToWorld, patch[2].vertex).xyz;
float2 p0 = patch[0].vertex.xz * _GridTransform.z / 2 + _GridTransform.xy;
float2 p1 = patch[1].vertex.xz * _GridTransform.z / 2 + _GridTransform.xy;
float2 p2 = patch[2].vertex.xz * _GridTransform.z / 2 + _GridTransform.xy;
TessellationFactors f;
float bias = 500 * _DisplacementStrength;
// if (TriangleIsCulled(p0, p1, p2, bias)) {
// f.edge[0] = f.edge[1] = f.edge[2] = f.inside = 0;
// }
// else {
f.edge[0] = TessellationEdgeFactor(p1, p2);
f.edge[1] = TessellationEdgeFactor(p2, p0);
f.edge[2] = TessellationEdgeFactor(p0, p1);
f.inside =
(TessellationEdgeFactor(p1, p2) +
TessellationEdgeFactor(p2, p0) +
TessellationEdgeFactor(p0, p1)) * (1 / 3.0);
// }
return f;
}
[UNITY_domain("tri")]
[UNITY_outputcontrolpoints(3)]
[UNITY_outputtopology("triangle_cw")]
[UNITY_partitioning("fractional_even")]
[UNITY_patchconstantfunc("MyPatchConstantFunction")]
TessellationControlPoint MyHullProgram (
InputPatch<TessellationControlPoint, 3> patch,
uint id : SV_OutputControlPointID
) {
return patch[id];
}
[UNITY_domain("tri")]
InterpolatorsVertex MyDomainProgram (
TessellationFactors factors,
OutputPatch<TessellationControlPoint, 3> patch,
float3 barycentricCoordinates : SV_DomainLocation
) {
VertexData data;
#define MY_DOMAIN_PROGRAM_INTERPOLATE(fieldName) data.fieldName = \
patch[0].fieldName * barycentricCoordinates.x + \
patch[1].fieldName * barycentricCoordinates.y + \
patch[2].fieldName * barycentricCoordinates.z;
MY_DOMAIN_PROGRAM_INTERPOLATE(vertex)
MY_DOMAIN_PROGRAM_INTERPOLATE(normal)
#if TESSELLATION_TANGENT
MY_DOMAIN_PROGRAM_INTERPOLATE(tangent)
#endif
MY_DOMAIN_PROGRAM_INTERPOLATE(uv)
#if TESSELLATION_UV1
MY_DOMAIN_PROGRAM_INTERPOLATE(uv1)
#endif
#if TESSELLATION_UV2
MY_DOMAIN_PROGRAM_INTERPOLATE(uv2)
#endif
return MyVertexProgram(data);
}
#endif