From b3f0df24c98dc6a7a341271dd85451345f2be1a7 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 31 Jan 2026 01:49:07 +0000 Subject: Initial commit using tesselation shader to create curves Disables glslangValidator because of file extension mess up. --- gfx/gl/sceneShader.cpp | 4 +++- gfx/gl/shaders/networkCurve.gs | 45 ++++++----------------------------------- gfx/gl/shaders/networkCurve.tcs | 43 +++++++++++++++++++++++++++++++++++++++ gfx/gl/shaders/networkCurve.tes | 30 +++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 40 deletions(-) create mode 100644 gfx/gl/shaders/networkCurve.tcs create mode 100644 gfx/gl/shaders/networkCurve.tes (limited to 'gfx/gl') diff --git a/gfx/gl/sceneShader.cpp b/gfx/gl/sceneShader.cpp index 4b82ae4..ec54fd1 100644 --- a/gfx/gl/sceneShader.cpp +++ b/gfx/gl/sceneShader.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include @@ -38,7 +40,7 @@ SceneShader::SceneShader() : spotLightInst {spotLight_vs, spotLight_gs, spotLight_fs}, pointLightInst {pointLight_vs, pointLight_gs, pointLight_fs}, landmass {landmass_vs, landmass_fs}, networkStraight {networkStraight_vs, networkStraight_gs, network_fs}, - networkCurve {networkCurve_vs, networkCurve_gs, network_fs} + networkCurve {networkCurve_vs, networkCurve_tcs, networkCurve_tes, networkCurve_gs, network_fs} { } diff --git a/gfx/gl/shaders/networkCurve.gs b/gfx/gl/shaders/networkCurve.gs index 15a6ec9..1002fd4 100644 --- a/gfx/gl/shaders/networkCurve.gs +++ b/gfx/gl/shaders/networkCurve.gs @@ -1,48 +1,15 @@ #version 460 core -flat in ivec3 apos[]; -flat in ivec3 bpos[]; -flat in ivec3 cpos[]; -flat in float reps[]; -flat in float aangle[]; -flat in float bangle[]; -flat in float radius[]; - -layout(points) in; -layout(triangle_strip, max_vertices = GL_MAX_GEOMETRY_OUTPUT_VERTICES) out; - -const mat2 rot = mat2(1); +flat in ivec3 pos[]; +flat in mat2 rot[]; +flat in float tpos[]; +layout(lines) in; +layout(triangle_strip, max_vertices = 10) out; include(`networkCommon.glsl') -mat2 -getRot(float angle) -{ - return mat2(cos(angle), sin(angle), -sin(angle), cos(angle)); -} - void main() { - float segs = clamp(round(reps[0] * radius[0] / 1000), 4, - min(floor(uint(GL_MAX_GEOMETRY_OUTPUT_VERTICES) / (profileLength * 2u)), - floor(uint(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS) / 5u))); - vec3 arcstep = vec3((bangle[0] - aangle[0]), // angle - reps[0], // texture - (bpos[0].z - apos[0].z)) // height - / segs; - - ivec3 prevPos = apos[0]; - mat2 prevRot = getRot(aangle[0]); - float prevTex = 0; - for (vec3 arc = arcstep; arc.y < reps[0] - 0.01; arc += arcstep) { - mat2 rot = getRot(arc.x + aangle[0]); - ivec3 pos = cpos[0] + ivec3(rot * vec2(radius[0], 0), arc.z); - float tex = arc.y; - doSeg(segDist(prevPos, pos), pos, prevPos, tex, prevTex, rot, prevRot); - prevPos = pos; - prevRot = rot; - prevTex = tex; - } - doSeg(segDist(prevPos, bpos[0]), bpos[0], prevPos, reps[0], prevTex, getRot(bangle[0]), prevRot); + doSeg(segDist(pos[0], pos[1]), pos[0], pos[1], tpos[0], tpos[1], rot[0], rot[1]); } diff --git a/gfx/gl/shaders/networkCurve.tcs b/gfx/gl/shaders/networkCurve.tcs new file mode 100644 index 0000000..4221e64 --- /dev/null +++ b/gfx/gl/shaders/networkCurve.tcs @@ -0,0 +1,43 @@ +#version 460 core + +layout(vertices = 1) out; +flat in ivec3 apos[]; +flat in ivec3 bpos[]; +flat in ivec3 cpos[]; +flat in float reps[]; +flat in float aangle[]; +flat in float bangle[]; +flat in float radius[]; + +flat out ivec3 c_apos[]; +flat out ivec3 c_bpos[]; +flat out ivec3 c_cpos[]; +flat out float c_reps[]; +flat out float c_aangle[]; +flat out float c_bangle[]; +flat out float c_radius[]; + +int +min2pow(float target) +{ + int x = 1; + while (x < target) { + x <<= 1; + } + return x; +} + +void +main() +{ + c_apos[gl_InvocationID] = apos[gl_InvocationID]; + c_bpos[gl_InvocationID] = bpos[gl_InvocationID]; + c_cpos[gl_InvocationID] = cpos[gl_InvocationID]; + c_reps[gl_InvocationID] = reps[gl_InvocationID]; + c_aangle[gl_InvocationID] = aangle[gl_InvocationID]; + c_bangle[gl_InvocationID] = bangle[gl_InvocationID]; + c_radius[gl_InvocationID] = radius[gl_InvocationID]; + + gl_TessLevelOuter[0] = 1; + gl_TessLevelOuter[1] = min2pow(reps[gl_InvocationID]); +} diff --git a/gfx/gl/shaders/networkCurve.tes b/gfx/gl/shaders/networkCurve.tes new file mode 100644 index 0000000..a02503c --- /dev/null +++ b/gfx/gl/shaders/networkCurve.tes @@ -0,0 +1,30 @@ +#version 460 core +layout(isolines, equal_spacing, cw) in; + +flat in ivec3 c_apos[]; +flat in ivec3 c_bpos[]; +flat in ivec3 c_cpos[]; +flat in float c_reps[]; +flat in float c_aangle[]; +flat in float c_bangle[]; +flat in float c_radius[]; + +flat out ivec3 pos; +flat out mat2 rot; +flat out float tpos; + +mat2 +getRot(float angle) +{ + return mat2(cos(angle), sin(angle), -sin(angle), cos(angle)); +} + +void +main() +{ + float angle = mix(c_bangle[0], c_aangle[0], gl_TessCoord.x); + int height = int(mix(c_bpos[0].z, c_apos[0].z, gl_TessCoord.x)) - c_cpos[0].z; + rot = getRot(angle); + tpos = c_reps[0] * gl_TessCoord.x; + pos = c_cpos[0] + ivec3(rot * vec2(c_radius[0], 0), height); +} -- cgit v1.2.3