1/* 2 This Source Code Form is subject to the terms of the Mozilla Public 3 License, v. 2.0. If a copy of the MPL was not distributed with this 4 file, You can obtain one at http://mozilla.org/MPL/2.0/. 5*/ 6 7#version 410 core 8 9layout(vertices = 9) out; 10 11uniform vec2 viewportSize; 12uniform float smoothness; 13 14in vec4 ctrl_position_obj[]; 15in vec3 ctrl_normal_obj[]; 16in vec3 ctrl_normal_view[]; 17 18out vec4 eval_position_obj[]; 19out vec3 eval_normal_obj[]; 20out vec3 eval_normal_view[]; 21out ScreenSpaceBlock { 22 flat vec3 heights_scr; 23 flat vec3 vertices_obj[3]; 24 flat vec3 normEdges_obj[3]; 25} eval_ss[]; 26 27bool isLinear(int i) { 28 vec4 p0 = eval_position_obj[3*i + 0]; 29 vec4 p1 = eval_position_obj[3*i + 1]; 30 vec4 p2 = eval_position_obj[3*i + 2]; 31 vec4 p3 = eval_position_obj[(3*i + 3)%9]; 32 33 vec4 p1off = p1 - (2*p0 + p3) / 3; 34 vec4 p2off = p2 - (p0 + 2*p3) / 3; 35 36 return dot(p1off, p1off) < 0.0001 37 && dot(p2off, p2off) < 0.0001; 38} 39 40float curviness(int i) { 41 vec4 p0 = eval_position_obj[3*i + 0]; 42 vec4 p1 = eval_position_obj[3*i + 1]; 43 vec4 p2 = eval_position_obj[3*i + 2]; 44 vec4 p3 = eval_position_obj[(3*i + 3)%9]; 45 46 vec4 p1off = p1 - (2*p0 + p3) / 3; 47 vec4 p2off = p2 - (p0 + 2*p3) / 3; 48 49 return max(length(p1off), length(p2off)) / distance(p0, p3); 50} 51 52void main(void) 53{ 54 gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; 55 eval_position_obj[gl_InvocationID] = ctrl_position_obj[gl_InvocationID]; 56 eval_normal_obj[gl_InvocationID] = ctrl_normal_obj[gl_InvocationID]; 57 eval_normal_view[gl_InvocationID] = ctrl_normal_view[gl_InvocationID]; 58 59 vec2 position_scr[3]; 60 for(int i=0; i<3; ++i) 61 { 62 position_scr[i] = (viewportSize * gl_in[i*3].gl_Position.xy) 63 / (2.0 * gl_in[i*3].gl_Position.z); 64 } 65 float area = abs(cross(vec3(position_scr[1] - position_scr[0], 0.0), 66 vec3(position_scr[2] - position_scr[0], 0.0)).z); 67 68 for(int i=0; i<3; ++i) 69 { 70 eval_ss[gl_InvocationID].heights_scr[i] 71 = area / length(position_scr[(i+2)%3] - position_scr[(i+1)%3]); 72 eval_ss[gl_InvocationID].vertices_obj[i] 73 = ctrl_position_obj[i*3].xyz; 74 eval_ss[gl_InvocationID].normEdges_obj[i] 75 = normalize(ctrl_position_obj[((i+2)%3)*3].xyz - ctrl_position_obj[((i+1)%3)*3].xyz); 76 } 77 78 bvec3 isEdgeLinear = bvec3(isLinear(0), isLinear(1), isLinear(2)); 79 gl_TessLevelOuter = float[4]( 80 isEdgeLinear[1]? 1: smoothness, 81 isEdgeLinear[2]? 1: smoothness, 82 isEdgeLinear[0]? 1: smoothness, 83 1); 84 gl_TessLevelInner = float[2](all(isEdgeLinear)? 1: smoothness, 1); 85 // Uncomment this for adaptive smoothing (using a very rough heristic). 86// gl_TessLevelOuter = float[4]( 87// max(curviness(1) * smoothness, 1), 88// max(curviness(2) * smoothness, 1), 89// max(curviness(0) * smoothness, 1), 90// 1); 91} 92