74 lines
1.7 KiB
WebGPU Shading Language
74 lines
1.7 KiB
WebGPU Shading Language
|
|
struct Point {
|
||
|
|
pos: vec3<f32>,
|
||
|
|
_pad: f32,
|
||
|
|
};
|
||
|
|
|
||
|
|
struct BillboardAxis {
|
||
|
|
vector : vec3<f32>,
|
||
|
|
_pad : f32,
|
||
|
|
};
|
||
|
|
|
||
|
|
struct VSOut {
|
||
|
|
@builtin(position) Position : vec4<f32>,
|
||
|
|
@location(0) uv : vec2<f32>,
|
||
|
|
@location(1) color : vec3<f32>,
|
||
|
|
};
|
||
|
|
|
||
|
|
@group(0) @binding(0) var<storage, read> positions: array<Point>;
|
||
|
|
|
||
|
|
@group(0) @binding(1) var<storage, read> sortedIndices: array<u32>; // New binding for sorted indices
|
||
|
|
|
||
|
|
@group(0) @binding(2) var<uniform> viewProjectionMatrix: mat4x4<f32>;
|
||
|
|
|
||
|
|
@group(0) @binding(3) var<uniform> cameraRight : BillboardAxis;
|
||
|
|
|
||
|
|
@group(0) @binding(4) var<uniform> cameraUp : BillboardAxis;
|
||
|
|
|
||
|
|
@vertex
|
||
|
|
fn vertexEntryPoint(
|
||
|
|
@builtin(vertex_index) vertexIndex: u32,
|
||
|
|
@builtin(instance_index) instanceIndex: u32,
|
||
|
|
@location(0) quadOffset: vec2<f32>
|
||
|
|
) -> VSOut {
|
||
|
|
|
||
|
|
var output: VSOut;
|
||
|
|
|
||
|
|
// Use the sorted index to get the actual particle index
|
||
|
|
let actualIndex = sortedIndices[instanceIndex];
|
||
|
|
|
||
|
|
let point = positions[actualIndex];
|
||
|
|
let center = point.pos;
|
||
|
|
let radius = 0.03;
|
||
|
|
|
||
|
|
let rightOffset = cameraRight.vector * quadOffset.x * radius;
|
||
|
|
let upOffset = cameraUp.vector * quadOffset.y * radius;
|
||
|
|
|
||
|
|
let worldPos = vec4<f32>(center + rightOffset + upOffset, 1.0);
|
||
|
|
|
||
|
|
output.Position = viewProjectionMatrix * worldPos;
|
||
|
|
output.uv = quadOffset;
|
||
|
|
output.color = (center + vec3<f32>(1.0, 1.0, 1.0)) * 0.5;
|
||
|
|
|
||
|
|
return output;
|
||
|
|
}
|
||
|
|
|
||
|
|
@fragment
|
||
|
|
fn fragmentEntryPoint(
|
||
|
|
@location(0) uv: vec2<f32>,
|
||
|
|
@location(1) color: vec3<f32>
|
||
|
|
) -> @location(0) vec4<f32> {
|
||
|
|
|
||
|
|
let dist = length(uv);
|
||
|
|
if (dist > 1.0) {
|
||
|
|
discard;
|
||
|
|
}
|
||
|
|
|
||
|
|
let z = sqrt(1.0 - dist * dist);
|
||
|
|
let normal = normalize(vec3<f32>(uv.x, uv.y, z));
|
||
|
|
let light = normalize(vec3<f32>(1.0, 1.0, 1.0));
|
||
|
|
|
||
|
|
let diffuse = max(dot(normal, light), 0.0);
|
||
|
|
|
||
|
|
return vec4<f32>(color * diffuse, 1.0);
|
||
|
|
}
|