72 lines
2.1 KiB
Plaintext
72 lines
2.1 KiB
Plaintext
#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);
|
|
}
|
|
}
|