// tessellation control shader #version 450 core // specify number of control points per patch output // this value controls the size of the input and output arrays layout (vertices=4) out; layout(binding = 0) uniform uniform_per_frame { mat4 view; mat4 proj; vec3 viewer_pos; uint light_count; } ubo_per_frame; layout (location=0) in VS_OUT { vec2 vsUV; vec4 vsWorldPos; vec3 vsNormal; vec3 vsBiTangent; vec3 vsTangent; mat3 vsTBN; flat uint vsChunkID; flat uint vsMaterialID; }tc_in[]; layout (location=0) out TC_OUT { vec2 vsUV; vec4 vsWorldPos; vec3 vsNormal; vec3 vsBiTangent; vec3 vsTangent; mat3 vsTBN; flat uint vsChunkID; flat uint vsMaterialID; }tc_out[]; float inv_lerp (float a, float b, float t) { return (t - a) / (b - a); } void main() { // ---------------------------------------------------------------------- // pass attributes through gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; tc_out[gl_InvocationID].vsUV = tc_in[gl_InvocationID].vsUV; tc_out[gl_InvocationID].vsWorldPos = tc_in[gl_InvocationID].vsWorldPos; tc_out[gl_InvocationID].vsNormal = tc_in[gl_InvocationID].vsNormal; tc_out[gl_InvocationID].vsBiTangent = tc_in[gl_InvocationID].vsBiTangent; tc_out[gl_InvocationID].vsTangent = tc_in[gl_InvocationID].vsTangent; tc_out[gl_InvocationID].vsTBN = tc_in[gl_InvocationID].vsTBN; tc_out[gl_InvocationID].vsChunkID = tc_in[gl_InvocationID].vsChunkID; tc_out[gl_InvocationID].vsMaterialID = tc_in[gl_InvocationID].vsMaterialID; vec3 centre = (gl_in[0].gl_Position.xyz + gl_in[1].gl_Position.xyz + gl_in[2].gl_Position.xyz + gl_in[3].gl_Position.xyz) / 4.0; float patch_width = abs(length(gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz)); float player_dist = abs(length(centre - ubo_per_frame.viewer_pos)) * 0.1; float tess_factor = 1.0 - inv_lerp(0, patch_width, player_dist); tess_factor = max(0.5, tess_factor); // ---------------------------------------------------------------------- // invocation zero controls tessellation levels for the entire patch if (gl_InvocationID == 0) { float edgedivs = 32.0; float innerdivs = tess_factor * 64.0; gl_TessLevelOuter[0] = edgedivs; gl_TessLevelOuter[1] = edgedivs; gl_TessLevelOuter[2] = edgedivs; gl_TessLevelOuter[3] = edgedivs; gl_TessLevelInner[0] = innerdivs; gl_TessLevelInner[1] = innerdivs; } }