summaryrefslogtreecommitdiff
path: root/VRCSDK3Avatars/Assets/Resources/RalivDynamicPenetrationSystem/Plugins/Xiexes-Unity-Shaders-development/Main/CGIncludes/XSGeom.cginc
blob: f1077558ff7666e2a6992316911cfd781e4c007b (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
#if defined(Geometry)
    #define TRANSFER_SHADOW_CASTER_NOPOS_GEOMETRY(o, opos, vertexPosition, vertexNormal) \
        opos = UnityClipSpaceShadowCasterPos(vertexPosition, vertexNormal); \
        opos = UnityApplyLinearShadowBias(opos);

    [maxvertexcount(6)]
    void geom(triangle v2g IN[3], inout TriangleStream<g2f> tristream)
    {
        g2f o = (g2f)0;

        //Main Mesh loop
        for (int i = 0; i < 3; i++)
        {
            o.pos = UnityObjectToClipPos(IN[i].vertex);
            o.worldPos = IN[i].worldPos;
            o.ntb[0] = IN[i].ntb[0];
            o.ntb[1] = IN[i].ntb[1];
            o.ntb[2] = IN[i].ntb[2];
            o.uv = IN[i].uv;
            o.uv1 = IN[i].uv1;
            o.color = float4(IN[i].color.rgb,0); // store if outline in alpha channel of vertex colors | 0 = not an outline
            o.screenPos = ComputeScreenPos(o.pos);
            o.objPos = normalize(IN[i].vertex);

            #if !defined(UNITY_PASS_SHADOWCASTER)
                UNITY_TRANSFER_SHADOW(o, o.uv);
                UNITY_TRANSFER_FOG(o, o.pos);
            #else
                TRANSFER_SHADOW_CASTER_NOPOS_GEOMETRY(o, o.pos, IN[i].vertex, IN[i].ntb[0]);
            #endif
            tristream.Append(o);
        }
        tristream.RestartStrip();

        //Outlines loop
        for (int i = 2; i >= 0; i--)
        {
            float4 worldPos = (mul(unity_ObjectToWorld, IN[i].vertex));
            half outlineWidthMask = tex2Dlod(_OutlineMask, float4(IN[i].uv, 0, 0));
            float3 outlineWidth = outlineWidthMask * _OutlineWidth * .01;
            outlineWidth *= min(distance(worldPos, _WorldSpaceCameraPos) * 3, 1);

            float3 vc = IN[i].color.rgb;
            if(_OutlineNormalMode == 2)
            {
                float2 xy = IN[i].uv1;
                if(_OutlineUVSelect == 1)
                    xy = IN[i].uv2;

                float reconstructedZ = sqrt(1-saturate(dot(xy, xy)));
                vc = normalize(float3(xy, reconstructedZ));
            }
            vc = vc * 2 - 1;
            float3 t = mul(unity_WorldToObject, IN[i].ntb[1]);
            float3 b = mul(unity_WorldToObject, IN[i].ntb[2]);
            float3 n = mul(unity_WorldToObject, IN[i].ntb[0]);
            half3 tspace0 = half3(t.x, b.x, n.x);
            half3 tspace1 = half3(t.y, b.y, n.y);
            half3 tspace2 = half3(t.z, b.z, n.z);

            half3 calcedNormal;
            calcedNormal.x = dot(tspace0, vc);
            calcedNormal.y = dot(tspace1, vc);
            calcedNormal.z = dot(tspace2, vc);

            half3 normalDir = normalize(lerp(IN[i].normal, calcedNormal, saturate(_OutlineNormalMode)));
            float4 outlinePos = float4(IN[i].vertex + normalDir * outlineWidth, 1);

            if(outlineWidthMask == 0)
                return;

            o.pos = UnityObjectToClipPos(outlinePos);
            o.worldPos = worldPos;
            o.ntb[0] = IN[i].ntb[0];
            o.ntb[1] = IN[i].ntb[1];
            o.ntb[2] = IN[i].ntb[2];
            o.uv = IN[i].uv;
            o.uv1 = IN[i].uv1;
            o.color = float4(IN[i].color.rgb, 1); // store if outline in alpha channel of vertex colors | 1 = is an outline
            o.screenPos = ComputeScreenPos(o.pos);
            o.objPos = normalize(outlinePos);

            #if !defined(UNITY_PASS_SHADOWCASTER)
                UNITY_TRANSFER_SHADOW(o, o.uv);
                UNITY_TRANSFER_FOG(o, o.pos);
            #else
                TRANSFER_SHADOW_CASTER_NOPOS_GEOMETRY(o, o.pos, outlinePos, IN[i].ntb[0]);
            #endif
            tristream.Append(o);
        }
        tristream.RestartStrip();


    }
#endif