res-avatar-unity/Assets/_PoiyomiShaders/Shaders/7.3/Includes/CGI_PoiTessellation.cginc

117 lines
3.9 KiB
HLSL
Raw Normal View History

2023-07-16 02:51:23 +00:00
#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