Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e5068dd
Tracking referentiality
iwoplaza Sep 26, 2025
c5189be
More progress on the implementation
iwoplaza Sep 27, 2025
eb8f520
Mostly works now
iwoplaza Sep 27, 2025
5312d1d
Track ref address space
iwoplaza Sep 27, 2025
52124a7
Enforcing copy when assigning
iwoplaza Sep 27, 2025
07ed411
JS const with ref value is WGSL let with pointer
iwoplaza Sep 27, 2025
ba2a4ff
Fix ptr return types, and invalid ref and deref op order
iwoplaza Sep 27, 2025
7b7e5dc
Const statements
iwoplaza Sep 27, 2025
9a75b1e
Not allowing references to be returned from a function (unless it's a
iwoplaza Sep 27, 2025
5dc3884
Move member access exceptions to `accessProp` so that it's shared with
iwoplaza Sep 27, 2025
755d13b
Better indexing
iwoplaza Sep 27, 2025
ec2657f
Indexing arrays at comptime
iwoplaza Sep 27, 2025
8497a35
Constant tracking
iwoplaza Sep 27, 2025
cc349ff
Infix
iwoplaza Sep 27, 2025
77ac0cc
Apply formatting
iwoplaza Sep 27, 2025
04fa183
Merge branch 'main' into feat/ref-value
iwoplaza Oct 7, 2025
aee85a6
A few tweaks
iwoplaza Oct 7, 2025
5173502
Update wgslGenerator.ts
iwoplaza Oct 7, 2025
c3bf598
Fixes
iwoplaza Oct 7, 2025
40b3f7a
Self review
iwoplaza Oct 7, 2025
7c5900b
Update accessor.ts
iwoplaza Oct 7, 2025
50741ce
More tweaks
iwoplaza Oct 7, 2025
4dff99e
Merge branch 'main' into feat/ref-value
iwoplaza Oct 7, 2025
51c2919
Apply suggestion from @aleksanderkatan
iwoplaza Oct 8, 2025
b035d45
Apply suggestion from @aleksanderkatan
iwoplaza Oct 8, 2025
3932b2f
Update stable-fluid.test.ts
iwoplaza Oct 9, 2025
62936f8
Simplify 3D Fish compute
iwoplaza Oct 9, 2025
14c7282
Update compute.ts
iwoplaza Oct 9, 2025
e90832d
Review fixes
iwoplaza Oct 9, 2025
549bc71
Merge branch 'main' into feat/ref-value
iwoplaza Oct 10, 2025
e3b3bba
Merge branch 'main' into feat/ref-value
iwoplaza Oct 13, 2025
1e2df56
Updates after changing 'kernel' to 'use gpu'
iwoplaza Oct 13, 2025
bbc0508
feat: Better constant handling for ref/value tracking (#1801)
iwoplaza Oct 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 31 additions & 57 deletions apps/typegpu-docs/src/examples/rendering/3d-fish/compute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,15 @@ import tgpu from 'typegpu';
import * as d from 'typegpu/data';
import * as std from 'typegpu/std';
import * as p from './params.ts';
import { computeBindGroupLayout as layout, ModelData } from './schemas.ts';
import { computeBindGroupLayout as layout } from './schemas.ts';
import { projectPointOnLine } from './tgsl-helpers.ts';

export const computeShader = tgpu['~unstable'].computeFn({
in: { gid: d.builtin.globalInvocationId },
workgroupSize: [p.workGroupSize],
})((input) => {
const fishIndex = input.gid.x;
// TODO: replace it with struct copy when Chromium is fixed
const fishData = ModelData({
position: layout.$.currentFishData[fishIndex].position,
direction: layout.$.currentFishData[fishIndex].direction,
scale: layout.$.currentFishData[fishIndex].scale,
variant: layout.$.currentFishData[fishIndex].variant,
applySeaDesaturation:
layout.$.currentFishData[fishIndex].applySeaDesaturation,
applySeaFog: layout.$.currentFishData[fishIndex].applySeaFog,
applySinWave: layout.$.currentFishData[fishIndex].applySinWave,
});
const fishData = layout.$.currentFishData[fishIndex];
let separation = d.vec3f();
let alignment = d.vec3f();
let alignmentCount = 0;
Expand All @@ -34,34 +24,22 @@ export const computeShader = tgpu['~unstable'].computeFn({
continue;
}

// TODO: replace it with struct copy when Chromium is fixed
const other = ModelData({
position: layout.$.currentFishData[i].position,
direction: layout.$.currentFishData[i].direction,
scale: layout.$.currentFishData[i].scale,
variant: layout.$.currentFishData[i].variant,
applySeaDesaturation: layout.$.currentFishData[i].applySeaDesaturation,
applySeaFog: layout.$.currentFishData[i].applySeaFog,
applySinWave: layout.$.currentFishData[i].applySinWave,
});
const dist = std.length(std.sub(fishData.position, other.position));
const other = layout.$.currentFishData[i];
const dist = std.length(fishData.position.sub(other.position));
if (dist < layout.$.fishBehavior.separationDist) {
separation = std.add(
separation,
std.sub(fishData.position, other.position),
);
separation = separation.add(fishData.position.sub(other.position));
}
if (dist < layout.$.fishBehavior.alignmentDist) {
alignment = std.add(alignment, other.direction);
alignment = alignment.add(other.direction);
alignmentCount = alignmentCount + 1;
}
if (dist < layout.$.fishBehavior.cohesionDist) {
cohesion = std.add(cohesion, other.position);
cohesion = cohesion.add(other.position);
cohesionCount = cohesionCount + 1;
}
}
if (alignmentCount > 0) {
alignment = std.mul(1 / d.f32(alignmentCount), alignment);
alignment = alignment.mul(1 / d.f32(alignmentCount));
}
if (cohesionCount > 0) {
cohesion = std.sub(
Expand All @@ -79,12 +57,12 @@ export const computeShader = tgpu['~unstable'].computeFn({

if (axisPosition > axisAquariumSize - distance) {
const str = axisPosition - (axisAquariumSize - distance);
wallRepulsion = std.sub(wallRepulsion, std.mul(str, repulsion));
wallRepulsion = wallRepulsion.sub(repulsion.mul(str));
}

if (axisPosition < -axisAquariumSize + distance) {
const str = -axisAquariumSize + distance - axisPosition;
wallRepulsion = std.add(wallRepulsion, std.mul(str, repulsion));
wallRepulsion = wallRepulsion.add(repulsion.mul(str));
}
}

Expand All @@ -93,42 +71,38 @@ export const computeShader = tgpu['~unstable'].computeFn({
fishData.position,
layout.$.mouseRay.line,
);
const diff = std.sub(fishData.position, proj);
const diff = fishData.position.sub(proj);
const limit = p.fishMouseRayRepulsionDistance;
const str = std.pow(2, std.clamp(limit - std.length(diff), 0, limit)) - 1;
rayRepulsion = std.mul(str, std.normalize(diff));
rayRepulsion = std.normalize(diff).mul(str);
}

fishData.direction = std.add(
fishData.direction,
std.mul(layout.$.fishBehavior.separationStr, separation),
let direction = d.vec3f(fishData.direction);

direction = direction.add(
separation.mul(layout.$.fishBehavior.separationStr),
);
fishData.direction = std.add(
fishData.direction,
std.mul(layout.$.fishBehavior.alignmentStr, alignment),
direction = direction.add(
alignment.mul(layout.$.fishBehavior.alignmentStr),
);
fishData.direction = std.add(
fishData.direction,
std.mul(layout.$.fishBehavior.cohesionStr, cohesion),
direction = direction.add(
cohesion.mul(layout.$.fishBehavior.cohesionStr),
);
fishData.direction = std.add(
fishData.direction,
std.mul(p.fishWallRepulsionStrength, wallRepulsion),
direction = direction.add(
wallRepulsion.mul(p.fishWallRepulsionStrength),
);
fishData.direction = std.add(
fishData.direction,
std.mul(p.fishMouseRayRepulsionStrength, rayRepulsion),
direction = direction.add(
rayRepulsion.mul(p.fishMouseRayRepulsionStrength),
);

fishData.direction = std.mul(
std.clamp(std.length(fishData.direction), 0.0, 0.01),
std.normalize(fishData.direction),
direction = std.normalize(direction).mul(
std.clamp(std.length(fishData.direction), 0, 0.01),
);

const translation = std.mul(
const translation = direction.mul(
d.f32(std.min(999, layout.$.timePassed)) / 8,
fishData.direction,
);
fishData.position = std.add(fishData.position, translation);
layout.$.nextFishData[fishIndex] = fishData;

const nextFishData = layout.$.nextFishData[fishIndex];
nextFishData.position = fishData.position.add(translation);
nextFishData.direction = d.vec3f(direction);
});
4 changes: 2 additions & 2 deletions apps/typegpu-docs/src/examples/rendering/3d-fish/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ const randomizeFishPositionsOnGPU = prepareDispatch(root, (x) => {
applySeaFog: 1,
applySeaDesaturation: 1,
});
buffer0mutable.$[x] = data;
buffer1mutable.$[x] = data;
buffer0mutable.$[x] = ModelData(data);
buffer1mutable.$[x] = ModelData(data);
});

const randomizeFishPositions = () => {
Expand Down
4 changes: 2 additions & 2 deletions apps/typegpu-docs/src/examples/rendering/3d-fish/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export const fragmentShader = tgpu['~unstable'].fragmentFn({
std.sub(layout.$.camera.position.xyz, input.worldPosition),
);

let desaturatedColor = lightedColor;
let desaturatedColor = d.vec3f(lightedColor);
if (input.applySeaDesaturation === 1) {
const desaturationFactor = -std.atan2((distanceFromCamera - 5) / 10, 1) /
3;
Expand All @@ -147,7 +147,7 @@ export const fragmentShader = tgpu['~unstable'].fragmentFn({
desaturatedColor = hsvToRgb(hsv);
}

let foggedColor = desaturatedColor;
let foggedColor = d.vec3f(desaturatedColor);
if (input.applySeaFog === 1) {
const fogParameter = std.max(0, (distanceFromCamera - 1.5) * 0.2);
const fogFactor = fogParameter / (1 + fogParameter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export class IcosphereGenerator {
in: { gid: d.builtin.globalInvocationId },
workgroupSize: [WORKGROUP_SIZE, 1, 1],
})((input) => {
const triangleCount = d.u32(std.arrayLength(prevVertices.value) / 3);
const triangleCount = d.u32(prevVertices.$.length / 3);
const triangleIndex = input.gid.x + input.gid.y * MAX_DISPATCH;
if (triangleIndex >= triangleCount) {
return;
Expand All @@ -142,13 +142,13 @@ export class IcosphereGenerator {
const baseIndexPrev = triangleIndex * 3;

const v1 = unpackVec2u(
prevVertices.value[baseIndexPrev].position,
prevVertices.$[baseIndexPrev].position,
);
const v2 = unpackVec2u(
prevVertices.value[baseIndexPrev + 1].position,
prevVertices.$[baseIndexPrev + 1].position,
);
const v3 = unpackVec2u(
prevVertices.value[baseIndexPrev + 2].position,
prevVertices.$[baseIndexPrev + 2].position,
);

const v12 = d.vec4f(
Expand Down Expand Up @@ -188,8 +188,8 @@ export class IcosphereGenerator {
const reprojectedVertex = newVertices[i];

const triBase = i - (i % 3);
let normal = reprojectedVertex;
if (smoothFlag.value === 0) {
let normal = d.vec4f(reprojectedVertex);
if (smoothFlag.$ === 0) {
normal = getAverageNormal(
newVertices[triBase],
newVertices[triBase + 1],
Expand All @@ -198,12 +198,12 @@ export class IcosphereGenerator {
}

const outIndex = baseIndexNext + i;
const nextVertex = nextVertices.value[outIndex];
const nextVertex = nextVertices.$[outIndex];

nextVertex.position = packVec2u(reprojectedVertex);
nextVertex.normal = packVec2u(normal);

nextVertices.value[outIndex] = nextVertex;
nextVertices.$[outIndex] = ComputeVertex(nextVertex);
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export const mainFragment4 = tgpu['~unstable'].fragmentFn({
std.abs(std.fract(aspectUv.x * 1.2) - 0.5),
std.abs(std.fract(aspectUv.y * 1.2) - 0.5),
).mul(2).sub(1);
aspectUv = mirroredUv;
aspectUv = d.vec2f(mirroredUv);
const originalUv = aspectUv;
let accumulatedColor = d.vec3f(0, 0, 0);
const time = timeAccess.$;
Expand Down
18 changes: 9 additions & 9 deletions apps/typegpu-docs/src/examples/rendering/ray-marching/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,13 @@ const rayMarch = (ro: d.v3f, rd: d.v3f): Shape => {
});

for (let i = 0; i < MAX_STEPS; i++) {
const p = std.add(ro, std.mul(rd, dO));
const p = ro.add(rd.mul(dO));
const scene = getSceneDist(p);
dO += scene.dist;

if (dO > MAX_DIST || scene.dist < SURF_DIST) {
result.dist = dO;
result.color = scene.color;
result.color = d.vec3f(scene.color);
break;
}
}
Expand All @@ -154,7 +154,7 @@ const softShadow = (

for (let i = 0; i < 100; i++) {
if (t >= maxT) break;
const h = getSceneDist(std.add(ro, std.mul(rd, t))).dist;
const h = getSceneDist(ro.add(rd.mul(t))).dist;
if (h < 0.001) return 0;
res = std.min(res, k * h / t);
t += std.max(h, 0.001);
Expand All @@ -169,9 +169,9 @@ const getNormal = (p: d.v3f): d.v3f => {
const e = 0.01;

const n = d.vec3f(
getSceneDist(std.add(p, d.vec3f(e, 0, 0))).dist - dist,
getSceneDist(std.add(p, d.vec3f(0, e, 0))).dist - dist,
getSceneDist(std.add(p, d.vec3f(0, 0, e))).dist - dist,
getSceneDist(p.add(d.vec3f(e, 0, 0))).dist - dist,
getSceneDist(p.add(d.vec3f(0, e, 0))).dist - dist,
getSceneDist(p.add(d.vec3f(0, 0, e))).dist - dist,
);

return std.normalize(n);
Expand Down Expand Up @@ -223,17 +223,17 @@ const fragmentMain = tgpu['~unstable'].fragmentFn({

// Lighting with orbiting light
const lightPos = getOrbitingLightPos(time.$);
const l = std.normalize(std.sub(lightPos, p));
const l = std.normalize(lightPos.sub(p));
const diff = std.max(std.dot(n, l), 0);

// Soft shadows
const shadowRo = p;
const shadowRd = l;
const shadowDist = std.length(std.sub(lightPos, p));
const shadowDist = std.length(lightPos.sub(p));
const shadow = softShadow(shadowRo, shadowRd, 0.1, shadowDist, d.f32(16));

// Combine lighting with shadows and color
const litColor = std.mul(march.color, diff);
const litColor = march.color.mul(diff);
const finalColor = std.mix(
std.mul(litColor, 0.5), // Shadow color
litColor, // Lit color
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const fragmentMain = tgpu['~unstable'].fragmentFn({
const p = sub(mul(z, dir), scale.$);
p.x -= time.$ + 3;
p.z -= time.$ + 3;
let q = p;
let q = d.vec3f(p);
let prox = p.y;
for (let i = 40.1; i > 0.01; i *= 0.2) {
q = sub(i * 0.9, abs(sub(mod(q, i + i), i)));
Expand Down
2 changes: 1 addition & 1 deletion apps/typegpu-docs/src/examples/simple/vaporrave/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const rayMarch = tgpu.fn(

if (scene.dist < c.SURF_DIST) {
result.dist = distOrigin;
result.color = scene.color;
result.color = d.vec3f(scene.color);
break;
}
}
Expand Down
4 changes: 2 additions & 2 deletions apps/typegpu-docs/src/examples/simulation/boids-next/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ const mainCompute = tgpu['~unstable'].computeFn({
workgroupSize: [1],
})((input) => {
const index = input.gid.x;
const instanceInfo = currentTrianglePos.value[index];
const instanceInfo = TriangleData(currentTrianglePos.value[index]);
let separation = d.vec2f();
let alignment = d.vec2f();
let cohesion = d.vec2f();
Expand Down Expand Up @@ -249,7 +249,7 @@ const mainCompute = tgpu['~unstable'].computeFn({

instanceInfo.position = std.add(instanceInfo.position, instanceInfo.velocity);

nextTrianglePos.value[index] = instanceInfo;
nextTrianglePos.value[index] = TriangleData(instanceInfo);
});

const computePipeline = root['~unstable']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ const coordsToIndex = (x: number, y: number) => {

const getCell = (x: number, y: number): d.v4f => {
'use gpu';
return inputGridSlot.$[coordsToIndex(x, y)];
return d.vec4f(inputGridSlot.$[coordsToIndex(x, y)]);
};

const setCell = (x: number, y: number, value: d.v4f) => {
'use gpu';
const index = coordsToIndex(x, y);
outputGridSlot.$[index] = value;
outputGridSlot.$[index] = d.vec4f(value);
};

const setVelocity = (x: number, y: number, velocity: d.v2f) => {
Expand Down Expand Up @@ -202,7 +202,7 @@ const mainInitWorld = tgpu['~unstable'].computeFn({
}
}

outputGridSlot.$[index] = value;
outputGridSlot.$[index] = d.vec4f(value);
});

const mainMoveObstacles = tgpu['~unstable'].computeFn({ workgroupSize: [1] })(
Expand Down Expand Up @@ -366,7 +366,7 @@ const mainCompute = tgpu['~unstable'].computeFn({
const minInflow = getMinimumInFlow(x, y);
next.z = std.max(minInflow, next.z);

outputGridSlot.$[index] = next;
outputGridSlot.$[index] = d.vec4f(next);
});

const OBSTACLE_BOX = 0;
Expand Down
Loading