117 lines
3.9 KiB
HLSL
117 lines
3.9 KiB
HLSL
|
#ifndef POI_TESSELLATION
|
||
|
#define POI_TESSELLATION
|
||
|
|
||
|
float _TessellationPhongStrength;
|
||
|
float _TessellationEdgeLength;
|
||
|
float _TessellationExtrusionAmount;
|
||
|
float _TessellationUniform;
|
||
|
|
||
|
struct TessellationControlPoint
|
||
|
{
|
||
|
float4 vertex: INTERNALTESSPOS;
|
||
|
float3 normal: NORMAL;
|
||
|
float4 tangent: TANGENT;
|
||
|
float4 color: COLOR;
|
||
|
float2 uv0: TEXCOORD0;
|
||
|
float2 uv1: TEXCOORD1;
|
||
|
float2 uv2: TEXCOORD2;
|
||
|
float2 uv3: TEXCOORD3;
|
||
|
};
|
||
|
|
||
|
struct TessellationFactors
|
||
|
{
|
||
|
float edge[3]: SV_TessFactor;
|
||
|
float inside: SV_InsideTessFactor;
|
||
|
};
|
||
|
|
||
|
TessellationControlPoint poiTessellationVert(appdata v)
|
||
|
{
|
||
|
TessellationControlPoint p;
|
||
|
p.vertex = v.vertex;
|
||
|
p.normal = v.normal;
|
||
|
p.tangent = v.tangent;
|
||
|
p.color = v.color;
|
||
|
p.uv0 = v.uv0;
|
||
|
p.uv1 = v.uv1;
|
||
|
p.uv2 = v.uv2;
|
||
|
p.uv3 = v.uv3;
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
float TessellationEdgeFactor(float3 p0, float3 p1)
|
||
|
{
|
||
|
#ifndef _FADING_ON
|
||
|
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
|
||
|
}
|
||
|
|
||
|
TessellationFactors poiPatchConst(
|
||
|
InputPatch < TessellationControlPoint, 3 > patch
|
||
|
)
|
||
|
{
|
||
|
|
||
|
TessellationFactors f;
|
||
|
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;
|
||
|
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_odd")]
|
||
|
[UNITY_patchconstantfunc("poiPatchConst")]
|
||
|
TessellationControlPoint poiHull(
|
||
|
InputPatch < TessellationControlPoint, 3 > patch,
|
||
|
uint id: SV_OutputControlPointID
|
||
|
)
|
||
|
{
|
||
|
return patch[id];
|
||
|
}
|
||
|
|
||
|
[UNITY_domain("tri")]
|
||
|
v2f poiDomain(
|
||
|
TessellationFactors factors,
|
||
|
OutputPatch < TessellationControlPoint, 3 > patch,
|
||
|
float3 barycentricCoordinates: SV_DomainLocation
|
||
|
)
|
||
|
{
|
||
|
appdata 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)
|
||
|
float3 pp[3];
|
||
|
for (int i = 0; i < 3; ++ i)
|
||
|
{
|
||
|
pp[i] = data.vertex.xyz - patch[i].normal * (dot(data.vertex.xyz, patch[i].normal) - dot(patch[i].vertex.xyz, patch[i].normal));
|
||
|
}
|
||
|
data.vertex.xyz = _TessellationPhongStrength * (pp[0] * barycentricCoordinates.x + pp[1] * barycentricCoordinates.y + pp[2] * barycentricCoordinates.z) + (1.0f - _TessellationPhongStrength) * data.vertex.xyz;
|
||
|
MY_DOMAIN_PROGRAM_INTERPOLATE(normal)
|
||
|
data.vertex.xyz += data.normal.xyz * _TessellationExtrusionAmount;
|
||
|
MY_DOMAIN_PROGRAM_INTERPOLATE(tangent)
|
||
|
MY_DOMAIN_PROGRAM_INTERPOLATE(color)
|
||
|
MY_DOMAIN_PROGRAM_INTERPOLATE(uv0)
|
||
|
MY_DOMAIN_PROGRAM_INTERPOLATE(uv1)
|
||
|
MY_DOMAIN_PROGRAM_INTERPOLATE(uv2)
|
||
|
MY_DOMAIN_PROGRAM_INTERPOLATE(uv3)
|
||
|
|
||
|
return vert(data);
|
||
|
}
|
||
|
|
||
|
#endif
|