From 9174f1ec0b0055b02e73eeea64634a9025d0ab0c Mon Sep 17 00:00:00 2001 From: Modin Modin Date: Mon, 6 Apr 2026 19:22:35 -0400 Subject: [PATCH] Sample 3 --- strand.comp | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 strand.comp diff --git a/strand.comp b/strand.comp new file mode 100644 index 0000000..310da9b --- /dev/null +++ b/strand.comp @@ -0,0 +1,71 @@ +#version 460 +#extension GL_EXT_debug_printf : enable +#extension GL_EXT_shader_atomic_float : enable + +layout(local_size_x = 64) in; + +struct CurveHeader { + uint poolOffset; + uint pointCount; + uint maxPoints; + uint _padding; + vec4 color; +}; + +struct PointData { + vec4 pos; // xyz = worldPos, w = radius +}; + +layout(std430, binding = 0) readonly buffer HeaderBuffer { CurveHeader headers[]; }; +layout(std430, binding = 1) readonly buffer PointPool { PointData pool[]; }; +layout(std430, binding = 2) writeonly buffer RenderBuffer { vec4 smoothPoints[]; }; +layout(r32f, binding = 3) uniform image3D shadowVolume; + +layout(push_constant) uniform Push { + mat4 viewProj; + vec3 gridOrigin; + float gridCellSize; + float gridExtent; + uint frameCount; + float _pad[2]; +} pc; + +shared vec4 s_Points[100]; +shared CurveHeader s_Header; + +void main() { + uint strandIdx = gl_WorkGroupID.x; + uint segmentIdx = gl_LocalInvocationID.x; // 0 to 63 + + if (segmentIdx == 0) s_Header = headers[strandIdx]; + barrier(); + + if (s_Header.pointCount == 0) return; + + for (uint i = segmentIdx; i < 100; i += 64) { + if (i < s_Header.pointCount) { + s_Points[i] = pool[s_Header.poolOffset + i].pos; + } + } + barrier(); + + float t_global = float(segmentIdx) / 63.0; + float segProgress = t_global * float(s_Header.pointCount - 1); + int i = int(floor(segProgress)); + float t_local = fract(segProgress); + + // Fetch from shared memory + vec3 p0 = s_Points[max(i - 1, 0)].xyz; + vec3 p1 = s_Points[i].xyz; + vec3 p2 = s_Points[min(i + 1, int(s_Header.pointCount - 1))].xyz; + vec3 p3 = s_Points[min(i + 2, int(s_Header.pointCount - 1))].xyz; + + vec3 finalPos = catmullRom(p0, p1, p2, p3, t_local); + float radius = mix(s_Points[i].w, s_Points[min(i + 1, int(s_Header.pointCount - 1))].w, t_local); + uint outIdx = (strandIdx * 64) + segmentIdx; + smoothPoints[outIdx] = vec4(finalPos, radius); + ivec3 voxel = ivec3(((finalPos - pc.gridOrigin) / pc.gridExtent)*pc.gridSize); + if (all(greaterThanEqual(voxel, ivec3(0))) && all(lessThan(voxel, ivec3(pc.gridSize)))) { + imageAtomicAdd(shadowVolume, voxel, 0.01); + } +}