summaryrefslogtreecommitdiff
path: root/VRCSDK3AvatarsLegacy/Assets/Avatars/Auri/materials/OptimizedShaders/body/Includes/CGI_PoiTessellation.cginc
blob: 4912473de5e76dabff208185585b1d194c0211a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#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