View difference between Paste ID: GqdnhKKC and TrV4fLK6
SHOW: | | - or go back to the newest paste.
1
#if defined(SHADER_API_D3D11) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE) || defined(SHADER_API_VULKAN) || defined(SHADER_API_METAL) || defined(SHADER_API_PSSL)
2
#define UNITY_CAN_COMPILE_TESSELLATION 1
3
#   define UNITY_domain                 domain
4
#   define UNITY_partitioning           partitioning
5
#   define UNITY_outputtopology         outputtopology
6
#   define UNITY_patchconstantfunc      patchconstantfunc
7
#   define UNITY_outputcontrolpoints    outputcontrolpoints
8
#endif
9
10
11
12
// The structure definition defines which variables it contains.
13
// This example uses the Attributes structure as an input structure in
14
// the vertex shader.
15
16
// vertex to fragment struct
17
struct Varyings
18
{
19
	float4 color : COLOR;
20
	float3 normal : NORMAL;
21
	float4 vertex : SV_POSITION;
22
	float2 uv : TEXCOORD0;
23
	float4 noise : TEXCOORD1;
24
};
25
26
27
// tessellation data
28
struct TessellationFactors
29
{
30
	float edge[3] : SV_TessFactor;
31
	float inside : SV_InsideTessFactor;
32
};
33
34
// Extra vertex struct
35
struct ControlPoint
36
{
37
	float4 vertex : INTERNALTESSPOS;
38
	float2 uv : TEXCOORD0;
39
	float4 color : COLOR;
40
	float3 normal : NORMAL;
41
};
42
43
// the original vertex struct
44
struct Attributes
45
{
46
	float4 vertex : POSITION;
47
	float3 normal : NORMAL;
48
	float2 uv : TEXCOORD0;
49
	float4 color : COLOR;
50
51
};
52
53
// tessellation variables, add these to your shader properties
54
float _Tess;
55
float _MaxTessDistance;
56
57
// info so the GPU knows what to do (triangles) and how to set it up , clockwise, fractional division
58
// hull takes the original vertices and outputs more
59
[UNITY_domain("tri")]
60
[UNITY_outputcontrolpoints(3)]
61
[UNITY_outputtopology("triangle_cw")]
62
[UNITY_partitioning("fractional_odd")]
63
//[UNITY_partitioning("fractional_even")]
64
//[UNITY_partitioning("pow2")]
65
//[UNITY_partitioning("integer")]
66
[UNITY_patchconstantfunc("patchConstantFunction")]
67
ControlPoint hull(InputPatch<ControlPoint, 3> patch, uint id : SV_OutputControlPointID)
68
{
69
	return patch[id];
70
}
71
72
TessellationFactors UnityCalcTriEdgeTessFactors (float3 triVertexFactors)
73
{
74
    TessellationFactors tess;
75
    tess.edge[0] = 0.5 * (triVertexFactors.y + triVertexFactors.z);
76
    tess.edge[1] = 0.5 * (triVertexFactors.x + triVertexFactors.z);
77
    tess.edge[2] = 0.5 * (triVertexFactors.x + triVertexFactors.y);
78
    tess.inside = (triVertexFactors.x + triVertexFactors.y + triVertexFactors.z) / 3.0f;
79
    return tess;
80
}
81
82
// fade tessellation at a distance
83
float CalcDistanceTessFactor(float4 vertex, float minDist, float maxDist, float tess)
84
{
85
				float3 worldPosition = mul(unity_ObjectToWorld, vertex).xyz;
86
				float dist = distance(worldPosition, _WorldSpaceCameraPos);
87
				float f = clamp(1.0 - (dist - minDist) / (maxDist - minDist), 0.01, 1.0);
88
89
				return f * tess;
90
}
91
92
TessellationFactors DistanceBasedTess(float4 v0, float4 v1, float4 v2, float minDist, float maxDist, float tess)
93
{
94
				float3 f;
95
				f.x = CalcDistanceTessFactor(v0, minDist, maxDist, tess);
96
				f.y = CalcDistanceTessFactor(v1, minDist, maxDist, tess);
97
				f.z = CalcDistanceTessFactor(v2, minDist, maxDist, tess);
98
99
				return UnityCalcTriEdgeTessFactors(f);
100
}
101
102
103
104
float UnityCalcEdgeTessFactor (float3 wpos0, float3 wpos1, float edgeLen)
105
{
106
    // distance to edge center
107
    float dist = distance (0.5 * (wpos0+wpos1), _WorldSpaceCameraPos);
108
    // length of the edge
109
    float len = distance(wpos0, wpos1);
110
    // edgeLen is approximate desired size in pixels
111
    float f = max(len * _ScreenParams.y / (edgeLen * dist), 1.0);
112
    return f;
113
}
114
115
116
float UnityDistanceFromPlane (float3 pos, float4 plane)
117
{
118
    float d = dot (float4(pos,1.0f), plane);
119
    return d;
120
}
121
122
123
// Returns true if triangle with given 3 world positions is outside of camera's view frustum.
124
// cullEps is distance outside of frustum that is still considered to be inside (i.e. max displacement)
125
bool UnityWorldViewFrustumCull (float3 wpos0, float3 wpos1, float3 wpos2, float cullEps)
126
{
127
    float4 planeTest;
128
129
    // left
130
    planeTest.x = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f ) +
131
                  (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f ) +
132
                  (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f );
133
    // right
134
    planeTest.y = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f ) +
135
                  (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f ) +
136
                  (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f );
137
    // top
138
    planeTest.z = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f ) +
139
                  (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f ) +
140
                  (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f );
141
    // bottom
142
    planeTest.w = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f ) +
143
                  (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f ) +
144
                  (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f );
145
146
    // has to pass all 4 plane tests to be visible
147
    return !all (planeTest);
148
}
149
150
151
// Desired edge length based tessellation:
152
// Approximate resulting edge length in pixels is "edgeLength".
153
// Does not take viewing FOV into account, just flat out divides factor by distance.
154
TessellationFactors UnityEdgeLengthBasedTess (float4 v0, float4 v1, float4 v2, float edgeLength)
155
{
156
    float3 pos0 = mul(unity_ObjectToWorld,v0).xyz;
157
    float3 pos1 = mul(unity_ObjectToWorld,v1).xyz;
158
    float3 pos2 = mul(unity_ObjectToWorld,v2).xyz;
159
    TessellationFactors tess;
160
    tess.edge[0] = UnityCalcEdgeTessFactor (pos1, pos2, edgeLength);
161
    tess.edge[1] = UnityCalcEdgeTessFactor (pos2, pos0, edgeLength);
162
    tess.edge[2] = UnityCalcEdgeTessFactor (pos0, pos1, edgeLength);
163
    tess.inside = (tess.edge[0] + tess.edge[1] + tess.edge[2]) / 3.0f;
164
    return tess;
165
}
166
167
168
// Same as UnityEdgeLengthBasedTess, but also does patch frustum culling:
169
// patches outside of camera's view are culled before GPU tessellation. Saves some wasted work.
170
TessellationFactors UnityEdgeLengthBasedTessCull (float4 v0, float4 v1, float4 v2, float edgeLength, float maxDisplacement)
171
{
172
    float3 pos0 = mul(unity_ObjectToWorld,v0).xyz;
173
    float3 pos1 = mul(unity_ObjectToWorld,v1).xyz;
174
    float3 pos2 = mul(unity_ObjectToWorld,v2).xyz;
175
    TessellationFactors tess;
176
177
    if (UnityWorldViewFrustumCull(pos0, pos1, pos2, maxDisplacement))
178
    {
179
        tess.edge[0] = 0.0f;
180
		tess.edge[1] = 0.0f;
181
		tess.edge[2] = 0.0f;
182
		tess.inside = 0.0f;
183
    }
184
    else
185
    {
186
        tess.edge[0] = UnityCalcEdgeTessFactor (pos1, pos2, edgeLength);
187
        tess.edge[1] = UnityCalcEdgeTessFactor (pos2, pos0, edgeLength);
188
        tess.edge[2] = UnityCalcEdgeTessFactor (pos0, pos1, edgeLength);
189
        tess.inside = (tess.edge[0] + tess.edge[1] + tess.edge[2]) / 3.0f;
190
    }
191
    return tess;
192
}
193
194
TessellationFactors patchConstantFunction(InputPatch<ControlPoint, 3> patch)
195
{
196
    float minDist = 2.0;
197
    float maxDist = _MaxTessDistance + minDist;
198
    TessellationFactors f;
199
200
    // distance based tesselation
201
    return DistanceBasedTess(patch[0].vertex, patch[1].vertex, patch[2].vertex, minDist, maxDist, _Tess);
202
    
203
    // continious tesselation based on _Tess being the edge length
204
   // return UnityEdgeLengthBasedTess(patch[0].vertex, patch[1].vertex, patch[2].vertex, _Tess);
205
    // continious tesselation based on _Tess being the edge length, with camrea culling
206
   // return UnityEdgeLengthBasedTessCull(patch[0].vertex, patch[1].vertex, patch[2].vertex, _Tess, _MaxTessDistance);
207
   
208
}
209
210
#define Interpolate(fieldName) v.fieldName = \
211
				patch[0].fieldName * barycentricCoordinates.x + \
212
				patch[1].fieldName * barycentricCoordinates.y + \
213
				patch[2].fieldName * barycentricCoordinates.z;
214
215
216
217
// second vertex, copy to shader
218
//Varyings vert(Attributes input)
219
//{
220
//	Varyings output;
221
//	// put your vertex manipulation here , ie: input.vertex.xyz += distortiontexture
222
//	output.vertex = TransformObjectToHClip(input.vertex.xyz);
223
//	output.color = input.color;
224
//	output.normal = input.normal;
225
//	output.uv = input.uv;
226
//	return output;
227
//}
228
229
230
231
// domain, copy to shader
232
//[UNITY_domain("tri")]
233
//Varyings domain(TessellationFactors factors, OutputPatch<ControlPoint, 3> patch, float3 barycentricCoordinates : SV_DomainLocation)
234
//{
235
//	Attributes v;
236
//
237
//
238
//	Interpolate(vertex)
239
//		Interpolate(uv)
240
//		Interpolate(color)
241
//		Interpolate(normal)
242
//
243
//		return vert(v);
244
//}
245