1/**************************************************************************** 2** 3** Copyright (C) 2014 NVIDIA Corporation. 4** Copyright (C) 2019 The Qt Company Ltd. 5** Contact: https://www.qt.io/licensing/ 6** 7** This file is part of Qt 3D Studio. 8** 9** $QT_BEGIN_LICENSE:GPL$ 10** Commercial License Usage 11** Licensees holding valid commercial Qt licenses may use this file in 12** accordance with the commercial license agreement provided with the 13** Software or, alternatively, in accordance with the terms contained in 14** a written agreement between you and The Qt Company. For licensing terms 15** and conditions see https://www.qt.io/terms-conditions. For further 16** information use the contact form at https://www.qt.io/contact-us. 17** 18** GNU General Public License Usage 19** Alternatively, this file may be used under the terms of the GNU 20** General Public License version 3 or (at your option) any later version 21** approved by the KDE Free Qt Foundation. The licenses are as published by 22** the Free Software Foundation and appearing in the file LICENSE.GPL3 23** included in the packaging of this file. Please review the following 24** information to ensure the GNU General Public License requirements will 25** be met: https://www.gnu.org/licenses/gpl-3.0.html. 26** 27** $QT_END_LICENSE$ 28** 29****************************************************************************/ 30 31#ifndef TESSELLATION_PHONG_GLSLLIB 32#define TESSELLATION_PHONG_GLSLLIB 33 34struct PhongTessPatch 35{ 36 float projIJ; 37 float projJK; 38 float projIK; 39}; 40 41#if TESSELLATION_CONTROL_SHADER 42layout (vertices = 3) out; 43 44layout(location = 15) out PhongTessPatch tcTessPatch[]; 45 46// global setup in main 47vec3 ctWorldPos[3]; 48vec3 ctNorm[3]; 49 50uniform vec3 cameraPosition; 51uniform vec2 distanceRange; 52uniform float disableCulling; 53 54float isBackFace() 55{ 56 vec3 faceNormal = normalize( cross( ctWorldPos[2] - ctWorldPos[0], ctWorldPos[1] - ctWorldPos[0] ) ); 57 58 vec3 ncd = normalize( ctWorldPos[0] - cameraPosition ); 59 60 return sign( 0.2 + dot(faceNormal, ncd) ); // 0.2 is a conservative offset to account for curved surfaces 61} 62 63float adaptiveCameraFactor( in float minTess, in float maxTess ) 64{ 65 float distanceValue0 = distance( cameraPosition, ctWorldPos[0] ); 66 float distanceValue1 = distance( cameraPosition, ctWorldPos[1] ); 67 float distanceValue2 = distance( cameraPosition, ctWorldPos[2] ); 68 69 float range = distanceRange[1] - distanceRange[0]; 70 71 vec3 edgeDistance; 72 edgeDistance[0] = ((distanceValue1 + distanceValue2) / 2.0) / range; 73 edgeDistance[1] = ((distanceValue2 + distanceValue0) / 2.0) / range; 74 edgeDistance[2] = ((distanceValue0 + distanceValue1) / 2.0) / range; 75 76 edgeDistance = clamp( edgeDistance, vec3(0.0), vec3(1.0) ); 77 78 //float af = mix( minTess, maxTess, 1.0 - edgeDistance[gl_InvocationID] ); 79 float af = 1.0 - edgeDistance[gl_InvocationID]; 80 af = clamp( af*af*maxTess , minTess, maxTess ); 81 82 return af; 83} 84 85float adaptiveFeatureFactor( in float minTess, in float maxTess ) 86{ 87 vec3 adaptValue; 88 adaptValue[0] = clamp( dot(ctNorm[1], ctNorm[2]), -1.0, 1.0 ); 89 adaptValue[1] = clamp( dot(ctNorm[2], ctNorm[0]), -1.0, 1.0 ); 90 adaptValue[2] = clamp( dot(ctNorm[0], ctNorm[1]), -1.0, 1.0 ); 91 92 //float af = min( adaptValue[0], min(adaptValue[1], adaptValue[2]) ); 93 // map [-1, +1] range to [0, 1] range 94 float af = (adaptValue[gl_InvocationID] + 1.0) / 2.0; 95 96 af = mix( minTess, maxTess, 1.0 - af ); 97 98 return af; 99} 100 101float mapToTangentPlane(int i, vec3 q) 102{ 103 vec3 q_minus_p = q - gl_in[i].gl_Position.xyz; 104 return q[gl_InvocationID] - dot(q_minus_p, ctNorm[i]) * ctNorm[i][gl_InvocationID]; 105} 106 107void tessShader ( in float tessEdge, in float tessInner ) 108{ 109 // compute projections separate for each xyz component 110 tcTessPatch[gl_InvocationID].projIJ = mapToTangentPlane(0, gl_in[1].gl_Position.xyz) + mapToTangentPlane(1, gl_in[0].gl_Position.xyz); 111 tcTessPatch[gl_InvocationID].projJK = mapToTangentPlane(1, gl_in[2].gl_Position.xyz) + mapToTangentPlane(2, gl_in[1].gl_Position.xyz); 112 tcTessPatch[gl_InvocationID].projIK = mapToTangentPlane(2, gl_in[0].gl_Position.xyz) + mapToTangentPlane(0, gl_in[2].gl_Position.xyz); 113 114 // compute backface 115 float bf = isBackFace(); 116 bf = max(disableCulling, bf); 117 // adapative tessellation factor regarding features 118 float af = adaptiveFeatureFactor( tessInner, tessEdge ); 119 // adapative tessellation factor regarding camera 120 //float cf = adaptiveFeatureFactor( tessInner, tessEdge ); 121 122 // the camera tess factor is the limit 123 //af = min(af, cf); 124 125 // Calculate the tessellation levels 126 gl_TessLevelInner[0] = af * bf; 127 gl_TessLevelOuter[gl_InvocationID] = af * bf; 128} 129 130#endif 131 132#if TESSELLATION_EVALUATION_SHADER 133layout (triangles, equal_spacing, ccw) in; 134 135layout(location = 15) in PhongTessPatch tcTessPatch[]; 136 137uniform float phongBlend; 138 139vec4 tessShader ( ) 140{ 141 // pre compute square tesselation coord 142 vec3 tessSquared = gl_TessCoord * gl_TessCoord; 143 144 // barycentric linear position 145 vec3 linearPos = gl_TessCoord.x * gl_in[0].gl_Position.xyz 146 + gl_TessCoord.y * gl_in[1].gl_Position.xyz 147 + gl_TessCoord.z * gl_in[2].gl_Position.xyz; 148 149 // projective terms 150 vec3 projJI = vec3(tcTessPatch[0].projIJ, tcTessPatch[1].projIJ, tcTessPatch[2].projIJ); 151 vec3 projKJ = vec3(tcTessPatch[0].projJK, tcTessPatch[1].projJK, tcTessPatch[2].projJK); 152 vec3 projIK = vec3(tcTessPatch[0].projIK, tcTessPatch[1].projIK, tcTessPatch[2].projIK); 153 154 // phong interpolated position 155 vec3 phongPos = tessSquared.x * gl_in[0].gl_Position.xyz 156 + tessSquared.y * gl_in[1].gl_Position.xyz 157 + tessSquared.z * gl_in[2].gl_Position.xyz 158 + gl_TessCoord.x * gl_TessCoord.y * projJI 159 + gl_TessCoord.y * gl_TessCoord.z * projKJ 160 + gl_TessCoord.z * gl_TessCoord.x * projIK; 161 162 // final blend between linear and phong interpolation 163 vec3 finalPos = (1.0-phongBlend)*linearPos + phongBlend*phongPos; 164 165 return vec4( finalPos, 1.0 ); 166} 167#endif 168 169#endif 170 171