diff --git a/.vscode/settings.json b/.vscode/settings.json index 2f5095b..17a7722 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,7 +8,8 @@ ], "typescript.tsdk": "node_modules/typescript/lib", "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, - "svg.preview.background": "dark-transparent" + "svg.preview.background": "dark-transparent", + "rust-analyzer.linkedProjects": ["./rust/Cargo.toml"] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 95b4a42..45c78db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # @antv/g-device-api +## 1.6.6 + +### Patch Changes + +- 5cfa31c: Display more granular error message when compiling wgsl with naga. + ## 1.6.5 ### Patch Changes diff --git a/examples/demos/3d-atomic-rasterizer.ts b/examples/demos/3d-atomic-rasterizer.ts index 715eae0..a73ab04 100644 --- a/examples/demos/3d-atomic-rasterizer.ts +++ b/examples/demos/3d-atomic-rasterizer.ts @@ -82,66 +82,66 @@ struct Custom { struct Camera { - pos: float3, - cam: float3x3, - fov: float, - size: float2 + pos: vec3f, + cam: mat3x3, + fov: f32, + size: vec2f } var camera : Camera; - var state : uint4; + var state : vec4u; - fn pcg4d(a: uint4) -> uint4 + fn pcg4d(a: vec4u) -> vec4u { var v = a * 1664525u + 1013904223u; v.x += v.y*v.w; v.y += v.z*v.x; v.z += v.x*v.y; v.w += v.y*v.z; - v = v ^ ( v >> uint4(16u) ); + v = v ^ ( v >> vec4u(16u) ); v.x += v.y*v.w; v.y += v.z*v.x; v.z += v.x*v.y; v.w += v.y*v.z; return v; } - fn rand4() -> float4 + fn rand4() -> vec4f { state = pcg4d(state); - return float4(state)/float(0xffffffffu); + return vec4f(state)/f32(0xffffffffu); } - fn nrand4(sigma: float, mean: float4) -> float4 + fn nrand4(sigma: f32, mean: vec4f) -> vec4f { let Z = rand4(); return mean + sigma * sqrt(-2.0 * log(Z.xxyy)) * - float4(cos(TWO_PI * Z.z),sin(TWO_PI * Z.z),cos(TWO_PI * Z.w),sin(TWO_PI * Z.w)); + vec4f(cos(TWO_PI * Z.z),sin(TWO_PI * Z.z),cos(TWO_PI * Z.w),sin(TWO_PI * Z.w)); } - fn GetCameraMatrix(ang: float2) -> float3x3 + fn GetCameraMatrix(ang: vec2f) -> mat3x3 { - let x_dir = float3(cos(ang.x)*sin(ang.y), cos(ang.y), sin(ang.x)*sin(ang.y)); - let y_dir = normalize(cross(x_dir, float3(0.0,1.0,0.0))); + let x_dir = vec3f(cos(ang.x)*sin(ang.y), cos(ang.y), sin(ang.x)*sin(ang.y)); + let y_dir = normalize(cross(x_dir, vec3f(0.0,1.0,0.0))); let z_dir = normalize(cross(y_dir, x_dir)); - return float3x3(-x_dir, y_dir, z_dir); + return mat3x3(-x_dir, y_dir, z_dir); } - fn SetCamera(ang: float2, fov: float) + fn SetCamera(ang: vec2f, fov: f32) { camera.fov = fov; camera.cam = GetCameraMatrix(ang); - camera.pos = - (camera.cam*float3(3.0*custom.Radius+0.5,0.0,0.0)); - camera.size = float2(textureDimensions(screen)); + camera.pos = - (camera.cam*vec3f(3.0*custom.Radius+0.5,0.0,0.0)); + camera.size = vec2f(textureDimensions(screen)); } //project to clip space - fn Project(cam: Camera, p: float3) -> float3 + fn Project(cam: Camera, p: vec3f) -> vec3f { let td = distance(cam.pos, p); let dir = (p - cam.pos)/td; let screen = dir*cam.cam; - return float3(screen.yz*cam.size.y/(cam.fov*screen.x) + 0.5*cam.size,screen.x*td); + return vec3f(screen.yz*cam.size.y/(cam.fov*screen.x) + 0.5*cam.size,screen.x*td); } @compute @workgroup_size(16, 16) - fn Clear(@builtin(global_invocation_id) id: uint3) { - let screen_size = int2(textureDimensions(screen)); - let idx0 = int(id.x) + int(screen_size.x * int(id.y)); + fn Clear(@builtin(global_invocation_id) id: vec3u) { + let screen_size = vec2i(textureDimensions(screen)); + let idx0 = i32(id.x) + i32(screen_size.x * i32(id.y)); atomicStore(&atomic_storage[idx0*4+0], 0); atomicStore(&atomic_storage[idx0*4+1], 0); @@ -149,18 +149,18 @@ struct Custom { atomicStore(&atomic_storage[idx0*4+3], 0); } - fn Pack(a: uint, b: uint) -> int + fn Pack(a: u32, b: u32) -> i32 { - return int(a + (b << (31u - DEPTH_BITS))); + return i32(a + (b << (31u - DEPTH_BITS))); } - fn Unpack(a: int) -> float + fn Unpack(a: i32) -> f32 { - let mask = (1 << (DEPTH_BITS - 1u)) - 1; - return float(a & mask)/256.0; + let mask = i32(1u << (DEPTH_BITS - 1u)) - 1i; + return f32(a & mask)/256.0; } - fn ClosestPoint(color: float3, depth: float, index: int) + fn ClosestPoint(color: vec3f, depth: f32, index: i32) { let inverseDepth = 1.0/depth; let scaledDepth = (inverseDepth - 1.0/DEPTH_MAX)/(1.0/DEPTH_MIN - 1.0/DEPTH_MAX); @@ -170,28 +170,28 @@ struct Custom { return; } - let uintDepth = uint(scaledDepth*float((1u << DEPTH_BITS) - 1u)); - let uintColor = uint3(color * 256.0); + let uintDepth = u32(scaledDepth*f32((1u << DEPTH_BITS) - 1u)); + let uintColor = vec3u(color * 256.0); atomicMax(&atomic_storage[index*4+0], Pack(uintColor.x, uintDepth)); atomicMax(&atomic_storage[index*4+1], Pack(uintColor.y, uintDepth)); atomicMax(&atomic_storage[index*4+2], Pack(uintColor.z, uintDepth)); } - fn AdditiveBlend(color: float3, depth: float, index: int) + fn AdditiveBlend(color: vec3f, depth: f32, index: i32) { let scaledColor = 256.0 * color/depth; - atomicAdd(&atomic_storage[index*4+0], int(scaledColor.x)); - atomicAdd(&atomic_storage[index*4+1], int(scaledColor.y)); - atomicAdd(&atomic_storage[index*4+2], int(scaledColor.z)); + atomicAdd(&atomic_storage[index*4+0], i32(scaledColor.x)); + atomicAdd(&atomic_storage[index*4+1], i32(scaledColor.y)); + atomicAdd(&atomic_storage[index*4+2], i32(scaledColor.z)); } - fn RasterizePoint(pos: float3, color: float3) + fn RasterizePoint(pos: vec3f, color: vec3f) { - let screen_size = int2(camera.size); + let screen_size = vec2i(camera.size); let projectedPos = Project(camera, pos); - let screenCoord = int2(projectedPos.xy); + let screenCoord = vec2i(projectedPos.xy); //outside of our view if(screenCoord.x < 0 || screenCoord.x >= screen_size.x || @@ -213,47 +213,47 @@ struct Custom { } @compute @workgroup_size(16, 16) - fn Rasterize(@builtin(global_invocation_id) id: uint3) { + fn Rasterize(@builtin(global_invocation_id) id: vec3u) { // Viewport resolution (in pixels) - let screen_size = int2(textureDimensions(screen)); - let screen_size_f = float2(screen_size); + let screen_size = vec2i(textureDimensions(screen)); + let screen_size_f = vec2f(screen_size); - // let ang = float2(mouse.pos.xy)*float2(-TWO_PI, PI)/screen_size_f + float2(0.4, 0.4); - let ang = float2(0.0, 0.0)*float2(-TWO_PI, PI)/screen_size_f + float2(0.4, 0.4); + // let ang = vec2f(mouse.pos.xy)*vec2f(-TWO_PI, PI)/screen_size_f + vec2f(0.4, 0.4); + let ang = vec2f(0.0, 0.0)*vec2f(-TWO_PI, PI)/screen_size_f + vec2f(0.4, 0.4); SetCamera(ang, FOV); //RNG state - state = uint4(id.x, id.y, id.z, 0u*time.frame); + state = vec4u(id.x, id.y, id.z, 0u*time.frame); - for(var i: i32 = 0; i < int(custom.Samples*MaxSamples + 1.0); i++) + for(var i: i32 = 0; i < i32(custom.Samples*MaxSamples + 1.0); i++) { - let rand = nrand4(1.0, float4(0.0)); + let rand = nrand4(1.0, vec4f(0.0)); var pos = 0.2*rand.xyz; - let col = float3(0.5 + 0.5*sin(10.0*pos)); + let col = vec3f(0.5 + 0.5*sin(10.0*pos)); let sec = 5.0+custom.Speed*time.elapsed; //move points along sines - pos += sin(float3(2.0,1.0,1.5)*sec)*0.1*sin(30.0*custom.Sinea*pos); - pos += sin(float3(2.0,1.0,1.5)*sec)*0.02*sin(30.0*custom.Sineb*pos.zxy); + pos += sin(vec3f(2.0,1.0,1.5)*sec)*0.1*sin(30.0*custom.Sinea*pos); + pos += sin(vec3f(2.0,1.0,1.5)*sec)*0.02*sin(30.0*custom.Sineb*pos.zxy); RasterizePoint(pos, col); } } - fn Sample(pos: int2) -> float3 + fn Sample(pos: vec2i) -> vec3f { - let screen_size = int2(textureDimensions(screen)); + let screen_size = vec2i(textureDimensions(screen)); let idx = pos.x + screen_size.x * pos.y; - var color: float3; + var color: vec3f; if(custom.Mode < 0.5) { - let x = float(atomicLoad(&atomic_storage[idx*4+0]))/(256.0); - let y = float(atomicLoad(&atomic_storage[idx*4+1]))/(256.0); - let z = float(atomicLoad(&atomic_storage[idx*4+2]))/(256.0); + let x = f32(atomicLoad(&atomic_storage[idx*4+0]))/(256.0); + let y = f32(atomicLoad(&atomic_storage[idx*4+1]))/(256.0); + let z = f32(atomicLoad(&atomic_storage[idx*4+2]))/(256.0); - color = tanh(0.1*float3(x,y,z)/(custom.Samples*MaxSamples + 1.0)); + color = tanh(0.1*vec3f(x,y,z)/(custom.Samples*MaxSamples + 1.0)); } else { @@ -261,27 +261,27 @@ struct Custom { let y = Unpack(atomicLoad(&atomic_storage[idx*4+1])); let z = Unpack(atomicLoad(&atomic_storage[idx*4+2])); - color = float3(x,y,z); + color = vec3f(x,y,z); } return abs(color); } @compute @workgroup_size(16, 16) - fn main_image(@builtin(global_invocation_id) id: uint3) + fn main_image(@builtin(global_invocation_id) id: vec3u) { - let screen_size = uint2(textureDimensions(screen)); + let screen_size = vec2u(textureDimensions(screen)); // Prevent overdraw for workgroups on the edge of the viewport if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } // Pixel coordinates (centre of pixel, origin at bottom left) - // let fragCoord = float2(float(id.x) + .5, float(id.y) + .5); + // let fragCoord = vec2f(f32(id.x) + .5, f32(id.y) + .5); - let color = float4(Sample(int2(id.xy)),1.0); + let color = vec4f(Sample(vec2i(id.xy)),1.0); // Output to screen (linear colour space) - textureStore(screen, int2(id.xy), color); + textureStore(screen, vec2i(id.xy), color); } `; diff --git a/examples/demos/black-hole-2.ts b/examples/demos/black-hole-2.ts index a062452..0a4c4ab 100644 --- a/examples/demos/black-hole-2.ts +++ b/examples/demos/black-hole-2.ts @@ -36,7 +36,7 @@ export async function render( const screen = device.createTexture({ // Use F32_RGBA - // @see https://www.w3.org/TR/webgpu/#float32-filterable + // @see https://www.w3.org/TR/webgpu/#vec3f2-filterable // @see https://github.com/compute-toys/wgpu-compute-toy/blob/master/src/bind.rs#L433 format: Format.F16_RGBA, width: $canvas.width, @@ -110,12 +110,12 @@ struct Custom { #import particle::{Particle, LoadParticle, SaveParticle}; #import custom::{Custom, custom}; -fn SetCamera(ang: float2, fov: float) +fn SetCamera(ang: vec2f, fov: f32) { camera.fov = fov; camera.cam = GetCameraMatrix(ang); - camera.pos = - (camera.cam*float3(50.0*custom.Radius+0.5,0.0,0.0)); - camera.size = float2(textureDimensions(screen)); + camera.pos = - (camera.cam*vec3f(50.0*custom.Radius+0.5,0.0,0.0)); + camera.size = vec2f(textureDimensions(screen)); } @group(2) @binding(0) var grid : ScreenIndexGrid; @@ -134,28 +134,28 @@ struct ScreenIndexGrid ids: array, SCREEN_GRID_Y>, SCREEN_GRID_X> } -fn GetCellID(pos: uint2) -> uint2 +fn GetCellID(pos: vec2u) -> vec2u { - let uv = float2(pos) / float2(SCREEN_WIDTH, SCREEN_HEIGHT); - return uint2(floor(uv * float2(f32(SCREEN_GRID_X), f32(SCREEN_GRID_Y))) - 1); + let uv = vec2f(pos) / vec2f(SCREEN_WIDTH, SCREEN_HEIGHT); + return vec2u(floor(uv * vec2f(f32(SCREEN_GRID_X), f32(SCREEN_GRID_Y))) - 1); } -fn AddToCell(cell: uint2, id: uint) +fn AddToCell(cell: vec2u, id: u32) { - let cid = atomicAdd(&grid.count[cell.x][cell.y], 1); + let cid = atomicAdd(&grid.count[cell.x][cell.y], 1u); if(cid < GRID_STORAGE) { grid.ids[cell.x][cell.y][cid] = id; } } -fn AddParticle(pos: uint2, id: uint) +fn AddParticle(pos: vec2u, id: u32) { let cell = GetCellID(pos); AddToCell(cell, id); } -fn AddParticleQuad(pos0: uint2, pos1: uint2, id: uint) +fn AddParticleQuad(pos0: vec2u, pos1: vec2u, id: u32) { let cell0 = GetCellID(pos0); let cell1 = GetCellID(pos1); @@ -164,14 +164,14 @@ fn AddParticleQuad(pos0: uint2, pos1: uint2, id: uint) { for(var j = cell0.y; j <= cell1.y; j++) { - AddToCell(uint2(i, j), id); + AddToCell(vec2u(i, j), id); } } } -fn ClearCell(cell: uint2) +fn ClearCell(cell: vec2u) { - atomicStore(&grid.count[cell.x][cell.y], 0); + atomicStore(&grid.count[cell.x][cell.y], 0u); } const MaxSamples = 8.0; @@ -184,31 +184,31 @@ const PARTICLE_COUNT_16 = 16u; const DEPTH_MIN = 0.2; const DEPTH_MAX = 5.0; const DEPTH_BITS = 16u; -const dq = float2(0.0, 1.0); +const dq = vec2f(0.0, 1.0); const eps = 0.01; -fn GetParticleID(pix: int2) -> uint +fn GetParticleID(pix: vec2i) -> u32 { - return uint(pix.x) + uint(pix.y)*PARTICLE_COUNT; + return u32(pix.x) + u32(pix.y)*PARTICLE_COUNT; } -fn GetParticlePix(id: uint) -> int2 +fn GetParticlePix(id: u32) -> vec2i { - return int2(int(id%PARTICLE_COUNT), int(id/PARTICLE_COUNT)); + return vec2i(i32(id%PARTICLE_COUNT), i32(id/PARTICLE_COUNT)); } const KerrM = 1.0; struct GeodesicRay { - q: float4, - qt: float4, - p: float4, + q: vec4f, + qt: vec4f, + p: vec4f, }; -var bokehRad : float; +var bokehRad : f32; -fn sdLine(p: float2, a: float2, b: float2) -> float +fn sdLine(p: vec2f, a: vec2f, b: vec2f) -> f32 { let pa = p - a; let ba = b - a; @@ -216,41 +216,41 @@ fn sdLine(p: float2, a: float2, b: float2) -> float return length(pa - ba*h); } -fn KerrGetR2(p: float3) -> float +fn KerrGetR2(p: vec3f) -> f32 { let rho = dot(p,p) - sqr(custom.KerrA); let r2 = 0.5 * (rho + sqrt(sqr(rho) + sqr(2.0 * custom.KerrA * p.z))); return r2; } -fn KerrGetK(p: float3) -> float4 +fn KerrGetK(p: vec3f) -> vec4f { let r2 = KerrGetR2(p); let r = sqrt(r2); let invr2 = 1.0 / (r2 + sqr(custom.KerrA) + 1e-3); - let k = float3((r*p.x - custom.KerrA*p.y) * invr2, (r*p.y + custom.KerrA*p.x) * invr2, p.z/(r + 1e-4)); + let k = vec3f((r*p.x - custom.KerrA*p.y) * invr2, (r*p.y + custom.KerrA*p.x) * invr2, p.z/(r + 1e-4)); let f = r2 * (2.0 * KerrM * r - sqr(custom.KerrQ)) / (r2 * r2 + sqr(custom.KerrA * p.z) + 1e-3); - return float4(k, f); + return vec4f(k, f); } -fn G(q: float4) -> float4x4 +fn G(q: vec4f) -> mat4x4f { //Kerr metric in Kerr-Schild coordinates let k = KerrGetK(q.yzw); - let kf = k.w*float4(1.0, k.xyz); - return diag(float4(-1.0,1.0,1.0,1.0)) + float4x4(kf, k.x*kf, k.y*kf, k.z*kf); + let kf = k.w*vec4f(1.0, k.xyz); + return diag(vec4f(-1.0,1.0,1.0,1.0)) + mat4x4f(kf, k.x*kf, k.y*kf, k.z*kf); } -fn Ginv(q: float4) -> float4x4 +fn Ginv(q: vec4f) -> mat4x4f { //inverse of Kerr metric in Kerr-Schild coordinates let k = KerrGetK(q.yzw); let kf = k.w*vec4(1.0, -k.xyz)/dot(k.xyz, k.xyz); - return diag(float4(-1.0,1.0,1.0,1.0)) + float4x4(-kf, k.x*kf, k.y*kf, k.z*kf); + return diag(vec4f(-1.0,1.0,1.0,1.0)) + mat4x4f(-kf, k.x*kf, k.y*kf, k.z*kf); } //lagrangian -fn Lmat(qt: float4, g: float4x4) -> float +fn Lmat(qt: vec4f, g: mat4x4f) -> f32 { return g[0][0]*qt.x*qt.x + g[1][1]*qt.y*qt.y + g[2][2]*qt.z*qt.z + g[3][3]*qt.w*qt.w + 2.0*(g[0][1]*qt.x*qt.y + g[0][2]*qt.x*qt.z + g[0][3]*qt.x*qt.w + @@ -258,22 +258,22 @@ fn Lmat(qt: float4, g: float4x4) -> float g[2][3]*qt.z*qt.w); } -fn L(qt: float4, q: float4) -> float +fn L(qt: vec4f, q: vec4f) -> f32 { return Lmat(qt, G(q)); } -fn H(p: float4, ginv: float4x4) -> float +fn H(p: vec4f, ginv: mat4x4f) -> f32 { return Lmat(p, ginv); } -fn ToMomentum(ray: GeodesicRay) -> float4 +fn ToMomentum(ray: GeodesicRay) -> vec4f { return G(ray.q)*ray.qt; } -fn FromMomentum(ray: GeodesicRay) -> float4 +fn FromMomentum(ray: GeodesicRay) -> vec4f { return Ginv(ray.q)*ray.p; } @@ -294,27 +294,27 @@ fn GeodesicToParticle(ray: GeodesicRay) -> Particle return particle; } -fn HamiltonianGradient(ray: GeodesicRay) -> float4 +fn HamiltonianGradient(ray: GeodesicRay) -> vec4f { let ginv = Ginv(ray.q); let H0 = H(ray.p, ginv); let delta = 0.1; - return (float4( + return (vec4f( L(ray.qt,ray.q+delta*dq.yxxx), L(ray.qt,ray.q+delta*dq.xyxx), L(ray.qt,ray.q+delta*dq.xxyx), L(ray.qt,ray.q+delta*dq.xxxy)) - H0)/delta; } -fn VelClamp(vel: float4) -> float4 +fn VelClamp(vel: vec4f) -> vec4f { - return vel;//float4(vel.x, vel.yzw / max(1.0, length(vel.yzw))); + return vel;//vec4f(vel.x, vel.yzw / max(1.0, length(vel.yzw))); } @compute @workgroup_size(16, 16) -fn SimulateParticles(@builtin(global_invocation_id) id: uint3) +fn SimulateParticles(@builtin(global_invocation_id) id: vec3u) { - var pix = int2(id.xy); + var pix = vec2i(id.xy); var p = LoadParticle(pix); if(pix.x > i32(PARTICLE_COUNT) || pix.y > i32(PARTICLE_COUNT)) @@ -322,7 +322,7 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) return; } - state = uint4(id.x, id.y, id.z, time.frame); + state = vec4u(id.x, id.y, id.z, time.frame); let r = sqrt(KerrGetR2(p.position.yzw)); @@ -330,7 +330,7 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) { let rng = rand4(); let rng1 = rand4(); - p.position = 30.0*float4(1.0, 1.0, 1.0, custom.InitThick) * float4(0.0,2.0*rng.xyz - 1.0); + p.position = 30.0*vec4f(1.0, 1.0, 1.0, custom.InitThick) * vec4f(0.0,2.0*rng.xyz - 1.0); let r01 = sqrt(KerrGetR2(p.position.yzw)); if(r01 < 0.9) @@ -338,11 +338,11 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) return; } - var vel = normalize(cross(p.position.yzw, float3(0.0,0.0,1.0))); + var vel = normalize(cross(p.position.yzw, vec3f(0.0,0.0,1.0))); vel += 0.3*(rng1.xyz * 0.5 - 0.25); let vscale = clamp(1.0 / (0.2 + 0.08*r01), 0., 1.0); - p.velocity = float4(-1.0,2.0*(custom.InitSpeed - 0.5)*vel*vscale); + p.velocity = vec4f(-1.0,2.0*(custom.InitSpeed - 0.5)*vel*vscale); } @@ -354,7 +354,7 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) // // return; // } - for(var i = 0; i < int(custom.Steps*16.0 + 1.0); i++) + for(var i = 0; i < i32(custom.Steps*16.0 + 1.0); i++) { ray.qt = FromMomentum(ray); let qt0 = ray.qt; @@ -368,23 +368,23 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) } @compute @workgroup_size(16, 16) -fn ClearScreenGrid(@builtin(global_invocation_id) id: uint3) +fn ClearScreenGrid(@builtin(global_invocation_id) id: vec3u) { let cell = id.xy; ClearCell(cell); } @compute @workgroup_size(16, 16) -fn UpdateScreenGrid(@builtin(global_invocation_id) id: uint3) { - let screen_size = int2(textureDimensions(screen)); - let screen_size_f = float2(screen_size); +fn UpdateScreenGrid(@builtin(global_invocation_id) id: vec3u) { + let screen_size = vec2i(textureDimensions(screen)); + let screen_size_f = vec2f(screen_size); - let ang = float2(0.0, 0.0); - // let ang = float2(mouse.pos.xy)*float2(-TWO_PI, PI)/screen_size_f + 1e-4; + let ang = vec2f(0.0, 0.0); + // let ang = vec2f(mouse.pos.xy)*vec2f(-TWO_PI, PI)/screen_size_f + 1e-4; SetCamera(ang, FOV); - var pix = int2(id.xy); + var pix = vec2i(id.xy); if(pix.x > i32(PARTICLE_COUNT) || pix.y > i32(PARTICLE_COUNT)) { @@ -394,7 +394,7 @@ fn UpdateScreenGrid(@builtin(global_invocation_id) id: uint3) { var p = LoadParticle(pix); var pos = p.position.ywz; let projectedPos = Project(camera, pos); - let screenCoord = int2(projectedPos.xy); + let screenCoord = vec2i(projectedPos.xy); //outside of our view if(screenCoord.x < 0 || screenCoord.x >= screen_size.x || @@ -402,34 +402,34 @@ fn UpdateScreenGrid(@builtin(global_invocation_id) id: uint3) { { return; } - let pos0 = uint2(clamp(screenCoord - int(PARTICLE_RAD), int2(0), screen_size)); - let pos1 = uint2(clamp(screenCoord + int(PARTICLE_RAD), int2(0), screen_size)); + let pos0 = vec2u(clamp(screenCoord - i32(PARTICLE_RAD), vec2i(0), screen_size)); + let pos1 = vec2u(clamp(screenCoord + i32(PARTICLE_RAD), vec2i(0), screen_size)); AddParticleQuad(pos0, pos1, GetParticleID(pix)); } -fn hue(v: float) -> float4 { - return .6 + .6 * cos(6.3 * v + float4(0.,23.,21.,0.)); +fn hue(v: f32) -> vec4f { + return .6 + .6 * cos(6.3 * v + vec4f(0.,23.,21.,0.)); } -fn RenderParticles(pix: uint2) -> float3 +fn RenderParticles(pix: vec2u) -> vec3f { //setup camera - let screen_size = int2(textureDimensions(screen)); - let screen_size_f = float2(screen_size); + let screen_size = vec2i(textureDimensions(screen)); + let screen_size_f = vec2f(screen_size); - let ang = float2(0.0, 0.0); - // let ang = float2(mouse.pos.xy)*float2(-TWO_PI, PI)/screen_size_f + 1e-4; + let ang = vec2f(0.0, 0.0); + // let ang = vec2f(mouse.pos.xy)*vec2f(-TWO_PI, PI)/screen_size_f + 1e-4; SetCamera(ang, FOV); //loop over particles in screen cell - let fpix = float2(pix); + let fpix = vec2f(pix); let cell = GetCellID(pix); let pcount = min(atomicLoad(&grid.count[cell.x][cell.y]), GRID_STORAGE); // //heatmap - // //return float3(uint3(pcount))/float(GRID_STORAGE); + // //return vec3f(vec3u(pcount))/f32(GRID_STORAGE); - var color = float3(0.0); + var color = vec3f(0.0); for(var i = 0u; i < pcount; i++) { let pid = grid.ids[cell.x][cell.y][i]; @@ -437,7 +437,7 @@ fn RenderParticles(pix: uint2) -> float3 var pos = p.position.ywz; let vel = p.velocity.ywz; var ang = atan2(vel.x, vel.z+0.000001)/6.28; - ang += (rand4s(uint4(pid, 0, 0, 0)).x - 0.5)*0.33; + ang += (rand4s(vec4u(pid, 0, 0, 0)).x - 0.5)*0.33; var col = hue(ang).xyz; let projectedPos0 = Project(camera, pos - vel*custom.MotionBlur); @@ -445,26 +445,26 @@ fn RenderParticles(pix: uint2) -> float3 let vlen = distance(projectedPos0.xy, projectedPos1.xy); let pdist = sdLine(fpix, projectedPos0.xy, projectedPos1.xy); let R = clamp(2.0*custom.BlurRadius*abs(projectedPos0.z- 100.*custom.FocalPlane), 1.5, PARTICLE_RAD); - //color = color + 0.05*float3(1,1,1)*smoothstep(PARTICLE_RAD, 0.0, pdist)/(0.25 + pdist*pdist); + //color = color + 0.05*vec3f(1,1,1)*smoothstep(PARTICLE_RAD, 0.0, pdist)/(0.25 + pdist*pdist); let area = R*vlen + R*R; color += 20.0*col*smoothstep(R, R - 1.0, pdist) / area; } let exposure = screen_size_f.x * screen_size_f.y *custom.Exposure / (896*504); color = 1.0 - exp(-exposure*color); - return pow(color, float3(3.0*custom.Gamma)); + return pow(color, vec3f(3.0*custom.Gamma)); } @compute @workgroup_size(16, 16) -fn main_image(@builtin(global_invocation_id) id: uint3) +fn main_image(@builtin(global_invocation_id) id: vec3u) { - let screen_size = uint2(textureDimensions(screen)); + let screen_size = vec2u(textureDimensions(screen)); // Prevent overdraw for workgroups on the edge of the viewport if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } - let color = float4(RenderParticles(id.xy), 1.0); + let color = vec4f(RenderParticles(id.xy), 1.0); - textureStore(screen, int2(id.xy), float4(color.xyz/color.w, 1.)); + textureStore(screen, vec2i(id.xy), vec4f(color.xyz/color.w, 1.)); } `; diff --git a/examples/demos/black-hole.ts b/examples/demos/black-hole.ts index 523fda6..8cfe147 100644 --- a/examples/demos/black-hole.ts +++ b/examples/demos/black-hole.ts @@ -51,7 +51,7 @@ export async function render( const screen = device.createTexture({ // Use F32_RGBA - // @see https://www.w3.org/TR/webgpu/#float32-filterable + // @see https://www.w3.org/TR/webgpu/#vec3f2-filterable // @see https://github.com/compute-toys/wgpu-compute-toy/blob/master/src/bind.rs#L433 format: Format.F16_RGBA, width: $canvas.width, @@ -134,63 +134,63 @@ const PARTICLE_COUNT = 1000; const DEPTH_MIN = 0.2; const DEPTH_MAX = 5.0; const DEPTH_BITS = 16u; -const dq = float2(0.0, 1.0); +const dq = vec2f(0.0, 1.0); const eps = 0.01; const KerrM = 1.0; struct GeodesicRay { - q: float4, - qt: float4, - p: float4, + q: vec4f, + qt: vec4f, + p: vec4f, }; -var bokehRad : float; +var bokehRad : f32; -fn SetCamera(ang: float2, fov: float) +fn SetCamera(ang: vec2f, fov: f32) { camera.fov = fov; camera.cam = GetCameraMatrix(ang); - camera.pos = - (camera.cam*float3(50.0*custom.Radius+0.5,0.0,0.0)); - camera.size = float2(textureDimensions(screen)); + camera.pos = - (camera.cam*vec3f(50.0*custom.Radius+0.5,0.0,0.0)); + camera.size = vec2f(textureDimensions(screen)); } -fn KerrGetR2(p: float3) -> float +fn KerrGetR2(p: vec3f) -> f32 { let rho = dot(p,p) - sqr(custom.KerrA); let r2 = 0.5*(rho + sqrt(sqr(rho) + sqr(2.0*custom.KerrA*p.z))); return r2; } -fn KerrGetK(p: float3) -> float4 +fn KerrGetK(p: vec3f) -> vec4f { let r2 = KerrGetR2(p); let r = sqrt(r2); let invr2 = 1.0 / (r2 + sqr(custom.KerrA) + 1e-3); - let k = float3((r*p.x - custom.KerrA*p.y) * invr2, (r*p.y + custom.KerrA*p.x) * invr2, p.z/(r + 1e-4)); + let k = vec3f((r*p.x - custom.KerrA*p.y) * invr2, (r*p.y + custom.KerrA*p.x) * invr2, p.z/(r + 1e-4)); let f = r2 * (2.0 * KerrM * r - sqr(custom.KerrQ)) / (r2 * r2 + sqr(custom.KerrA * p.z) + 1e-3); - return float4(k, f); + return vec4f(k, f); } -fn G(q: float4) -> float4x4 +fn G(q: vec4f) -> mat4x4 { //Kerr metric in Kerr-Schild coordinates let k = KerrGetK(q.yzw); - let kf = k.w*float4(1.0, k.xyz); - return diag(float4(-1.0,1.0,1.0,1.0)) + float4x4(kf, k.x*kf, k.y*kf, k.z*kf); + let kf = k.w*vec4f(1.0, k.xyz); + return diag(vec4f(-1.0,1.0,1.0,1.0)) + mat4x4(kf, k.x*kf, k.y*kf, k.z*kf); } -fn Ginv(q: float4) -> float4x4 +fn Ginv(q: vec4f) -> mat4x4 { //inverse of Kerr metric in Kerr-Schild coordinates let k = KerrGetK(q.yzw); let kf = k.w*vec4(1.0, -k.xyz)/dot(k.xyz, k.xyz); - return diag(float4(-1.0,1.0,1.0,1.0)) + float4x4(-kf, k.x*kf, k.y*kf, k.z*kf); + return diag(vec4f(-1.0,1.0,1.0,1.0)) + mat4x4(-kf, k.x*kf, k.y*kf, k.z*kf); } //lagrangian -fn Lmat(qt: float4, g: float4x4) -> float +fn Lmat(qt: vec4f, g: mat4x4) -> f32 { return g[0][0]*qt.x*qt.x + g[1][1]*qt.y*qt.y + g[2][2]*qt.z*qt.z + g[3][3]*qt.w*qt.w + 2.0*(g[0][1]*qt.x*qt.y + g[0][2]*qt.x*qt.z + g[0][3]*qt.x*qt.w + @@ -198,22 +198,22 @@ fn Lmat(qt: float4, g: float4x4) -> float g[2][3]*qt.z*qt.w); } -fn L(qt: float4, q: float4) -> float +fn L(qt: vec4f, q: vec4f) -> f32 { return Lmat(qt, G(q)); } -fn H(p: float4, ginv: float4x4) -> float +fn H(p: vec4f, ginv: mat4x4) -> f32 { return Lmat(p, ginv); } -fn ToMomentum(ray: GeodesicRay) -> float4 +fn ToMomentum(ray: GeodesicRay) -> vec4f { return G(ray.q)*ray.qt; } -fn FromMomentum(ray: GeodesicRay) -> float4 +fn FromMomentum(ray: GeodesicRay) -> vec4f { return Ginv(ray.q)*ray.p; } @@ -234,27 +234,27 @@ fn GeodesicToParticle(ray: GeodesicRay) -> Particle return particle; } -fn HamiltonianGradient(ray: GeodesicRay) -> float4 +fn HamiltonianGradient(ray: GeodesicRay) -> vec4f { let ginv = Ginv(ray.q); let H0 = H(ray.p, ginv); let delta = 0.1; - return (float4( + return (vec4f( L(ray.qt,ray.q+delta*dq.yxxx), L(ray.qt,ray.q+delta*dq.xyxx), L(ray.qt,ray.q+delta*dq.xxyx), L(ray.qt,ray.q+delta*dq.xxxy)) - H0)/delta; } -fn VelClamp(vel: float4) -> float4 +fn VelClamp(vel: vec4f) -> vec4f { - return vel;//float4(vel.x, vel.yzw / max(1.0, length(vel.yzw))); + return vel;//vec4f(vel.x, vel.yzw / max(1.0, length(vel.yzw))); } @compute @workgroup_size(16, 16) -fn SimulateParticles(@builtin(global_invocation_id) id: uint3) +fn SimulateParticles(@builtin(global_invocation_id) id: vec3u) { - var pix = int2(id.xy); + var pix = vec2i(id.xy); var p = LoadParticle(pix); if(pix.x > PARTICLE_COUNT || pix.y > PARTICLE_COUNT) @@ -262,7 +262,7 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) return; } - state = uint4(id.x, id.y, id.z, time.frame); + state = vec4u(id.x, id.y, id.z, time.frame); let r = sqrt(KerrGetR2(p.position.yzw)); @@ -270,7 +270,7 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) { let rng = rand4(); let rng1 = rand4(); - p.position = 30.0*float4(1.0, 1.0, 1.0, custom.InitThick) * float4(0.0,2.0*rng.xyz - 1.0); + p.position = 30.0*vec4f(1.0, 1.0, 1.0, custom.InitThick) * vec4f(0.0,2.0*rng.xyz - 1.0); let r01 = sqrt(KerrGetR2(p.position.yzw)); if(r01 < 0.9) @@ -278,11 +278,11 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) return; } - var vel = normalize(cross(p.position.yzw, float3(0.0,0.0,1.0))); + var vel = normalize(cross(p.position.yzw, vec3f(0.0,0.0,1.0))); vel += 0.3*(rng1.xyz * 0.5 - 0.25); let vscale = clamp(1.0 / (0.2 + 0.08*r01), 0., 1.0); - p.velocity = float4(-1.0,2.0*(custom.InitSpeed - 0.5)*vel*vscale); + p.velocity = vec4f(-1.0,2.0*(custom.InitSpeed - 0.5)*vel*vscale); } @@ -294,7 +294,7 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) // // return; // } - for(var i = 0; i < int(custom.Steps*16.0 + 1.0); i++) + for(var i = 0; i < i32(custom.Steps*16.0 + 1.0); i++) { ray.qt = FromMomentum(ray); let qt0 = ray.qt; @@ -308,9 +308,9 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) } @compute @workgroup_size(16, 16) -fn Clear(@builtin(global_invocation_id) id: uint3) { - let screen_size = int2(textureDimensions(screen)); - let idx0 = int(id.x) + int(screen_size.x * int(id.y)); +fn Clear(@builtin(global_invocation_id) id: vec3u) { + let screen_size = vec2i(textureDimensions(screen)); + let idx0 = i32(id.x) + i32(screen_size.x * i32(id.y)); atomicStore(&atomic_storage[idx0*4+0], 0); atomicStore(&atomic_storage[idx0*4+1], 0); @@ -319,17 +319,17 @@ fn Clear(@builtin(global_invocation_id) id: uint3) { } @compute @workgroup_size(16, 16) -fn Rasterize(@builtin(global_invocation_id) id: uint3) { +fn Rasterize(@builtin(global_invocation_id) id: vec3u) { // Viewport resolution (in pixels) - let screen_size = int2(textureDimensions(screen)); - let screen_size_f = float2(screen_size); + let screen_size = vec2i(textureDimensions(screen)); + let screen_size_f = vec2f(screen_size); - let ang = float2(mouse.pos.xy)*float2(-TWO_PI, PI)/screen_size_f + 1e-4; + let ang = vec2f(mouse.pos.xy)*vec2f(-TWO_PI, PI)/screen_size_f + 1e-4; SetCamera(ang, FOV); //RNG state - state = uint4(id.x, id.y, id.z, 0u); + state = vec4u(id.x, id.y, id.z, 0u); let rng = rand4(); bokehRad = pow(rng.x, custom.BlurExponentA); @@ -339,7 +339,7 @@ fn Rasterize(@builtin(global_invocation_id) id: uint3) { state.w = time.frame; } - var pix = int2(id.xy); + var pix = vec2i(id.xy); if(pix.x > PARTICLE_COUNT || pix.y > PARTICLE_COUNT) { @@ -350,53 +350,53 @@ fn Rasterize(@builtin(global_invocation_id) id: uint3) { var pos = p.position.ywz; let vel = abs(p.velocity.ywz); - var col = clamp(8.5*abs(vel)*dot(vel,vel)+0.1, float3(0.0), float3(5.0)); + var col = clamp(8.5*abs(vel)*dot(vel,vel)+0.1, vec3f(0.0), vec3f(5.0)); col /= (0.1+bokehRad); let impSample = (col.x + col.y + col.z)*bokehRad; - let sampleCount = clamp(int(impSample*custom.Samples*MaxSamples + 1.0), 1, 1024); - let normalCount = int(custom.Samples*MaxSamples + 1.0); + let sampleCount = clamp(i32(impSample*custom.Samples*MaxSamples + 1.0), 1, 1024); + let normalCount = i32(custom.Samples*MaxSamples + 1.0); - col *= float(normalCount)/float(sampleCount); + col *= f32(normalCount)/f32(sampleCount); for(var i = 0; i < sampleCount; i++) { let R = 2.0*custom.BlurRadius*bokehRad; let rng = rand4(); - let dpos = R*normalize(nrand4(1.0, float4(0.0)).xyz)*pow(rng.x, custom.BlurExponentB); + let dpos = R*normalize(nrand4(1.0, vec4f(0.0)).xyz)*pow(rng.x, custom.BlurExponentB); RasterizePoint(pos + dpos, col); } } -fn Sample(pos: int2) -> float3 +fn Sample(pos: vec2i) -> vec3f { - let screen_size = int2(textureDimensions(screen)); + let screen_size = vec2i(textureDimensions(screen)); let idx = pos.x + screen_size.x * pos.y; - var color: float3; - let x = float(atomicLoad(&atomic_storage[idx*4+0]))/(256.0); - let y = float(atomicLoad(&atomic_storage[idx*4+1]))/(256.0); - let z = float(atomicLoad(&atomic_storage[idx*4+2]))/(256.0); + var color: vec3f; + let x = f32(atomicLoad(&atomic_storage[idx*4+0]))/(256.0); + let y = f32(atomicLoad(&atomic_storage[idx*4+1]))/(256.0); + let z = f32(atomicLoad(&atomic_storage[idx*4+2]))/(256.0); - color = tanh(custom.Exposure*0.03*float(screen_size.x)*float3(x,y,z)/(custom.Samples*MaxSamples + 1.0)); + color = tanh(custom.Exposure*0.03*f32(screen_size.x)*vec3f(x,y,z)/(custom.Samples*MaxSamples + 1.0)); return abs(color); } @compute @workgroup_size(16, 16) -fn main_image(@builtin(global_invocation_id) id: uint3) +fn main_image(@builtin(global_invocation_id) id: vec3u) { - let screen_size = uint2(textureDimensions(screen)); + let screen_size = vec2u(textureDimensions(screen)); // Prevent overdraw for workgroups on the edge of the viewport if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } // Pixel coordinates (centre of pixel, origin at bottom left) - let fragCoord = float2(float(id.x) + .5, float(id.y) + .5); + let fragCoord = vec2f(f32(id.x) + .5, f32(id.y) + .5); - var color = float4(Sample(int2(id.xy)),1.0); + var color = vec4f(Sample(vec2i(id.xy)),1.0); - let oldColor = textureLoad(pass_in, int2(id.xy), 2, 0); + let oldColor = textureLoad(pass_in, vec2i(id.xy), 2, 0); if(mouse.click == 1 && custom.AnimatedNoise > 0.5) { @@ -404,9 +404,9 @@ fn main_image(@builtin(global_invocation_id) id: uint3) } // Output to buffer - textureStore(pass_out, int2(id.xy), 2, color); + textureStore(pass_out, vec2i(id.xy), 2, color); - textureStore(screen, int2(id.xy), float4(color.xyz/color.w, 1.)); + textureStore(screen, vec2i(id.xy), vec4f(color.xyz/color.w, 1.)); } `; diff --git a/examples/demos/caustics.ts b/examples/demos/caustics.ts index 7558c21..a7fdc1b 100644 --- a/examples/demos/caustics.ts +++ b/examples/demos/caustics.ts @@ -35,7 +35,7 @@ export async function render( const screen = device.createTexture({ // Use F32_RGBA - // @see https://www.w3.org/TR/webgpu/#float32-filterable + // @see https://www.w3.org/TR/webgpu/#vec3f2-filterable // @see https://github.com/compute-toys/wgpu-compute-toy/blob/master/src/bind.rs#L433 format: Format.F16_RGBA, width: $canvas.width, @@ -90,91 +90,91 @@ export async function render( // 2022 David A Roberts // https://www.shadertoy.com/view/4djSRW -fn hash44(p: float4) -> float4 { - var p4 = fract(p * float4(.1031, .1030, .0973, .1099)); +fn hash44(p: vec4f) -> vec4f { + var p4 = fract(p * vec4f(.1031, .1030, .0973, .1099)); p4 = p4 + dot(p4, p4.wzxy+33.33); return fract((p4.xxyz+p4.yzzw)*p4.zywx); } const dt = 1.; -const n = float2(0., 1.); -const e = float2(1., 0.); -const s = float2(0., -1.); -const w = float2(-1., 0.); +const n = vec2f(0., 1.); +const e = vec2f(1., 0.); +const s = vec2f(0., -1.); +const w = vec2f(-1., 0.); -fn A(fragCoord: float2) -> float4 { - return passLoad(0, int2(fragCoord), 0); +fn A(fragCoord: vec2f) -> vec4f { + return passLoad(0, vec2i(fragCoord), 0); } -fn B(fragCoord: float2) -> float4 { - return passSampleLevelBilinearRepeat(1, fragCoord / float2(textureDimensions(screen)), 0.); +fn B(fragCoord: vec2f) -> vec4f { + return passSampleLevelBilinearRepeat(1, fragCoord / vec2f(textureDimensions(screen)), 0.); } -fn T(fragCoord: float2) -> float4 { +fn T(fragCoord: vec2f) -> vec4f { return B(fragCoord - dt * B(fragCoord).xy); } @compute @workgroup_size(16, 16) -fn main_velocity(@builtin(global_invocation_id) id: uint3) { - let screen_size = uint2(textureDimensions(screen)); +fn main_velocity(@builtin(global_invocation_id) id: vec3u) { + let screen_size = vec2u(textureDimensions(screen)); if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } - let u = float2(id.xy) + 0.5; + let u = vec2f(id.xy) + 0.5; var r = T(u); r.x = r.x - dt * 0.25 * (T(u+e).z - T(u+w).z); r.y = r.y - dt * 0.25 * (T(u+n).z - T(u+s).z); - if (u32(time.frame) < 3u) { r = float4(0.); } - passStore(0, int2(id.xy), r); + if (u32(time.frame) < 3u) { r = vec4f(0.); } + passStore(0, vec2i(id.xy), r); } @compute @workgroup_size(16, 16) -fn main_pressure(@builtin(global_invocation_id) id: uint3) { - let screen_size = uint2(textureDimensions(screen)); +fn main_pressure(@builtin(global_invocation_id) id: vec3u) { + let screen_size = vec2u(textureDimensions(screen)); if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } - let u = float2(id.xy) + 0.5; + let u = vec2f(id.xy) + 0.5; var r = A(u); r.z = r.z - dt * 0.25 * (A(u+e).x - A(u+w).x + A(u+n).y - A(u+s).y); - let t = float(time.frame) / 120.; - let o = float2(screen_size)/2. * (1. + .75 * float2(cos(t/15.), sin(2.7*t/15.))); - r = mix(r, float4(0.5 * sin(dt * 2. * t) * sin(dt * t), 0., r.z, 1.), exp(-0.2 * length(u - o))); - passStore(1, int2(id.xy), r); + let t = f32(time.frame) / 120.; + let o = vec2f(screen_size)/2. * (1. + .75 * vec2f(cos(t/15.), sin(2.7*t/15.))); + r = mix(r, vec4f(0.5 * sin(dt * 2. * t) * sin(dt * t), 0., r.z, 1.), exp(-0.2 * length(u - o))); + passStore(1, vec2i(id.xy), r); } @compute @workgroup_size(16, 16) -fn main_caustics(@builtin(global_invocation_id) id: uint3) { - let screen_size = uint2(textureDimensions(screen)); +fn main_caustics(@builtin(global_invocation_id) id: vec3u) { + let screen_size = vec2u(textureDimensions(screen)); if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } for (var i = 0; i < 25; i = i+1) { - let h = hash44(float4(float2(id.xy), float(time.frame), float(i))); - var p = float2(id.xy) + h.xy; + let h = hash44(vec4f(vec2f(id.xy), f32(time.frame), f32(i))); + var p = vec2f(id.xy) + h.xy; let z = mix(.3, 1., h.z); - let c = max(cos(z*6.2+float4(1.,2.,3.,4.)),float4(0.)); - let grad = 0.25 * float2(B(p+e).z - B(p+w).z, B(p+n).z - B(p+s).z); + let c = max(cos(z*6.2+vec4f(1.,2.,3.,4.)),vec4f(0.)); + let grad = 0.25 * vec2f(B(p+e).z - B(p+w).z, B(p+n).z - B(p+s).z); p = p + 1e5 * grad * z; - p = fract(p / float2(screen_size)) * float2(screen_size); - let idx = int(p.x) + int(p.y) * int(screen_size.x); - atomicAdd(&atomic_storage[idx*4+0], int(c.x * 256.)); - atomicAdd(&atomic_storage[idx*4+1], int(c.y * 256.)); - atomicAdd(&atomic_storage[idx*4+2], int(c.z * 256.)); + p = fract(p / vec2f(screen_size)) * vec2f(screen_size); + let idx = i32(p.x) + i32(p.y) * i32(screen_size.x); + atomicAdd(&atomic_storage[idx*4+0], i32(c.x * 256.)); + atomicAdd(&atomic_storage[idx*4+1], i32(c.y * 256.)); + atomicAdd(&atomic_storage[idx*4+2], i32(c.z * 256.)); } } @compute @workgroup_size(16, 16) -fn main_image(@builtin(global_invocation_id) id: uint3) { - let screen_size = uint2(textureDimensions(screen)); +fn main_image(@builtin(global_invocation_id) id: vec3u) { + let screen_size = vec2u(textureDimensions(screen)); if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } - let idx = int(id.x) + int(id.y) * int(screen_size.x); - let x = float(atomicLoad(&atomic_storage[idx*4+0])); - let y = float(atomicLoad(&atomic_storage[idx*4+1])); - let z = float(atomicLoad(&atomic_storage[idx*4+2])); - var r = float3(x, y, z) / 256.; + let idx = i32(id.x) + i32(id.y) * i32(screen_size.x); + let x = f32(atomicLoad(&atomic_storage[idx*4+0])); + let y = f32(atomicLoad(&atomic_storage[idx*4+1])); + let z = f32(atomicLoad(&atomic_storage[idx*4+2])); + var r = vec3f(x, y, z) / 256.; r = r * sqrt(r) / 5e3; - r = r * float3(.5, .75, 1.); - textureStore(screen, int2(id.xy), float4(r, 1.)); - atomicStore(&atomic_storage[idx*4+0], int(x * .9)); - atomicStore(&atomic_storage[idx*4+1], int(y * .9)); - atomicStore(&atomic_storage[idx*4+2], int(z * .9)); + r = r * vec3f(.5, .75, 1.); + textureStore(screen, vec2i(id.xy), vec4f(r, 1.)); + atomicStore(&atomic_storage[idx*4+0], i32(x * .9)); + atomicStore(&atomic_storage[idx*4+1], i32(y * .9)); + atomicStore(&atomic_storage[idx*4+2], i32(z * .9)); } `; diff --git a/examples/demos/origami.ts b/examples/demos/origami.ts index 4c20ce2..8091aaa 100644 --- a/examples/demos/origami.ts +++ b/examples/demos/origami.ts @@ -84,7 +84,7 @@ fn main_image(@builtin(global_invocation_id) id: vec3u) { u -= R*clamp(u*R,-vec2f(i),vec2f(i)); l = max(length(u),0.1); //Compute anti-aliased alpha using SDF - A = min((l - 0.1) * r.y / 5, 1); + A = min((l - 0.1) * r.y / 5., 1.); //Pick layer color h = sin(i*10+a/3+vec4f(1,3,5,0))/5+0.8; //Color blending and lighting diff --git a/examples/demos/raymarching.ts b/examples/demos/raymarching.ts index 3a86669..300a9f9 100644 --- a/examples/demos/raymarching.ts +++ b/examples/demos/raymarching.ts @@ -46,12 +46,12 @@ export async function render( wgsl: /* wgsl */ ` #import prelude::{screen, time} -fn sphereMap(p: float3) -> float +fn sphereMap(p: vec3) -> f32 { return length(p) - 1.; // distance to a sphere of radius 1 } -fn rayMarchSphere(ro: float3, rd: float3, tmin: float, tmax: float) -> float +fn rayMarchSphere(ro: vec3, rd: vec3, tmin: f32, tmax: f32) -> f32 { var t = tmin; for(var i=0; i<400; i++ ) @@ -66,27 +66,27 @@ fn rayMarchSphere(ro: float3, rd: float3, tmin: float, tmax: float) -> float } @compute @workgroup_size(16, 16) -fn main_image(@builtin(global_invocation_id) id: uint3) { - let screen_size = uint2(textureDimensions(screen)); - if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } - let fragCoord = float2(id.xy) + .5; - let resolution = float2(screen_size); - - var ignore = time.elapsed / time.elapsed; // to avoid rewriting run without the time bindings. - var uv = (fragCoord * 2. - resolution.xy) / resolution.y * ignore; - // var uv = (fragCoord * 2. - resolution.xy) / resolution.y; - - // camera - let ro = vec3(0.0, 0, -3.0); - let rd = normalize(vec3(uv, 1.)); - - //---------------------------------- - // raycast terrain and tree envelope - //---------------------------------- - let tmax = 2000.0; - let t = rayMarchSphere(ro, rd, 0, tmax); - let col = vec3(t * .2); - textureStore(screen, int2(id.xy), float4(col, 1.)); +fn main_image(@builtin(global_invocation_id) id: vec3) { + let screen_size = vec2(textureDimensions(screen)); + if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } + let fragCoord = vec2(id.xy) + .5; + let resolution = vec2(screen_size); + + var ignore = time.elapsed / time.elapsed; // to avoid rewriting run without the time bindings. + var uv = (fragCoord * 2. - resolution.xy) / resolution.y * ignore; + // var uv = (fragCoord * 2. - resolution.xy) / resolution.y; + + // camera + let ro = vec3(0.0, 0, -3.0); + let rd = normalize(vec3(uv, 1.)); + + //---------------------------------- + // raycast terrain and tree envelope + //---------------------------------- + let tmax = 2000.0; + let t = rayMarchSphere(ro, rd, 0.0, tmax); + let col = vec3(t * .2); + textureStore(screen, vec2(id.xy), vec4(col, 1.)); } `, }, diff --git a/examples/demos/sdf-2d.ts b/examples/demos/sdf-2d.ts index fdbfa9c..815f0e0 100644 --- a/examples/demos/sdf-2d.ts +++ b/examples/demos/sdf-2d.ts @@ -307,15 +307,15 @@ fn sdPolygon(p: vec2f, v: ptr>) -> f32 { var s: f32 = 1.; for (var i: i32 = 0; i < N; i = i + 1) { let j = (i + 1) % N; - let e = c[i] - c[j]; - let w = p - c[j]; - let b = w - e * clamp(dot(w, e) / dot(e, e), 0., 1.); - d = min(d, dot(b, b)); - let c1 = p.y >= c[j].y; - let c2 = p.y < c[i].y; - let c3 = e.x * w.y > e.y * w.x; - let c = vec3(c1, c2, c3); - if (all(c) || all(!c)) { s = -s; }; + // let e = c[i] - c[j]; + // let w = p - c[j]; + // let b = w - e * clamp(dot(w, e) / dot(e, e), 0., 1.); + // d = min(d, dot(b, b)); + // let c1 = p.y >= c[j].y; + // let c2 = p.y < c[i].y; + // let c3 = e.x * w.y > e.y * w.x; + // let c = vec3(c1, c2, c3); + // if (all(c) || all(!c)) { s = -s; }; } return s * sqrt(d); } @@ -449,7 +449,7 @@ fn sdBlobbyCross(pos: vec2f, he: f32) -> f32 { } @compute @workgroup_size(16, 16) -fn main_image(@builtin(global_invocation_id) id: uint3) { +fn main_image(@builtin(global_invocation_id) id: vec3) { let screen_size = textureDimensions(screen); if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } let fragCoord = vec2f(f32(id.x) + .5, f32(screen_size.y - id.y) - .5); diff --git a/examples/demos/simple-storage.ts b/examples/demos/simple-storage.ts index 9b4f2c4..daa719f 100644 --- a/examples/demos/simple-storage.ts +++ b/examples/demos/simple-storage.ts @@ -43,20 +43,20 @@ export async function render( const computeWgsl = /* wgsl */ ` #import prelude::{screen} -@group(2) @binding(0) var stor1 : array; +@group(2) @binding(0) var stor1 : array; @compute @workgroup_size(16, 16) -fn pas(@builtin(global_invocation_id) id: uint3) { +fn pas(@builtin(global_invocation_id) id: vec3u) { let idx = id.y * textureDimensions(screen).x + id.x; - stor1[idx] = float(id.x) / float(textureDimensions(screen).x); + stor1[idx] = f32(id.x) / f32(textureDimensions(screen).x); } @compute @workgroup_size(16, 16) -fn main_image(@builtin(global_invocation_id) id: uint3) { +fn main_image(@builtin(global_invocation_id) id: vec3u) { let idx = id.y * textureDimensions(screen).x + id.x; let val = stor1[idx]; - let col = float3(val); - textureStore(screen, int2(id.xy), float4(col, 1.)); + let col = vec3f(val); + textureStore(screen, vec2i(id.xy), vec4f(col, 1.)); } `; diff --git a/examples/demos/simplex-noise.ts b/examples/demos/simplex-noise.ts index c9d8976..303c379 100644 --- a/examples/demos/simplex-noise.ts +++ b/examples/demos/simplex-noise.ts @@ -52,13 +52,13 @@ export async function render( // Simplex Noise 2D: https://www.shadertoy.com/view/Msf3WH -fn hash(p: float2) -> float2 // replace this by something better +fn hash(p: vec2f) -> vec2f // replace this by something better { - let p2 = float2( dot(p,float2(127.1,311.7)), dot(p,float2(269.5,183.3)) ); + let p2 = vec2f( dot(p,vec2f(127.1,311.7)), dot(p,vec2f(269.5,183.3)) ); return -1.0 + 2.0*fract(sin(p2)*43758.5453123); } -fn simplex2d(p: float2) -> float +fn simplex2d(p: vec2f) -> f32 { let K1 = 0.366025404; // (sqrt(3)-1)/2; let K2 = 0.211324865; // (3-sqrt(3))/6; @@ -67,19 +67,19 @@ fn simplex2d(p: float2) -> float let o = step(a.yx,a.xy); let b = a - o + K2; let c = a - 1.0 + 2.0*K2; - let h = max( 0.5-float3(dot(a,a), dot(b,b), dot(c,c) ), float3(0.) ); - let n = h*h*h*h*float3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0))); - return dot( n, float3(70.0) ); + let h = max( 0.5-vec3f(dot(a,a), dot(b,b), dot(c,c) ), vec3f(0.) ); + let n = h*h*h*h*vec3f( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0))); + return dot( n, vec3f(70.0) ); } // Simplex Noise 3D: https://www.shadertoy.com/view/XsX3zB /* discontinuous pseudorandom uniformly distributed in [-0.5, +0.5]^3 */ -fn random3(c: float3) -> float3 +fn random3(c: vec3f) -> vec3f { var j = 4096.0*sin(dot(c,vec3(17.0, 59.4, 15.0))); - var r = float3(0.); + var r = vec3f(0.); r.z = fract(512.0*j); j *= .125; r.x = fract(512.0*j); @@ -93,7 +93,7 @@ const F3 = 0.3333333; const G3 = 0.1666667; /* 3d simplex noise */ -fn simplex3d(p: float3) -> float +fn simplex3d(p: vec3f) -> f32 { /* 1. find current tetrahedron T and it's four vertices */ /* s, s+i1, s+i2, s+1.0 - absolute skewed (integer) coordinates of T vertices */ @@ -114,8 +114,8 @@ fn simplex3d(p: float3) -> float let x3 = x - 1.0 + 3.0*G3; /* 2. find four surflets and store them in d */ - var w = float4(0.); - var d = float4(0.); + var w = vec4f(0.); + var d = vec4f(0.); /* calculate surflet weights */ w.x = dot(x, x); @@ -124,7 +124,7 @@ fn simplex3d(p: float3) -> float w.w = dot(x3, x3); /* w fades from 0.6 at the center of the surflet to 0.0 at the margin */ - w = max(0.6 - w, float4(0.0)); + w = max(0.6 - w, vec4f(0.0)); /* calculate surflet components */ d.x = dot(random3(s), x); @@ -147,7 +147,7 @@ const rot2 = mat3x3(-0.55,-0.39, 0.74, 0.33,-0.91,-0.24,0.77, 0.12,0.63); const rot3 = mat3x3(-0.71, 0.52,-0.47,-0.08,-0.72,-0.68,-0.7,-0.45,0.56); /* directional artifacts can be reduced by rotating each octave */ -fn simplex3d_fractal(m: float3) -> float +fn simplex3d_fractal(m: vec3f) -> f32 { return 0.5333333*simplex3d(m*rot1) +0.2666667*simplex3d(2.0*m*rot2) @@ -156,15 +156,15 @@ fn simplex3d_fractal(m: float3) -> float } @compute @workgroup_size(16, 16) -fn main_image(@builtin(global_invocation_id) id: uint3) { - let screen_size = uint2(textureDimensions(screen)); +fn main_image(@builtin(global_invocation_id) id: vec3u) { + let screen_size = vec2u(textureDimensions(screen)); if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } - let fragCoord = float2(id.xy) + .5; - let resolution = float2(screen_size); + let fragCoord = vec2f(id.xy) + .5; + let resolution = vec2f(screen_size); let p = fragCoord / resolution.x; - let p3 = float3(p, time.elapsed*0.025); + let p3 = vec3f(p, time.elapsed*0.025); - var uv = p * float2(resolution.x / resolution.y, 1.) + time.elapsed * .25; + var uv = p * vec2f(resolution.x / resolution.y, 1.) + time.elapsed * .25; var f = 0.; if (p.x < .6) { // left: value noise //f = simplex2d( 16.0*uv ); @@ -182,7 +182,7 @@ fn main_image(@builtin(global_invocation_id) id: uint3) { f *= smoothstep( 0.0, 0.005, abs(p.x - 0.6) ); f = pow(f, 2.2); // perceptual gradient to linear colour space - textureStore(screen, int2(id.xy), float4(f, f, f, 1.)); + textureStore(screen, vec2i(id.xy), vec4f(f, f, f, 1.)); } `, diff --git a/examples/demos/stardust.ts b/examples/demos/stardust.ts index 9b699c4..1e29401 100644 --- a/examples/demos/stardust.ts +++ b/examples/demos/stardust.ts @@ -36,7 +36,7 @@ export async function render( const screen = device.createTexture({ // Use F32_RGBA - // @see https://www.w3.org/TR/webgpu/#float32-filterable + // @see https://www.w3.org/TR/webgpu/#vec3f2-filterable // @see https://github.com/compute-toys/wgpu-compute-toy/blob/master/src/bind.rs#L433 format: Format.F16_RGBA, width: $canvas.width, @@ -115,28 +115,28 @@ const DEPTH_MAX = 5.0; const DEPTH_BITS = 16u; -var bokehRad : float; +var bokehRad : f32; -fn SetCamera(ang: float2, fov: float) +fn SetCamera(ang: vec2f, fov: f32) { camera.fov = fov; camera.cam = GetCameraMatrix(ang); - camera.pos = - (camera.cam*float3(15.0*custom.Radius+0.5,0.0,0.0)); - camera.size = float2(textureDimensions(screen)); + camera.pos = - (camera.cam*vec3f(15.0*custom.Radius+0.5,0.0,0.0)); + camera.size = vec2f(textureDimensions(screen)); } -fn ForceField(pos: float3, t: float) -> float4 +fn ForceField(pos: vec3f, t: f32) -> vec4f { - let a0 = float3(sin(t),cos(0.4*t),cos(t)); + let a0 = vec3f(sin(t),cos(0.4*t),cos(t)); let d = distance(pos, a0); let F = (a0 - pos)*(1.0/(d*d*d + 1e-3) - 0.4/(d*d*d*d + 1e-3)) + 1e-3; - return 0.2*float4(F, 0.0); + return 0.2*vec4f(F, 0.0); } @compute @workgroup_size(16, 16) -fn SimulateParticles(@builtin(global_invocation_id) id: uint3) +fn SimulateParticles(@builtin(global_invocation_id) id: vec3u) { - var pix = int2(id.xy); + var pix = vec2i(id.xy); var p = LoadParticle(pix); if(pix.x > PARTICLE_COUNT || pix.y > PARTICLE_COUNT) @@ -144,15 +144,15 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) return; } - state = uint4(id.x, id.y, id.z, time.frame); + state = vec4u(id.x, id.y, id.z, time.frame); if(time.frame == 0u) { let rng = rand4(); - p.position = float4(2.0*rng.xyz - 1.0, 0.0); - p.velocity = float4(0.0,0.0,0.0,0.0); + p.position = vec4f(2.0*rng.xyz - 1.0, 0.0); + p.velocity = vec4f(0.0,0.0,0.0,0.0); } - let t = fract(custom.Speed*float(time.frame)/800.0)*30.0; + let t = fract(custom.Speed*f32(time.frame)/800.0)*30.0; // if(mouse.click == 1) // { @@ -172,9 +172,9 @@ fn SimulateParticles(@builtin(global_invocation_id) id: uint3) } @compute @workgroup_size(16, 16) -fn Clear(@builtin(global_invocation_id) id: uint3) { - let screen_size = int2(textureDimensions(screen)); - let idx0 = int(id.x) + int(screen_size.x * int(id.y)); +fn Clear(@builtin(global_invocation_id) id: vec3u) { + let screen_size = vec2i(textureDimensions(screen)); + let idx0 = i32(id.x) + i32(screen_size.x * i32(id.y)); atomicStore(&atomic_storage[idx0*4+0], 0); atomicStore(&atomic_storage[idx0*4+1], 0); @@ -183,18 +183,18 @@ fn Clear(@builtin(global_invocation_id) id: uint3) { } @compute @workgroup_size(16, 16) -fn Rasterize(@builtin(global_invocation_id) id: uint3) { +fn Rasterize(@builtin(global_invocation_id) id: vec3u) { // Viewport resolution (in pixels) - let screen_size = int2(textureDimensions(screen)); - let screen_size_f = float2(screen_size); + let screen_size = vec2i(textureDimensions(screen)); + let screen_size_f = vec2f(screen_size); - let ang = float2(-TWO_PI, PI)/screen_size_f + 1e-4; - // let ang = float2(mouse.pos.xy)*float2(-TWO_PI, PI)/screen_size_f + 1e-4; + let ang = vec2f(-TWO_PI, PI)/screen_size_f + 1e-4; + // let ang = vec2f(mouse.pos.xy)*vec2f(-TWO_PI, PI)/screen_size_f + 1e-4; SetCamera(ang, FOV); //RNG state - state = uint4(id.x, id.y, id.z, 0u); + state = vec4u(id.x, id.y, id.z, 0u); let rng = rand4(); bokehRad = pow(rng.x, custom.BlurExponentA); @@ -204,7 +204,7 @@ fn Rasterize(@builtin(global_invocation_id) id: uint3) { // state.w = time.frame; // } - var pix = int2(id.xy); + var pix = vec2i(id.xy); if(pix.x > PARTICLE_COUNT || pix.y > PARTICLE_COUNT) { @@ -217,52 +217,52 @@ fn Rasterize(@builtin(global_invocation_id) id: uint3) { var col = 5.5*abs(p.velocity.xyz)*dot(p.velocity,p.velocity)+0.1; col /= (0.1+bokehRad); let impSample = (col.x + col.y + col.z)*bokehRad; - let sampleCount = clamp(int(impSample*custom.Samples*MaxSamples + 1.0), 1, 1024); - let normalCount = int(custom.Samples*MaxSamples + 1.0); + let sampleCount = clamp(i32(impSample*custom.Samples*MaxSamples + 1.0), 1, 1024); + let normalCount = i32(custom.Samples*MaxSamples + 1.0); - col *= float(normalCount)/float(sampleCount); + col *= f32(normalCount)/f32(sampleCount); for(var i = 0; i < sampleCount; i++) { let R = 2.0*custom.BlurRadius*bokehRad; let rng = rand4(); - let dpos = R*normalize(nrand4(1.0, float4(0.0)).xyz)*pow(rng.x, custom.BlurExponentB); + let dpos = R*normalize(nrand4(1.0, vec4f(0.0)).xyz)*pow(rng.x, custom.BlurExponentB); RasterizePoint(pos + dpos, col); } } -fn Sample(pos: int2) -> float3 +fn Sample(pos: vec2i) -> vec3f { - let screen_size = int2(textureDimensions(screen)); + let screen_size = vec2i(textureDimensions(screen)); let idx = pos.x + screen_size.x * pos.y; - var color: float3; - let x = float(atomicLoad(&atomic_storage[idx*4+0]))/(256.0); - let y = float(atomicLoad(&atomic_storage[idx*4+1]))/(256.0); - let z = float(atomicLoad(&atomic_storage[idx*4+2]))/(256.0); + var color: vec3f; + let x = f32(atomicLoad(&atomic_storage[idx*4+0]))/(256.0); + let y = f32(atomicLoad(&atomic_storage[idx*4+1]))/(256.0); + let z = f32(atomicLoad(&atomic_storage[idx*4+2]))/(256.0); color = tanh( - custom.Exposure * 0.03 * float(screen_size.y) * float3(x,y,z) + custom.Exposure * 0.03 * f32(screen_size.y) * vec3f(x,y,z) / (custom.Samples * MaxSamples + 1.0)); return abs(color); } @compute @workgroup_size(16, 16) -fn main_image(@builtin(global_invocation_id) id: uint3) +fn main_image(@builtin(global_invocation_id) id: vec3u) { - let screen_size = uint2(textureDimensions(screen)); + let screen_size = vec2u(textureDimensions(screen)); // Prevent overdraw for workgroups on the edge of the viewport if (id.x >= screen_size.x || id.y >= screen_size.y) { return; } // Pixel coordinates (centre of pixel, origin at bottom left) - let fragCoord = float2(float(id.x) + .5, float(id.y) + .5); + let fragCoord = vec2f(f32(id.x) + .5, f32(id.y) + .5); - var color = float4(Sample(int2(id.xy)),1.0); + var color = vec4f(Sample(vec2i(id.xy)),1.0); - let oldColor = textureLoad(pass_in, int2(id.xy), 2, 0); + let oldColor = textureLoad(pass_in, vec2i(id.xy), 2, 0); // if(mouse.click == 1 && custom.AnimatedNoise > 0.5) // { @@ -270,9 +270,9 @@ fn main_image(@builtin(global_invocation_id) id: uint3) // } // Output to buffer - textureStore(pass_out, int2(id.xy), 2, color); + textureStore(pass_out, vec2i(id.xy), 2, color); - textureStore(screen, int2(id.xy), float4(color.xyz/color.w, 1.)); + textureStore(screen, vec2i(id.xy), vec4f(color.xyz/color.w, 1.)); } `; diff --git a/examples/public/glsl_wgsl_compiler_bg.wasm b/examples/public/glsl_wgsl_compiler_bg.wasm index dbccb88..6f027b2 100644 Binary files a/examples/public/glsl_wgsl_compiler_bg.wasm and b/examples/public/glsl_wgsl_compiler_bg.wasm differ diff --git a/examples/utils/compute-toys.ts b/examples/utils/compute-toys.ts index b06a695..b422fdb 100644 --- a/examples/utils/compute-toys.ts +++ b/examples/utils/compute-toys.ts @@ -14,7 +14,7 @@ import { */ export function registerShaderModule(device: Device, shader: string): string { const compiler = device['WGSLComposer']; - return compiler.wgsl_compile(alias + shader); + return compiler.load_composable(alias + shader); } export function defineStr(k: string, v: string): string { @@ -49,31 +49,32 @@ export function createProgram( return device.createProgram(desc); } +// We cannot use alias for now. @see https://github.com/bevyengine/naga_oil/issues/79 export const alias = /* wgsl */ ` -alias int = i32; -alias uint = u32; -alias float = f32; -alias int2 = vec2; -alias int3 = vec3; -alias int4 = vec4; -alias uint2 = vec2; -alias uint3 = vec3; -alias uint4 = vec4; -alias float2 = vec2; -alias float3 = vec3; -alias float4 = vec4; -alias bool2 = vec2; -alias bool3 = vec3; -alias bool4 = vec4; -alias float2x2 = mat2x2; -alias float2x3 = mat2x3; -alias float2x4 = mat2x4; -alias float3x2 = mat3x2; -alias float3x3 = mat3x3; -alias float3x4 = mat3x4; -alias float4x2 = mat4x2; -alias float4x3 = mat4x3; -alias float4x4 = mat4x4; +// alias int = i32; +// alias uint = u32; +// alias float = f32; +// alias int2 = vec2; +// alias int3 = vec3; +// alias int4 = vec4; +// alias uint2 = vec2; +// alias uint3 = vec3; +// alias uint4 = vec4; +// alias float2 = vec2; +// alias float3 = vec3; +// alias float4 = vec4; +// alias bool2 = vec2; +// alias bool3 = vec3; +// alias bool4 = vec4; +// alias float2x2 = mat2x2; +// alias float2x3 = mat2x3; +// alias float2x4 = mat2x4; +// alias float3x2 = mat3x2; +// alias float3x3 = mat3x3; +// alias float3x4 = mat3x4; +// alias float4x2 = mat4x2; +// alias float4x3 = mat4x3; +// alias float4x4 = mat4x4; `; /** @@ -89,8 +90,8 @@ struct Time { } struct Mouse { - pos: uint2, - click: int + pos: vec2, + click: i32 } @group(0) @binding(0) var time : Time; @@ -100,15 +101,15 @@ struct Mouse { @group(3) @binding(0) var screen : texture_storage_2d; @group(3) @binding(1) var pass_out: texture_storage_2d_array; -fn passStore(pass_index: int, coord: int2, value: float4) { +fn passStore(pass_index: i32, coord: vec2, value: vec4) { textureStore(pass_out, coord, pass_index, value); } -fn passLoad(pass_index: int, coord: int2, lod: int) -> float4 { +fn passLoad(pass_index: i32, coord: vec2, lod: i32) -> vec4 { return textureLoad(pass_in, coord, pass_index, lod); } -fn passSampleLevelBilinearRepeat(pass_index: int, uv: float2, lod: float) -> float4 { +fn passSampleLevelBilinearRepeat(pass_index: i32, uv: vec2, lod: f32) -> vec4 { return textureSampleLevel(pass_in, bilinear, fract(uv), pass_index, lod); } `; @@ -237,43 +238,43 @@ export const math = /* wgsl */ ` const PI = 3.14159265; const TWO_PI = 6.28318530718; -var state : uint4; +var state : vec4; -fn pcg4d(a: uint4) -> uint4 +fn pcg4d(a: vec4) -> vec4 { var v = a * 1664525u + 1013904223u; v.x += v.y*v.w; v.y += v.z*v.x; v.z += v.x*v.y; v.w += v.y*v.z; - v = v ^ ( v >> uint4(16u) ); + v = v ^ ( v >> vec4(16u) ); v.x += v.y*v.w; v.y += v.z*v.x; v.z += v.x*v.y; v.w += v.y*v.z; return v; } -fn rand4() -> float4 +fn rand4() -> vec4 { state = pcg4d(state); - return float4(state)/float(0xffffffffu); + return vec4(state)/f32(0xffffffffu); } -fn nrand4(sigma: float, mean: float4) -> float4 +fn nrand4(sigma: f32, mean: vec4) -> vec4 { let Z = rand4(); return mean + sigma * sqrt(-2.0 * log(Z.xxyy)) * - float4(cos(TWO_PI * Z.z),sin(TWO_PI * Z.z),cos(TWO_PI * Z.w),sin(TWO_PI * Z.w)); + vec4(cos(TWO_PI * Z.z),sin(TWO_PI * Z.z),cos(TWO_PI * Z.w),sin(TWO_PI * Z.w)); } -fn disk(r: float2) -> float2 +fn disk(r: vec2) -> vec2 { return vec2(sin(TWO_PI*r.x), cos(TWO_PI*r.x))*(r.y); } -fn sqr(x: float) -> float +fn sqr(x: f32) -> f32 { return x*x; } -fn diag(a: float4) -> float4x4 +fn diag(a: vec4) -> mat4x4 { - return float4x4( + return mat4x4( a.x,0.0,0.0,0.0, 0.0,a.y,0.0,0.0, 0.0,0.0,a.z,0.0, @@ -281,9 +282,9 @@ fn diag(a: float4) -> float4x4 ); } -fn rand4s(seed: uint4) -> float4 +fn rand4s(seed: vec4) -> vec4 { - return float4(pcg4d(seed))/float(0xffffffffu); + return vec4(pcg4d(seed))/f32(0xffffffffu); } `; @@ -292,29 +293,29 @@ export const camera = /* wgsl */ ` struct Camera { - pos: float3, - cam: float3x3, - fov: float, - size: float2 + pos: vec3, + cam: mat3x3, + fov: f32, + size: vec2 } var camera : Camera; -fn GetCameraMatrix(ang: float2) -> float3x3 +fn GetCameraMatrix(ang: vec2) -> mat3x3 { - let x_dir = float3(cos(ang.x)*sin(ang.y), cos(ang.y), sin(ang.x)*sin(ang.y)); - let y_dir = normalize(cross(x_dir, float3(0.0,1.0,0.0))); + let x_dir = vec3(cos(ang.x)*sin(ang.y), cos(ang.y), sin(ang.x)*sin(ang.y)); + let y_dir = normalize(cross(x_dir, vec3(0.0,1.0,0.0))); let z_dir = normalize(cross(y_dir, x_dir)); - return float3x3(-x_dir, y_dir, z_dir); + return mat3x3(-x_dir, y_dir, z_dir); } //project to clip space -fn Project(cam: Camera, p: float3) -> float3 +fn Project(cam: Camera, p: vec3) -> vec3 { let td = distance(cam.pos, p); let dir = (p - cam.pos)/td; let screen = dir*cam.cam; - return float3(screen.yz*cam.size.y/(cam.fov*screen.x) + 0.5*cam.size,screen.x*td); + return vec3(screen.yz*cam.size.y/(cam.fov*screen.x) + 0.5*cam.size,screen.x*td); } `; @@ -326,27 +327,27 @@ export const particle = /* wgsl */ ` struct Particle { - position: float4, - velocity: float4, + position: vec4, + velocity: vec4, } @group(2) @binding(0) var atomic_storage : array>; -fn AdditiveBlend(color: float3, depth: float, index: int) +fn AdditiveBlend(color: vec3, depth: f32, index: i32) { let scaledColor = 256.0 * color/depth; - atomicAdd(&atomic_storage[index*4+0], int(scaledColor.x)); - atomicAdd(&atomic_storage[index*4+1], int(scaledColor.y)); - atomicAdd(&atomic_storage[index*4+2], int(scaledColor.z)); + atomicAdd(&atomic_storage[index*4+0], i32(scaledColor.x)); + atomicAdd(&atomic_storage[index*4+1], i32(scaledColor.y)); + atomicAdd(&atomic_storage[index*4+2], i32(scaledColor.z)); } -fn RasterizePoint(pos: float3, color: float3) +fn RasterizePoint(pos: vec3, color: vec3) { - let screen_size = int2(camera.size); + let screen_size = vec2(camera.size); let projectedPos = Project(camera, pos); - let screenCoord = int2(projectedPos.xy); + let screenCoord = vec2(projectedPos.xy); //outside of our view if(screenCoord.x < 0 || screenCoord.x >= screen_size.x || @@ -360,7 +361,7 @@ fn RasterizePoint(pos: float3, color: float3) AdditiveBlend(color, projectedPos.z, idx); } -fn LoadParticle(pix: int2) -> Particle +fn LoadParticle(pix: vec2) -> Particle { var p: Particle; p.position = textureLoad(pass_in, pix, 0, 0); @@ -368,7 +369,7 @@ fn LoadParticle(pix: int2) -> Particle return p; } -fn SaveParticle(pix: int2, p: Particle) +fn SaveParticle(pix: vec2, p: Particle) { textureStore(pass_out, pix, 0, p.position); textureStore(pass_out, pix, 1, p.velocity); diff --git a/package.json b/package.json index a5d9df9..4250d5b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-device-api", - "version": "1.6.5", + "version": "1.6.6", "description": "A Device API references WebGPU implementations", "keywords": [ "antv", diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 0e15c9e..e80c1fc 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -146,9 +146,9 @@ checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" [[package]] name = "naga" -version = "0.14.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cd05939c491da968a42986204b7431678be21fdcd4b10cc84997ba130ada5a4" +checksum = "50e3524642f53d9af419ab5e8dd29d3ba155708267667c2f3f06c88c9e130843" dependencies = [ "bit-set", "bitflags", @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "naga_oil" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff3f369dd665ee365daeab786466a6f70ff53e4a95a76117363b1077e1b0492" +checksum = "c0ea62ae0f2787456afca7209ca180522b41f00cbe159ee369eba1e07d365cd1" dependencies = [ "bit-set", "codespan-reporting", @@ -177,7 +177,7 @@ dependencies = [ "naga", "once_cell", "regex", - "regex-syntax 0.7.5", + "regex-syntax", "rustc-hash", "thiserror", "tracing", @@ -216,18 +216,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -241,7 +241,7 @@ dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] @@ -252,15 +252,9 @@ checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - [[package]] name = "regex-syntax" version = "0.8.2" @@ -275,9 +269,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "syn" -version = "2.0.31" +version = "2.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" dependencies = [ "proc-macro2", "quote", @@ -286,27 +280,27 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 391163a..0d2f6aa 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -13,8 +13,8 @@ crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2.79" wee_alloc = { version = "0.4.5", optional = true } -naga = { version = "0.14.1", features = ["glsl-in", "wgsl-in", "wgsl-out"] } -naga_oil = "0.11.0" +naga = { version = "0.19.2", features = ["glsl-in", "wgsl-in", "wgsl-out"] } +naga_oil = "0.13.0" [dependencies.web-sys] version = "0.3.4" diff --git a/rust/pkg/.gitignore b/rust/pkg/.gitignore index e69de29..f59ec20 100644 --- a/rust/pkg/.gitignore +++ b/rust/pkg/.gitignore @@ -0,0 +1 @@ +* \ No newline at end of file diff --git a/rust/pkg/glsl_wgsl_compiler.d.ts b/rust/pkg/glsl_wgsl_compiler.d.ts index 6b4883f..54c3a14 100644 --- a/rust/pkg/glsl_wgsl_compiler.d.ts +++ b/rust/pkg/glsl_wgsl_compiler.d.ts @@ -16,6 +16,10 @@ export class WGSLComposer { constructor(); /** * @param {string} source +*/ + load_composable(source: string): void; +/** +* @param {string} source * @returns {string} */ wgsl_compile(source: string): string; @@ -27,11 +31,12 @@ export interface InitOutput { readonly memory: WebAssembly.Memory; readonly __wbg_wgslcomposer_free: (a: number) => void; readonly wgslcomposer_new: () => number; + readonly wgslcomposer_load_composable: (a: number, b: number, c: number) => void; readonly wgslcomposer_wgsl_compile: (a: number, b: number, c: number, d: number) => void; readonly glsl_compile: (a: number, b: number, c: number, d: number, e: number, f: number) => void; - readonly __wbindgen_add_to_stack_pointer: (a: number) => number; readonly __wbindgen_malloc: (a: number, b: number) => number; readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; + readonly __wbindgen_add_to_stack_pointer: (a: number) => number; readonly __wbindgen_free: (a: number, b: number, c: number) => void; } diff --git a/rust/pkg/glsl_wgsl_compiler.js b/rust/pkg/glsl_wgsl_compiler.js index c185199..cead55f 100644 --- a/rust/pkg/glsl_wgsl_compiler.js +++ b/rust/pkg/glsl_wgsl_compiler.js @@ -193,6 +193,18 @@ export class WGSLComposer { const ret = wasm.wgslcomposer_new(); return WGSLComposer.__wrap(ret); } + /** + * @param {string} source + */ + load_composable(source) { + const ptr0 = passStringToWasm0( + source, + wasm.__wbindgen_malloc, + wasm.__wbindgen_realloc, + ); + const len0 = WASM_VECTOR_LEN; + wasm.wgslcomposer_load_composable(this.__wbg_ptr, ptr0, len0); + } /** * @param {string} source * @returns {string} diff --git a/rust/pkg/glsl_wgsl_compiler_bg.wasm b/rust/pkg/glsl_wgsl_compiler_bg.wasm index 95dd637..6f027b2 100644 Binary files a/rust/pkg/glsl_wgsl_compiler_bg.wasm and b/rust/pkg/glsl_wgsl_compiler_bg.wasm differ diff --git a/rust/pkg/glsl_wgsl_compiler_bg.wasm.d.ts b/rust/pkg/glsl_wgsl_compiler_bg.wasm.d.ts index ebda879..3c52a29 100644 --- a/rust/pkg/glsl_wgsl_compiler_bg.wasm.d.ts +++ b/rust/pkg/glsl_wgsl_compiler_bg.wasm.d.ts @@ -3,9 +3,10 @@ export const memory: WebAssembly.Memory; export function __wbg_wgslcomposer_free(a: number): void; export function wgslcomposer_new(): number; +export function wgslcomposer_load_composable(a: number, b: number, c: number): void; export function wgslcomposer_wgsl_compile(a: number, b: number, c: number, d: number): void; export function glsl_compile(a: number, b: number, c: number, d: number, e: number, f: number): void; -export function __wbindgen_add_to_stack_pointer(a: number): number; export function __wbindgen_malloc(a: number, b: number): number; export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number; +export function __wbindgen_add_to_stack_pointer(a: number): number; export function __wbindgen_free(a: number, b: number, c: number): void; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 5adeec6..ede2173 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -27,20 +27,34 @@ impl WGSLComposer { } } - pub fn wgsl_compile(&mut self, source: &str) -> String { - self.composer.add_composable_module( + pub fn load_composable(&mut self, source: &str) { + match self.composer.add_composable_module( ComposableModuleDescriptor { source: &source, ..Default::default() } - ); + ) { + Ok(v) => v, + Err(e) => { + show_error(&"add_composable_module", e); + panic!(); + } + }; + } - let module = self.composer.make_naga_module( + pub fn wgsl_compile(&mut self, source: &str) -> String { + let module = match self.composer.make_naga_module( NagaModuleDescriptor { source: &source, ..Default::default() }, - ).unwrap(); + ) { + Ok(v) => v, + Err(e) => { + show_error(&"make_naga_module", e); + panic!(); + } + }; let info = match naga::valid::Validator::new(naga::valid::ValidationFlags::all(), naga::valid::Capabilities::all()) .validate(&module)