// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkCellGridShaderTessellationControl.h" const char *vtkCellGridShaderTessellationControl = "//VTK::System::Dec\n" "// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n" "// SPDX-License-Identifier: BSD-3-Clause\n" "\n" "//VTK::Camera::Dec\n" "\n" "layout(vertices = {PatchSize}) out;\n" "\n" "flat in int cellIdVSOutput[];\n" "flat in int sideIdVSOutput[];\n" "flat in int instanceIdVSOutput[];\n" "smooth in vec3 pcoordVSOutput[];\n" "\n" "patch out int cellIdTCSOutput;\n" "patch out int sideIdTCSOutput;\n" "patch out int instanceIdTCSOutput;\n" "out vec3 pcoordTCSOutput[];\n" "\n" "uniform ivec2 tessellation_levels_range;\n" "uniform float max_distance;\n" "\n" "#if {PatchSize} == 2\n" "void prepareTessellationLevels()\n" "{{\n" " // ----------------------------------------------------------------------\n" " int min_tl = tessellation_levels_range[0];\n" " int max_tl = tessellation_levels_range[1];\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 1: transform each vertex into eye space\n" " vec4 eyeSpacePos0 = MCVCMatrix * gl_in[0].gl_Position;\n" " vec4 eyeSpacePos1 = MCVCMatrix * gl_in[1].gl_Position;\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 2: \"distance\" from camera scaled between 0 and 1\n" " float distance0 = clamp((abs(eyeSpacePos0.z)) / (max_distance), 0.0f, 1.0f);\n" " float distance1 = clamp((abs(eyeSpacePos1.z)) / (max_distance), 0.0f, 1.0f);\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 3: interpolate edge tessellation level based on closer vertex\n" " float tessLevel0 = mix(max_tl, min_tl, min(distance1, distance0));\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 4: set the corresponding outer edge tessellation levels\n" " gl_TessLevelOuter[0] = 1;\n" " gl_TessLevelOuter[1] = tessLevel0;\n" "}}\n" "#elif {PatchSize} == 3\n" "void prepareTessellationLevels()\n" "{{\n" " // ----------------------------------------------------------------------\n" " int min_tl = tessellation_levels_range[0];\n" " int max_tl = tessellation_levels_range[1];\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 1: transform each vertex into eye space\n" " vec4 eyeSpacePos00 = MCVCMatrix * gl_in[0].gl_Position;\n" " vec4 eyeSpacePos01 = MCVCMatrix * gl_in[1].gl_Position;\n" " vec4 eyeSpacePos11 = MCVCMatrix * gl_in[2].gl_Position;\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 2: \"distance\" from camera scaled between 0 and 1\n" " float distance00 = clamp((abs(eyeSpacePos00.z)) / (max_distance), 0.0f, 1.0f);\n" " float distance01 = clamp((abs(eyeSpacePos01.z)) / (max_distance), 0.0f, 1.0f);\n" " float distance11 = clamp((abs(eyeSpacePos11.z)) / (max_distance), 0.0f, 1.0f);\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 3: interpolate edge tessellation level based on closer vertex\n" " float tessLevel0 = mix(max_tl, min_tl, min(distance11, distance00));\n" " float tessLevel1 = mix(max_tl, min_tl, min(distance00, distance01));\n" " float tessLevel2 = mix(max_tl, min_tl, min(distance01, distance11));\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 4: set the corresponding outer edge tessellation levels\n" " gl_TessLevelOuter[0] = tessLevel0;\n" " gl_TessLevelOuter[1] = tessLevel1;\n" " gl_TessLevelOuter[2] = tessLevel2;\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 5: set the inner tessellation levels to the max of the three edges\n" " gl_TessLevelInner[0] = max(tessLevel0, max(tessLevel1, tessLevel2));\n" "}}\n" "#elif {PatchSize} == 4\n" "void prepareTessellationLevels()\n" "{{\n" " // ----------------------------------------------------------------------\n" " int min_tl = tessellation_levels_range[0];\n" " int max_tl = tessellation_levels_range[1];\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 1: transform each vertex into eye space\n" " vec4 eyeSpacePos00 = MCVCMatrix * gl_in[0].gl_Position;\n" " vec4 eyeSpacePos01 = MCVCMatrix * gl_in[1].gl_Position;\n" " vec4 eyeSpacePos10 = MCVCMatrix * gl_in[2].gl_Position;\n" " vec4 eyeSpacePos11 = MCVCMatrix * gl_in[3].gl_Position;\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 2: \"distance\" from camera scaled between 0 and 1\n" " float distance00 = clamp((abs(eyeSpacePos00.z)) / (max_distance), 0.0f, 1.0f);\n" " float distance01 = clamp((abs(eyeSpacePos01.z)) / (max_distance), 0.0f, 1.0f);\n" " float distance10 = clamp((abs(eyeSpacePos10.z)) / (max_distance), 0.0f, 1.0f);\n" " float distance11 = clamp((abs(eyeSpacePos11.z)) / (max_distance), 0.0f, 1.0f);\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 3: interpolate edge tessellation level based on closer vertex\n" " float tessLevel0 = mix(max_tl, min_tl, min(distance10, distance00));\n" " float tessLevel1 = mix(max_tl, min_tl, min(distance00, distance01));\n" " float tessLevel2 = mix(max_tl, min_tl, min(distance01, distance11));\n" " float tessLevel3 = mix(max_tl, min_tl, min(distance11, distance10));\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 4: set the corresponding outer edge tessellation levels\n" " gl_TessLevelOuter[0] = tessLevel0;\n" " gl_TessLevelOuter[1] = tessLevel1;\n" " gl_TessLevelOuter[2] = tessLevel2;\n" " gl_TessLevelOuter[3] = tessLevel3;\n" "\n" " // ----------------------------------------------------------------------\n" " // Step 5: set the inner tessellation levels to the max of the two parallel edges\n" " gl_TessLevelInner[0] = max(tessLevel1, tessLevel3);\n" " gl_TessLevelInner[1] = max(tessLevel0, tessLevel2);\n" "}}\n" "#endif\n" "\n" "void main()\n" "{{\n" " if (gl_InvocationID == 0)\n" " {{\n" " prepareTessellationLevels();\n" "\n" " // It's okay to copy only the first value, because all patch vertices come from the same cell/side\n" " cellIdTCSOutput = cellIdVSOutput[0];\n" " sideIdTCSOutput = sideIdVSOutput[0];\n" " }}\n" "\n" " instanceIdTCSOutput = instanceIdVSOutput[gl_InvocationID];\n" " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" " pcoordTCSOutput[gl_InvocationID] = pcoordVSOutput[gl_InvocationID];\n" "}}\n" "";