Skip to content

Commit 4a01705

Browse files
committed
all compute shaders in tgpu
1 parent 1e78a2c commit 4a01705

File tree

1 file changed

+81
-68
lines changed
  • apps/typegpu-docs/src/examples/threejs/compute-geometry

1 file changed

+81
-68
lines changed

apps/typegpu-docs/src/examples/threejs/compute-geometry/index.ts

Lines changed: 81 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ camera.position.set(0, 0, 1);
2424

2525
const scene = new THREE.Scene();
2626

27-
// top left is (0,0) - just recalling
2827
const bgColor = TSL.screenUV.y.mix(TSL.color(0x9f87f7), TSL.color(0xf2cdcd));
2928
const bgVignette = TSL.screenUV.distance(0.5).remapClamp(0.3, 0.8).oneMinus();
3029
const bgIntensity = 4;
@@ -37,86 +36,100 @@ const elasticity = TSL.uniform(0.4);
3736
const damping = TSL.uniform(0.94);
3837
const brushSize = TSL.uniform(0.25);
3938
const brushStrength = TSL.uniform(0.22);
40-
const pointerPositionUniform = fromTSL(pointerPosition, { type: d.vec4f });
41-
const elasticityUniform = fromTSL(elasticity, { type: d.f32 });
42-
const dampingUniform = fromTSL(damping, { type: d.f32 });
43-
const brushSizeUniform = fromTSL(brushSize, { type: d.f32 });
44-
const brushStrengthUniform = fromTSL(brushStrength, { type: d.f32 });
39+
const pointerPositionAccessor = fromTSL(pointerPosition, { type: d.vec4f });
40+
const elasticityAccessor = fromTSL(elasticity, { type: d.f32 });
41+
const dampingAccessor = fromTSL(damping, { type: d.f32 });
42+
const brushSizeAccessor = fromTSL(brushSize, { type: d.f32 });
43+
const brushStrengthAccessor = fromTSL(brushStrength, { type: d.f32 });
4544

4645
const jelly = TSL.Fn(({ renderer, geometry, object }) => {
4746
const count = geometry.attributes.position.count;
4847

49-
// Create storage buffer attribute for modified position.
50-
51-
const positionBaseAttribute = geometry.attributes.position;
5248
const positionStorageBufferAttribute = new THREE.StorageBufferAttribute(
5349
count,
5450
3,
5551
);
56-
const speedBufferAttribute = new THREE.StorageBufferAttribute(count, 3);
57-
5852
geometry.setAttribute('storagePosition', positionStorageBufferAttribute);
5953

60-
// Attributes
61-
62-
const positionAttribute = TSL.storage(
63-
positionBaseAttribute as THREE.BufferAttribute,
64-
'vec3',
65-
count,
54+
const instanceIndexAccessor = fromTSL(TSL.instanceIndex, { type: d.u32 });
55+
const basePositionAccessor = fromTSL(
56+
TSL.storage(
57+
geometry.attributes.position as THREE.BufferAttribute,
58+
'vec3',
59+
count,
60+
),
61+
{
62+
type: d.arrayOf(d.vec3f),
63+
},
6664
);
67-
const positionStorageAttribute = TSL.storage(
68-
positionStorageBufferAttribute,
69-
'vec3',
70-
count,
65+
const positionAccessor = fromTSL(
66+
TSL.storage(
67+
positionStorageBufferAttribute,
68+
'vec3',
69+
count,
70+
),
71+
{
72+
type: d.arrayOf(d.vec3f),
73+
},
74+
);
75+
const speedAccessor = fromTSL(
76+
TSL.storage(
77+
new THREE.StorageBufferAttribute(count, 3),
78+
'vec3',
79+
count,
80+
),
81+
{
82+
type: d.arrayOf(d.vec3f),
83+
},
7184
);
7285

73-
const speedAttribute = TSL.storage(speedBufferAttribute, 'vec3', count);
74-
75-
// Vectors
76-
77-
// Base vec3 position of the mesh vertices.
78-
const basePosition = positionAttribute.element(TSL.instanceIndex);
79-
// Mesh vertices after compute modification.
80-
const currentPosition = positionStorageAttribute.element(TSL.instanceIndex);
81-
// Speed of each mesh vertex.
82-
const currentSpeed = speedAttribute.element(TSL.instanceIndex);
83-
84-
const computeInit = TSL.Fn(() => {
85-
// Modified storage position starts out the same as the base position.
86-
87-
currentPosition.assign(basePosition);
88-
})().compute(count);
89-
90-
const computeUpdate = TSL.Fn(() => {
91-
// pinch
92-
93-
TSL.If(pointerPosition.w.equal(1), () => {
94-
const worldPosition = TSL.objectWorldMatrix(object).mul(currentPosition);
95-
96-
const dist = worldPosition.distance(pointerPosition.xyz);
97-
const direction = pointerPosition.xyz.sub(worldPosition).normalize();
98-
99-
const power = brushSize.sub(dist).max(0).mul(brushStrength);
100-
101-
currentPosition.addAssign(direction.mul(power));
102-
});
103-
104-
// compute ( jelly )
105-
106-
const distance = basePosition.distance(currentPosition);
107-
const force = elasticity
108-
.mul(distance)
109-
.mul(basePosition.sub(currentPosition));
110-
111-
currentSpeed.addAssign(force);
112-
currentSpeed.mulAssign(damping);
113-
114-
currentPosition.addAssign(currentSpeed);
115-
})()
116-
.compute(count)
117-
.setName('Update Jelly');
118-
119-
// initialize the storage buffer with the base position
86+
const computeInit = toTSL(() => {
87+
'use gpu';
88+
positionAccessor.$[instanceIndexAccessor.$] =
89+
basePositionAccessor.$[instanceIndexAccessor.$];
90+
}).compute(count).setName('Init Mesh');
91+
92+
const modelMatrixAccessor = fromTSL(TSL.objectWorldMatrix(object), {
93+
type: d.mat4x4f,
94+
});
95+
96+
const computeUpdate = toTSL(() => {
97+
'use gpu';
98+
const instanceIdx = instanceIndexAccessor.$;
99+
const basePosition = basePositionAccessor.$[instanceIdx];
100+
let position = positionAccessor.$[instanceIdx];
101+
102+
if (pointerPositionAccessor.$.w === 1) {
103+
const worldPosition = modelMatrixAccessor.$.mul(
104+
d.vec4f(position, 1),
105+
).xyz;
106+
const dist = std.distance(worldPosition, pointerPositionAccessor.$.xyz);
107+
const direction = std.normalize(
108+
pointerPositionAccessor.$.xyz.sub(worldPosition),
109+
);
110+
const power = std.max(brushSizeAccessor.$ - dist, 0) *
111+
brushStrengthAccessor.$;
112+
113+
positionAccessor.$[instanceIndexAccessor.$] = position.add(
114+
direction.mul(power),
115+
);
116+
position = positionAccessor.$[instanceIdx];
117+
}
118+
119+
const dist = std.distance(
120+
basePosition,
121+
position,
122+
);
123+
const force = basePosition
124+
.sub(position)
125+
.mul(elasticityAccessor.$ * dist);
126+
const speed = speedAccessor.$[instanceIdx]
127+
.add(force)
128+
.mul(dampingAccessor.$);
129+
130+
speedAccessor.$[instanceIdx] = d.vec3f(speed);
131+
positionAccessor.$[instanceIdx] = position.add(speed);
132+
}).compute(count).setName('Update Jelly');
120133

121134
computeUpdate.onInit(() => renderer.compute(computeInit));
122135

0 commit comments

Comments
 (0)