diff --git a/apps/typegpu-docs/tests/individual-example-tests/3d-fish.test.ts b/apps/typegpu-docs/tests/individual-example-tests/3d-fish.test.ts index dca6c22f4e..3ff3be2bca 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/3d-fish.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/3d-fish.test.ts @@ -72,7 +72,7 @@ describe('3d fish example', () => { fn wrappedCallback(x: u32, _arg_1: u32, _arg_2: u32) { randSeed2(vec2f(f32(x), seedUniform)); - var data = ModelData(vec3f(((randFloat01() * 10f) - 5f), ((randFloat01() * 4f) - 2f), ((randFloat01() * 10f) - 5f)), vec3f(((randFloat01() * 0.1f) - 0.05f), ((randFloat01() * 0.1f) - 0.05f), ((randFloat01() * 0.1f) - 0.05f)), (0.07f * (1f + ((randFloat01() - 0.5f) * 0.8f))), randFloat01(), 1u, 1u, 1u); + let data = ModelData(vec3f(((randFloat01() * 10f) - 5f), ((randFloat01() * 4f) - 2f), ((randFloat01() * 10f) - 5f)), vec3f(((randFloat01() * 0.1f) - 0.05f), ((randFloat01() * 0.1f) - 0.05f), ((randFloat01() * 0.1f) - 0.05f)), (0.07f * (1f + ((randFloat01() - 0.5f) * 0.8f))), randFloat01(), 1u, 1u, 1u); fish_data_0[x] = data; fish_data_1[x] = data; } @@ -115,7 +115,7 @@ describe('3d fish example', () => { } fn projectPointOnLine(point: vec3f, line: Line3) -> vec3f { - var pointVector = (point - line.origin); + let pointVector = (point - line.origin); let projection = dot(pointVector, line.dir); return (line.origin + (line.dir * projection)); } @@ -207,8 +207,8 @@ describe('3d fish example', () => { wallRepulsion = (wallRepulsion + (repulsion * str)); } } - var proj = projectPointOnLine((*fishData).position, mouseRay); - var diff = ((*fishData).position - proj); + let proj = projectPointOnLine((*fishData).position, mouseRay); + let diff = ((*fishData).position - proj); const limit = 1.2; let str = (pow(2f, clamp((limit - length(diff)), 0f, limit)) - 1f); rayRepulsion = (normalize(diff) * str); @@ -219,7 +219,7 @@ describe('3d fish example', () => { direction += (wallRepulsion * 1e-4f); direction += (rayRepulsion * 0.0015f); direction = (normalize(direction) * clamp(length((*fishData).direction), 0f, 0.01f)); - var translation = (direction * (min(999f, timePassed) / 8f)); + let translation = (direction * (min(999f, timePassed) / 8f)); let nextFishData_1 = (&nextFishData[fishIndex]); (*nextFishData_1).position = ((*fishData).position + translation); (*nextFishData_1).direction = direction; @@ -256,11 +256,11 @@ describe('3d fish example', () => { var posMod = vec3f(); posMod.z = (sin((f32(index) + (((time / a) + vertex.position.x) / b))) / c); let coeff = (cos((f32(index) + (((time / a) + vertex.position.x) / b))) / c); - var newOX = normalize(vec3f(1f, 0f, coeff)); - var newOZ = vec3f(-(newOX.z), 0f, newOX.x); - var newNormalXZ = ((newOX * vertex.normal.x) + (newOZ * vertex.normal.z)); - var wavedNormal = vec3f(newNormalXZ.x, vertex.normal.y, newNormalXZ.z); - var wavedPosition = (vertex.position + posMod); + let newOX = normalize(vec3f(1f, 0f, coeff)); + let newOZ = vec3f(-(newOX.z), 0f, newOX.x); + let newNormalXZ = ((newOX * vertex.normal.x) + (newOZ * vertex.normal.z)); + let wavedNormal = vec3f(newNormalXZ.x, vertex.normal.y, newNormalXZ.z); + let wavedPosition = (vertex.position + posMod); return PosAndNormal(wavedPosition, wavedNormal); } @@ -291,29 +291,20 @@ describe('3d fish example', () => { if (((*currentModelData).applySinWave == 1u)) { wavedVertex = applySinWave(_arg_instanceIndex, PosAndNormal(_arg_modelPosition, _arg_modelNormal), currentTime); } - var direction = normalize((*currentModelData).direction); + let direction = normalize((*currentModelData).direction); let yaw = (-(atan2(direction.z, direction.x)) + 3.141592653589793f); let pitch = asin(-(direction.y)); - var scaleMatrix = mat4x4f(vec3f((*currentModelData).scale).x, 0, 0, 0, 0, vec3f((*currentModelData).scale).y, 0, 0, 0, 0, vec3f((*currentModelData).scale).z, 0, 0, 0, 0, 1); - var pitchMatrix = mat4x4f(cos(pitch), sin(pitch), 0, 0, -sin(pitch), cos(pitch), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - var yawMatrix = mat4x4f(cos(yaw), 0, -sin(yaw), 0, 0, 1, 0, 0, sin(yaw), 0, cos(yaw), 0, 0, 0, 0, 1); - var translationMatrix = mat4x4f(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, (*currentModelData).position.x, (*currentModelData).position.y, (*currentModelData).position.z, 1); + let scaleMatrix = mat4x4f(vec3f((*currentModelData).scale).x, 0, 0, 0, 0, vec3f((*currentModelData).scale).y, 0, 0, 0, 0, vec3f((*currentModelData).scale).z, 0, 0, 0, 0, 1); + let pitchMatrix = mat4x4f(cos(pitch), sin(pitch), 0, 0, -sin(pitch), cos(pitch), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + let yawMatrix = mat4x4f(cos(yaw), 0, -sin(yaw), 0, 0, 1, 0, 0, sin(yaw), 0, cos(yaw), 0, 0, 0, 0, 1); + let translationMatrix = mat4x4f(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, (*currentModelData).position.x, (*currentModelData).position.y, (*currentModelData).position.z, 1); var worldPosition = ((((translationMatrix * yawMatrix) * pitchMatrix) * scaleMatrix) * vec4f(wavedVertex.position, 1f)); - var worldNormal = normalize(((yawMatrix * pitchMatrix) * vec4f(wavedVertex.normal, 1f)).xyz); + let worldNormal = normalize(((yawMatrix * pitchMatrix) * vec4f(wavedVertex.normal, 1f)).xyz); let worldPositionUniform = (&worldPosition); - var canvasPosition = ((camera.projection * camera.view) * (*worldPositionUniform)); + let canvasPosition = ((camera.projection * camera.view) * (*worldPositionUniform)); return vertexShader_Output(worldPosition.xyz, worldNormal, canvasPosition, (*currentModelData).variant, _arg_textureUV, (*currentModelData).applySeaFog, (*currentModelData).applySeaDesaturation); } - struct fragmentShader_Input { - @location(0) worldPosition: vec3f, - @location(1) worldNormal: vec3f, - @location(2) variant: f32, - @location(3) textureUV: vec2f, - @location(4) @interpolate(flat) applySeaFog: u32, - @location(5) @interpolate(flat) applySeaDesaturation: u32, - } - @group(0) @binding(1) var modelTexture: texture_2d; @group(0) @binding(3) var sampler_1: sampler; @@ -418,17 +409,26 @@ describe('3d fish example', () => { return vec3f(r, g, b); } + struct fragmentShader_Input { + @location(0) worldPosition: vec3f, + @location(1) worldNormal: vec3f, + @location(2) variant: f32, + @location(3) textureUV: vec2f, + @location(4) @interpolate(flat) applySeaFog: u32, + @location(5) @interpolate(flat) applySeaDesaturation: u32, + } + @fragment fn fragmentShader(_arg_0: fragmentShader_Input) -> @location(0) vec4f { - var textureColorWithAlpha = textureSample(modelTexture, sampler_1, _arg_0.textureUV); - var textureColor = textureColorWithAlpha.rgb; - var ambient = ((0.5f * textureColor) * vec3f(0.800000011920929, 0.800000011920929, 1)); + let textureColorWithAlpha = textureSample(modelTexture, sampler_1, _arg_0.textureUV); + let textureColor = textureColorWithAlpha.rgb; + let ambient = ((0.5f * textureColor) * vec3f(0.800000011920929, 0.800000011920929, 1)); let cosTheta = dot(_arg_0.worldNormal, vec3f(-0.2357022613286972, 0.9428090453147888, -0.2357022613286972)); - var diffuse = ((max(0f, cosTheta) * textureColor) * vec3f(0.800000011920929, 0.800000011920929, 1)); - var viewSource = normalize((camera.position.xyz - _arg_0.worldPosition)); - var reflectSource = normalize(reflect(vec3f(0.2357022613286972, -0.9428090453147888, 0.2357022613286972), _arg_0.worldNormal)); + let diffuse = ((max(0f, cosTheta) * textureColor) * vec3f(0.800000011920929, 0.800000011920929, 1)); + let viewSource = normalize((camera.position.xyz - _arg_0.worldPosition)); + let reflectSource = normalize(reflect(vec3f(0.2357022613286972, -0.9428090453147888, 0.2357022613286972), _arg_0.worldNormal)); let specularStrength = pow(max(0f, dot(viewSource, reflectSource)), 16f); - var specular = (specularStrength * vec3f(0.800000011920929, 0.800000011920929, 1)); - var lightedColor = ((ambient + diffuse) + specular); + let specular = (specularStrength * vec3f(0.800000011920929, 0.800000011920929, 1)); + let lightedColor = ((ambient + diffuse) + specular); let distanceFromCamera = length((camera.position.xyz - _arg_0.worldPosition)); var desaturatedColor = lightedColor; if ((_arg_0.applySeaDesaturation == 1u)) { diff --git a/apps/typegpu-docs/tests/individual-example-tests/ascii-filter.test.ts b/apps/typegpu-docs/tests/individual-example-tests/ascii-filter.test.ts index d9748aa2db..85ede7a576 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/ascii-filter.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/ascii-filter.test.ts @@ -45,7 +45,7 @@ describe('ascii filter example', () => { @group(0) @binding(4) var charsetExtended: u32; fn characterFn(n: u32, p: vec2f) -> f32 { - var pos = floor(((p * vec2f(-4, 4)) + 2.5f)); + let pos = floor(((p * vec2f(-4, 4)) + 2.5f)); if (((((pos.x < 0f) || (pos.x > 4f)) || (pos.y < 0f)) || (pos.y > 4f))) { return 0f; } @@ -60,13 +60,13 @@ describe('ascii filter example', () => { } @fragment fn fragment(_arg_0: FragmentIn) -> @location(0) vec4f { - var uv2 = ((uvTransformBuffer * (_arg_0.uv - 0.5f)) + 0.5f); - var textureSize = vec2f(textureDimensions(externalTexture)); - var pix = (uv2 * textureSize); + let uv2 = ((uvTransformBuffer * (_arg_0.uv - 0.5f)) + 0.5f); + let textureSize = vec2f(textureDimensions(externalTexture)); + let pix = (uv2 * textureSize); let cellSize = f32(glyphSize); let halfCell = (cellSize * 0.5f); - var blockCoord = ((floor((pix / cellSize)) * cellSize) / textureSize); - var color = textureSampleBaseClampToEdge(externalTexture, shaderSampler, blockCoord); + let blockCoord = ((floor((pix / cellSize)) * cellSize) / textureSize); + let color = textureSampleBaseClampToEdge(externalTexture, shaderSampler, blockCoord); let rawGray = (((0.3f * color.x) + (0.59f * color.y)) + (0.11f * color.z)); let gray = pow(rawGray, gammaCorrection); var n = 4096u; @@ -221,7 +221,7 @@ describe('ascii filter example', () => { n = 11512810u; } } - var p = vec2f((((pix.x / halfCell) % 2f) - 1f), (((pix.y / halfCell) % 2f) - 1f)); + let p = vec2f((((pix.x / halfCell) % 2f) - 1f), (((pix.y / halfCell) % 2f) - 1f)); let charValue = characterFn(n, p); var resultColor = vec3f(1); if ((displayMode == 0u)) { diff --git a/apps/typegpu-docs/tests/individual-example-tests/bitonic-sort.test.ts b/apps/typegpu-docs/tests/individual-example-tests/bitonic-sort.test.ts index 06b1c586cb..6368fd715f 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/bitonic-sort.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/bitonic-sort.test.ts @@ -118,12 +118,12 @@ describe('bitonic sort example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } + @group(0) @binding(0) var data_1: array; + struct fragmentFn_Input { @location(0) uv: vec2f, } - @group(0) @binding(0) var data_1: array; - @fragment fn fragmentFn(_arg_0: fragmentFn_Input) -> @location(0) vec4f { let data = (&data_1); let arrayLength_1 = arrayLength(&(*data)); diff --git a/apps/typegpu-docs/tests/individual-example-tests/blur.test.ts b/apps/typegpu-docs/tests/individual-example-tests/blur.test.ts index 00df4923ed..6e9617f7c7 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/blur.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/blur.test.ts @@ -45,8 +45,8 @@ describe('blur example', () => { @compute @workgroup_size(32, 1, 1) fn computeFn(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_id) lid: vec3u) { let settings = (&settingsUniform); let filterOffset = i32((f32(((*settings).filterDim - 1i)) / 2f)); - var dims = vec2i(textureDimensions(inTexture)); - var baseIndex = (vec2i(((wid.xy * vec2u((*settings).blockDim, 4u)) + (lid.xy * vec2u(4, 1)))) - vec2i(filterOffset, 0i)); + let dims = vec2i(textureDimensions(inTexture)); + let baseIndex = (vec2i(((wid.xy * vec2u((*settings).blockDim, 4u)) + (lid.xy * vec2u(4, 1)))) - vec2i(filterOffset, 0i)); // unrolled iteration #0 { // unrolled iteration #0 @@ -470,14 +470,14 @@ describe('blur example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct renderFragment_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var renderView: texture_2d; @group(0) @binding(1) var sampler_1: sampler; + struct renderFragment_Input { + @location(0) uv: vec2f, + } + @fragment fn renderFragment(_arg_0: renderFragment_Input) -> @location(0) vec4f { return textureSample(renderView, sampler_1, _arg_0.uv); }" diff --git a/apps/typegpu-docs/tests/individual-example-tests/boids.test.ts b/apps/typegpu-docs/tests/individual-example-tests/boids.test.ts index 67d0886c76..410c70f767 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/boids.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/boids.test.ts @@ -73,7 +73,7 @@ describe('boids example', () => { cohesion /= f32(cohesionCount); cohesion -= self_1.position; } - var velocity = (((paramsBuffer.separationStrength * separation) + (paramsBuffer.alignmentStrength * alignment)) + (paramsBuffer.cohesionStrength * cohesion)); + let velocity = (((paramsBuffer.separationStrength * separation) + (paramsBuffer.alignmentStrength * alignment)) + (paramsBuffer.cohesionStrength * cohesion)); self_1.velocity += velocity; self_1.velocity = (clamp(length(self_1.velocity), 0f, 0.01f) * normalize(self_1.velocity)); self_1.position += self_1.velocity; @@ -108,9 +108,9 @@ describe('boids example', () => { @vertex fn mainVert(@location(0) _arg_v: vec2f, @location(1) _arg_center: vec2f, @location(2) _arg_velocity: vec2f) -> mainVert_Output { let angle = getRotationFromVelocity(_arg_velocity); - var rotated = rotate(_arg_v, angle); - var pos = vec4f((rotated + _arg_center), 0f, 1f); - var color = vec4f(((sin((colorPalette + angle)) * 0.45f) + 0.45f), 1f); + let rotated = rotate(_arg_v, angle); + let pos = vec4f((rotated + _arg_center), 0f, 1f); + let color = vec4f(((sin((colorPalette + angle)) * 0.45f) + 0.45f), 1f); return mainVert_Output(pos, color); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/box-raytracing.test.ts b/apps/typegpu-docs/tests/individual-example-tests/box-raytracing.test.ts index 838cdac465..915c2723e0 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/box-raytracing.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/box-raytracing.test.ts @@ -39,8 +39,8 @@ describe('box raytracing example', () => { } @vertex fn mainVertex(_arg_0: VertexIn) -> VertexOut { - var pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); - var rayWorldOrigin = (uniforms.invViewMatrix * vec4f(0, 0, 0, 1)).xyz; + let pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); + let rayWorldOrigin = (uniforms.invViewMatrix * vec4f(0, 0, 0, 1)).xyz; return VertexOut(vec4f(pos[_arg_0.vertexIndex], 0f, 1f), rayWorldOrigin); } @@ -136,13 +136,13 @@ describe('box raytracing example', () => { } @fragment fn fragmentFunction(_arg_0: FragmentIn) -> @location(0) vec4f { - var boxSize3 = vec3f(uniforms.boxSize); - var halfBoxSize3 = (0.5f * boxSize3); - var halfCanvasDims = (0.5f * uniforms.canvasDims); + let boxSize3 = vec3f(uniforms.boxSize); + let halfBoxSize3 = (0.5f * boxSize3); + let halfCanvasDims = (0.5f * uniforms.canvasDims); let minDim = min(uniforms.canvasDims.x, uniforms.canvasDims.y); - var viewCoords = ((_arg_0.position.xy - halfCanvasDims) / minDim); - var ray = Ray(_arg_0.rayWorldOrigin, (uniforms.invViewMatrix * vec4f(normalize(vec3f(viewCoords, 1f)), 0f)).xyz); - var bigBoxIntersection = getBoxIntersection(AxisAlignedBounds((-1f * halfBoxSize3), (vec3f(7) + halfBoxSize3)), ray); + let viewCoords = ((_arg_0.position.xy - halfCanvasDims) / minDim); + let ray = Ray(_arg_0.rayWorldOrigin, (uniforms.invViewMatrix * vec4f(normalize(vec3f(viewCoords, 1f)), 0f)).xyz); + let bigBoxIntersection = getBoxIntersection(AxisAlignedBounds((-1f * halfBoxSize3), (vec3f(7) + halfBoxSize3)), ray); if (!bigBoxIntersection.intersects) { discard;; return vec4f(); @@ -156,8 +156,8 @@ describe('box raytracing example', () => { if ((boxMatrix[i][j][k].isActive == 0u)) { continue; } - var ijkScaled = vec3f(f32(i), f32(j), f32(k)); - var intersection = getBoxIntersection(AxisAlignedBounds((ijkScaled - halfBoxSize3), (ijkScaled + halfBoxSize3)), ray); + let ijkScaled = vec3f(f32(i), f32(j), f32(k)); + let intersection = getBoxIntersection(AxisAlignedBounds((ijkScaled - halfBoxSize3), (ijkScaled + halfBoxSize3)), ray); if (intersection.intersects) { let boxDensity = (max(0f, (intersection.tMax - intersection.tMin)) * pow(uniforms.materialDensity, 2f)); density += boxDensity; @@ -167,10 +167,10 @@ describe('box raytracing example', () => { } } } - var linear = (1f / invColor); - var srgb = linearToSrgb(linear); + let linear = (1f / invColor); + let srgb = linearToSrgb(linear); const gamma = 2.2; - var corrected = pow(srgb, vec3f((1f / gamma))); + let corrected = pow(srgb, vec3f((1f / gamma))); if (intersectionFound) { return (min(density, 1f) * vec4f(min(corrected, vec3f(1)), 1f)); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/camera-thresholding.test.ts b/apps/typegpu-docs/tests/individual-example-tests/camera-thresholding.test.ts index 43e10c97b2..349dc06379 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/camera-thresholding.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/camera-thresholding.test.ts @@ -32,10 +32,6 @@ describe('camera thresholding example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct mainFrag_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var uvTransformUniform: mat2x2f; @group(1) @binding(0) var inputTexture: texture_external; @@ -48,11 +44,15 @@ describe('camera thresholding example', () => { @group(0) @binding(3) var thresholdBuffer: f32; + struct mainFrag_Input { + @location(0) uv: vec2f, + } + @fragment fn mainFrag(_arg_0: mainFrag_Input) -> @location(0) vec4f { - var uv2 = ((uvTransformUniform * (_arg_0.uv - 0.5f)) + 0.5f); + let uv2 = ((uvTransformUniform * (_arg_0.uv - 0.5f)) + 0.5f); var col = textureSampleBaseClampToEdge(inputTexture, sampler_1, uv2); - var ycbcr = (col.rgb * rgbToYcbcrMatrix); - var colycbcr = (colorUniform * rgbToYcbcrMatrix); + let ycbcr = (col.rgb * rgbToYcbcrMatrix); + let colycbcr = (colorUniform * rgbToYcbcrMatrix); let crDiff = abs((ycbcr.y - colycbcr.y)); let cbDiff = abs((ycbcr.z - colycbcr.z)); let distance_1 = length(vec2f(crDiff, cbDiff)); diff --git a/apps/typegpu-docs/tests/individual-example-tests/caustics.test.ts b/apps/typegpu-docs/tests/individual-example-tests/caustics.test.ts index a1938d5c34..ea519c5db7 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/caustics.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/caustics.test.ts @@ -26,20 +26,16 @@ describe('caustics example', () => { } @vertex fn mainVertex(@builtin(vertex_index) vertexIndex: u32) -> mainVertex_Output { - var pos = array(vec2f(0, 0.800000011920929), vec2f(-0.800000011920929), vec2f(0.800000011920929, -0.800000011920929)); - var uv = array(vec2f(0.5, 1), vec2f(), vec2f(1, 0)); + let pos = array(vec2f(0, 0.800000011920929), vec2f(-0.800000011920929), vec2f(0.800000011920929, -0.800000011920929)); + let uv = array(vec2f(0.5, 1), vec2f(), vec2f(1, 0)); return mainVertex_Output(vec4f(pos[vertexIndex], 0f, 1f), uv[vertexIndex]); } - struct mainFragment_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var tileDensity: f32; fn tilePattern(uv: vec2f) -> f32 { - var tiledUv = fract(uv); - var proximity = abs(((tiledUv * 2f) - 1f)); + let tiledUv = fract(uv); + let proximity = abs(((tiledUv * 2f) - 1f)); let maxProximity = max(proximity.x, proximity.y); return saturate((pow((1f - maxProximity), 0.6f) * 5f)); } @@ -79,8 +75,8 @@ describe('caustics example', () => { } fn dotProdGrid(pos: vec3f, junction: vec3f) -> f32 { - var relative = (pos - junction); - var gridVector = computeJunctionGradient(vec3i(junction)); + let relative = (pos - junction); + let gridVector = computeJunctionGradient(vec3i(junction)); return dot(relative, gridVector); } @@ -89,7 +85,7 @@ describe('caustics example', () => { } fn sample(pos: vec3f) -> f32 { - var minJunction = floor(pos); + let minJunction = floor(pos); let xyz = dotProdGrid(pos, minJunction); let xyZ = dotProdGrid(pos, (minJunction + vec3f(0, 0, 1))); let xYz = dotProdGrid(pos, (minJunction + vec3f(0, 1, 0))); @@ -98,8 +94,8 @@ describe('caustics example', () => { let XyZ = dotProdGrid(pos, (minJunction + vec3f(1, 0, 1))); let XYz = dotProdGrid(pos, (minJunction + vec3f(1, 1, 0))); let XYZ = dotProdGrid(pos, (minJunction + vec3f(1))); - var partial = (pos - minJunction); - var smoothPartial = quinticInterpolation(partial); + let partial = (pos - minJunction); + let smoothPartial = quinticInterpolation(partial); let xy = mix(xyz, xyZ, smoothPartial.z); let xY = mix(xYz, xYZ, smoothPartial.z); let Xy = mix(Xyz, XyZ, smoothPartial.z); @@ -111,7 +107,7 @@ describe('caustics example', () => { fn caustics(uv: vec2f, time_1: f32, profile: vec3f) -> vec3f { let distortion = sample(vec3f((uv * 0.5f), (time_1 * 0.2f))); - var uv2 = (uv + distortion); + let uv2 = (uv + distortion); let noise = abs(sample(vec3f((uv2 * 5f), time_1))); return pow(vec3f((1f - noise)), profile); } @@ -120,23 +116,27 @@ describe('caustics example', () => { return mat2x2f(vec2f(cos(angle), sin(angle)), vec2f(-(sin(angle)), cos(angle))); } + struct mainFragment_Input { + @location(0) uv: vec2f, + } + @fragment fn mainFragment(_arg_0: mainFragment_Input) -> @location(0) vec4f { - var skewMat = mat2x2f(vec2f(0.9800665974617004, 0.19866932928562164), vec2f((-1.9866933079506122f + (_arg_0.uv.x * 3f)), 4.900332889206208f)); - var skewedUv = (skewMat * _arg_0.uv); + let skewMat = mat2x2f(vec2f(0.9800665974617004, 0.19866932928562164), vec2f((-1.9866933079506122f + (_arg_0.uv.x * 3f)), 4.900332889206208f)); + let skewedUv = (skewMat * _arg_0.uv); let tile = tilePattern((skewedUv * tileDensity)); - var albedo = mix(vec3f(0.10000000149011612), vec3f(1), tile); - var cuv = vec2f(((_arg_0.uv.x * (pow((_arg_0.uv.y * 1.5f), 3f) + 0.1f)) * 5f), (pow((((_arg_0.uv.y * 1.5f) + 0.1f) * 1.5f), 3f) * 1f)); - var c1 = (caustics(cuv, (time * 0.2f), vec3f(4, 4, 1)) * vec3f(0.4000000059604645, 0.6499999761581421, 1)); - var c2 = (caustics((cuv * 2f), (time * 0.4f), vec3f(16, 1, 4)) * vec3f(0.18000000715255737, 0.30000001192092896, 0.5)); - var blendCoord = vec3f((_arg_0.uv * vec2f(5, 10)), ((time * 0.2f) + 5f)); + let albedo = mix(vec3f(0.10000000149011612), vec3f(1), tile); + let cuv = vec2f(((_arg_0.uv.x * (pow((_arg_0.uv.y * 1.5f), 3f) + 0.1f)) * 5f), (pow((((_arg_0.uv.y * 1.5f) + 0.1f) * 1.5f), 3f) * 1f)); + let c1 = (caustics(cuv, (time * 0.2f), vec3f(4, 4, 1)) * vec3f(0.4000000059604645, 0.6499999761581421, 1)); + let c2 = (caustics((cuv * 2f), (time * 0.4f), vec3f(16, 1, 4)) * vec3f(0.18000000715255737, 0.30000001192092896, 0.5)); + let blendCoord = vec3f((_arg_0.uv * vec2f(5, 10)), ((time * 0.2f) + 5f)); let blend = saturate((sample(blendCoord) + 0.3f)); - var noFogColor = (albedo * mix(vec3f(0.20000000298023224, 0.5, 1), (c1 + c2), blend)); + let noFogColor = (albedo * mix(vec3f(0.20000000298023224, 0.5, 1), (c1 + c2), blend)); let fog = min((pow(_arg_0.uv.y, 0.5f) * 1.2f), 1f); - var godRayUv = ((rotateXY(-0.3f) * _arg_0.uv) * vec2f(15, 3)); + let godRayUv = ((rotateXY(-0.3f) * _arg_0.uv) * vec2f(15, 3)); let godRayFactor = _arg_0.uv.y; - var godRay1 = (((sample(vec3f(godRayUv, (time * 0.5f))) + 1f) * vec3f(0.18000000715255737, 0.30000001192092896, 0.5)) * godRayFactor); - var godRay2 = ((((sample(vec3f((godRayUv * 2f), (time * 0.3f))) + 1f) * vec3f(0.18000000715255737, 0.30000001192092896, 0.5)) * godRayFactor) * 0.4f); - var godRays = (godRay1 + godRay2); + let godRay1 = (((sample(vec3f(godRayUv, (time * 0.5f))) + 1f) * vec3f(0.18000000715255737, 0.30000001192092896, 0.5)) * godRayFactor); + let godRay2 = ((((sample(vec3f((godRayUv * 2f), (time * 0.3f))) + 1f) * vec3f(0.18000000715255737, 0.30000001192092896, 0.5)) * godRayFactor) * 0.4f); + let godRays = (godRay1 + godRay2); return vec4f((mix(noFogColor, vec3f(0.05000000074505806, 0.20000000298023224, 0.699999988079071), fog) + godRays), 1f); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/chroma-keying.test.ts b/apps/typegpu-docs/tests/individual-example-tests/chroma-keying.test.ts index 9b25129771..d48c80f5b0 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/chroma-keying.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/chroma-keying.test.ts @@ -32,10 +32,6 @@ describe('chroma keying example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct fragment_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var uvTransform: mat2x2f; @group(1) @binding(0) var inputTexture: texture_external; @@ -48,11 +44,15 @@ describe('chroma keying example', () => { @group(0) @binding(3) var threshold: f32; + struct fragment_Input { + @location(0) uv: vec2f, + } + @fragment fn fragment(_arg_0: fragment_Input) -> @location(0) vec4f { - var uv2 = ((uvTransform * (_arg_0.uv - 0.5f)) + 0.5f); - var col = textureSampleBaseClampToEdge(inputTexture, sampler_1, uv2); - var ycbcr = (col.rgb * rgbToYcbcrMatrix); - var colycbcr = (color * rgbToYcbcrMatrix); + let uv2 = ((uvTransform * (_arg_0.uv - 0.5f)) + 0.5f); + let col = textureSampleBaseClampToEdge(inputTexture, sampler_1, uv2); + let ycbcr = (col.rgb * rgbToYcbcrMatrix); + let colycbcr = (color * rgbToYcbcrMatrix); let crDiff = abs((ycbcr.y - colycbcr.y)); let cbDiff = abs((ycbcr.z - colycbcr.z)); let distance_1 = length(vec2f(crDiff, cbDiff)); diff --git a/apps/typegpu-docs/tests/individual-example-tests/circles.test.ts b/apps/typegpu-docs/tests/individual-example-tests/circles.test.ts index 4a527d3dca..f9c7e9e239 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/circles.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/circles.test.ts @@ -58,7 +58,7 @@ describe('circles example', () => { const PI: f32 = 3.141592653589793f; fn circle(vertexIndex: u32) -> vec2f { - var subdiv = getSubdivLevel(vertexIndex); + let subdiv = getSubdivLevel(vertexIndex); let i = consecutiveTriangleVertexIndex(subdiv.vertexIndexInLevel); let pointCount = subdiv.pointCount; let angle = (((2f * PI) * f32(i)) / f32(pointCount)); @@ -73,8 +73,8 @@ describe('circles example', () => { @vertex fn mainVertexMaxArea(@builtin(vertex_index) vertexIndex: u32, @builtin(instance_index) instanceIndex: u32) -> mainVertexMaxArea_Output { let C = (&circles[instanceIndex]); - var unit = circle(vertexIndex); - var pos = ((*C).position + (unit * (*C).radius)); + let unit = circle(vertexIndex); + let pos = ((*C).position + (unit * (*C).radius)); return mainVertexMaxArea_Output(vec4f(pos, 0f, 1f), unit, instanceIndex); } @@ -84,7 +84,7 @@ describe('circles example', () => { } @fragment fn mainFragment(_arg_0: mainFragment_Input) -> @location(0) vec4f { - var color = vec3f(1f, cos(f32(_arg_0.instanceIndex)), sin((5f * f32(_arg_0.instanceIndex)))); + let color = vec3f(1f, cos(f32(_arg_0.instanceIndex)), sin((5f * f32(_arg_0.instanceIndex)))); let r = length(_arg_0.uv); return vec4f(mix(color, vec3f(), clamp(((r - 0.9f) * 20f), 0f, 0.5f)), 1f); }" diff --git a/apps/typegpu-docs/tests/individual-example-tests/clouds.test.ts b/apps/typegpu-docs/tests/individual-example-tests/clouds.test.ts index 870effa75b..d7da120837 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/clouds.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/clouds.test.ts @@ -71,11 +71,11 @@ describe('clouds example', () => { @group(1) @binding(2) var sampler_1: sampler; fn noise3d(pos: vec3f) -> f32 { - var idx = floor(pos); - var frac = fract(pos); - var smooth_1 = ((frac * frac) * (3f - (2f * frac))); - var texCoord0 = fract((((idx.xy + frac.xy) + (vec2f(37, 239) * idx.z)) / 256f)); - var texCoord1 = fract((((idx.xy + frac.xy) + (vec2f(37, 239) * (idx.z + 1f))) / 256f)); + let idx = floor(pos); + let frac = fract(pos); + let smooth_1 = ((frac * frac) * (3f - (2f * frac))); + let texCoord0 = fract((((idx.xy + frac.xy) + (vec2f(37, 239) * idx.z)) / 256f)); + let texCoord1 = fract((((idx.xy + frac.xy) + (vec2f(37, 239) * (idx.z + 1f))) / 256f)); let val0 = textureSampleLevel(noiseTexture, sampler_1, texCoord0, 0).x; let val1 = textureSampleLevel(noiseTexture, sampler_1, texCoord1, 0).x; return ((mix(val0, val1, smooth_1.z) * 2f) - 1f); @@ -116,17 +116,17 @@ describe('clouds example', () => { let stepSize = (1f / f32(maxSteps)); var dist = (randFloat01() * stepSize); for (var i = 0; (i < maxSteps); i++) { - var samplePos = (rayOrigin + ((rayDir * dist) * maxDepth)); + let samplePos = (rayOrigin + ((rayDir * dist) * maxDepth)); let cloudDensity = sampleDensity(samplePos); if ((cloudDensity > 0f)) { - var shadowPos = (samplePos + sunDir); + let shadowPos = (samplePos + sunDir); let shadowDensity = sampleDensityCheap(shadowPos); let shadow = saturate((cloudDensity - shadowDensity)); let lightVal = mix(0.3f, 1f, shadow); - var light = (vec3f(0.6600000262260437, 0.4949999749660492, 0.824999988079071) + ((vec3f(1, 0.699999988079071, 0.30000001192092896) * lightVal) * 0.9f)); - var color = mix(vec3f(1), vec3f(0.20000000298023224), cloudDensity); - var lit = (color * light); - var contrib = ((vec4f(lit, 1f) * cloudDensity) * (0.88f - accum.a)); + let light = (vec3f(0.6600000262260437, 0.4949999749660492, 0.824999988079071) + ((vec3f(1, 0.699999988079071, 0.30000001192092896) * lightVal) * 0.9f)); + let color = mix(vec3f(1), vec3f(0.20000000298023224), cloudDensity); + let lit = (color * light); + let contrib = ((vec4f(lit, 1f) * cloudDensity) * (0.88f - accum.a)); accum += contrib; if ((accum.a >= 0.879f)) { break; @@ -147,16 +147,16 @@ describe('clouds example', () => { let aspect = ((*screenRes).x / (*screenRes).y); var screenPos = ((_arg_0.uv - 0.5f) * 2f); screenPos = vec2f((screenPos.x * max(aspect, 1f)), (screenPos.y * max((1f / aspect), 1f))); - var sunDir = vec3f(1, 0, 0); + let sunDir = vec3f(1, 0, 0); let time = params.time; - var rayOrigin = vec3f((sin((time * 0.6f)) * 0.5f), ((cos((time * 0.8f)) * 0.5f) - 1f), (time * 1f)); - var rayDir = normalize(vec3f(screenPos.x, screenPos.y, 1f)); + let rayOrigin = vec3f((sin((time * 0.6f)) * 0.5f), ((cos((time * 0.8f)) * 0.5f) - 1f), (time * 1f)); + let rayDir = normalize(vec3f(screenPos.x, screenPos.y, 1f)); let sunDot = saturate(dot(rayDir, sunDir)); let sunGlow = pow(sunDot, 1.371742112482853f); var skyCol = (vec3f(0.75, 0.6600000262260437, 0.8999999761581421) - ((vec3f(1, 0.699999988079071, 0.4300000071525574) * rayDir.y) * 0.35f)); skyCol += (vec3f(1, 0.3700000047683716, 0.17000000178813934) * sunGlow); - var cloudCol = raymarch(rayOrigin, rayDir, sunDir); - var finalCol = ((skyCol * (1.1f - cloudCol.a)) + cloudCol.rgb); + let cloudCol = raymarch(rayOrigin, rayDir, sunDir); + let finalCol = ((skyCol * (1.1f - cloudCol.a)) + cloudCol.rgb); return vec4f(finalCol, 1f); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/confetti.test.ts b/apps/typegpu-docs/tests/individual-example-tests/confetti.test.ts index 3e39636f7a..4dfdef4775 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/confetti.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/confetti.test.ts @@ -59,16 +59,16 @@ describe('confetti example', () => { struct VertexIn { @location(0) tilt: f32, - @location(1) angle: f32, - @location(2) color: vec4f, - @location(3) center: vec2f, @builtin(vertex_index) vertexIndex: u32, + @location(1) angle: f32, + @location(2) center: vec2f, + @location(3) color: vec4f, } @vertex fn vertex(_arg_0: VertexIn) -> VertexOut { let width = (_arg_0.tilt / 350f); let height = (width / 2f); - var local = array(vec2f(), vec2f(width, 0f), vec2f(0f, height), vec2f(width, height)); + let local = array(vec2f(), vec2f(width, 0f), vec2f(0f, height), vec2f(width, height)); var pos = (rotate(local[_arg_0.vertexIndex], _arg_0.angle) + _arg_0.center); if ((aspectRatio < 1f)) { pos.x /= aspectRatio; diff --git a/apps/typegpu-docs/tests/individual-example-tests/cubemap-reflection.test.ts b/apps/typegpu-docs/tests/individual-example-tests/cubemap-reflection.test.ts index c77faffba2..4bfd0d95b1 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/cubemap-reflection.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/cubemap-reflection.test.ts @@ -42,8 +42,8 @@ describe('cubemap reflection example', () => { @group(0) @binding(2) var smoothFlag_1: u32; fn unpackVec2u(packed: vec2u) -> vec4f { - var xy = unpack2x16float(packed.x); - var zw = unpack2x16float(packed.y); + let xy = unpack2x16float(packed.x); + let zw = unpack2x16float(packed.y); return vec4f(xy, zw); } @@ -52,8 +52,8 @@ describe('cubemap reflection example', () => { } fn getAverageNormal(v1: vec4f, v2: vec4f, v3: vec4f) -> vec4f { - var edge1 = (v2.xyz - v1.xyz); - var edge2 = (v3.xyz - v1.xyz); + let edge1 = (v2.xyz - v1.xyz); + let edge2 = (v3.xyz - v1.xyz); return normalize(vec4f(cross(edge1, edge2), 0f)); } @@ -73,12 +73,12 @@ describe('cubemap reflection example', () => { return; } let baseIndexPrev = (triangleIndex * 3u); - var v1 = unpackVec2u((*prevVertices)[baseIndexPrev].position); - var v2 = unpackVec2u((*prevVertices)[(baseIndexPrev + 1u)].position); - var v3 = unpackVec2u((*prevVertices)[(baseIndexPrev + 2u)].position); - var v12 = vec4f(normalize(calculateMidpoint(v1, v2).xyz), 1f); - var v23 = vec4f(normalize(calculateMidpoint(v2, v3).xyz), 1f); - var v31 = vec4f(normalize(calculateMidpoint(v3, v1).xyz), 1f); + let v1 = unpackVec2u((*prevVertices)[baseIndexPrev].position); + let v2 = unpackVec2u((*prevVertices)[(baseIndexPrev + 1u)].position); + let v3 = unpackVec2u((*prevVertices)[(baseIndexPrev + 2u)].position); + let v12 = vec4f(normalize(calculateMidpoint(v1, v2).xyz), 1f); + let v23 = vec4f(normalize(calculateMidpoint(v2, v3).xyz), 1f); + let v31 = vec4f(normalize(calculateMidpoint(v3, v1).xyz), 1f); var newVertices = array(v1, v12, v31, v2, v23, v12, v3, v31, v23, v12, v23, v31); let baseIndexNext = (triangleIndex * 12u); // unrolled iteration #0 @@ -253,18 +253,18 @@ describe('cubemap reflection example', () => { } @vertex fn cubeVertexFn(@location(0) _arg_position: vec3f) -> cubeVertexFn_Output { - var viewPos = (camera.view * vec4f(_arg_position.xyz, 0f)).xyz; + let viewPos = (camera.view * vec4f(_arg_position.xyz, 0f)).xyz; return cubeVertexFn_Output((camera.projection * vec4f(viewPos, 1f)), _arg_position.xyz); } - struct cubeFragmentFn_Input { - @location(0) texCoord: vec3f, - } - @group(1) @binding(0) var cubemap: texture_cube; @group(1) @binding(1) var texSampler: sampler; + struct cubeFragmentFn_Input { + @location(0) texCoord: vec3f, + } + @fragment fn cubeFragmentFn(_arg_0: cubeFragmentFn_Input) -> @location(0) vec4f { return textureSample(cubemap, texSampler, normalize(_arg_0.texCoord)); } @@ -287,11 +287,6 @@ describe('cubemap reflection example', () => { return vertexFn_Output((camera.projection * (camera.view * _arg_position)), _arg_normal, _arg_position); } - struct fragmentFn_Input { - @location(0) normal: vec4f, - @location(1) worldPos: vec4f, - } - struct DirectionalLight { direction: vec3f, color: vec3f, @@ -314,20 +309,25 @@ describe('cubemap reflection example', () => { @group(1) @binding(1) var texSampler: sampler; + struct fragmentFn_Input { + @location(0) normal: vec4f, + @location(1) worldPos: vec4f, + } + @fragment fn fragmentFn(_arg_0: fragmentFn_Input) -> @location(0) vec4f { - var normalizedNormal = normalize(_arg_0.normal.xyz); - var normalizedLightDir = normalize(light.direction); - var ambientLight = ((material.ambient * light.color) * light.intensity); + let normalizedNormal = normalize(_arg_0.normal.xyz); + let normalizedLightDir = normalize(light.direction); + let ambientLight = ((material.ambient * light.color) * light.intensity); let diffuseFactor = max(dot(normalizedNormal, normalizedLightDir), 0f); - var diffuseLight = (((material.diffuse * light.color) * light.intensity) * diffuseFactor); - var viewDirection = normalize((camera.position.xyz - _arg_0.worldPos.xyz)); - var reflectionDirection = reflect(-(normalizedLightDir), normalizedNormal); + let diffuseLight = (((material.diffuse * light.color) * light.intensity) * diffuseFactor); + let viewDirection = normalize((camera.position.xyz - _arg_0.worldPos.xyz)); + let reflectionDirection = reflect(-(normalizedLightDir), normalizedNormal); let specularFactor = pow(max(dot(viewDirection, reflectionDirection), 0f), material.shininess); - var specularLight = (((material.specular * light.color) * light.intensity) * specularFactor); - var reflectionVector = reflect(-(viewDirection), normalizedNormal); - var environmentColor = textureSample(cubemap, texSampler, reflectionVector); - var directLighting = (ambientLight + (diffuseLight + specularLight)); - var finalColor = mix(directLighting, environmentColor.rgb, material.reflectivity); + let specularLight = (((material.specular * light.color) * light.intensity) * specularFactor); + let reflectionVector = reflect(-(viewDirection), normalizedNormal); + let environmentColor = textureSample(cubemap, texSampler, reflectionVector); + let directLighting = (ambientLight + (diffuseLight + specularLight)); + let finalColor = mix(directLighting, environmentColor.rgb, material.reflectivity); return vec4f(finalColor, 1f); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/disco.test.ts b/apps/typegpu-docs/tests/individual-example-tests/disco.test.ts index 8ea4e8d7f7..a6a8f7f785 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/disco.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/disco.test.ts @@ -27,15 +27,11 @@ describe('disco example', () => { } @vertex fn mainVertex(@builtin(vertex_index) vertexIndex: u32) -> mainVertex_Output { - var pos = array(vec2f(-1, 1), vec2f(-1), vec2f(1, -1), vec2f(-1, 1), vec2f(1, -1), vec2f(1)); - var uv = array(vec2f(0, 1), vec2f(), vec2f(1, 0), vec2f(0, 1), vec2f(1, 0), vec2f(1)); + let pos = array(vec2f(-1, 1), vec2f(-1), vec2f(1, -1), vec2f(-1, 1), vec2f(1, -1), vec2f(1)); + let uv = array(vec2f(0, 1), vec2f(), vec2f(1, 0), vec2f(0, 1), vec2f(1, 0), vec2f(1)); return mainVertex_Output(vec4f(pos[vertexIndex], 0f, 1f), uv[vertexIndex]); } - struct mainFragment2_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var resolutionUniform: vec2f; fn aspectCorrected(uv: vec2f) -> vec2f { @@ -53,11 +49,11 @@ describe('disco example', () => { @group(0) @binding(1) var time: f32; fn palette(t: f32) -> vec3f { - var a = vec3f(0.5, 0.5899999737739563, 0.8500000238418579); - var b = vec3f(0.18000000715255737, 0.41999998688697815, 0.4000000059604645); - var c = vec3f(0.18000000715255737, 0.47999998927116394, 0.4099999964237213); - var e = vec3f(0.3499999940395355, 0.12999999523162842, 0.3199999928474426); - var expr = cos((6.28318f * ((c * t) + e))); + let a = vec3f(0.5, 0.5899999737739563, 0.8500000238418579); + let b = vec3f(0.18000000715255737, 0.41999998688697815, 0.4000000059604645); + let c = vec3f(0.18000000715255737, 0.47999998927116394, 0.4099999964237213); + let e = vec3f(0.3499999940395355, 0.12999999523162842, 0.3199999928474426); + let expr = cos((6.28318f * ((c * t) + e))); return (a + (b * expr)); } @@ -65,14 +61,18 @@ describe('disco example', () => { return (acc + (col * weight)); } + struct mainFragment2_Input { + @location(0) uv: vec2f, + } + @fragment fn mainFragment2(_arg_0: mainFragment2_Input) -> @location(0) vec4f { - var originalUv = aspectCorrected(_arg_0.uv); + let originalUv = aspectCorrected(_arg_0.uv); var aspectUv = originalUv; var accumulatedColor = vec3f(); for (var iteration = 0; (iteration < 3i); iteration++) { aspectUv = (fract((aspectUv * -0.9f)) - 0.5f); var radialLength = (length(aspectUv) * exp((-(length(originalUv)) * 0.5f))); - var paletteColor = palette((length(originalUv) + (time * 0.9f))); + let paletteColor = palette((length(originalUv) + (time * 0.9f))); radialLength = (sin(((radialLength * 8f) + time)) / 8f); radialLength = abs(radialLength); radialLength = smoothstep(0f, 0.1f, radialLength); @@ -87,7 +87,7 @@ describe('disco example', () => { } @fragment fn mainFragment3(_arg_0: mainFragment3_Input) -> @location(0) vec4f { - var originalUv = aspectCorrected(_arg_0.uv); + let originalUv = aspectCorrected(_arg_0.uv); var aspectUv = originalUv; var accumulatedColor = vec3f(); let baseAngle = (time * 0.3f); @@ -101,7 +101,7 @@ describe('disco example', () => { aspectUv = (aspectUv * (1.15f + (iterationF32 * 0.05f))); aspectUv = (fract((aspectUv * (1.2f * sin(((time * 0.9f) + (iterationF32 * 0.3f)))))) - 0.5f); var radialLength = (length(aspectUv) * exp((-(length(originalUv)) * 1.6f))); - var paletteColor = palette(((length(originalUv) + (time * 0.8f)) + (iterationF32 * 0.05f))); + let paletteColor = palette(((length(originalUv) + (time * 0.8f)) + (iterationF32 * 0.05f))); radialLength = (sin(((radialLength * 7f) + (time * 0.9f))) / 8f); radialLength = abs(radialLength); radialLength = smoothstep(0f, 0.11f, radialLength); @@ -117,9 +117,9 @@ describe('disco example', () => { @fragment fn mainFragment4(_arg_0: mainFragment4_Input) -> @location(0) vec4f { var aspectUv = aspectCorrected(_arg_0.uv); - var mirroredUv = ((vec2f(abs((fract((aspectUv.x * 1.2f)) - 0.5f)), abs((fract((aspectUv.y * 1.2f)) - 0.5f))) * 2f) - 1f); + let mirroredUv = ((vec2f(abs((fract((aspectUv.x * 1.2f)) - 0.5f)), abs((fract((aspectUv.y * 1.2f)) - 0.5f))) * 2f) - 1f); aspectUv = mirroredUv; - var originalUv = aspectUv; + let originalUv = aspectUv; var accumulatedColor = vec3f(); let time_1 = time; for (var iteration = 0; (iteration < 4i); iteration++) { @@ -136,7 +136,7 @@ describe('disco example', () => { radialLength = abs(radialLength); radialLength = smoothstep(0f, 0.105f, radialLength); radialLength = ((0.058f + (iterationF32 * 6e-3f)) / (radialLength + 1e-5f)); - var paletteColor = palette(((length(originalUv) + (time_1 * 0.65f)) + (iterationF32 * 0.045f))); + let paletteColor = palette(((length(originalUv) + (time_1 * 0.65f)) + (iterationF32 * 0.045f))); accumulatedColor = accumulate(accumulatedColor, paletteColor, radialLength); } return vec4f(accumulatedColor, 1f); @@ -147,7 +147,7 @@ describe('disco example', () => { } @fragment fn mainFragment5(_arg_0: mainFragment5_Input) -> @location(0) vec4f { - var originalUv = aspectCorrected(_arg_0.uv); + let originalUv = aspectCorrected(_arg_0.uv); var aspectUv = originalUv; var accumulatedColor = vec3f(); for (var iteration = 0; (iteration < 3i); iteration++) { @@ -161,7 +161,7 @@ describe('disco example', () => { aspectUv = (vec2f(rotatedX, rotatedY) * (-0.85f - (iterationF32 * 0.07f))); aspectUv = (fract(aspectUv) - 0.5f); var radialLength = (length(aspectUv) * exp((-(length(originalUv)) * (0.4f + (iterationF32 * 0.1f))))); - var paletteColor = palette(((length(originalUv) + (time * 0.9f)) + (iterationF32 * 0.08f))); + let paletteColor = palette(((length(originalUv) + (time * 0.9f)) + (iterationF32 * 0.08f))); radialLength = (sin(((radialLength * (6f + iterationF32)) + time)) / 8f); radialLength = abs(radialLength); radialLength = smoothstep(0f, 0.1f, radialLength); @@ -177,7 +177,7 @@ describe('disco example', () => { @fragment fn mainFragment6(_arg_0: mainFragment6_Input) -> @location(0) vec4f { var aspectUv = aspectCorrected(_arg_0.uv); - var originalUv = aspectUv; + let originalUv = aspectUv; var accumulatedColor = vec3f(); let time_1 = time; for (var iteration = 0; (iteration < 5i); iteration++) { @@ -188,13 +188,13 @@ describe('disco example', () => { let rotatedX = ((aspectUv.x * cosAngle) - (aspectUv.y * sinAngle)); let rotatedY = ((aspectUv.x * sinAngle) + (aspectUv.y * cosAngle)); aspectUv = (vec2f(rotatedX, rotatedY) * (1.08f + (iterationF32 * 0.04f))); - var warpedUv = (fract((aspectUv * (1.3f + (iterationF32 * 0.2f)))) - 0.5f); + let warpedUv = (fract((aspectUv * (1.3f + (iterationF32 * 0.2f)))) - 0.5f); var radialLength = (length(warpedUv) * exp((-(length(originalUv)) * (1.4f + (iterationF32 * 0.05f))))); radialLength = (sin(((radialLength * (7f + (iterationF32 * 0.7f))) + (time_1 * (0.9f + (iterationF32 * 0.15f))))) / 8f); radialLength = abs(radialLength); radialLength = smoothstep(0f, 0.1f, radialLength); radialLength = ((0.05f + (iterationF32 * 5e-3f)) / (radialLength + 1e-5f)); - var paletteColor = palette(((length(originalUv) + (time_1 * 0.7f)) + (iterationF32 * 0.04f))); + let paletteColor = palette(((length(originalUv) + (time_1 * 0.7f)) + (iterationF32 * 0.04f))); accumulatedColor = accumulate(accumulatedColor, paletteColor, radialLength); } return vec4f(accumulatedColor, 1f); @@ -207,7 +207,7 @@ describe('disco example', () => { @fragment fn mainFragment7(_arg_0: mainFragment7_Input) -> @location(0) vec4f { var aspectUv = aspectCorrected(_arg_0.uv); aspectUv = (vec2f(abs((fract((aspectUv.x * 1.5f)) - 0.5f)), abs((fract((aspectUv.y * 1.5f)) - 0.5f))) * 2f); - var originalUv = aspectUv; + let originalUv = aspectUv; var accumulatedColor = vec3f(); let time_1 = time; for (var iteration = 0; (iteration < 4i); iteration++) { @@ -226,7 +226,7 @@ describe('disco example', () => { radialLength = abs(radialLength); radialLength = smoothstep(0f, 0.11f, radialLength); radialLength = ((0.06f + (iterationF32 * 5e-3f)) / (radialLength + 1e-5f)); - var paletteColor = palette(((length(originalUv) + (time_1 * 0.75f)) + (iterationF32 * 0.05f))); + let paletteColor = palette(((length(originalUv) + (time_1 * 0.75f)) + (iterationF32 * 0.05f))); accumulatedColor = accumulate(accumulatedColor, paletteColor, radialLength); } return vec4f(accumulatedColor, 1f); @@ -238,15 +238,11 @@ describe('disco example', () => { } @vertex fn mainVertex(@builtin(vertex_index) vertexIndex: u32) -> mainVertex_Output { - var pos = array(vec2f(-1, 1), vec2f(-1), vec2f(1, -1), vec2f(-1, 1), vec2f(1, -1), vec2f(1)); - var uv = array(vec2f(0, 1), vec2f(), vec2f(1, 0), vec2f(0, 1), vec2f(1, 0), vec2f(1)); + let pos = array(vec2f(-1, 1), vec2f(-1), vec2f(1, -1), vec2f(-1, 1), vec2f(1, -1), vec2f(1)); + let uv = array(vec2f(0, 1), vec2f(), vec2f(1, 0), vec2f(0, 1), vec2f(1, 0), vec2f(1)); return mainVertex_Output(vec4f(pos[vertexIndex], 0f, 1f), uv[vertexIndex]); } - struct mainFragment1_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var resolutionUniform: vec2f; fn aspectCorrected(uv: vec2f) -> vec2f { @@ -264,11 +260,11 @@ describe('disco example', () => { @group(0) @binding(1) var time: f32; fn palette(t: f32) -> vec3f { - var a = vec3f(0.5, 0.5899999737739563, 0.8500000238418579); - var b = vec3f(0.18000000715255737, 0.41999998688697815, 0.4000000059604645); - var c = vec3f(0.18000000715255737, 0.47999998927116394, 0.4099999964237213); - var e = vec3f(0.3499999940395355, 0.12999999523162842, 0.3199999928474426); - var expr = cos((6.28318f * ((c * t) + e))); + let a = vec3f(0.5, 0.5899999737739563, 0.8500000238418579); + let b = vec3f(0.18000000715255737, 0.41999998688697815, 0.4000000059604645); + let c = vec3f(0.18000000715255737, 0.47999998927116394, 0.4099999964237213); + let e = vec3f(0.3499999940395355, 0.12999999523162842, 0.3199999928474426); + let expr = cos((6.28318f * ((c * t) + e))); return (a + (b * expr)); } @@ -276,8 +272,12 @@ describe('disco example', () => { return (acc + (col * weight)); } + struct mainFragment1_Input { + @location(0) uv: vec2f, + } + @fragment fn mainFragment1(_arg_0: mainFragment1_Input) -> @location(0) vec4f { - var originalUv = aspectCorrected(_arg_0.uv); + let originalUv = aspectCorrected(_arg_0.uv); var aspectUv = originalUv; var accumulatedColor = vec3f(); for (var iteration = 0; (iteration < 5i); iteration++) { @@ -287,7 +287,7 @@ describe('disco example', () => { radialLength = abs(radialLength); radialLength = smoothstep(0f, 0.1f, radialLength); radialLength = (0.06f / radialLength); - var paletteColor = palette((length(originalUv) + (time * 0.9f))); + let paletteColor = palette((length(originalUv) + (time * 0.9f))); accumulatedColor = accumulate(accumulatedColor, paletteColor, radialLength); } return vec4f(accumulatedColor, 1f); diff --git a/apps/typegpu-docs/tests/individual-example-tests/fluid-double-buffering.test.ts b/apps/typegpu-docs/tests/individual-example-tests/fluid-double-buffering.test.ts index ef73e74189..38038d6f9a 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/fluid-double-buffering.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/fluid-double-buffering.test.ts @@ -173,13 +173,13 @@ describe('fluid double buffering example', () => { fn computeVelocity(x: i32, y: i32) -> vec2f { const gravityCost = 0.5; var neighborOffsets = array(vec2i(0, 1), vec2i(0, -1), vec2i(1, 0), vec2i(-1, 0)); - var cell = getCell(x, y); + let cell = getCell(x, y); var leastCost = cell.z; var dirChoices = array(vec2f(), vec2f(), vec2f(), vec2f()); var dirChoiceCount = 1; // unrolled iteration #0 { - var neighborDensity = getCell((x + neighborOffsets[0u].x), (y + neighborOffsets[0u].y)); + let neighborDensity = getCell((x + neighborOffsets[0u].x), (y + neighborOffsets[0u].y)); let cost = (neighborDensity.z + (f32(neighborOffsets[0u].y) * gravityCost)); if (isValidFlowOut((x + neighborOffsets[0u].x), (y + neighborOffsets[0u].y))) { if ((cost == leastCost)) { @@ -197,7 +197,7 @@ describe('fluid double buffering example', () => { } // unrolled iteration #1 { - var neighborDensity = getCell((x + neighborOffsets[1u].x), (y + neighborOffsets[1u].y)); + let neighborDensity = getCell((x + neighborOffsets[1u].x), (y + neighborOffsets[1u].y)); let cost = (neighborDensity.z + (f32(neighborOffsets[1u].y) * gravityCost)); if (isValidFlowOut((x + neighborOffsets[1u].x), (y + neighborOffsets[1u].y))) { if ((cost == leastCost)) { @@ -215,7 +215,7 @@ describe('fluid double buffering example', () => { } // unrolled iteration #2 { - var neighborDensity = getCell((x + neighborOffsets[2u].x), (y + neighborOffsets[2u].y)); + let neighborDensity = getCell((x + neighborOffsets[2u].x), (y + neighborOffsets[2u].y)); let cost = (neighborDensity.z + (f32(neighborOffsets[2u].y) * gravityCost)); if (isValidFlowOut((x + neighborOffsets[2u].x), (y + neighborOffsets[2u].y))) { if ((cost == leastCost)) { @@ -233,7 +233,7 @@ describe('fluid double buffering example', () => { } // unrolled iteration #3 { - var neighborDensity = getCell((x + neighborOffsets[3u].x), (y + neighborOffsets[3u].y)); + let neighborDensity = getCell((x + neighborOffsets[3u].x), (y + neighborOffsets[3u].y)); let cost = (neighborDensity.z + (f32(neighborOffsets[3u].y) * gravityCost)); if (isValidFlowOut((x + neighborOffsets[3u].x), (y + neighborOffsets[3u].y))) { if ((cost == leastCost)) { @@ -257,9 +257,9 @@ describe('fluid double buffering example', () => { if (!isValidCoord(x, y)) { return 0; } - var src = getCell(x, y); - var destPos = vec2i((x + i32(src.x)), (y + i32(src.y))); - var dest = getCell(destPos.x, destPos.y); + let src = getCell(x, y); + let destPos = vec2i((x + i32(src.x)), (y + i32(src.y))); + let dest = getCell(destPos.x, destPos.y); let diff = (src.z - dest.z); var outFlow = min(max(0.01f, (0.3f + (diff * 0.1f))), src.z); if ((length(src.xy) < 0.5f)) { @@ -285,7 +285,7 @@ describe('fluid double buffering example', () => { fn getMinimumInFlow(x: i32, y: i32) -> f32 { const gridSizeF = 256f; let sourceRadius = max(1f, (sourceParams.radius * gridSizeF)); - var sourcePos = vec2f((sourceParams.center.x * gridSizeF), (sourceParams.center.y * gridSizeF)); + let sourcePos = vec2f((sourceParams.center.x * gridSizeF), (sourceParams.center.y * gridSizeF)); if ((distance(vec2f(f32(x), f32(y)), sourcePos) < sourceRadius)) { return sourceParams.intensity; } @@ -300,7 +300,7 @@ describe('fluid double buffering example', () => { let index = coordsToIndex(x, y); randSeed2(vec2f(f32(index), time)); var next = getCell(x, y); - var nextVelocity = computeVelocity(x, y); + let nextVelocity = computeVelocity(x, y); next.x = nextVelocity.x; next.y = nextVelocity.y; next.z = flowFromCell(x, y, x, y); @@ -400,13 +400,13 @@ describe('fluid double buffering example', () => { fn computeVelocity(x: i32, y: i32) -> vec2f { const gravityCost = 0.5; var neighborOffsets = array(vec2i(0, 1), vec2i(0, -1), vec2i(1, 0), vec2i(-1, 0)); - var cell = getCell(x, y); + let cell = getCell(x, y); var leastCost = cell.z; var dirChoices = array(vec2f(), vec2f(), vec2f(), vec2f()); var dirChoiceCount = 1; // unrolled iteration #0 { - var neighborDensity = getCell((x + neighborOffsets[0u].x), (y + neighborOffsets[0u].y)); + let neighborDensity = getCell((x + neighborOffsets[0u].x), (y + neighborOffsets[0u].y)); let cost = (neighborDensity.z + (f32(neighborOffsets[0u].y) * gravityCost)); if (isValidFlowOut((x + neighborOffsets[0u].x), (y + neighborOffsets[0u].y))) { if ((cost == leastCost)) { @@ -424,7 +424,7 @@ describe('fluid double buffering example', () => { } // unrolled iteration #1 { - var neighborDensity = getCell((x + neighborOffsets[1u].x), (y + neighborOffsets[1u].y)); + let neighborDensity = getCell((x + neighborOffsets[1u].x), (y + neighborOffsets[1u].y)); let cost = (neighborDensity.z + (f32(neighborOffsets[1u].y) * gravityCost)); if (isValidFlowOut((x + neighborOffsets[1u].x), (y + neighborOffsets[1u].y))) { if ((cost == leastCost)) { @@ -442,7 +442,7 @@ describe('fluid double buffering example', () => { } // unrolled iteration #2 { - var neighborDensity = getCell((x + neighborOffsets[2u].x), (y + neighborOffsets[2u].y)); + let neighborDensity = getCell((x + neighborOffsets[2u].x), (y + neighborOffsets[2u].y)); let cost = (neighborDensity.z + (f32(neighborOffsets[2u].y) * gravityCost)); if (isValidFlowOut((x + neighborOffsets[2u].x), (y + neighborOffsets[2u].y))) { if ((cost == leastCost)) { @@ -460,7 +460,7 @@ describe('fluid double buffering example', () => { } // unrolled iteration #3 { - var neighborDensity = getCell((x + neighborOffsets[3u].x), (y + neighborOffsets[3u].y)); + let neighborDensity = getCell((x + neighborOffsets[3u].x), (y + neighborOffsets[3u].y)); let cost = (neighborDensity.z + (f32(neighborOffsets[3u].y) * gravityCost)); if (isValidFlowOut((x + neighborOffsets[3u].x), (y + neighborOffsets[3u].y))) { if ((cost == leastCost)) { @@ -484,9 +484,9 @@ describe('fluid double buffering example', () => { if (!isValidCoord(x, y)) { return 0; } - var src = getCell(x, y); - var destPos = vec2i((x + i32(src.x)), (y + i32(src.y))); - var dest = getCell(destPos.x, destPos.y); + let src = getCell(x, y); + let destPos = vec2i((x + i32(src.x)), (y + i32(src.y))); + let dest = getCell(destPos.x, destPos.y); let diff = (src.z - dest.z); var outFlow = min(max(0.01f, (0.3f + (diff * 0.1f))), src.z); if ((length(src.xy) < 0.5f)) { @@ -512,7 +512,7 @@ describe('fluid double buffering example', () => { fn getMinimumInFlow(x: i32, y: i32) -> f32 { const gridSizeF = 256f; let sourceRadius = max(1f, (sourceParams.radius * gridSizeF)); - var sourcePos = vec2f((sourceParams.center.x * gridSizeF), (sourceParams.center.y * gridSizeF)); + let sourcePos = vec2f((sourceParams.center.x * gridSizeF), (sourceParams.center.y * gridSizeF)); if ((distance(vec2f(f32(x), f32(y)), sourcePos) < sourceRadius)) { return sourceParams.intensity; } @@ -527,7 +527,7 @@ describe('fluid double buffering example', () => { let index = coordsToIndex(x, y); randSeed2(vec2f(f32(index), time)); var next = getCell(x, y); - var nextVelocity = computeVelocity(x, y); + let nextVelocity = computeVelocity(x, y); next.x = nextVelocity.x; next.y = nextVelocity.y; next.z = flowFromCell(x, y, x, y); @@ -553,15 +553,11 @@ describe('fluid double buffering example', () => { } @vertex fn vertexMain(@builtin(vertex_index) _arg_idx: u32) -> vertexMain_Output { - var pos = array(vec2f(1), vec2f(-1, 1), vec2f(1, -1), vec2f(-1)); - var uv = array(vec2f(1), vec2f(0, 1), vec2f(1, 0), vec2f()); + let pos = array(vec2f(1), vec2f(-1, 1), vec2f(1, -1), vec2f(-1)); + let uv = array(vec2f(1), vec2f(0, 1), vec2f(1, 0), vec2f()); return vertexMain_Output(vec4f(pos[_arg_idx].x, pos[_arg_idx].y, 0f, 1f), uv[_arg_idx]); } - struct fragmentMain_Input { - @location(0) uv: vec2f, - } - fn coordsToIndex(x: i32, y: i32) -> i32 { return (x + (y * 256i)); } @@ -595,17 +591,21 @@ describe('fluid double buffering example', () => { return false; } + struct fragmentMain_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentMain(_arg_0: fragmentMain_Input) -> @location(0) vec4f { let x = i32((_arg_0.uv.x * 256f)); let y = i32((_arg_0.uv.y * 256f)); let index = coordsToIndex(x, y); let cell = (&gridAlphaBuffer[index]); let density = max(0f, (*cell).z); - var obstacleColor = vec4f(0.10000000149011612, 0.10000000149011612, 0.10000000149011612, 1); - var background = vec4f(0.8999999761581421, 0.8999999761581421, 0.8999999761581421, 1); - var firstColor = vec4f(0.20000000298023224, 0.6000000238418579, 1, 1); - var secondColor = vec4f(0.20000000298023224, 0.30000001192092896, 0.6000000238418579, 1); - var thirdColor = vec4f(0.10000000149011612, 0.20000000298023224, 0.4000000059604645, 1); + let obstacleColor = vec4f(0.10000000149011612, 0.10000000149011612, 0.10000000149011612, 1); + let background = vec4f(0.8999999761581421, 0.8999999761581421, 0.8999999761581421, 1); + let firstColor = vec4f(0.20000000298023224, 0.6000000238418579, 1, 1); + let secondColor = vec4f(0.20000000298023224, 0.30000001192092896, 0.6000000238418579, 1); + let thirdColor = vec4f(0.10000000149011612, 0.20000000298023224, 0.4000000059604645, 1); const firstThreshold = 2f; const secondThreshold = 10f; const thirdThreshold = 20f; diff --git a/apps/typegpu-docs/tests/individual-example-tests/function-visualizer.test.ts b/apps/typegpu-docs/tests/individual-example-tests/function-visualizer.test.ts index 492f38c59d..eb44a19266 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/function-visualizer.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/function-visualizer.test.ts @@ -45,7 +45,7 @@ describe('function visualizer example', () => { let end = ((*properties).transformation * vec4f(1, 0, 0, 1)).x; let pointX = (start + (((end - start) / (f32((*properties).interpolationPoints) - 1f)) * f32(x))); let pointY = interpolatedFunction(pointX); - var result = ((*properties).inverseTransformation * vec4f(pointX, pointY, 0f, 1f)); + let result = ((*properties).inverseTransformation * vec4f(pointX, pointY, 0f, 1f)); lineVertices[x] = result.xy; } @@ -79,7 +79,7 @@ describe('function visualizer example', () => { let end = ((*properties).transformation * vec4f(1, 0, 0, 1)).x; let pointX = (start + (((end - start) / (f32((*properties).interpolationPoints) - 1f)) * f32(x))); let pointY = interpolatedFunction(pointX); - var result = ((*properties).inverseTransformation * vec4f(pointX, pointY, 0f, 1f)); + let result = ((*properties).inverseTransformation * vec4f(pointX, pointY, 0f, 1f)); lineVertices[x] = result.xy; } @@ -113,7 +113,7 @@ describe('function visualizer example', () => { let end = ((*properties).transformation * vec4f(1, 0, 0, 1)).x; let pointX = (start + (((end - start) / (f32((*properties).interpolationPoints) - 1f)) * f32(x))); let pointY = interpolatedFunction(pointX); - var result = ((*properties).inverseTransformation * vec4f(pointX, pointY, 0f, 1f)); + let result = ((*properties).inverseTransformation * vec4f(pointX, pointY, 0f, 1f)); lineVertices[x] = result.xy; } @@ -139,11 +139,11 @@ describe('function visualizer example', () => { @vertex fn backgroundVertex(@builtin(vertex_index) vid: u32, @builtin(instance_index) iid: u32) -> backgroundVertex_Output { let properties = (&propertiesUniform); - var leftBot = ((*properties).transformation * vec4f(-1, -1, 0, 1)); - var rightTop = ((*properties).transformation * vec4f(1, 1, 0, 1)); + let leftBot = ((*properties).transformation * vec4f(-1, -1, 0, 1)); + let rightTop = ((*properties).transformation * vec4f(1, 1, 0, 1)); let aspectRatio = ((rightTop.x - leftBot.x) / (rightTop.y - leftBot.y)); - var transformedPoints = array(vec2f(leftBot.x, 0f), vec2f(rightTop.x, 0f), vec2f(0f, leftBot.y), vec2f(0f, rightTop.y)); - var currentPoint = ((*properties).inverseTransformation * vec4f(transformedPoints[((2u * iid) + u32((f32(vid) / 2f)))].xy, 0f, 1f)); + let transformedPoints = array(vec2f(leftBot.x, 0f), vec2f(rightTop.x, 0f), vec2f(0f, leftBot.y), vec2f(0f, rightTop.y)); + let currentPoint = ((*properties).inverseTransformation * vec4f(transformedPoints[((2u * iid) + u32((f32(vid) / 2f)))].xy, 0f, 1f)); return backgroundVertex_Output(vec4f((currentPoint.x + (((f32(iid) * select(-1f, 1f, ((vid % 2u) == 0u))) * 5e-3f) / aspectRatio)), (currentPoint.y + ((f32((1u - iid)) * select(-1f, 1f, ((vid % 2u) == 0u))) * 5e-3f)), currentPoint.zw)); } @@ -163,8 +163,8 @@ describe('function visualizer example', () => { @group(1) @binding(0) var lineVertices_1: array; fn orthonormalForLine(p1: vec2f, p2: vec2f) -> vec2f { - var line = (p2 - p1); - var ortho = vec2f(-(line.y), line.x); + let line = (p2 - p1); + let ortho = vec2f(-(line.y), line.x); return normalize(ortho); } @@ -176,9 +176,9 @@ describe('function visualizer example', () => { let previous = (&(*lineVertices)[u32((index - 1f))]); let current = (&(*lineVertices)[u32(index)]); let next = (&(*lineVertices)[u32((index + 1f))]); - var n1 = orthonormalForLine((*previous), (*current)); - var n2 = orthonormalForLine((*current), (*next)); - var avg = ((n1 + n2) / 2f); + let n1 = orthonormalForLine((*previous), (*current)); + let n2 = orthonormalForLine((*current), (*next)); + let avg = ((n1 + n2) / 2f); return normalize(avg); } @@ -190,12 +190,12 @@ describe('function visualizer example', () => { let properties = (&propertiesUniform); let lineVertices = (&lineVertices_1); let currentVertex = (f32(vid) / 2f); - var orthonormal = orthonormalForVertex(currentVertex); - var offset = ((orthonormal * (*properties).lineWidth) * select(-1f, 1f, ((vid % 2u) == 0u))); - var leftBot = ((*properties).transformation * vec4f(-1, -1, 0, 1)); - var rightTop = ((*properties).transformation * vec4f(1, 1, 0, 1)); + let orthonormal = orthonormalForVertex(currentVertex); + let offset = ((orthonormal * (*properties).lineWidth) * select(-1f, 1f, ((vid % 2u) == 0u))); + let leftBot = ((*properties).transformation * vec4f(-1, -1, 0, 1)); + let rightTop = ((*properties).transformation * vec4f(1, 1, 0, 1)); let canvasRatio = ((rightTop.x - leftBot.x) / (rightTop.y - leftBot.y)); - var adjustedOffset = vec2f((offset.x / canvasRatio), offset.y); + let adjustedOffset = vec2f((offset.x / canvasRatio), offset.y); return vertex_Output(vec4f(((*lineVertices)[u32(currentVertex)] + adjustedOffset), 0f, 1f)); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/game-of-life.test.ts b/apps/typegpu-docs/tests/individual-example-tests/game-of-life.test.ts index 3028c19bf5..f1b93c8c5b 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/game-of-life.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/game-of-life.test.ts @@ -76,7 +76,7 @@ describe('game of life example', () => { @compute @workgroup_size(16, 16) fn naiveCompute(@builtin(global_invocation_id) gid: vec3u) { let gs = gameSizeUniform; let vmax = (gs - 1u); - var p = gid.xy; + let p = gid.xy; var neighbors = 0u; for (var oy = -1; (oy <= 1i); oy++) { for (var ox = -1; (ox <= 1i); ox++) { @@ -124,8 +124,8 @@ describe('game of life example', () => { @compute @workgroup_size(16, 16) fn tiledCompute(@builtin(global_invocation_id) gid: vec3u, @builtin(local_invocation_id) lid: vec3u, @builtin(workgroup_id) wgid: vec3u) { let gs = f32(gameSizeUniform); - var texelSize = (vec2f(1) / gs); - var tileOrigin = ((vec2f(wgid.xy) * 16f) - 1f); + let texelSize = (vec2f(1) / gs); + let tileOrigin = ((vec2f(wgid.xy) * 16f) - 1f); let linearId = ((lid.y * 16u) + lid.x); const numGathers = 81u; if ((linearId < numGathers)) { @@ -133,8 +133,8 @@ describe('game of life example', () => { let gy = u32((f32(linearId) / 9f)); let sx = (gx * 2u); let sy = (gy * 2u); - var uv = ((tileOrigin + vec2f(f32((sx + 1u)), f32((sy + 1u)))) * texelSize); - var g = textureGather(0i, current, sampler_1, uv); + let uv = ((tileOrigin + vec2f(f32((sx + 1u)), f32((sy + 1u)))) * texelSize); + let g = textureGather(0i, current, sampler_1, uv); sharedTile[tileIdx(sx, sy)] = g.w; sharedTile[tileIdx((sx + 1u), sy)] = g.z; sharedTile[tileIdx(sx, (sy + 1u))] = g.x; @@ -177,8 +177,8 @@ describe('game of life example', () => { @compute @workgroup_size(16, 16) fn tiledCompute(@builtin(global_invocation_id) gid: vec3u, @builtin(local_invocation_id) lid: vec3u, @builtin(workgroup_id) wgid: vec3u) { let gs = f32(gameSizeUniform); - var texelSize = (vec2f(1) / gs); - var tileOrigin = ((vec2f(wgid.xy) * 16f) - 1f); + let texelSize = (vec2f(1) / gs); + let tileOrigin = ((vec2f(wgid.xy) * 16f) - 1f); let linearId = ((lid.y * 16u) + lid.x); const numGathers = 81u; if ((linearId < numGathers)) { @@ -186,8 +186,8 @@ describe('game of life example', () => { let gy = u32((f32(linearId) / 9f)); let sx = (gx * 2u); let sy = (gy * 2u); - var uv = ((tileOrigin + vec2f(f32((sx + 1u)), f32((sy + 1u)))) * texelSize); - var g = textureGather(0i, current, sampler_1, uv); + let uv = ((tileOrigin + vec2f(f32((sx + 1u)), f32((sy + 1u)))) * texelSize); + let g = textureGather(0i, current, sampler_1, uv); sharedTile[tileIdx(sx, sy)] = g.w; sharedTile[tileIdx((sx + 1u), sy)] = g.z; sharedTile[tileIdx(sx, (sy + 1u))] = g.x; @@ -214,10 +214,6 @@ describe('game of life example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct displayFragment_Input { - @location(0) uv: vec2f, - } - struct ZoomParams { enabled: u32, level: f32, @@ -230,7 +226,7 @@ describe('game of life example', () => { @group(0) @binding(1) var gameSizeUniform: u32; fn sdRoundedBox2d(point: vec2f, size: vec2f, cornerRadius: f32) -> f32 { - var d = ((abs(point) - size) + vec2f(cornerRadius)); + let d = ((abs(point) - size) + vec2f(cornerRadius)); return ((length(max(d, vec2f())) + min(max(d.x, d.y), 0f)) - cornerRadius); } @@ -242,17 +238,21 @@ describe('game of life example', () => { @group(0) @binding(2) var viewModeUniform: u32; + struct displayFragment_Input { + @location(0) uv: vec2f, + } + @fragment fn displayFragment(_arg_0: displayFragment_Input) -> @location(0) vec4f { let zoom = (&zoomUniform); let gs = f32(gameSizeUniform); let halfView = (0.5f / (*zoom).level); - var clampedCenter = clamp(vec2f((*zoom).centerX, (*zoom).centerY), vec2f(halfView), vec2f((1f - halfView))); - var minimapMin = vec2f(0.7799999713897705); - var minimapMax = vec2f(0.9800000190734863); + let clampedCenter = clamp(vec2f((*zoom).centerX, (*zoom).centerY), vec2f(halfView), vec2f((1f - halfView))); + let minimapMin = vec2f(0.7799999713897705); + let minimapMax = vec2f(0.9800000190734863); const minimapSize = 0.2; let inMinimap = ((((((*zoom).enabled == 1u) && (_arg_0.uv.x >= minimapMin.x)) && (_arg_0.uv.x <= minimapMax.x)) && (_arg_0.uv.y >= minimapMin.y)) && (_arg_0.uv.y <= minimapMax.y)); if (inMinimap) { - var localUv = ((_arg_0.uv - minimapMin) / minimapSize); + let localUv = ((_arg_0.uv - minimapMin) / minimapSize); let edgeDist = sdRoundedBox2d((localUv - 0.5f), vec2f(0.5), 0.02f); if ((edgeDist > -0.02f)) { let alpha = (1f - smoothstep(0f, 0.02f, edgeDist)); @@ -262,12 +262,12 @@ describe('game of life example', () => { let dist = sdRoundedBox2d((localUv - clampedCenter), vec2f((viewSize / 2f)), 0.01f); const borderWidth = 0.015; if (((dist > -(borderWidth)) && (dist < borderWidth))) { - var borderColor = mix(vec4f(0.7689999938011169, 0.3919999897480011, 1, 1), vec4f(0.11400000005960464, 0.44699999690055847, 0.9409999847412109, 1), localUv.x); + let borderColor = mix(vec4f(0.7689999938011169, 0.3919999897480011, 1, 1), vec4f(0.11400000005960464, 0.44699999690055847, 0.9409999847412109, 1), localUv.x); let a = (1f - smoothstep(0f, borderWidth, abs(dist))); return vec4f(borderColor.x, borderColor.y, borderColor.z, a); } let value = sampleRegular(localUv, gs); - var alive = select(vec4f((localUv.x / 2.5f), (localUv.y / 2.5f), ((1f - localUv.x) / 2.5f), 0.8f), vec4f(0.6000000238418579, 0.6000000238418579, 0.6000000238418579, 0.800000011920929), (viewModeUniform == 1u)); + let alive = select(vec4f((localUv.x / 2.5f), (localUv.y / 2.5f), ((1f - localUv.x) / 2.5f), 0.8f), vec4f(0.6000000238418579, 0.6000000238418579, 0.6000000238418579, 0.800000011920929), (viewModeUniform == 1u)); return select(vec4f(0, 0, 0, 0.800000011920929), alive, (value == 1u)); } var sampleUv = _arg_0.uv; @@ -276,8 +276,8 @@ describe('game of life example', () => { } let value = sampleRegular(sampleUv, gs); let isClassic = (viewModeUniform == 1u); - var alive = select(normalize(vec4f((sampleUv.x / 1.5f), (sampleUv.y / 1.5f), (1f - (sampleUv.x / 1.5f)), 1f)), vec4f(1), isClassic); - var dead = select(vec4f(), vec4f(0, 0, 0, 1), isClassic); + let alive = select(normalize(vec4f((sampleUv.x / 1.5f), (sampleUv.y / 1.5f), (1f - (sampleUv.x / 1.5f)), 1f)), vec4f(1), isClassic); + let dead = select(vec4f(), vec4f(0, 0, 0, 1), isClassic); return select(dead, alive, (value == 1u)); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/global-wind-map.test.ts b/apps/typegpu-docs/tests/individual-example-tests/global-wind-map.test.ts index 0853d247e9..ea5ca7f7ad 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/global-wind-map.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/global-wind-map.test.ts @@ -45,9 +45,9 @@ describe('global wind map example', () => { let currentPosIndex = (frameCount % 20u); let prevPosIndex = (((20u + frameCount) - 1u) % 20u); let pos = (&(*particle).positions[prevPosIndex]); - var v0 = vectorField((*pos)); - var v1 = vectorField(((*pos) + (v0 * (0.5f * stepSize)))); - var newPos = ((*pos) + (v1 * stepSize)); + let v0 = vectorField((*pos)); + let v1 = vectorField(((*pos) + (v0 * (0.5f * stepSize)))); + let newPos = ((*pos) + (v1 * stepSize)); (*particle).positions[currentPosIndex] = newPos; particles[particleIndex] = (*particle); } @@ -99,13 +99,13 @@ describe('global wind map example', () => { let b = (distance_1.y * sinDivLen); let c = (distance_1.x * sinDivLen); let d = (distance_1.y * cosDivLen); - var nL = vec2f((a - b), (c + d)); - var nR = vec2f((a + b), (-(c) + d)); + let nL = vec2f((a - b), (c + d)); + let nR = vec2f((a + b), (-(c) + d)); return ExternalNormals(nL, nR); } fn miterPointNoCheck(a: vec2f, b: vec2f) -> vec2f { - var ab = (a + b); + let ab = (a + b); return (ab * (2f / dot(ab, ab))); } @@ -125,10 +125,10 @@ describe('global wind map example', () => { let tooCloseToJoinR = (dot(eAB.nR, eBC.nR) > 0.99f); let shouldJoinL = (isHairpin || (underLimitL && !tooCloseToJoinL)); let shouldJoinR = (isHairpin || (underLimitR && !tooCloseToJoinR)); - var dLMiter = miterPointNoCheck(eAB.nL, eBC.nL); - var dRMiter = miterPointNoCheck(eBC.nR, eAB.nR); - var dL = select(eBC.nL, dLMiter, (!isCap && !shouldJoinL)); - var dR = select(eBC.nR, dRMiter, (!isCap && !shouldJoinR)); + let dLMiter = miterPointNoCheck(eAB.nL, eBC.nL); + let dRMiter = miterPointNoCheck(eBC.nR, eAB.nR); + let dL = select(eBC.nL, dLMiter, (!isCap && !shouldJoinL)); + let dR = select(eBC.nR, dRMiter, (!isCap && !shouldJoinR)); return JoinResult(dL, dR, shouldJoinL, shouldJoinR, isHairpin); } @@ -143,10 +143,10 @@ describe('global wind map example', () => { } fn intersectLines(A1: vec2f, A2: vec2f, B1: vec2f, B2: vec2f) -> Intersection { - var a = (A2 - A1); - var b = (B2 - B1); + let a = (A2 - A1); + let b = (B2 - B1); let axb = cross2d(a, b); - var AB = (B1 - A1); + let AB = (B1 - A1); let t = (cross2d(AB, b) / axb); return Intersection((((axb != 0f) && (t >= 0f)) && (t <= 1f)), t, (A1 + (a * t))); } @@ -167,12 +167,12 @@ describe('global wind map example', () => { } fn arrow(join: JoinInput, joinVertexIndex: u32, _maxJoinCount: u32) -> vec2f { - var bw = -(normalize(join.fw)); - var vert = rot90ccw(bw); + let bw = -(normalize(join.fw)); + let vert = rot90ccw(bw); let sgn = sign(cross2d(bw, join.d)); - var svert = (vert * sgn); - var v0 = (svert + (bw * 7.5f)); - var v1 = (v0 + ((bw + svert) * 1.5f)); + let svert = (vert * sgn); + let v0 = (svert + (bw * 7.5f)); + let v1 = (v0 + ((bw + svert) * 1.5f)); if ((joinVertexIndex == 0u)) { return (join.C.position + (v0 * join.C.radius)); } @@ -183,10 +183,10 @@ describe('global wind map example', () => { } fn butt(join: JoinInput, _joinVertexIndex: u32, _maxJoinCount: u32) -> vec2f { - var fw = normalize(join.fw); - var vert = rot90ccw(fw); + let fw = normalize(join.fw); + let vert = rot90ccw(fw); let sgn = sign(cross2d(fw, join.d)); - var svert = (vert * sgn); + let svert = (vert * sgn); return (join.C.position + (svert * join.C.radius)); } @@ -197,9 +197,9 @@ describe('global wind map example', () => { fn bisectCcw(a: vec2f, b: vec2f) -> vec2f { let sin_1 = cross2d(a, b); let sinSign = select(-1f, 1f, (sin_1 >= 0f)); - var orthoA = rot90ccw(a); - var orthoB = rot90cw(b); - var dir = select(((a + b) * sinSign), (orthoA + orthoB), (dot(a, b) < 0f)); + let orthoA = rot90ccw(a); + let orthoB = rot90cw(b); + let dir = select(((a + b) * sinSign), (orthoA + orthoB), (dot(a, b) < 0f)); return normalize(dir); } @@ -208,7 +208,7 @@ describe('global wind map example', () => { } fn slerpApprox(a: vec2f, b: vec2f, t: f32) -> vec2f { - var mid = bisectNoCheck(a, b); + let mid = bisectNoCheck(a, b); var a_ = a; var b_ = mid; var t_ = (2f * t); @@ -224,15 +224,15 @@ describe('global wind map example', () => { if ((joinVertexIndex == 0u)) { return join.v; } - var dir = slerpApprox(join.d, bisectCcw(join.start, join.end), (f32(joinVertexIndex) / f32(maxJoinCount))); + let dir = slerpApprox(join.d, bisectCcw(join.start, join.end), (f32(joinVertexIndex) / f32(maxJoinCount))); return (join.C.position + (dir * join.C.radius)); } fn lineSegmentVariableWidth(vertexIndex: u32, A: LineControlPoint, B: LineControlPoint, C: LineControlPoint, D: LineControlPoint, maxJoinCount: u32) -> LineSegmentOutput { - var AB = (B.position - A.position); - var BC = (C.position - B.position); - var DC = (C.position - D.position); - var CB = -(BC); + let AB = (B.position - A.position); + let BC = (C.position - B.position); + let DC = (C.position - D.position); + let CB = -(BC); let radiusABDelta = (A.radius - B.radius); let radiusBCDelta = (B.radius - C.radius); let radiusCDDelta = (C.radius - D.radius); @@ -241,10 +241,10 @@ describe('global wind map example', () => { } let isCapB = (dot(AB, AB) <= (radiusABDelta * radiusABDelta)); let isCapC = (dot(DC, DC) <= (radiusCDDelta * radiusCDDelta)); - var eAB = externalNormals(AB, A.radius, B.radius); - var eBC = externalNormals(BC, B.radius, C.radius); - var eCB = ExternalNormals(eBC.nR, eBC.nL); - var eDC = externalNormals(DC, D.radius, C.radius); + let eAB = externalNormals(AB, A.radius, B.radius); + let eBC = externalNormals(BC, B.radius, C.radius); + let eCB = ExternalNormals(eBC.nR, eBC.nL); + let eDC = externalNormals(DC, D.radius, C.radius); let joinLimit = dot(eBC.nL, BC); var joinB = solveJoin(AB, BC, eAB, eBC, joinLimit, isCapB); var joinC = solveJoin(DC, CB, eDC, eCB, -(joinLimit), isCapC); @@ -252,16 +252,16 @@ describe('global wind map example', () => { let d3 = (&joinB.dR); let d4 = (&joinC.dL); let d5 = (&joinC.dR); - var v2orig = (B.position + ((*d2) * B.radius)); - var v3orig = (B.position + ((*d3) * B.radius)); - var v4orig = (C.position + ((*d4) * C.radius)); - var v5orig = (C.position + ((*d5) * C.radius)); - var limL = intersectLines(B.position, v2orig, C.position, v5orig); - var limR = intersectLines(B.position, v3orig, C.position, v4orig); - var v2 = select(v2orig, limL.point, limL.valid); - var v5 = select(v5orig, limL.point, limL.valid); - var v3 = select(v3orig, limR.point, limR.valid); - var v4 = select(v4orig, limR.point, limR.valid); + let v2orig = (B.position + ((*d2) * B.radius)); + let v3orig = (B.position + ((*d3) * B.radius)); + let v4orig = (C.position + ((*d4) * C.radius)); + let v5orig = (C.position + ((*d5) * C.radius)); + let limL = intersectLines(B.position, v2orig, C.position, v5orig); + let limR = intersectLines(B.position, v3orig, C.position, v4orig); + let v2 = select(v2orig, limL.point, limL.valid); + let v5 = select(v5orig, limL.point, limL.valid); + let v3 = select(v3orig, limR.point, limR.valid); + let v4 = select(v4orig, limR.point, limR.valid); if ((vertexIndex == 0u)) { return LineSegmentOutput(B.position, (1f / B.radius)); } @@ -319,11 +319,11 @@ describe('global wind map example', () => { let iB = trailIndex; let iC = (((20i + trailIndex) - 1i) % 20i); let iD = (((20i + trailIndex) - 2i) % 20i); - var A = LineControlPoint((*particle).positions[iA], lineWidth((f32(trailIndexOriginal) / 19f))); - var B = LineControlPoint((*particle).positions[iB], lineWidth((f32((trailIndexOriginal + 1u)) / 19f))); - var C = LineControlPoint((*particle).positions[iC], lineWidth((f32((trailIndexOriginal + 2u)) / 19f))); - var D = LineControlPoint((*particle).positions[iD], lineWidth((f32((trailIndexOriginal + 3u)) / 19f))); - var result = lineSegmentVariableWidth(vertexIndex, A, B, C, D, 3u); + let A = LineControlPoint((*particle).positions[iA], lineWidth((f32(trailIndexOriginal) / 19f))); + let B = LineControlPoint((*particle).positions[iB], lineWidth((f32((trailIndexOriginal + 1u)) / 19f))); + let C = LineControlPoint((*particle).positions[iC], lineWidth((f32((trailIndexOriginal + 2u)) / 19f))); + let D = LineControlPoint((*particle).positions[iD], lineWidth((f32((trailIndexOriginal + 3u)) / 19f))); + let result = lineSegmentVariableWidth(vertexIndex, A, B, C, D, 3u); return mainVertex_Output(vec4f(result.vertexPosition, 0f, 1f), result.vertexPosition, (f32(trailIndexOriginal) / 19f)); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/gradient-tiles.test.ts b/apps/typegpu-docs/tests/individual-example-tests/gradient-tiles.test.ts index f0d3016198..d3c209eb18 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/gradient-tiles.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/gradient-tiles.test.ts @@ -32,12 +32,12 @@ describe('gradient tiles example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } + @group(0) @binding(0) var spanUniform: vec2f; + struct fragment_Input { @location(0) uv: vec2f, } - @group(0) @binding(0) var spanUniform: vec2f; - @fragment fn fragment(_arg_0: fragment_Input) -> @location(0) vec4f { let red = (floor((_arg_0.uv.x * spanUniform.x)) / spanUniform.x); let green = (floor((_arg_0.uv.y * spanUniform.y)) / spanUniform.y); diff --git a/apps/typegpu-docs/tests/individual-example-tests/gravity.test.ts b/apps/typegpu-docs/tests/individual-example-tests/gravity.test.ts index 55ed0d2fb8..61311326c3 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/gravity.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/gravity.test.ts @@ -98,11 +98,11 @@ describe('gravity example', () => { } if (((current.collisionBehavior == 1u) && ((*other).collisionBehavior == 1u))) { if (isSmaller(currentId, otherId)) { - var dir = normalize((current.position - (*other).position)); + let dir = normalize((current.position - (*other).position)); current.position = ((*other).position + (dir * (radiusOf(current) + radiusOf((*other))))); } - var posDiff = (current.position - (*other).position); - var velDiff = (current.velocity - (*other).velocity); + let posDiff = (current.position - (*other).position); + let velDiff = (current.velocity - (*other).velocity); let posDiffFactor = ((((2f * (*other).mass) / (current.mass + (*other).mass)) * dot(velDiff, posDiff)) / dot(posDiff, posDiff)); current.velocity = ((current.velocity - (posDiff * posDiffFactor)) * 0.99f); } @@ -163,7 +163,7 @@ describe('gravity example', () => { } let dist = max((radiusOf(current) + radiusOf((*other))), distance(current.position, (*other).position)); let gravityForce = (((current.mass * (*other).mass) / dist) / dist); - var direction = normalize(((*other).position - current.position)); + let direction = normalize(((*other).position - current.position)); current.velocity += ((direction * (gravityForce / current.mass)) * dt); } current.position += (current.velocity * dt); @@ -188,18 +188,18 @@ describe('gravity example', () => { } @vertex fn skyBoxVertex(@location(0) _arg_position: vec3f) -> skyBoxVertex_Output { - var viewPos = (camera.view * vec4f(_arg_position, 0f)).xyz; + let viewPos = (camera.view * vec4f(_arg_position, 0f)).xyz; return skyBoxVertex_Output((camera.projection * vec4f(viewPos, 1f)), _arg_position.xyz); } - struct skyBoxFragment_Input { - @location(0) texCoord: vec3f, - } - @group(0) @binding(1) var skyBox: texture_cube; @group(0) @binding(2) var sampler_1: sampler; + struct skyBoxFragment_Input { + @location(0) texCoord: vec3f, + } + @fragment fn skyBoxFragment(_arg_0: skyBoxFragment_Input) -> @location(0) vec4f { return textureSample(skyBox, sampler_1, normalize(_arg_0.texCoord)); } @@ -244,12 +244,18 @@ describe('gravity example', () => { @vertex fn mainVertex(@location(0) _arg_position: vec3f, @location(1) _arg_normal: vec3f, @location(2) _arg_uv: vec2f, @builtin(instance_index) _arg_instanceIndex: u32) -> mainVertex_Output { let currentBody = (&celestialBodies[_arg_instanceIndex]); - var worldPosition = ((*currentBody).position + (_arg_position.xyz * radiusOf((*currentBody)))); + let worldPosition = ((*currentBody).position + (_arg_position.xyz * radiusOf((*currentBody)))); let camera = (&camera_1); - var positionOnCanvas = (((*camera).projection * (*camera).view) * vec4f(worldPosition, 1f)); + let positionOnCanvas = (((*camera).projection * (*camera).view) * vec4f(worldPosition, 1f)); return mainVertex_Output(positionOnCanvas, _arg_uv, _arg_normal, worldPosition, (*currentBody).textureIndex, (*currentBody).destroyed, (*currentBody).ambientLightFactor); } + @group(1) @binding(0) var celestialBodyTextures: texture_2d_array; + + @group(0) @binding(1) var sampler_1: sampler; + + @group(0) @binding(2) var lightSource: vec3f; + struct mainFragment_Input { @location(0) uv: vec2f, @location(1) normals: vec3f, @@ -259,23 +265,17 @@ describe('gravity example', () => { @location(5) ambientLightFactor: f32, } - @group(1) @binding(0) var celestialBodyTextures: texture_2d_array; - - @group(0) @binding(1) var sampler_1: sampler; - - @group(0) @binding(2) var lightSource: vec3f; - @fragment fn mainFragment(_arg_0: mainFragment_Input) -> @location(0) vec4f { if ((_arg_0.destroyed == 1u)) { discard;; } - var lightColor = vec3f(1, 0.8999999761581421, 0.8999999761581421); - var textureColor = textureSample(celestialBodyTextures, sampler_1, _arg_0.uv, _arg_0.sphereTextureIndex).rgb; - var ambient = ((textureColor * lightColor) * _arg_0.ambientLightFactor); + let lightColor = vec3f(1, 0.8999999761581421, 0.8999999761581421); + let textureColor = textureSample(celestialBodyTextures, sampler_1, _arg_0.uv, _arg_0.sphereTextureIndex).rgb; + let ambient = ((textureColor * lightColor) * _arg_0.ambientLightFactor); let normal = _arg_0.normals; - var lightDirection = normalize((lightSource - _arg_0.worldPosition)); + let lightDirection = normalize((lightSource - _arg_0.worldPosition)); let cosTheta = dot(normal, lightDirection); - var diffuse = ((textureColor * lightColor) * max(0f, cosTheta)); + let diffuse = ((textureColor * lightColor) * max(0f, cosTheta)); return vec4f((ambient + diffuse), 1f); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/image-tuning.test.ts b/apps/typegpu-docs/tests/individual-example-tests/image-tuning.test.ts index a9fa1865c8..f825d77895 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/image-tuning.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/image-tuning.test.ts @@ -37,10 +37,6 @@ describe('image tuning example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct fragment_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var imageView: texture_2d; @group(0) @binding(1) var imageSampler: sampler; @@ -68,16 +64,20 @@ describe('image tuning example', () => { @group(0) @binding(4) var adjustments: Adjustments; + struct fragment_Input { + @location(0) uv: vec2f, + } + @fragment fn fragment(_arg_0: fragment_Input) -> @location(0) vec4f { - var color = textureSample(imageView, imageSampler, _arg_0.uv).rgb; + let color = textureSample(imageView, imageSampler, _arg_0.uv).rgb; let inputLuminance = dot(color, vec3f(0.29899999499320984, 0.5870000123977661, 0.11400000005960464)); - var normColor = saturate(((color - lut.min) / (lut.max - lut.min))); - var lutColor = select(color, textureSampleLevel(currentLUTTexture, lutSampler, normColor, 0).rgb, bool(lut.enabled)); - var lutColorNormalized = saturate(lutColor); + let normColor = saturate(((color - lut.min) / (lut.max - lut.min))); + let lutColor = select(color, textureSampleLevel(currentLUTTexture, lutSampler, normColor, 0).rgb, bool(lut.enabled)); + let lutColorNormalized = saturate(lutColor); let exposureBiased = (adjustments.exposure * 0.25f); - var exposureColor = clamp((lutColorNormalized * pow(2f, exposureBiased)), vec3f(), vec3f(2)); + let exposureColor = clamp((lutColorNormalized * pow(2f, exposureBiased)), vec3f(), vec3f(2)); let exposureLuminance = clamp((inputLuminance * pow(2f, exposureBiased)), 0f, 2f); - var contrastColor = (((exposureColor - 0.5f) * adjustments.contrast) + 0.5f); + let contrastColor = (((exposureColor - 0.5f) * adjustments.contrast) + 0.5f); let contrastLuminance = (((exposureLuminance - 0.5f) * adjustments.contrast) + 0.5f); let contrastColorLuminance = dot(contrastColor, vec3f(0.29899999499320984, 0.5870000123977661, 0.11400000005960464)); let highlightShift = (adjustments.highlights - 1f); @@ -86,15 +86,15 @@ describe('image tuning example', () => { let highlightWeight = smoothstep(0.5f, 1f, contrastColorLuminance); let highlightLuminanceAdjust = (contrastLuminance * highlightFactor); let highlightLuminance = mix(contrastLuminance, saturate(highlightLuminanceAdjust), highlightWeight); - var highlightColor = mix(contrastColor, saturate((contrastColor * highlightFactor)), highlightWeight); + let highlightColor = mix(contrastColor, saturate((contrastColor * highlightFactor)), highlightWeight); let shadowWeight = (1f - contrastColorLuminance); - var shadowAdjust = pow(highlightColor, vec3f((1f / adjustments.shadows))); + let shadowAdjust = pow(highlightColor, vec3f((1f / adjustments.shadows))); let shadowLuminanceAdjust = pow(highlightLuminance, (1f / adjustments.shadows)); - var toneColor = mix(highlightColor, shadowAdjust, shadowWeight); + let toneColor = mix(highlightColor, shadowAdjust, shadowWeight); let toneLuminance = mix(highlightLuminance, shadowLuminanceAdjust, shadowWeight); - var finalToneColor = saturate(toneColor); - var grayscaleColor = vec3f(toneLuminance); - var finalColor = mix(grayscaleColor, finalToneColor, adjustments.saturation); + let finalToneColor = saturate(toneColor); + let grayscaleColor = vec3f(toneLuminance); + let finalColor = mix(grayscaleColor, finalToneColor, adjustments.saturation); return vec4f(finalColor, 1f); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/jelly-slider.test.ts b/apps/typegpu-docs/tests/individual-example-tests/jelly-slider.test.ts index 941ee300b4..fefdfc76f6 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/jelly-slider.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/jelly-slider.test.ts @@ -66,10 +66,6 @@ describe('jelly-slider example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct raymarchFn_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var randomUniform: vec2f; var seed: vec2f; @@ -97,14 +93,14 @@ describe('jelly-slider example', () => { } fn getRay(ndc: vec2f) -> Ray { - var clipPos = vec4f(ndc.x, ndc.y, -1f, 1f); + let clipPos = vec4f(ndc.x, ndc.y, -1f, 1f); let invView = (&uniform_1.viewInv); let invProj = (&uniform_1.projInv); - var viewPos = ((*invProj) * clipPos); - var viewPosNormalized = vec4f((viewPos.xyz / viewPos.w), 1f); - var worldPos = ((*invView) * viewPosNormalized); - var rayOrigin = (*invView)[3i].xyz; - var rayDir = normalize((worldPos.xyz - rayOrigin)); + let viewPos = ((*invProj) * clipPos); + let viewPosNormalized = vec4f((viewPos.xyz / viewPos.w), 1f); + let worldPos = ((*invView) * viewPosNormalized); + let rayOrigin = (*invView)[3i].xyz; + let rayDir = normalize((worldPos.xyz - rayOrigin)); return Ray(rayOrigin, rayDir); } @@ -113,7 +109,7 @@ describe('jelly-slider example', () => { } fn sdRoundedBox2d(point: vec2f, size: vec2f, cornerRadius: f32) -> f32 { - var d = ((abs(point) - size) + vec2f(cornerRadius)); + let d = ((abs(point) - size) + vec2f(cornerRadius)); return ((length(max(d, vec2f())) + min(max(d.x, d.y), 0f)) - cornerRadius); } @@ -123,7 +119,7 @@ describe('jelly-slider example', () => { } fn opExtrudeY(point: vec3f, dd: f32, halfHeight: f32) -> f32 { - var w = vec2f(dd, (abs(point.y) - halfHeight)); + let w = vec2f(dd, (abs(point.y) - halfHeight)); return (min(max(w.x, w.y), 0f) + length(max(w, vec2f()))); } @@ -181,16 +177,16 @@ describe('jelly-slider example', () => { } fn getNormalFromSdf(position: vec3f, epsilon: f32) -> vec3f { - var k = vec3f(1, -1, 0); - var offset1 = (k.xyy * epsilon); - var offset2 = (k.yyx * epsilon); - var offset3 = (k.yxy * epsilon); - var offset4 = (k.xxx * epsilon); - var sample1 = (offset1 * getMainSceneDist((position + offset1))); - var sample2 = (offset2 * getMainSceneDist((position + offset2))); - var sample3 = (offset3 * getMainSceneDist((position + offset3))); - var sample4 = (offset4 * getMainSceneDist((position + offset4))); - var gradient = (((sample1 + sample2) + sample3) + sample4); + let k = vec3f(1, -1, 0); + let offset1 = (k.xyy * epsilon); + let offset2 = (k.yyx * epsilon); + let offset3 = (k.yxy * epsilon); + let offset4 = (k.xxx * epsilon); + let sample1 = (offset1 * getMainSceneDist((position + offset1))); + let sample2 = (offset2 * getMainSceneDist((position + offset2))); + let sample3 = (offset3 * getMainSceneDist((position + offset3))); + let sample4 = (offset4 * getMainSceneDist((position + offset4))); + let gradient = (((sample1 + sample2) + sample3) + sample4); return normalize(gradient); } @@ -219,10 +215,10 @@ describe('jelly-slider example', () => { return ((vec3f(1) * edgeDarkening) * (lightGradient * 0.5f)); } else { - var finalUV = vec2f((((position.x - ((position.z * lightDir.x) * sign(lightDir.z))) * 0.5f) + 0.5f), ((1f - ((-(position.z) / lightDir.z) * 0.5f)) - 0.2f)); - var data = textureSampleLevel(bezierTexture, filteringSampler, finalUV, 0); + let finalUV = vec2f((((position.x - ((position.z * lightDir.x) * sign(lightDir.z))) * 0.5f) + 0.5f), ((1f - ((-(position.z) / lightDir.z) * 0.5f)) - 0.2f)); + let data = textureSampleLevel(bezierTexture, filteringSampler, finalUV, 0); let jellySaturation = mix(0f, data.y, saturate(((position.x * 1.5f) + 1.1f))); - var shadowColor = mix(vec3f(), (*jellyColor).rgb, jellySaturation); + let shadowColor = mix(vec3f(), (*jellyColor).rgb, jellySaturation); let contrast = ((20f * saturate(finalUV.y)) * (0.8f + (endCapX * 0.2f))); const shadowOffset = -0.3; const featherSharpness = 10f; @@ -233,17 +229,17 @@ describe('jelly-slider example', () => { } fn calculateLighting(hitPosition: vec3f, normal: vec3f, rayOrigin: vec3f) -> vec3f { - var lightDir = -(lightUniform.direction); - var fakeShadow = getFakeShadow(hitPosition, lightDir); + let lightDir = -(lightUniform.direction); + let fakeShadow = getFakeShadow(hitPosition, lightDir); let diffuse = max(dot(normal, lightDir), 0f); - var viewDir = normalize((rayOrigin - hitPosition)); - var reflectDir = reflect(-(lightDir), normal); + let viewDir = normalize((rayOrigin - hitPosition)); + let reflectDir = reflect(-(lightDir), normal); let specularFactor = pow(max(dot(viewDir, reflectDir), 0f), 10f); - var specular = (lightUniform.color * (specularFactor * 0.6f)); - var baseColor = vec3f(0.8999999761581421); - var directionalLight = (((baseColor * lightUniform.color) * diffuse) * fakeShadow); - var ambientLight = ((baseColor * vec3f(0.6000000238418579)) * 0.6f); - var finalSpecular = (specular * fakeShadow); + let specular = (lightUniform.color * (specularFactor * 0.6f)); + let baseColor = vec3f(0.8999999761581421); + let directionalLight = (((baseColor * lightUniform.color) * diffuse) * fakeShadow); + let ambientLight = ((baseColor * vec3f(0.6000000238418579)) * 0.6f); + let finalSpecular = (specular * fakeShadow); return saturate(((directionalLight + ambientLight) + finalSpecular)); } @@ -265,28 +261,28 @@ describe('jelly-slider example', () => { } fn sdInflatedPolyline2D(p: vec2f) -> LineInfo { - var bbox = getSliderBbox(); - var uv = vec2f(((p.x - bbox.left) / (bbox.right - bbox.left)), ((bbox.top - p.y) / (bbox.top - bbox.bottom))); - var clampedUV = saturate(uv); - var sampledColor = textureSampleLevel(bezierTexture, filteringSampler, clampedUV, 0); + let bbox = getSliderBbox(); + let uv = vec2f(((p.x - bbox.left) / (bbox.right - bbox.left)), ((bbox.top - p.y) / (bbox.top - bbox.bottom))); + let clampedUV = saturate(uv); + let sampledColor = textureSampleLevel(bezierTexture, filteringSampler, clampedUV, 0); let segUnsigned = sampledColor.x; let progress = sampledColor.y; - var normal = sampledColor.zw; + let normal = sampledColor.zw; return LineInfo(progress, segUnsigned, normal); } fn opExtrudeZ(point: vec3f, dd: f32, halfHeight: f32) -> f32 { - var w = vec2f(dd, (abs(point.z) - halfHeight)); + let w = vec2f(dd, (abs(point.z) - halfHeight)); return (min(max(w.x, w.y), 0f) + length(max(w, vec2f()))); } fn sliderApproxDist(position: vec3f) -> f32 { - var bbox = getSliderBbox(); - var p = position.xy; + let bbox = getSliderBbox(); + let p = position.xy; if (((((p.x < bbox.left) || (p.x > bbox.right)) || (p.y < bbox.bottom)) || (p.y > bbox.top))) { return 1000000000; } - var poly2D = sdInflatedPolyline2D(p); + let poly2D = sdInflatedPolyline2D(p); let dist3D = (opExtrudeZ(position, poly2D.distance, 0.17f) - 0.024f); return dist3D; } @@ -303,7 +299,7 @@ describe('jelly-slider example', () => { const stepDistance = 0.03333333333333333; for (var i = 1; (i <= 3i); i++) { let sampleHeight = (stepDistance * f32(i)); - var samplePosition = (position + (normal * sampleHeight)); + let samplePosition = (position + (normal * sampleHeight)); let distanceToSurface = (getSceneDistForAO(samplePosition) - 5e-3f); let occlusionContribution = max(0f, (sampleHeight - distanceToSurface)); totalOcclusion += (occlusionContribution * sampleWeight); @@ -318,13 +314,13 @@ describe('jelly-slider example', () => { fn applyAO(litColor: vec3f, hitPosition: vec3f, normal: vec3f) -> vec4f { let ao = calculateAO(hitPosition, normal); - var finalColor = (litColor * ao); + let finalColor = (litColor * ao); return vec4f(finalColor, 1f); } fn renderBackground(rayOrigin: vec3f, rayDirection: vec3f, backgroundHitDist: f32, offset: f32) -> vec4f { - var hitPosition = (rayOrigin + (rayDirection * backgroundHitDist)); - var percentageSample = renderPercentageOnGround(hitPosition, vec3f(0.7200000286102295, 0, 0), u32(((endCapUniform.x + 0.43f) * 84f))); + let hitPosition = (rayOrigin + (rayDirection * backgroundHitDist)); + let percentageSample = renderPercentageOnGround(hitPosition, vec3f(0.7200000286102295, 0, 0), u32(((endCapUniform.x + 0.43f) * 84f))); var highlights = 0f; const highlightWidth = 1f; const highlightHeight = 0.2; @@ -339,8 +335,8 @@ describe('jelly-slider example', () => { if (((abs((hitPosition.x + offsetX)) < highlightWidth) && (abs((hitPosition.z + offsetZ)) < highlightHeight))) { let uvX_orig = ((((hitPosition.x + offsetX) + (highlightWidth * 2f)) / highlightWidth) * 0.5f); let uvZ_orig = ((((hitPosition.z + offsetZ) + (highlightHeight * 2f)) / highlightHeight) * 0.5f); - var centeredUV = vec2f((uvX_orig - 0.5f), (uvZ_orig - 0.5f)); - var finalUV = vec2f(centeredUV.x, (1f - (pow((abs((centeredUV.y - 0.5f)) * 2f), 2f) * 0.3f))); + let centeredUV = vec2f((uvX_orig - 0.5f), (uvZ_orig - 0.5f)); + let finalUV = vec2f(centeredUV.x, (1f - (pow((abs((centeredUV.y - 0.5f)) * 2f), 2f) * 0.3f))); let density = max(0f, ((textureSampleLevel(bezierTexture, filteringSampler, finalUV, 0).x - 0.25f) * 8f)); let fadeX = smoothstep(0f, -0.2f, (hitPosition.x - endCapX)); let fadeZ = (1f - pow((abs((centeredUV.y - 0.5f)) * 2f), 3f)); @@ -349,15 +345,15 @@ describe('jelly-slider example', () => { highlights = ((((pow(density, 3f) * edgeFade) * 3f) * (1f + (*lightDir).z)) / 1.5f); } let originYBound = saturate((rayOrigin.y + 0.01f)); - var posOffset = (hitPosition + (vec3f(0, 1, 0) * ((offset * (originYBound / (1f + originYBound))) * (1f + (randFloat01() / 2f))))); - var newNormal = getNormalMain(posOffset); + let posOffset = (hitPosition + (vec3f(0, 1, 0) * ((offset * (originYBound / (1f + originYBound))) * (1f + (randFloat01() / 2f))))); + let newNormal = getNormalMain(posOffset); let jellyColor = (&jellyColorUniform); let sqDist = sqLength((hitPosition - vec3f(endCapX, 0f, 0f))); - var bounceLight = ((*jellyColor).rgb * ((1f / ((sqDist * 15f) + 1f)) * 0.4f)); - var sideBounceLight = (((*jellyColor).rgb * ((1f / ((sqDist * 40f) + 1f)) * 0.3f)) * abs(newNormal.z)); - var litColor = calculateLighting(posOffset, newNormal, rayOrigin); - var backgroundColor = ((applyAO((vec3f(1) * litColor), posOffset, newNormal) + vec4f(bounceLight, 0f)) + vec4f(sideBounceLight, 0f)); - var textColor = saturate((backgroundColor.rgb * vec3f(0.5))); + let bounceLight = ((*jellyColor).rgb * ((1f / ((sqDist * 15f) + 1f)) * 0.4f)); + let sideBounceLight = (((*jellyColor).rgb * ((1f / ((sqDist * 40f) + 1f)) * 0.3f)) * abs(newNormal.z)); + let litColor = calculateLighting(posOffset, newNormal, rayOrigin); + let backgroundColor = ((applyAO((vec3f(1) * litColor), posOffset, newNormal) + vec4f(bounceLight, 0f)) + vec4f(sideBounceLight, 0f)); + let textColor = saturate((backgroundColor.rgb * vec3f(0.5))); return vec4f((mix(backgroundColor.rgb, textColor, percentageSample.x) * (1f + highlights)), 1f); } @@ -368,11 +364,11 @@ describe('jelly-slider example', () => { } fn intersectBox(rayOrigin: vec3f, rayDirection: vec3f, boxMin: vec3f, boxMax: vec3f) -> BoxIntersection { - var invDir = (vec3f(1) / rayDirection); - var t1 = ((boxMin - rayOrigin) * invDir); - var t2 = ((boxMax - rayOrigin) * invDir); - var tMinVec = min(t1, t2); - var tMaxVec = max(t1, t2); + let invDir = (vec3f(1) / rayDirection); + let t1 = ((boxMin - rayOrigin) * invDir); + let t2 = ((boxMax - rayOrigin) * invDir); + let tMinVec = min(t1, t2); + let tMaxVec = max(t1, t2); let tMin = max(max(tMinVec.x, tMinVec.y), tMinVec.z); let tMax = min(min(tMaxVec.x, tMaxVec.y), tMaxVec.z); var result = BoxIntersection(); @@ -392,10 +388,10 @@ describe('jelly-slider example', () => { fn cap3D(position: vec3f) -> f32 { let endCap = (&endCapUniform); - var secondLastPoint = vec2f((*endCap).x, (*endCap).y); - var lastPoint = vec2f((*endCap).z, (*endCap).w); + let secondLastPoint = vec2f((*endCap).x, (*endCap).y); + let lastPoint = vec2f((*endCap).z, (*endCap).w); let angle = atan2((lastPoint.y - secondLastPoint.y), (lastPoint.x - secondLastPoint.x)); - var rot = mat2x2f(cos(angle), -(sin(angle)), sin(angle), cos(angle)); + let rot = mat2x2f(cos(angle), -(sin(angle)), sin(angle), cos(angle)); var pieP = (position - vec3f(secondLastPoint, 0f)); pieP = vec3f((rot * pieP.xy), pieP.z); let hmm = sdPie(pieP.zx, vec2f(1, 0), 0.17f); @@ -404,7 +400,7 @@ describe('jelly-slider example', () => { } fn sliderSdf3D(position: vec3f) -> LineInfo { - var poly2D = sdInflatedPolyline2D(position.xy); + let poly2D = sdInflatedPolyline2D(position.xy); var finalDist = 0f; if ((poly2D.t > 0.94f)) { finalDist = cap3D(position); @@ -424,7 +420,7 @@ describe('jelly-slider example', () => { fn getSceneDist(position: vec3f) -> HitInfo { let mainScene = getMainSceneDist(position); - var poly3D = sliderSdf3D(position); + let poly3D = sliderSdf3D(position); var hitInfo = HitInfo(); if ((poly3D.distance < mainScene)) { hitInfo.distance = poly3D.distance; @@ -439,16 +435,16 @@ describe('jelly-slider example', () => { } fn getNormalFromSdf_1(position: vec3f, epsilon: f32) -> vec3f { - var k = vec3f(1, -1, 0); - var offset1 = (k.xyy * epsilon); - var offset2 = (k.yyx * epsilon); - var offset3 = (k.yxy * epsilon); - var offset4 = (k.xxx * epsilon); - var sample1 = (offset1 * cap3D((position + offset1))); - var sample2 = (offset2 * cap3D((position + offset2))); - var sample3 = (offset3 * cap3D((position + offset3))); - var sample4 = (offset4 * cap3D((position + offset4))); - var gradient = (((sample1 + sample2) + sample3) + sample4); + let k = vec3f(1, -1, 0); + let offset1 = (k.xyy * epsilon); + let offset2 = (k.yyx * epsilon); + let offset3 = (k.yxy * epsilon); + let offset4 = (k.xxx * epsilon); + let sample1 = (offset1 * cap3D((position + offset1))); + let sample2 = (offset2 * cap3D((position + offset2))); + let sample3 = (offset3 * cap3D((position + offset3))); + let sample4 = (offset4 * cap3D((position + offset4))); + let gradient = (((sample1 + sample2) + sample3) + sample4); return normalize(gradient); } @@ -466,15 +462,15 @@ describe('jelly-slider example', () => { const edgeContrib = 0.9; let zContrib = (1f - edgeContrib); let zDirection = sign(position.z); - var zAxisVector = vec3f(0f, 0f, zDirection); + let zAxisVector = vec3f(0f, 0f, zDirection); let edgeBlendDistance = ((edgeContrib * 0.024f) + (zContrib * 0.17f)); let blendFactor = smoothstep(edgeBlendDistance, 0f, ((zDistance * zContrib) + (edgeDistance * edgeContrib))); - var normal2D = vec3f((*gradient2D).xy, 0f); - var blendedNormal = mix(zAxisVector, normal2D, ((blendFactor * 0.5f) + 0.5f)); + let normal2D = vec3f((*gradient2D).xy, 0f); + let blendedNormal = mix(zAxisVector, normal2D, ((blendFactor * 0.5f) + 0.5f)); var normal = normalize(blendedNormal); if ((hitInfo.t > 0.94f)) { let ratio = ((hitInfo.t - 0.94f) / 0.02f); - var fullNormal = getNormalCap(position); + let fullNormal = getNormalCap(position); normal = normalize(mix(normal, fullNormal, ratio)); } return normal; @@ -498,7 +494,7 @@ describe('jelly-slider example', () => { var distanceFromOrigin = 0f; var hit = 0f; for (var i = 0; (i < 6i); i++) { - var p = (rayOrigin + (rayDirection * distanceFromOrigin)); + let p = (rayOrigin + (rayDirection * distanceFromOrigin)); hit = getMainSceneDist(p); distanceFromOrigin += hit; if (((distanceFromOrigin > 10f) || (hit < 0.01f))) { @@ -519,19 +515,19 @@ describe('jelly-slider example', () => { var totalSteps = 0u; var backgroundDist = 0f; for (var i = 0; (i < 64i); i++) { - var p = (rayOrigin + (rayDirection * backgroundDist)); + let p = (rayOrigin + (rayDirection * backgroundDist)); let hit = getMainSceneDist(p); backgroundDist += hit; if ((hit < 1e-3f)) { break; } } - var background = renderBackground(rayOrigin, rayDirection, backgroundDist, 0f); - var bbox = getSliderBbox(); + let background = renderBackground(rayOrigin, rayDirection, backgroundDist, 0f); + let bbox = getSliderBbox(); const zDepth = 0.25f; - var sliderMin = vec3f(bbox.left, bbox.bottom, -(zDepth)); - var sliderMax = vec3f(bbox.right, bbox.top, zDepth); - var intersection = intersectBox(rayOrigin, rayDirection, sliderMin, sliderMax); + let sliderMin = vec3f(bbox.left, bbox.bottom, -(zDepth)); + let sliderMax = vec3f(bbox.right, bbox.top, zDepth); + let intersection = intersectBox(rayOrigin, rayDirection, sliderMin, sliderMax); if (!intersection.hit) { return background; } @@ -540,40 +536,40 @@ describe('jelly-slider example', () => { if ((totalSteps >= 64u)) { break; } - var currentPosition = (rayOrigin + (rayDirection * distanceFromOrigin)); - var hitInfo = getSceneDist(currentPosition); + let currentPosition = (rayOrigin + (rayDirection * distanceFromOrigin)); + let hitInfo = getSceneDist(currentPosition); distanceFromOrigin += hitInfo.distance; totalSteps++; if ((hitInfo.distance < 1e-3f)) { - var hitPosition = (rayOrigin + (rayDirection * distanceFromOrigin)); + let hitPosition = (rayOrigin + (rayDirection * distanceFromOrigin)); if (!(hitInfo.objectType == 1i)) { break; } - var N = getNormal(hitPosition, hitInfo); + let N = getNormal(hitPosition, hitInfo); let I = rayDirection; let cosi = min(1f, max(0f, dot(-(I), N))); let F = fresnelSchlick(cosi, 1f, 1.4199999570846558f); - var reflection = saturate(vec3f((hitPosition.y + 0.2f))); + let reflection = saturate(vec3f((hitPosition.y + 0.2f))); const eta = 0.7042253521126761; let k = (1f - ((eta * eta) * (1f - (cosi * cosi)))); var refractedColor = vec3f(); if ((k > 0f)) { - var refrDir = normalize(((I * eta) + (N * ((eta * cosi) - sqrt(k))))); - var p = (hitPosition + (refrDir * 2e-3f)); - var exitPos = (p + (refrDir * 2e-3f)); - var env = rayMarchNoJelly(exitPos, refrDir); + let refrDir = normalize(((I * eta) + (N * ((eta * cosi) - sqrt(k))))); + let p = (hitPosition + (refrDir * 2e-3f)); + let exitPos = (p + (refrDir * 2e-3f)); + let env = rayMarchNoJelly(exitPos, refrDir); let progress = hitInfo.t; let jellyColor = (&jellyColorUniform); - var scatterTint = ((*jellyColor).rgb * 1.5f); + let scatterTint = ((*jellyColor).rgb * 1.5f); const density = 20f; - var absorb = ((vec3f(1) - (*jellyColor).rgb) * density); - var T = beerLambert((absorb * pow(progress, 2f)), 0.08f); - var lightDir = -(lightUniform.direction); + let absorb = ((vec3f(1) - (*jellyColor).rgb) * density); + let T = beerLambert((absorb * pow(progress, 2f)), 0.08f); + let lightDir = -(lightUniform.direction); let forward = max(0f, dot(lightDir, refrDir)); - var scatter = (scatterTint * ((3f * forward) * pow(progress, 3f))); + let scatter = (scatterTint * ((3f * forward) * pow(progress, 3f))); refractedColor = ((env * T) + scatter); } - var jelly = ((reflection * F) + (refractedColor * (1f - F))); + let jelly = ((reflection * F) + (refractedColor * (1f - F))); return vec4f(jelly, 1f); } if ((distanceFromOrigin > backgroundDist)) { @@ -583,11 +579,15 @@ describe('jelly-slider example', () => { return background; } + struct raymarchFn_Input { + @location(0) uv: vec2f, + } + @fragment fn raymarchFn(_arg_0: raymarchFn_Input) -> @location(0) vec4f { randSeed2((randomUniform * _arg_0.uv)); - var ndc = vec2f(((_arg_0.uv.x * 2f) - 1f), -(((_arg_0.uv.y * 2f) - 1f))); - var ray = getRay(ndc); - var color = rayMarch(ray.origin, ray.direction, _arg_0.uv); + let ndc = vec2f(((_arg_0.uv.x * 2f) - 1f), -(((_arg_0.uv.y * 2f) - 1f))); + let ray = getRay(ndc); + let color = rayMarch(ray.origin, ray.direction, _arg_0.uv); return vec4f(tanh((color.rgb * 1.3f)), 1f); } @@ -598,34 +598,34 @@ describe('jelly-slider example', () => { @group(0) @binding(2) var outputTexture: texture_storage_2d; @compute @workgroup_size(16, 16) fn taaResolveFn(@builtin(global_invocation_id) gid: vec3u) { - var currentColor = textureLoad(currentTexture, gid.xy, 0); - var historyColor = textureLoad(historyTexture, gid.xy, 0); + let currentColor = textureLoad(currentTexture, gid.xy, 0); + let historyColor = textureLoad(historyTexture, gid.xy, 0); var minColor = vec3f(9999); var maxColor = vec3f(-9999); - var dimensions = textureDimensions(currentTexture); + let dimensions = textureDimensions(currentTexture); // unrolled iteration #0 { // unrolled iteration #0 { - var sampleCoord = (vec2i(gid.xy) + vec2i(-1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(-1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #1 { - var sampleCoord = (vec2i(gid.xy) + vec2i(-1, 0)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #2 { - var sampleCoord = (vec2i(gid.xy) + vec2i(-1, 1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } @@ -634,25 +634,25 @@ describe('jelly-slider example', () => { { // unrolled iteration #0 { - var sampleCoord = (vec2i(gid.xy) + vec2i(0, -1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(0, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #1 { - var sampleCoord = (vec2i(gid.xy) + vec2i()); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i()); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #2 { - var sampleCoord = (vec2i(gid.xy) + vec2i(0, 1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(0, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } @@ -661,31 +661,31 @@ describe('jelly-slider example', () => { { // unrolled iteration #0 { - var sampleCoord = (vec2i(gid.xy) + vec2i(1, -1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(1, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #1 { - var sampleCoord = (vec2i(gid.xy) + vec2i(1, 0)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #2 { - var sampleCoord = (vec2i(gid.xy) + vec2i(1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } } - var historyColorClamped = clamp(historyColor.rgb, minColor, maxColor); - var uv = (vec2f(gid.xy) / vec2f(dimensions.xy)); + let historyColorClamped = clamp(historyColor.rgb, minColor, maxColor); + let uv = (vec2f(gid.xy) / vec2f(dimensions.xy)); const textRegionMinX = 0.7099999785423279f; const textRegionMaxX = 0.8500000238418579f; const textRegionMinY = 0.4699999988079071f; @@ -697,7 +697,7 @@ describe('jelly-slider example', () => { let fadeOutY = (1f - smoothstep((textRegionMaxY - borderSize), (textRegionMaxY + borderSize), uv.y)); let inTextRegion = (((fadeInX * fadeOutX) * fadeInY) * fadeOutY); let blendFactor = mix(0.8999999761581421f, 0.699999988079071f, inTextRegion); - var resolvedColor = vec4f(mix(currentColor.rgb, historyColorClamped, blendFactor), 1f); + let resolvedColor = vec4f(mix(currentColor.rgb, historyColorClamped, blendFactor), 1f); textureStore(outputTexture, vec2u(gid.x, gid.y), resolvedColor); } @@ -713,14 +713,14 @@ describe('jelly-slider example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct fragmentMain_Input { - @location(0) uv: vec2f, - } - @group(1) @binding(0) var currentTexture: texture_2d; @group(0) @binding(0) var filteringSampler: sampler; + struct fragmentMain_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentMain(_arg_0: fragmentMain_Input) -> @location(0) vec4f { return textureSample(currentTexture, filteringSampler, _arg_0.uv); } @@ -738,10 +738,10 @@ describe('jelly-slider example', () => { } fn sdBezier(point: vec2f, A: vec2f, B: vec2f, C: vec2f) -> f32 { - var a = (B - A); - var b = ((A - (B * 2f)) + C); - var c = (a * 2f); - var d = (A - point); + let a = (B - A); + let b = ((A - (B * 2f)) + C); + let c = (a * 2f); + let d = (A - point); let dotB = max(dot(b, b), 1e-4f); let kk = (1f / dotB); let kx = (kk * dot(a, b)); @@ -754,8 +754,8 @@ describe('jelly-slider example', () => { var h = ((q * q) + (4f * p3)); if ((h >= 0f)) { h = sqrt(h); - var x = ((vec2f(h, -(h)) - q) * 0.5f); - var uv = (sign(x) * pow(abs(x), vec2f(0.3333333432674408))); + let x = ((vec2f(h, -(h)) - q) * 0.5f); + let uv = (sign(x) * pow(abs(x), vec2f(0.3333333432674408))); let t = saturate(((uv.x + uv.y) - kx)); res = dot2((d + ((c + (b * t)) * t))); } @@ -764,22 +764,22 @@ describe('jelly-slider example', () => { let v = (acos((q / ((p * z) * 2f))) / 3f); let m = cos(v); let n = (sin(v) * 1.732050808f); - var t = saturate(((vec3f((m + m), (-(n) - m), (n - m)) * z) - kx)); + let t = saturate(((vec3f((m + m), (-(n) - m), (n - m)) * z) - kx)); res = min(dot2((d + ((c + (b * t.x)) * t.x))), dot2((d + ((c + (b * t.y)) * t.y)))); } return sqrt(res); } fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { - var size = textureDimensions(bezierWriteView); - var pixelUV = ((vec2f(f32(x), f32(y)) + 0.5f) / vec2f(size)); - var sliderPos = vec2f((-1.0189999997615815f + (pixelUV.x * 2.108999973535538f)), (0.65f - (pixelUV.y * 0.95f))); + let size = textureDimensions(bezierWriteView); + let pixelUV = ((vec2f(f32(x), f32(y)) + 0.5f) / vec2f(size)); + let sliderPos = vec2f((-1.0189999997615815f + (pixelUV.x * 2.108999973535538f)), (0.65f - (pixelUV.y * 0.95f))); var minDist = 1e+10f; var closestSegment = 0i; var closestT = 0f; const epsilon = 0.029999999329447746f; - var xOffset = vec2f(epsilon, 0f); - var yOffset = vec2f(0f, epsilon); + let xOffset = vec2f(epsilon, 0f); + let yOffset = vec2f(0f, epsilon); var xPlusDist = 1e+10f; var xMinusDist = 1e+10f; var yPlusDist = 1e+10f; @@ -792,8 +792,8 @@ describe('jelly-slider example', () => { if ((dist < minDist)) { minDist = dist; closestSegment = i; - var AB = ((*B) - (*A)); - var AP = (sliderPos - (*A)); + let AB = ((*B) - (*A)); + let AP = (sliderPos - (*A)); let ABLength = length(AB); if ((ABLength > 0f)) { closestT = clamp((dot(AP, AB) / (ABLength * ABLength)), 0f, 1f); diff --git a/apps/typegpu-docs/tests/individual-example-tests/jelly-switch.test.ts b/apps/typegpu-docs/tests/individual-example-tests/jelly-switch.test.ts index 7a192b5f54..09ef507fb1 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/jelly-switch.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/jelly-switch.test.ts @@ -37,10 +37,6 @@ describe('jelly switch example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct raymarchFn_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var randomUniform: vec2f; var seed: vec2f; @@ -68,14 +64,14 @@ describe('jelly switch example', () => { } fn getRay(ndc: vec2f) -> Ray { - var clipPos = vec4f(ndc.x, ndc.y, -1f, 1f); + let clipPos = vec4f(ndc.x, ndc.y, -1f, 1f); let invView = (&uniform_1.viewInv); let invProj = (&uniform_1.projInv); - var viewPos = ((*invProj) * clipPos); - var viewPosNormalized = vec4f((viewPos.xyz / viewPos.w), 1f); - var worldPos = ((*invView) * viewPosNormalized); - var rayOrigin = (*invView)[3i].xyz; - var rayDir = normalize((worldPos.xyz - rayOrigin)); + let viewPos = ((*invProj) * clipPos); + let viewPosNormalized = vec4f((viewPos.xyz / viewPos.w), 1f); + let worldPos = ((*invView) * viewPosNormalized); + let rayOrigin = (*invView)[3i].xyz; + let rayDir = normalize((worldPos.xyz - rayOrigin)); return Ray(rayOrigin, rayDir); } @@ -84,7 +80,7 @@ describe('jelly switch example', () => { } fn sdRoundedBox2d(point: vec2f, size: vec2f, cornerRadius: f32) -> f32 { - var d = ((abs(point) - size) + vec2f(cornerRadius)); + let d = ((abs(point) - size) + vec2f(cornerRadius)); return ((length(max(d, vec2f())) + min(max(d.x, d.y), 0f)) - cornerRadius); } @@ -95,7 +91,7 @@ describe('jelly switch example', () => { } fn opExtrudeY(point: vec3f, dd: f32, halfHeight: f32) -> f32 { - var w = vec2f(dd, (abs(point.y) - halfHeight)); + let w = vec2f(dd, (abs(point.y) - halfHeight)); return (min(max(w.x, w.y), 0f) + length(max(w, vec2f()))); } @@ -125,20 +121,20 @@ describe('jelly switch example', () => { fn opCheapBend(p: vec3f, k: f32) -> vec3f { let c = cos((k * p.x)); let s = sin((k * p.x)); - var m = mat2x2f(c, -(s), s, c); + let m = mat2x2f(c, -(s), s, c); return vec3f((m * p.xy), p.z); } fn sdRoundedBox3d(point: vec3f, size: vec3f, cornerRadius: f32) -> f32 { - var d = ((abs(point) - size) + vec3f(cornerRadius)); + let d = ((abs(point) - size) + vec3f(cornerRadius)); return ((length(max(d, vec3f())) + min(max(max(d.x, d.y), d.z), 0f)) - cornerRadius); } fn getJellyDist(position: vec3f) -> f32 { let state = (&stateUniform); - var jellyOrigin = vec3f(((((*state).progress - 0.5f) * 0.4f) - (((*state).squashX * ((*state).progress - 0.5f)) * 0.2f)), 0.15000000596046448f, 0f); - var jellyInvScale = vec3f((1f - (*state).squashX), 1f, (1f - (*state).squashZ)); - var localPos = opRotateAxisAngle(((position - jellyOrigin) * jellyInvScale), vec3f(0, 0, 1), (*state).wiggleX); + let jellyOrigin = vec3f(((((*state).progress - 0.5f) * 0.4f) - (((*state).squashX * ((*state).progress - 0.5f)) * 0.2f)), 0.15000000596046448f, 0f); + let jellyInvScale = vec3f((1f - (*state).squashX), 1f, (1f - (*state).squashZ)); + let localPos = opRotateAxisAngle(((position - jellyOrigin) * jellyInvScale), vec3f(0, 0, 1), (*state).wiggleX); return sdRoundedBox3d(opCheapBend(localPos, 0.8f), vec3f(0.25, 0.20000001788139343, 0.20000001788139343), 0.1f); } @@ -164,7 +160,7 @@ describe('jelly switch example', () => { fn getApproxNormal(p: vec3f, e: f32) -> vec3f { let dist = getSceneDist(p).distance; - var n = vec3f((getSceneDist((p + vec3f(e, 0f, 0f))).distance - dist), (getSceneDist((p + vec3f(0f, e, 0f))).distance - dist), (getSceneDist((p + vec3f(0f, 0f, e))).distance - dist)); + let n = vec3f((getSceneDist((p + vec3f(e, 0f, 0f))).distance - dist), (getSceneDist((p + vec3f(0f, e, 0f))).distance - dist), (getSceneDist((p + vec3f(0f, 0f, e))).distance - dist)); return normalize(n); } @@ -201,17 +197,17 @@ describe('jelly switch example', () => { } fn calculateLighting(hitPosition: vec3f, normal: vec3f, rayOrigin: vec3f) -> vec3f { - var lightDir = -(lightUniform.direction); - var fakeShadow = getFakeShadow(hitPosition, lightDir); + let lightDir = -(lightUniform.direction); + let fakeShadow = getFakeShadow(hitPosition, lightDir); let diffuse = max(dot(normal, lightDir), 0f); - var viewDir = normalize((rayOrigin - hitPosition)); - var reflectDir = reflect(-(lightDir), normal); + let viewDir = normalize((rayOrigin - hitPosition)); + let reflectDir = reflect(-(lightDir), normal); let specularFactor = pow(max(dot(viewDir, reflectDir), 0f), 10f); - var specular = (lightUniform.color * (specularFactor * 0.6f)); - var baseColor = vec3f(0.8999999761581421); - var directionalLight = (((baseColor * lightUniform.color) * diffuse) * fakeShadow); - var ambientLight = ((baseColor * vec3f(0.6000000238418579)) * 0.6f); - var finalSpecular = (specular * fakeShadow); + let specular = (lightUniform.color * (specularFactor * 0.6f)); + let baseColor = vec3f(0.8999999761581421); + let directionalLight = (((baseColor * lightUniform.color) * diffuse) * fakeShadow); + let ambientLight = ((baseColor * vec3f(0.6000000238418579)) * 0.6f); + let finalSpecular = (specular * fakeShadow); return saturate(((directionalLight + ambientLight) + finalSpecular)); } @@ -229,7 +225,7 @@ describe('jelly switch example', () => { const stepDistance = 0.03333333333333333; for (var i = 1; (i <= 3i); i++) { let sampleHeight = (stepDistance * f32(i)); - var samplePosition = (position + (normal * sampleHeight)); + let samplePosition = (position + (normal * sampleHeight)); let distanceToSurface = (getSceneDistForAO(samplePosition) - 5e-3f); let occlusionContribution = max(0f, (sampleHeight - distanceToSurface)); totalOcclusion += (occlusionContribution * sampleWeight); @@ -244,22 +240,22 @@ describe('jelly switch example', () => { fn applyAO(litColor: vec3f, hitPosition: vec3f, normal: vec3f) -> vec4f { let ao = calculateAO(hitPosition, normal); - var finalColor = (litColor * ao); + let finalColor = (litColor * ao); return vec4f(finalColor, 1f); } fn renderBackground(rayOrigin: vec3f, rayDirection: vec3f, backgroundHitDist: f32) -> vec4f { let state = (&stateUniform); - var hitPosition = (rayOrigin + (rayDirection * backgroundHitDist)); - var newNormal = getNormal(hitPosition); + let hitPosition = (rayOrigin + (rayDirection * backgroundHitDist)); + let newNormal = getNormal(hitPosition); let switchX = (((*state).progress - 0.5f) * 0.4f); let jellyColor = (&jellyColorUniform); let sqDist = sqLength((hitPosition - vec3f(switchX, 0f, 0f))); - var bounceLight = ((*jellyColor).rgb * ((1f / ((sqDist * 15f) + 1f)) * 0.4f)); - var sideBounceLight = (((*jellyColor).rgb * ((1f / ((sqDist * 40f) + 1f)) * 0.3f)) * abs(newNormal.z)); + let bounceLight = ((*jellyColor).rgb * ((1f / ((sqDist * 15f) + 1f)) * 0.4f)); + let sideBounceLight = (((*jellyColor).rgb * ((1f / ((sqDist * 40f) + 1f)) * 0.3f)) * abs(newNormal.z)); let emission = ((smoothstep(0.7f, 1f, (*state).progress) * 2f) + 0.7f); - var litColor = calculateLighting(hitPosition, newNormal, rayOrigin); - var backgroundColor = ((applyAO((select(vec3f(1), vec3f(0.20000000298023224), (darkModeUniform == 1u)) * litColor), hitPosition, newNormal) + vec4f((bounceLight * emission), 0f)) + vec4f((sideBounceLight * emission), 0f)); + let litColor = calculateLighting(hitPosition, newNormal, rayOrigin); + let backgroundColor = ((applyAO((select(vec3f(1), vec3f(0.20000000298023224), (darkModeUniform == 1u)) * litColor), hitPosition, newNormal) + vec4f((bounceLight * emission), 0f)) + vec4f((sideBounceLight * emission), 0f)); return vec4f(backgroundColor.rgb, 1f); } @@ -279,11 +275,11 @@ describe('jelly switch example', () => { } fn intersectBox(rayOrigin: vec3f, rayDirection: vec3f, box: BoundingBox) -> BoxIntersection { - var invDir = (vec3f(1) / rayDirection); - var t1 = ((box.min - rayOrigin) * invDir); - var t2 = ((box.max - rayOrigin) * invDir); - var tMinVec = min(t1, t2); - var tMaxVec = max(t1, t2); + let invDir = (vec3f(1) / rayDirection); + let t1 = ((box.min - rayOrigin) * invDir); + let t2 = ((box.max - rayOrigin) * invDir); + let tMinVec = min(t1, t2); + let tMaxVec = max(t1, t2); let tMin = max(max(tMinVec.x, tMinVec.y), tMinVec.z); let tMax = min(min(tMaxVec.x, tMaxVec.y), tMaxVec.z); var result = BoxIntersection(); @@ -302,7 +298,7 @@ describe('jelly switch example', () => { var distanceFromOrigin = 0f; var hit = 0f; for (var i = 0; (i < 6i); i++) { - var p = (rayOrigin + (rayDirection * distanceFromOrigin)); + let p = (rayOrigin + (rayDirection * distanceFromOrigin)); hit = getMainSceneDist(p); distanceFromOrigin += hit; if (((distanceFromOrigin > 10f) || (hit < 0.01f))) { @@ -323,16 +319,16 @@ describe('jelly switch example', () => { var totalSteps = 0u; var backgroundDist = 0f; for (var i = 0; (i < 64i); i++) { - var p = (rayOrigin + (rayDirection * backgroundDist)); + let p = (rayOrigin + (rayDirection * backgroundDist)); let hit = getMainSceneDist(p); backgroundDist += hit; if ((hit < 1e-3f)) { break; } } - var background = renderBackground(rayOrigin, rayDirection, backgroundDist); - var bbox = getJellyBounds(); - var intersection = intersectBox(rayOrigin, rayDirection, bbox); + let background = renderBackground(rayOrigin, rayDirection, backgroundDist); + let bbox = getJellyBounds(); + let intersection = intersectBox(rayOrigin, rayDirection, bbox); if (!intersection.hit) { return background; } @@ -341,41 +337,41 @@ describe('jelly switch example', () => { if ((totalSteps >= 64u)) { break; } - var currentPosition = (rayOrigin + (rayDirection * distanceFromOrigin)); - var hitInfo = getSceneDist(currentPosition); + let currentPosition = (rayOrigin + (rayDirection * distanceFromOrigin)); + let hitInfo = getSceneDist(currentPosition); distanceFromOrigin += hitInfo.distance; totalSteps++; if ((hitInfo.distance < 1e-3f)) { - var hitPosition = (rayOrigin + (rayDirection * distanceFromOrigin)); + let hitPosition = (rayOrigin + (rayDirection * distanceFromOrigin)); if (!(hitInfo.objectType == 1i)) { break; } - var N = getNormal(hitPosition); + let N = getNormal(hitPosition); let I = rayDirection; let cosi = min(1f, max(0f, dot(-(I), N))); let F = fresnelSchlick(cosi, 1f, 1.4199999570846558f); - var reflection = saturate(vec3f((hitPosition.y + 0.2f))); + let reflection = saturate(vec3f((hitPosition.y + 0.2f))); const eta = 0.7042253521126761; let k = (1f - ((eta * eta) * (1f - (cosi * cosi)))); var refractedColor = vec3f(); if ((k > 0f)) { - var refrDir = normalize(((I * eta) + (N * ((eta * cosi) - sqrt(k))))); - var p = (hitPosition + (refrDir * 2e-3f)); - var exitPos = (p + (refrDir * 2e-3f)); - var env = rayMarchNoJelly(exitPos, refrDir); + let refrDir = normalize(((I * eta) + (N * ((eta * cosi) - sqrt(k))))); + let p = (hitPosition + (refrDir * 2e-3f)); + let exitPos = (p + (refrDir * 2e-3f)); + let env = rayMarchNoJelly(exitPos, refrDir); let jellyColor = (&jellyColorUniform); - var scatterTint = ((*jellyColor).rgb * 1.5f); + let scatterTint = ((*jellyColor).rgb * 1.5f); const density = 20f; - var absorb = ((vec3f(1) - (*jellyColor).rgb) * density); + let absorb = ((vec3f(1) - (*jellyColor).rgb) * density); let state = (&stateUniform); let progress = (saturate(mix(1f, 0.6f, ((hitPosition.y * 1.6666666004392863f) + 0.25f))) * (*state).progress); - var T = beerLambert((absorb * pow(progress, 2f)), 0.08f); - var lightDir = -(lightUniform.direction); + let T = beerLambert((absorb * pow(progress, 2f)), 0.08f); + let lightDir = -(lightUniform.direction); let forward = max(0f, dot(lightDir, refrDir)); - var scatter = (scatterTint * ((3f * forward) * pow(progress, 3f))); + let scatter = (scatterTint * ((3f * forward) * pow(progress, 3f))); refractedColor = ((env * T) + scatter); } - var jelly = ((reflection * F) + (refractedColor * (1f - F))); + let jelly = ((reflection * F) + (refractedColor * (1f - F))); return vec4f(jelly, 1f); } if ((distanceFromOrigin > backgroundDist)) { @@ -385,11 +381,15 @@ describe('jelly switch example', () => { return background; } + struct raymarchFn_Input { + @location(0) uv: vec2f, + } + @fragment fn raymarchFn(_arg_0: raymarchFn_Input) -> @location(0) vec4f { randSeed2((randomUniform * _arg_0.uv)); - var ndc = vec2f(((_arg_0.uv.x * 2f) - 1f), -(((_arg_0.uv.y * 2f) - 1f))); - var ray = getRay(ndc); - var color = rayMarch(ray.origin, ray.direction, _arg_0.uv); + let ndc = vec2f(((_arg_0.uv.x * 2f) - 1f), -(((_arg_0.uv.y * 2f) - 1f))); + let ray = getRay(ndc); + let color = rayMarch(ray.origin, ray.direction, _arg_0.uv); let exposure = select(1.5, 2., (darkModeUniform == 1u)); return vec4f(tanh((color.rgb * exposure)), 1f); } @@ -401,34 +401,34 @@ describe('jelly switch example', () => { @group(0) @binding(2) var outputTexture: texture_storage_2d; @compute @workgroup_size(16, 16) fn taaResolveFn(@builtin(global_invocation_id) gid: vec3u) { - var currentColor = textureLoad(currentTexture, gid.xy, 0); - var historyColor = textureLoad(historyTexture, gid.xy, 0); + let currentColor = textureLoad(currentTexture, gid.xy, 0); + let historyColor = textureLoad(historyTexture, gid.xy, 0); var minColor = vec3f(9999); var maxColor = vec3f(-9999); - var dimensions = textureDimensions(currentTexture); + let dimensions = textureDimensions(currentTexture); // unrolled iteration #0 { // unrolled iteration #0 { - var sampleCoord = (vec2i(gid.xy) + vec2i(-1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(-1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #1 { - var sampleCoord = (vec2i(gid.xy) + vec2i(-1, 0)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #2 { - var sampleCoord = (vec2i(gid.xy) + vec2i(-1, 1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } @@ -437,25 +437,25 @@ describe('jelly switch example', () => { { // unrolled iteration #0 { - var sampleCoord = (vec2i(gid.xy) + vec2i(0, -1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(0, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #1 { - var sampleCoord = (vec2i(gid.xy) + vec2i()); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i()); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #2 { - var sampleCoord = (vec2i(gid.xy) + vec2i(0, 1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(0, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } @@ -464,32 +464,32 @@ describe('jelly switch example', () => { { // unrolled iteration #0 { - var sampleCoord = (vec2i(gid.xy) + vec2i(1, -1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(1, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #1 { - var sampleCoord = (vec2i(gid.xy) + vec2i(1, 0)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } // unrolled iteration #2 { - var sampleCoord = (vec2i(gid.xy) + vec2i(1)); - var clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - var neighborColor = textureLoad(currentTexture, clampedCoord, 0); + let sampleCoord = (vec2i(gid.xy) + vec2i(1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); minColor = min(minColor, neighborColor.rgb); maxColor = max(maxColor, neighborColor.rgb); } } - var historyColorClamped = clamp(historyColor.rgb, minColor, maxColor); + let historyColorClamped = clamp(historyColor.rgb, minColor, maxColor); const blendFactor = 0.8999999761581421f; - var resolvedColor = vec4f(mix(currentColor.rgb, historyColorClamped, blendFactor), 1f); + let resolvedColor = vec4f(mix(currentColor.rgb, historyColorClamped, blendFactor), 1f); textureStore(outputTexture, vec2u(gid.x, gid.y), resolvedColor); } @@ -505,14 +505,14 @@ describe('jelly switch example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct fragmentMain_Input { - @location(0) uv: vec2f, - } - @group(1) @binding(0) var currentTexture: texture_2d; @group(0) @binding(0) var filteringSampler: sampler; + struct fragmentMain_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentMain(_arg_0: fragmentMain_Input) -> @location(0) vec4f { return textureSample(currentTexture, filteringSampler, _arg_0.uv); }" diff --git a/apps/typegpu-docs/tests/individual-example-tests/jump-flood-distance.test.ts b/apps/typegpu-docs/tests/individual-example-tests/jump-flood-distance.test.ts index 3fb0e7d685..295b97b687 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/jump-flood-distance.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/jump-flood-distance.test.ts @@ -29,14 +29,14 @@ describe('jump flood (distance) example', () => { @group(1) @binding(0) var maskTexture: texture_storage_2d; fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { - var size = textureDimensions(writeView); - var pos = vec2f(f32(x), f32(y)); - var uv = (pos / vec2f(size)); + let size = textureDimensions(writeView); + let pos = vec2f(f32(x), f32(y)); + let uv = (pos / vec2f(size)); let mask = textureLoad(maskTexture, vec2i(i32(x), i32(y))).x; let inside = (mask > 0u); - var invalid = vec2f(-1); - var insideCoord = select(invalid, uv, inside); - var outsideCoord = select(uv, invalid, inside); + let invalid = vec2f(-1); + let insideCoord = select(invalid, uv, inside); + let outsideCoord = select(uv, invalid, inside); textureStore(writeView, vec2i(i32(x), i32(y)), vec4f(insideCoord, outsideCoord)); } @@ -59,13 +59,13 @@ describe('jump flood (distance) example', () => { } fn sampleWithOffset(tex: texture_storage_2d, pos: vec2i, offset: vec2i) -> SampleResult { - var dims = textureDimensions(tex); - var samplePos = (pos + offset); + let dims = textureDimensions(tex); + let samplePos = (pos + offset); let outOfBounds = ((((samplePos.x < 0i) || (samplePos.y < 0i)) || (samplePos.x >= i32(dims.x))) || (samplePos.y >= i32(dims.y))); - var safePos = clamp(samplePos, vec2i(), vec2i((dims - 1u))); - var loaded = textureLoad(tex, safePos); - var inside = loaded.xy; - var outside = loaded.zw; + let safePos = clamp(samplePos, vec2i(), vec2i((dims - 1u))); + let loaded = textureLoad(tex, safePos); + let inside = loaded.xy; + let outside = loaded.zw; return SampleResult(select(inside, vec2f(-1), outOfBounds), select(outside, vec2f(-1), outOfBounds)); } @@ -73,8 +73,8 @@ describe('jump flood (distance) example', () => { fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { let offset = offsetUniform; - var size = textureDimensions(readView); - var pos = vec2f(f32(x), f32(y)); + let size = textureDimensions(readView); + let pos = vec2f(f32(x), f32(y)); var bestInsideCoord = vec2f(-1); var bestOutsideCoord = vec2f(-1); var bestInsideDist = 1e+20; @@ -83,7 +83,7 @@ describe('jump flood (distance) example', () => { { // unrolled iteration #0 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (-1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (-1i * offset))); if ((sample.inside.x >= 0f)) { let dInside = distance(pos, (sample.inside * vec2f(size))); if ((dInside < bestInsideDist)) { @@ -101,7 +101,7 @@ describe('jump flood (distance) example', () => { } // unrolled iteration #1 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (0i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (0i * offset))); if ((sample.inside.x >= 0f)) { let dInside = distance(pos, (sample.inside * vec2f(size))); if ((dInside < bestInsideDist)) { @@ -119,7 +119,7 @@ describe('jump flood (distance) example', () => { } // unrolled iteration #2 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (1i * offset))); if ((sample.inside.x >= 0f)) { let dInside = distance(pos, (sample.inside * vec2f(size))); if ((dInside < bestInsideDist)) { @@ -140,7 +140,7 @@ describe('jump flood (distance) example', () => { { // unrolled iteration #0 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (-1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (-1i * offset))); if ((sample.inside.x >= 0f)) { let dInside = distance(pos, (sample.inside * vec2f(size))); if ((dInside < bestInsideDist)) { @@ -158,7 +158,7 @@ describe('jump flood (distance) example', () => { } // unrolled iteration #1 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (0i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (0i * offset))); if ((sample.inside.x >= 0f)) { let dInside = distance(pos, (sample.inside * vec2f(size))); if ((dInside < bestInsideDist)) { @@ -176,7 +176,7 @@ describe('jump flood (distance) example', () => { } // unrolled iteration #2 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (1i * offset))); if ((sample.inside.x >= 0f)) { let dInside = distance(pos, (sample.inside * vec2f(size))); if ((dInside < bestInsideDist)) { @@ -197,7 +197,7 @@ describe('jump flood (distance) example', () => { { // unrolled iteration #0 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (-1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (-1i * offset))); if ((sample.inside.x >= 0f)) { let dInside = distance(pos, (sample.inside * vec2f(size))); if ((dInside < bestInsideDist)) { @@ -215,7 +215,7 @@ describe('jump flood (distance) example', () => { } // unrolled iteration #1 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (0i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (0i * offset))); if ((sample.inside.x >= 0f)) { let dInside = distance(pos, (sample.inside * vec2f(size))); if ((dInside < bestInsideDist)) { @@ -233,7 +233,7 @@ describe('jump flood (distance) example', () => { } // unrolled iteration #2 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (1i * offset))); if ((sample.inside.x >= 0f)) { let dInside = distance(pos, (sample.inside * vec2f(size))); if ((dInside < bestInsideDist)) { @@ -267,11 +267,11 @@ describe('jump flood (distance) example', () => { @group(2) @binding(0) var distTexture: texture_storage_2d; fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { - var pos = vec2f(f32(x), f32(y)); - var size = textureDimensions(readView); - var texel = textureLoad(readView, vec2i(i32(x), i32(y))); - var insideCoord = texel.xy; - var outsideCoord = texel.zw; + let pos = vec2f(f32(x), f32(y)); + let size = textureDimensions(readView); + let texel = textureLoad(readView, vec2i(i32(x), i32(y))); + let insideCoord = texel.xy; + let outsideCoord = texel.zw; var insideDist = 1e+20; var outsideDist = 1e+20; if ((insideCoord.x >= 0f)) { @@ -303,10 +303,6 @@ describe('jump flood (distance) example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct distanceFrag_Input { - @location(0) uv: vec2f, - } - @group(1) @binding(0) var distTexture: texture_2d; @group(1) @binding(1) var sampler_1: sampler; @@ -322,8 +318,12 @@ describe('jump flood (distance) example', () => { const insideGradient: array = array(vec3f(0.05000000074505806, 0.05000000074505806, 0.15000000596046448), vec3f(0.10000000149011612, 0.20000000298023224, 0.30000001192092896), vec3f(0.20000000298023224, 0.44999998807907104, 0.550000011920929), vec3f(0.4000000059604645, 0.75, 0.699999988079071), vec3f(0.8999999761581421, 1, 0.949999988079071)); + struct distanceFrag_Input { + @location(0) uv: vec2f, + } + @fragment fn distanceFrag(_arg_0: distanceFrag_Input) -> @location(0) vec4f { - var size = textureDimensions(distTexture); + let size = textureDimensions(distTexture); var dist = textureSample(distTexture, sampler_1, _arg_0.uv).x; if (((paramsUniform.showInside == 0u) && (dist < 0f))) { dist = 0f; @@ -337,15 +337,15 @@ describe('jump flood (distance) example', () => { let gradientPos = (t * 4f); let idx = u32(gradientPos); let frac = fract(gradientPos); - var outsideBase = mix(outsideGradient[min(idx, 4u)], outsideGradient[min((idx + 1u), 4u)], frac); - var insideBase = mix(insideGradient[min(idx, 4u)], insideGradient[min((idx + 1u), 4u)], frac); + let outsideBase = mix(outsideGradient[min(idx, 4u)], outsideGradient[min((idx + 1u), 4u)], frac); + let insideBase = mix(insideGradient[min(idx, 4u)], insideGradient[min((idx + 1u), 4u)], frac); var baseColor = outsideBase; if ((dist < 0f)) { baseColor = insideBase; } let contourFreq = (maxDist / 12f); let contour = smoothstep(0f, 0.15f, abs((fract((unsigned / contourFreq)) - 0.5f))); - var color = (baseColor * (0.7f + (0.3f * contour))); + let color = (baseColor * (0.7f + (0.3f * contour))); return vec4f(color, 1f); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/jump-flood-voronoi.test.ts b/apps/typegpu-docs/tests/individual-example-tests/jump-flood-voronoi.test.ts index 445bfdf43d..fa0e4cd1e5 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/jump-flood-voronoi.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/jump-flood-voronoi.test.ts @@ -55,14 +55,14 @@ describe('jump flood (voronoi) example', () => { const palette: array = array(vec3f(0.9215686321258545, 0.8117647171020508, 1), vec3f(0.7176470756530762, 0.545098066329956, 0.9803921580314636), vec3f(0.545098066329956, 0.3607843220233917, 0.9647058844566345), vec3f(0.4274509847164154, 0.2666666805744171, 0.9490196108818054)); fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { - var size = textureDimensions(writeView); + let size = textureDimensions(writeView); randSeed2(((vec2f(f32(x), f32(y)) / vec2f(size)) + timeUniform)); let randomVal = randFloat01(); let isSeed = (randomVal >= seedThresholdUniform); let paletteColor = palette[u32(floor((randFloat01() * 4f)))]; - var variation = (vec3f((randFloat01() - 0.5f), (randFloat01() - 0.5f), (randFloat01() - 0.5f)) * 0.15f); - var color = select(vec4f(), vec4f(saturate((paletteColor + variation)), 1f), isSeed); - var coord = select(vec2f(-1), (vec2f(f32(x), f32(y)) / vec2f(size)), isSeed); + let variation = (vec3f((randFloat01() - 0.5f), (randFloat01() - 0.5f), (randFloat01() - 0.5f)) * 0.15f); + let color = select(vec4f(), vec4f(saturate((paletteColor + variation)), 1f), isSeed); + let coord = select(vec2f(-1), (vec2f(f32(x), f32(y)) / vec2f(size)), isSeed); textureStore(writeView, vec2i(i32(x), i32(y)), 0, color); textureStore(writeView, vec2i(i32(x), i32(y)), 1, vec4f(coord, 0f, 0f)); } @@ -110,12 +110,12 @@ describe('jump flood (voronoi) example', () => { } fn sampleWithOffset(tex: texture_storage_2d_array, pos: vec2i, offset: vec2i) -> SampleResult { - var dims = textureDimensions(tex); - var samplePos = (pos + offset); + let dims = textureDimensions(tex); + let samplePos = (pos + offset); let outOfBounds = ((((samplePos.x < 0i) || (samplePos.y < 0i)) || (samplePos.x >= i32(dims.x))) || (samplePos.y >= i32(dims.y))); - var safePos = clamp(samplePos, vec2i(), vec2i((dims - 1u))); - var loadedColor = textureLoad(tex, safePos, 0); - var loadedCoord = textureLoad(tex, safePos, 1).xy; + let safePos = clamp(samplePos, vec2i(), vec2i((dims - 1u))); + let loadedColor = textureLoad(tex, safePos, 0); + let loadedCoord = textureLoad(tex, safePos, 1).xy; return SampleResult(select(loadedColor, vec4f(), outOfBounds), select(loadedCoord, vec2f(-1), outOfBounds)); } @@ -123,14 +123,14 @@ describe('jump flood (voronoi) example', () => { fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { let offset = offsetUniform; - var size = textureDimensions(readView); + let size = textureDimensions(readView); var minDist = 1e+20; var bestSample = SampleResult(vec4f(), vec2f(-1)); // unrolled iteration #0 { // unrolled iteration #0 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (-1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (-1i * offset))); if ((sample.coord.x >= 0f)) { let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); if ((dist < minDist)) { @@ -141,7 +141,7 @@ describe('jump flood (voronoi) example', () => { } // unrolled iteration #1 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (-1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (-1i * offset))); if ((sample.coord.x >= 0f)) { let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); if ((dist < minDist)) { @@ -152,7 +152,7 @@ describe('jump flood (voronoi) example', () => { } // unrolled iteration #2 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (-1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (-1i * offset))); if ((sample.coord.x >= 0f)) { let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); if ((dist < minDist)) { @@ -166,7 +166,7 @@ describe('jump flood (voronoi) example', () => { { // unrolled iteration #0 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (0i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (0i * offset))); if ((sample.coord.x >= 0f)) { let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); if ((dist < minDist)) { @@ -177,7 +177,7 @@ describe('jump flood (voronoi) example', () => { } // unrolled iteration #1 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (0i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (0i * offset))); if ((sample.coord.x >= 0f)) { let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); if ((dist < minDist)) { @@ -188,7 +188,7 @@ describe('jump flood (voronoi) example', () => { } // unrolled iteration #2 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (0i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (0i * offset))); if ((sample.coord.x >= 0f)) { let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); if ((dist < minDist)) { @@ -202,7 +202,7 @@ describe('jump flood (voronoi) example', () => { { // unrolled iteration #0 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (1i * offset))); if ((sample.coord.x >= 0f)) { let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); if ((dist < minDist)) { @@ -213,7 +213,7 @@ describe('jump flood (voronoi) example', () => { } // unrolled iteration #1 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (1i * offset))); if ((sample.coord.x >= 0f)) { let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); if ((dist < minDist)) { @@ -224,7 +224,7 @@ describe('jump flood (voronoi) example', () => { } // unrolled iteration #2 { - var sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (1i * offset))); + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (1i * offset))); if ((sample.coord.x >= 0f)) { let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); if ((dist < minDist)) { diff --git a/apps/typegpu-docs/tests/individual-example-tests/lines-combinations.test.ts b/apps/typegpu-docs/tests/individual-example-tests/lines-combinations.test.ts index f17d94772f..ba2a90eec3 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/lines-combinations.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/lines-combinations.test.ts @@ -39,7 +39,7 @@ describe('lines combinations example', () => { let s = sin(time); let c = cos(time); const r = 0.25; - var points = array(vec2f(((r * s) - 0.25f), (r * c)), vec2f(-0.25, 0), vec2f(0.25, 0), vec2f(((-(r) * s) + 0.25f), (r * c))); + let points = array(vec2f(((r * s) - 0.25f), (r * c)), vec2f(-0.25, 0), vec2f(0.25, 0), vec2f(((-(r) * s) + 0.25f), (r * c))); let i = clamp((i32(vertexIndex) - 1i), 0i, 3i); return LineControlPoint(points[i], 0.2f); } @@ -72,13 +72,13 @@ describe('lines combinations example', () => { let b = (distance_1.y * sinDivLen); let c = (distance_1.x * sinDivLen); let d = (distance_1.y * cosDivLen); - var nL = vec2f((a - b), (c + d)); - var nR = vec2f((a + b), (-(c) + d)); + let nL = vec2f((a - b), (c + d)); + let nR = vec2f((a + b), (-(c) + d)); return ExternalNormals(nL, nR); } fn miterPointNoCheck(a: vec2f, b: vec2f) -> vec2f { - var ab = (a + b); + let ab = (a + b); return (ab * (2f / dot(ab, ab))); } @@ -98,10 +98,10 @@ describe('lines combinations example', () => { let tooCloseToJoinR = (dot(eAB.nR, eBC.nR) > 0.99f); let shouldJoinL = (isHairpin || (underLimitL && !tooCloseToJoinL)); let shouldJoinR = (isHairpin || (underLimitR && !tooCloseToJoinR)); - var dLMiter = miterPointNoCheck(eAB.nL, eBC.nL); - var dRMiter = miterPointNoCheck(eBC.nR, eAB.nR); - var dL = select(eBC.nL, dLMiter, (!isCap && !shouldJoinL)); - var dR = select(eBC.nR, dRMiter, (!isCap && !shouldJoinR)); + let dLMiter = miterPointNoCheck(eAB.nL, eBC.nL); + let dRMiter = miterPointNoCheck(eBC.nR, eAB.nR); + let dL = select(eBC.nL, dLMiter, (!isCap && !shouldJoinL)); + let dR = select(eBC.nR, dRMiter, (!isCap && !shouldJoinR)); return JoinResult(dL, dR, shouldJoinL, shouldJoinR, isHairpin); } @@ -116,10 +116,10 @@ describe('lines combinations example', () => { } fn intersectLines(A1: vec2f, A2: vec2f, B1: vec2f, B2: vec2f) -> Intersection { - var a = (A2 - A1); - var b = (B2 - B1); + let a = (A2 - A1); + let b = (B2 - B1); let axb = cross2d(a, b); - var AB = (B1 - A1); + let AB = (B1 - A1); let t = (cross2d(AB, b) / axb); return Intersection((((axb != 0f) && (t >= 0f)) && (t <= 1f)), t, (A1 + (a * t))); } @@ -146,9 +146,9 @@ describe('lines combinations example', () => { fn bisectCcw(a: vec2f, b: vec2f) -> vec2f { let sin_1 = cross2d(a, b); let sinSign = select(-1f, 1f, (sin_1 >= 0f)); - var orthoA = rot90ccw(a); - var orthoB = rot90cw(b); - var dir = select(((a + b) * sinSign), (orthoA + orthoB), (dot(a, b) < 0f)); + let orthoA = rot90ccw(a); + let orthoB = rot90cw(b); + let dir = select(((a + b) * sinSign), (orthoA + orthoB), (dot(a, b) < 0f)); return normalize(dir); } @@ -157,7 +157,7 @@ describe('lines combinations example', () => { } fn slerpApprox(a: vec2f, b: vec2f, t: f32) -> vec2f { - var mid = bisectNoCheck(a, b); + let mid = bisectNoCheck(a, b); var a_ = a; var b_ = mid; var t_ = (2f * t); @@ -173,15 +173,15 @@ describe('lines combinations example', () => { if ((joinVertexIndex == 0u)) { return join.v; } - var dir = slerpApprox(join.d, bisectCcw(join.start, join.end), (f32(joinVertexIndex) / f32(maxJoinCount))); + let dir = slerpApprox(join.d, bisectCcw(join.start, join.end), (f32(joinVertexIndex) / f32(maxJoinCount))); return (join.C.position + (dir * join.C.radius)); } fn lineSegmentVariableWidth(vertexIndex: u32, A: LineControlPoint, B: LineControlPoint, C: LineControlPoint, D: LineControlPoint, maxJoinCount: u32) -> LineSegmentOutput { - var AB = (B.position - A.position); - var BC = (C.position - B.position); - var DC = (C.position - D.position); - var CB = -(BC); + let AB = (B.position - A.position); + let BC = (C.position - B.position); + let DC = (C.position - D.position); + let CB = -(BC); let radiusABDelta = (A.radius - B.radius); let radiusBCDelta = (B.radius - C.radius); let radiusCDDelta = (C.radius - D.radius); @@ -190,10 +190,10 @@ describe('lines combinations example', () => { } let isCapB = (dot(AB, AB) <= (radiusABDelta * radiusABDelta)); let isCapC = (dot(DC, DC) <= (radiusCDDelta * radiusCDDelta)); - var eAB = externalNormals(AB, A.radius, B.radius); - var eBC = externalNormals(BC, B.radius, C.radius); - var eCB = ExternalNormals(eBC.nR, eBC.nL); - var eDC = externalNormals(DC, D.radius, C.radius); + let eAB = externalNormals(AB, A.radius, B.radius); + let eBC = externalNormals(BC, B.radius, C.radius); + let eCB = ExternalNormals(eBC.nR, eBC.nL); + let eDC = externalNormals(DC, D.radius, C.radius); let joinLimit = dot(eBC.nL, BC); var joinB = solveJoin(AB, BC, eAB, eBC, joinLimit, isCapB); var joinC = solveJoin(DC, CB, eDC, eCB, -(joinLimit), isCapC); @@ -201,16 +201,16 @@ describe('lines combinations example', () => { let d3 = (&joinB.dR); let d4 = (&joinC.dL); let d5 = (&joinC.dR); - var v2orig = (B.position + ((*d2) * B.radius)); - var v3orig = (B.position + ((*d3) * B.radius)); - var v4orig = (C.position + ((*d4) * C.radius)); - var v5orig = (C.position + ((*d5) * C.radius)); - var limL = intersectLines(B.position, v2orig, C.position, v5orig); - var limR = intersectLines(B.position, v3orig, C.position, v4orig); - var v2 = select(v2orig, limL.point, limL.valid); - var v5 = select(v5orig, limL.point, limL.valid); - var v3 = select(v3orig, limR.point, limR.valid); - var v4 = select(v4orig, limR.point, limR.valid); + let v2orig = (B.position + ((*d2) * B.radius)); + let v3orig = (B.position + ((*d3) * B.radius)); + let v4orig = (C.position + ((*d4) * C.radius)); + let v5orig = (C.position + ((*d5) * C.radius)); + let limL = intersectLines(B.position, v2orig, C.position, v5orig); + let limR = intersectLines(B.position, v3orig, C.position, v4orig); + let v2 = select(v2orig, limL.point, limL.valid); + let v5 = select(v5orig, limL.point, limL.valid); + let v3 = select(v3orig, limR.point, limR.valid); + let v4 = select(v4orig, limR.point, limR.valid); if ((vertexIndex == 0u)) { return LineSegmentOutput(B.position, (1f / B.radius)); } @@ -256,14 +256,14 @@ describe('lines combinations example', () => { @vertex fn mainVertex(@builtin(vertex_index) vertexIndex: u32, @builtin(instance_index) instanceIndex: u32) -> mainVertex_Output { let t = uniforms.time; - var A = item(instanceIndex, t); - var B = item((instanceIndex + 1u), t); - var C = item((instanceIndex + 2u), t); - var D = item((instanceIndex + 3u), t); + let A = item(instanceIndex, t); + let B = item((instanceIndex + 1u), t); + let C = item((instanceIndex + 2u), t); + let D = item((instanceIndex + 3u), t); if (((((A.radius < 0f) || (B.radius < 0f)) || (C.radius < 0f)) || (D.radius < 0f))) { return mainVertex_Output(); } - var result = lineSegmentVariableWidth(vertexIndex, A, B, C, D, 6u); + let result = lineSegmentVariableWidth(vertexIndex, A, B, C, D, 6u); return mainVertex_Output(vec4f((result.vertexPosition * result.w), 0f, result.w), result.vertexPosition, vec2f(0f, select(0f, 1f, (vertexIndex > 1u))), instanceIndex, vertexIndex, 0u); } @@ -278,7 +278,7 @@ describe('lines combinations example', () => { @fragment fn mainFragment(_arg_0: mainFragment_Input, @builtin(front_facing) frontFacing: bool, @builtin(position) screenPosition: vec4f) -> @location(0) vec4f { let fillType = uniforms.fillType; var color = vec3f(); - var colors = array(vec3f(1, 0, 0), vec3f(0, 1, 0), vec3f(0, 0, 1), vec3f(1, 0, 1), vec3f(1, 1, 0), vec3f(0, 1, 1), vec3f(0.75, 0.25, 0.25), vec3f(0.25, 0.75, 0.25), vec3f(0.25, 0.25, 0.75)); + let colors = array(vec3f(1, 0, 0), vec3f(0, 1, 0), vec3f(0, 0, 1), vec3f(1, 0, 1), vec3f(1, 1, 0), vec3f(0, 1, 1), vec3f(0.75, 0.25, 0.25), vec3f(0.25, 0.75, 0.25), vec3f(0.25, 0.25, 0.75)); if ((fillType == 1u)) { color = mix(vec3f(0.7699999809265137, 0.38999998569488525, 1), vec3f(0.10999999940395355, 0.4399999976158142, 0.9399999976158142), ((_arg_0.position.x * 0.5f) + 0.5f)); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/liquid-glass.test.ts b/apps/typegpu-docs/tests/individual-example-tests/liquid-glass.test.ts index e247d26a22..c470fad45a 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/liquid-glass.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/liquid-glass.test.ts @@ -64,10 +64,6 @@ describe('liquid-glass example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct fragmentShader_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var mousePosUniform: vec2f; struct Params { @@ -87,7 +83,7 @@ describe('liquid-glass example', () => { @group(0) @binding(1) var paramsUniform: Params; fn sdRoundedBox2d(point: vec2f, size: vec2f, cornerRadius: f32) -> f32 { - var d = ((abs(point) - size) + vec2f(cornerRadius)); + let d = ((abs(point) - size) + vec2f(cornerRadius)); return ((length(max(d, vec2f())) + min(max(d.x, d.y), 0f)) - cornerRadius); } @@ -112,17 +108,17 @@ describe('liquid-glass example', () => { var samples = array(); // unrolled iteration #0 { - var channelOffset = ((dir * -1f) * offset); + let channelOffset = ((dir * -1f) * offset); samples[0i] = textureSampleBias(tex, sampler_2, (uv - channelOffset), blur).rgb; } // unrolled iteration #1 { - var channelOffset = ((dir * 0f) * offset); + let channelOffset = ((dir * 0f) * offset); samples[1i] = textureSampleBias(tex, sampler_2, (uv - channelOffset), blur).rgb; } // unrolled iteration #2 { - var channelOffset = ((dir * 1f) * offset); + let channelOffset = ((dir * 1f) * offset); samples[2i] = textureSampleBias(tex, sampler_2, (uv - channelOffset), blur).rgb; } return vec3f(samples[0i].x, samples[1i].y, samples[2i].z); @@ -137,20 +133,24 @@ describe('liquid-glass example', () => { return mix(vec4f(color, 1f), vec4f(tint.color, 1f), tint.strength); } + struct fragmentShader_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentShader(_arg_0: fragmentShader_Input) -> @location(0) vec4f { - var posInBoxSpace = (_arg_0.uv - mousePosUniform); + let posInBoxSpace = (_arg_0.uv - mousePosUniform); let sdfDist = sdRoundedBox2d(posInBoxSpace, paramsUniform.rectDims, paramsUniform.radius); - var dir = normalize((posInBoxSpace * paramsUniform.rectDims.yx)); + let dir = normalize((posInBoxSpace * paramsUniform.rectDims.yx)); let normalizedDist = ((sdfDist - paramsUniform.start) / (paramsUniform.end - paramsUniform.start)); - var texDim = textureDimensions(sampledView, 0); + let texDim = textureDimensions(sampledView, 0); let featherUV = (paramsUniform.edgeFeather / f32(max(texDim.x, texDim.y))); - var weights = calculateWeights(sdfDist, paramsUniform.start, paramsUniform.end, featherUV); - var blurSample = textureSampleBias(sampledView, sampler_1, _arg_0.uv, paramsUniform.blur); - var refractedSample = sampleWithChromaticAberration(sampledView, sampler_1, (_arg_0.uv + (dir * (paramsUniform.refractionStrength * normalizedDist))), (paramsUniform.chromaticStrength * normalizedDist), dir, (paramsUniform.blur * paramsUniform.edgeBlurMultiplier)); - var normalSample = textureSampleLevel(sampledView, sampler_1, _arg_0.uv, 0); - var tint = TintParams(paramsUniform.tintColor, paramsUniform.tintStrength); - var tintedBlur = applyTint(blurSample.rgb, tint); - var tintedRing = applyTint(refractedSample, tint); + let weights = calculateWeights(sdfDist, paramsUniform.start, paramsUniform.end, featherUV); + let blurSample = textureSampleBias(sampledView, sampler_1, _arg_0.uv, paramsUniform.blur); + let refractedSample = sampleWithChromaticAberration(sampledView, sampler_1, (_arg_0.uv + (dir * (paramsUniform.refractionStrength * normalizedDist))), (paramsUniform.chromaticStrength * normalizedDist), dir, (paramsUniform.blur * paramsUniform.edgeBlurMultiplier)); + let normalSample = textureSampleLevel(sampledView, sampler_1, _arg_0.uv, 0); + let tint = TintParams(paramsUniform.tintColor, paramsUniform.tintStrength); + let tintedBlur = applyTint(blurSample.rgb, tint); + let tintedRing = applyTint(refractedSample, tint); return (((tintedBlur * weights.inside) + (tintedRing * weights.ring)) + (normalSample * weights.outside)); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/log-test.test.ts b/apps/typegpu-docs/tests/individual-example-tests/log-test.test.ts index 3ee6a9035b..df7d438e69 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/log-test.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/log-test.test.ts @@ -976,13 +976,13 @@ describe('console log example', () => { } fn wrappedCallback(_arg_0: u32, _arg_1: u32, _arg_2: u32) { - var simpleStruct = SimpleStruct(vec3u(1, 2, 3), 4u); + let simpleStruct = SimpleStruct(vec3u(1, 2, 3), 4u); log1(simpleStruct); - var complexStruct = ComplexStruct(simpleStruct, true); + let complexStruct = ComplexStruct(simpleStruct, true); log2_1(complexStruct); - var simpleArray = array(1u, 2u); + let simpleArray = array(1u, 2u); log3(simpleArray); - var complexArray = array, 3>(array(3u, 4u), array(5u, 6u), array(7u, 8u)); + let complexArray = array, 3>(array(3u, 4u), array(5u, 6u), array(7u, 8u)); log4(complexArray); } @@ -1449,7 +1449,7 @@ describe('console log example', () => { } @vertex fn mainVertex(@builtin(vertex_index) _arg_vertexIndex: u32) -> mainVertex_Output { - var positions = array(vec2f(0, 0.5), vec2f(-0.5), vec2f(0.5, -0.5)); + let positions = array(vec2f(0, 0.5), vec2f(-0.5), vec2f(0.5, -0.5)); return mainVertex_Output(vec4f(positions[_arg_vertexIndex], 0f, 1f)); } @@ -1502,7 +1502,7 @@ describe('console log example', () => { } @vertex fn mainVertex(@builtin(vertex_index) _arg_vertexIndex: u32) -> mainVertex_Output { - var positions = array(vec2f(0, 0.5), vec2f(-0.5), vec2f(0.5, -0.5)); + let positions = array(vec2f(0, 0.5), vec2f(-0.5), vec2f(0.5, -0.5)); return mainVertex_Output(vec4f(positions[_arg_vertexIndex], 0f, 1f)); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/oklab.test.ts b/apps/typegpu-docs/tests/individual-example-tests/oklab.test.ts index b8e64d3654..396869d6d7 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/oklab.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/oklab.test.ts @@ -32,10 +32,6 @@ describe('oklab example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct mainFragment_Input { - @location(0) uv: vec2f, - } - struct item { hue: f32, alpha: f32, @@ -134,7 +130,7 @@ describe('oklab example', () => { fn findCusp(a: f32, b: f32) -> LC { let S_cusp = computeMaxSaturation(a, b); - var rgb_at_max = oklabToLinearRgb(vec3f(1f, (S_cusp * a), (S_cusp * b))); + let rgb_at_max = oklabToLinearRgb(vec3f(1f, (S_cusp * a), (S_cusp * b))); let L_cusp = cbrt((1f / max(max(rgb_at_max.x, rgb_at_max.y), rgb_at_max.z))); let C_cusp = (L_cusp * S_cusp); return LC(L_cusp, C_cusp); @@ -207,7 +203,7 @@ describe('oklab example', () => { let Ld = (L - 0.5f); let e1 = ((0.5f + abs(Ld)) + (alpha * C)); let L0 = (0.5f * (1f + (sign(Ld) * (e1 - sqrt(max(0f, ((e1 * e1) - (2f * abs(Ld))))))))); - var cusp = findCusp(a_, b_); + let cusp = findCusp(a_, b_); let t = clamp(findGamutIntersection(a_, b_, L, C, L0, cusp), 0f, 1f); let L_clipped = mix(L0, L, t); let C_clipped = (t * C); @@ -226,16 +222,20 @@ describe('oklab example', () => { return 1f; } + struct mainFragment_Input { + @location(0) uv: vec2f, + } + @fragment fn mainFragment(_arg_0: mainFragment_Input) -> @location(0) vec4f { - var uv = ((_arg_0.uv - 0.5f) * vec2f(2, -2)); + let uv = ((_arg_0.uv - 0.5f) * vec2f(2, -2)); let hue = uniforms.hue; - var pos = scaleView(uv); - var yzDir = vec2f(cos(hue), sin(hue)); - var lab = vec3f(pos.y, (yzDir * pos.x)); - var rgb = oklabToLinearRgb(lab); + let pos = scaleView(uv); + let yzDir = vec2f(cos(hue), sin(hue)); + let lab = vec3f(pos.y, (yzDir * pos.x)); + let rgb = oklabToLinearRgb(lab); let outOfGamut = (any((rgb < vec3f())) || any((rgb > vec3f(1)))); - var clipLab = gamutClipAdaptiveL05(lab); - var color = oklabToRgb(lab); + let clipLab = gamutClipAdaptiveL05(lab); + let color = oklabToRgb(lab); let patternScaled = ((item_1(uv, clipLab) * 0.1f) + 0.9f); return vec4f(select(color, (color * patternScaled), outOfGamut), 1f); }" diff --git a/apps/typegpu-docs/tests/individual-example-tests/perlin-noise.test.ts b/apps/typegpu-docs/tests/individual-example-tests/perlin-noise.test.ts index 56c00a8203..8351e9c7d4 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/perlin-noise.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/perlin-noise.test.ts @@ -92,7 +92,7 @@ describe('perlin noise example', () => { @group(1) @binding(1) var perlin3dCache__memory: array; fn getJunctionGradient(pos: vec3i) -> vec3f { - var size = vec3i(perlin3dCache__size.xyz); + let size = vec3i(perlin3dCache__size.xyz); let x = (((pos.x % size.x) + size.x) % size.x); let y = (((pos.y % size.y) + size.y) % size.y); let z = (((pos.z % size.z) + size.z) % size.z); @@ -100,8 +100,8 @@ describe('perlin noise example', () => { } fn dotProdGrid(pos: vec3f, junction: vec3f) -> f32 { - var relative = (pos - junction); - var gridVector = getJunctionGradient(vec3i(junction)); + let relative = (pos - junction); + let gridVector = getJunctionGradient(vec3i(junction)); return dot(relative, gridVector); } @@ -110,7 +110,7 @@ describe('perlin noise example', () => { } fn sample(pos: vec3f) -> f32 { - var minJunction = floor(pos); + let minJunction = floor(pos); let xyz = dotProdGrid(pos, minJunction); let xyZ = dotProdGrid(pos, (minJunction + vec3f(0, 0, 1))); let xYz = dotProdGrid(pos, (minJunction + vec3f(0, 1, 0))); @@ -119,8 +119,8 @@ describe('perlin noise example', () => { let XyZ = dotProdGrid(pos, (minJunction + vec3f(1, 0, 1))); let XYz = dotProdGrid(pos, (minJunction + vec3f(1, 1, 0))); let XYZ = dotProdGrid(pos, (minJunction + vec3f(1))); - var partial = (pos - minJunction); - var smoothPartial = quinticInterpolation(partial); + let partial = (pos - minJunction); + let smoothPartial = quinticInterpolation(partial); let xy = mix(xyz, xyZ, smoothPartial.z); let xY = mix(xYz, xYZ, smoothPartial.z); let Xy = mix(Xyz, XyZ, smoothPartial.z); @@ -141,12 +141,12 @@ describe('perlin noise example', () => { } @fragment fn fragment(_arg_0: FragmentIn) -> @location(0) vec4f { - var suv = (gridSize * _arg_0.uv); + let suv = (gridSize * _arg_0.uv); let n = sample(vec3f(suv, time)); let sharp = exponentialSharpen(n, sharpness); let n01 = ((sharp * 0.5f) + 0.5f); - var dark = vec3f(0, 0.20000000298023224, 1); - var light = vec3f(1, 0.30000001192092896, 0.5); + let dark = vec3f(0, 0.20000000298023224, 1); + let light = vec3f(1, 0.30000001192092896, 0.5); return vec4f(mix(dark, light, n01), 1f); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/phong-reflection.test.ts b/apps/typegpu-docs/tests/individual-example-tests/phong-reflection.test.ts index 1cfbf878ea..12ec94a289 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/phong-reflection.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/phong-reflection.test.ts @@ -48,17 +48,12 @@ describe('phong reflection example', () => { } @vertex fn vertexShader(@location(0) _arg_modelPosition: vec3f, @location(1) _arg_modelNormal: vec3f) -> vertexShader_Output { - var worldPosition = vec4f(_arg_modelPosition, 1f); + let worldPosition = vec4f(_arg_modelPosition, 1f); let camera = (&cameraUniform); - var canvasPosition = (((*camera).projection * (*camera).view) * worldPosition); + let canvasPosition = (((*camera).projection * (*camera).view) * worldPosition); return vertexShader_Output(_arg_modelPosition, _arg_modelNormal, canvasPosition); } - struct fragmentShader_Input { - @location(0) worldPosition: vec3f, - @location(1) worldNormal: vec3f, - } - struct ExampleControls { lightColor: vec3f, lightDirection: vec3f, @@ -69,19 +64,24 @@ describe('phong reflection example', () => { @group(0) @binding(1) var exampleControlsUniform: ExampleControls; + struct fragmentShader_Input { + @location(0) worldPosition: vec3f, + @location(1) worldNormal: vec3f, + } + @fragment fn fragmentShader(_arg_0: fragmentShader_Input) -> @location(0) vec4f { - var lightColor = normalize(exampleControlsUniform.lightColor); - var lightDirection = normalize(exampleControlsUniform.lightDirection); + let lightColor = normalize(exampleControlsUniform.lightColor); + let lightDirection = normalize(exampleControlsUniform.lightDirection); let ambientColor = (&exampleControlsUniform.ambientColor); let ambientStrength = exampleControlsUniform.ambientStrength; let specularStrength = exampleControlsUniform.specularExponent; - var ambient = ((*ambientColor) * ambientStrength); + let ambient = ((*ambientColor) * ambientStrength); let cosTheta = dot(_arg_0.worldNormal, lightDirection); - var diffuse = (lightColor * max(0f, cosTheta)); - var reflectionDirection = reflect((lightDirection * -1f), _arg_0.worldNormal); - var viewDirection = normalize((cameraUniform.position.xyz - _arg_0.worldPosition)); - var specular = (lightColor * pow(max(0f, dot(reflectionDirection, viewDirection)), specularStrength)); - var color = ((ambient + diffuse) + specular); + let diffuse = (lightColor * max(0f, cosTheta)); + let reflectionDirection = reflect((lightDirection * -1f), _arg_0.worldNormal); + let viewDirection = normalize((cameraUniform.position.xyz - _arg_0.worldPosition)); + let specular = (lightColor * pow(max(0f, dot(reflectionDirection, viewDirection)), specularStrength)); + let color = ((ambient + diffuse) + specular); return vec4f(color, 1f); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/point-light-shadow.test.ts b/apps/typegpu-docs/tests/individual-example-tests/point-light-shadow.test.ts index 283d8d652b..351db35ed2 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/point-light-shadow.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/point-light-shadow.test.ts @@ -35,18 +35,18 @@ describe('point light shadow example', () => { } @vertex fn vertexDepth(@location(0) position: vec3f, @location(3) column1: vec4f, @location(4) column2: vec4f, @location(5) column3: vec4f, @location(6) column4: vec4f) -> vertexDepth_Output { - var modelMatrix = mat4x4f(column1, column2, column3, column4); - var worldPos = (modelMatrix * vec4f(position, 1f)).xyz; - var pos = (camera.viewProjectionMatrix * vec4f(worldPos, 1f)); + let modelMatrix = mat4x4f(column1, column2, column3, column4); + let worldPos = (modelMatrix * vec4f(position, 1f)).xyz; + let pos = (camera.viewProjectionMatrix * vec4f(worldPos, 1f)); return vertexDepth_Output(pos, worldPos); } + @group(0) @binding(1) var lightPosition: vec3f; + struct fragmentDepth_Input { @location(0) worldPos: vec3f, } - @group(0) @binding(1) var lightPosition: vec3f; - @fragment fn fragmentDepth(_arg_0: fragmentDepth_Input) -> @builtin(frag_depth) f32 { let dist = length((_arg_0.worldPos - lightPosition)); return (dist / 100f); @@ -67,19 +67,13 @@ describe('point light shadow example', () => { } @vertex fn vertexMain(@location(0) position: vec3f, @location(2) uv: vec2f, @location(1) normal: vec3f, @location(3) column1: vec4f, @location(4) column2: vec4f, @location(5) column3: vec4f, @location(6) column4: vec4f) -> vertexMain_Output { - var modelMatrix = mat4x4f(column1, column2, column3, column4); - var worldPos = (modelMatrix * vec4f(position, 1f)).xyz; - var pos = (camera.viewProjectionMatrix * vec4f(worldPos, 1f)); - var worldNormal = normalize((modelMatrix * vec4f(normal, 0f)).xyz); + let modelMatrix = mat4x4f(column1, column2, column3, column4); + let worldPos = (modelMatrix * vec4f(position, 1f)).xyz; + let pos = (camera.viewProjectionMatrix * vec4f(worldPos, 1f)); + let worldNormal = normalize((modelMatrix * vec4f(normal, 0f)).xyz); return vertexMain_Output(pos, worldPos, uv, worldNormal); } - struct fragmentMain_Input { - @location(0) worldPos: vec3f, - @location(1) uv: vec2f, - @location(2) normal: vec3f, - } - @group(1) @binding(3) var lightPosition: vec3f; struct item { @@ -97,33 +91,39 @@ describe('point light shadow example', () => { @group(1) @binding(2) var shadowSampler: sampler_comparison; + struct fragmentMain_Input { + @location(0) worldPos: vec3f, + @location(1) uv: vec2f, + @location(2) normal: vec3f, + } + @fragment fn fragmentMain(_arg_0: fragmentMain_Input) -> @location(0) vec4f { let lightPos = (&lightPosition); - var toLight = ((*lightPos) - _arg_0.worldPos); + let toLight = ((*lightPos) - _arg_0.worldPos); let dist = length(toLight); - var lightDir = (toLight / dist); + let lightDir = (toLight / dist); let ndotl = max(dot(_arg_0.normal, lightDir), 0f); let normalBiasWorld = (shadowParams.normalBiasBase + (shadowParams.normalBiasSlope * (1f - ndotl))); - var biasedPos = (_arg_0.worldPos + (_arg_0.normal * normalBiasWorld)); - var toLightBiased = (biasedPos - (*lightPos)); + let biasedPos = (_arg_0.worldPos + (_arg_0.normal * normalBiasWorld)); + let toLightBiased = (biasedPos - (*lightPos)); let distBiased = length(toLightBiased); - var dir = ((toLightBiased / distBiased) * vec3f(-1, 1, 1)); + let dir = ((toLightBiased / distBiased) * vec3f(-1, 1, 1)); let depthRef = (distBiased / 100f); - var up = select(vec3f(1, 0, 0), vec3f(0, 1, 0), (abs(dir.y) < 0.9998999834060669f)); - var right = normalize(cross(up, dir)); - var realUp = cross(dir, right); + let up = select(vec3f(1, 0, 0), vec3f(0, 1, 0), (abs(dir.y) < 0.9998999834060669f)); + let right = normalize(cross(up, dir)); + let realUp = cross(dir, right); let PCF_SAMPLES = shadowParams.pcfSamples; let diskRadius = shadowParams.diskRadius; var visibilityAcc = 0f; for (var i = 0u; (i < PCF_SAMPLES); i++) { - var o = (samplesUniform[i].xy * diskRadius); - var sampleDir = ((dir + (right * o.x)) + (realUp * o.y)); + let o = (samplesUniform[i].xy * diskRadius); + let sampleDir = ((dir + (right * o.x)) + (realUp * o.y)); visibilityAcc += textureSampleCompare(shadowDepthCube, shadowSampler, sampleDir, depthRef); } let rawNdotl = dot(_arg_0.normal, lightDir); let visibility = select((visibilityAcc / f32(PCF_SAMPLES)), 0f, (rawNdotl < 0f)); - var baseColor = vec3f(1, 0.5, 0.3100000023841858); - var color = (baseColor * ((ndotl * visibility) + 0.1f)); + let baseColor = vec3f(1, 0.5, 0.3100000023841858); + let color = (baseColor * ((ndotl * visibility) + 0.1f)); return vec4f(color, 1f); } @@ -141,8 +141,8 @@ describe('point light shadow example', () => { } @vertex fn vertexLightIndicator(@location(0) position: vec3f) -> vertexLightIndicator_Output { - var worldPos = ((position * 0.15f) + lightPosition); - var pos = (camera.viewProjectionMatrix * vec4f(worldPos, 1f)); + let worldPos = ((position * 0.15f) + lightPosition); + let pos = (camera.viewProjectionMatrix * vec4f(worldPos, 1f)); return vertexLightIndicator_Output(pos); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/probability.test.ts b/apps/typegpu-docs/tests/individual-example-tests/probability.test.ts index a4ae7762a4..5e6c7c9c61 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/probability.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/probability.test.ts @@ -55,8 +55,8 @@ describe('probability distribution plot example', () => { fn randInUnitSphere() -> vec3f { let u = sample(); - var v = vec3f(randNormal(0f, 1f), randNormal(0f, 1f), randNormal(0f, 1f)); - var vNorm = normalize(v); + let v = vec3f(randNormal(0f, 1f), randNormal(0f, 1f), randNormal(0f, 1f)); + let vNorm = normalize(v); return (vNorm * pow(u, 0.33f)); } @@ -300,13 +300,13 @@ describe('probability distribution plot example', () => { fn randInUnitSphere() -> vec3f { let u = sample(); - var v = vec3f(randNormal(0f, 1f), randNormal(0f, 1f), randNormal(0f, 1f)); - var vNorm = normalize(v); + let v = vec3f(randNormal(0f, 1f), randNormal(0f, 1f), randNormal(0f, 1f)); + let vNorm = normalize(v); return (vNorm * pow(u, 0.33f)); } fn randInUnitHemisphere(normal: vec3f) -> vec3f { - var value = randInUnitSphere(); + let value = randInUnitSphere(); let alignment = dot(normal, value); return (sign(alignment) * value); } @@ -356,7 +356,7 @@ describe('probability distribution plot example', () => { } fn randOnUnitHemisphere(normal: vec3f) -> vec3f { - var value = randOnUnitSphere(); + let value = randOnUnitSphere(); let alignment = dot(normal, value); return (sign(alignment) * value); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/ray-marching.test.ts b/apps/typegpu-docs/tests/individual-example-tests/ray-marching.test.ts index 1d56a2d307..49f9a60c4d 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/ray-marching.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/ray-marching.test.ts @@ -26,15 +26,11 @@ describe('ray-marching example', () => { } @vertex fn vertexMain(@builtin(vertex_index) idx: u32) -> vertexMain_Output { - var pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); - var uv = array(vec2f(), vec2f(2, 0), vec2f(0, 2)); + let pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); + let uv = array(vec2f(), vec2f(2, 0), vec2f(0, 2)); return vertexMain_Output(vec4f(pos[idx], 0f, 1f), uv[idx]); } - struct fragmentMain_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var resolution: vec2f; struct Shape { @@ -47,8 +43,8 @@ describe('ray-marching example', () => { } fn sdBoxFrame3d(point: vec3f, size: vec3f, thickness: f32) -> f32 { - var p1 = (abs(point) - size); - var q = (abs((p1 + thickness)) - vec3f(thickness)); + let p1 = (abs(point) - size); + let q = (abs((p1 + thickness)) - vec3f(thickness)); let d1 = (length(max(vec3f(p1.x, q.y, q.z), vec3f())) + min(max(p1.x, max(q.y, q.z)), 0f)); let d2 = (length(max(vec3f(q.x, p1.y, q.z), vec3f())) + min(max(q.x, max(p1.y, q.z)), 0f)); let d3 = (length(max(vec3f(q.x, q.y, p1.z), vec3f())) + min(max(q.x, max(q.y, p1.z)), 0f)); @@ -60,30 +56,30 @@ describe('ray-marching example', () => { let m = (h * h); let dist = (min(a.dist, b.dist) - ((m * k) * 0.25f)); let weight = (m + select(0f, (1f - m), (a.dist > b.dist))); - var color = mix(a.color, b.color, weight); + let color = mix(a.color, b.color, weight); return Shape(color, dist); } fn getMorphingShape(p: vec3f, t: f32) -> Shape { - var center = vec3f(0, 2, 6); - var localP = (p - center); - var rotMatZ = mat4x4f(cos(-(t)), sin(-(t)), 0, 0, -sin(-(t)), cos(-(t)), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - var rotMatX = mat4x4f(1, 0, 0, 0, 0, cos((-(t) * 0.6f)), sin((-(t) * 0.6f)), 0, 0, -sin((-(t) * 0.6f)), cos((-(t) * 0.6f)), 0, 0, 0, 0, 1); - var rotatedP = (rotMatZ * (rotMatX * vec4f(localP, 1f))).xyz; - var boxSize = vec3f(0.699999988079071); - var sphere1Offset = vec3f((cos((t * 2f)) * 0.8f), (sin((t * 3f)) * 0.3f), (sin((t * 2f)) * 0.8f)); - var sphere2Offset = vec3f((cos(((t * 2f) + 3.14f)) * 0.8f), (sin(((t * 3f) + 1.57f)) * 0.3f), (sin(((t * 2f) + 3.14f)) * 0.8f)); - var sphere1 = Shape(vec3f(0.4000000059604645, 0.5, 1), sdSphere((localP - sphere1Offset), 0.5f)); - var sphere2 = Shape(vec3f(1, 0.800000011920929, 0.20000000298023224), sdSphere((localP - sphere2Offset), 0.3f)); - var box = Shape(vec3f(1, 0.30000001192092896, 0.30000001192092896), sdBoxFrame3d(rotatedP, boxSize, 0.1f)); - var spheres = smoothShapeUnion(sphere1, sphere2, 0.1f); + let center = vec3f(0, 2, 6); + let localP = (p - center); + let rotMatZ = mat4x4f(cos(-(t)), sin(-(t)), 0, 0, -sin(-(t)), cos(-(t)), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + let rotMatX = mat4x4f(1, 0, 0, 0, 0, cos((-(t) * 0.6f)), sin((-(t) * 0.6f)), 0, 0, -sin((-(t) * 0.6f)), cos((-(t) * 0.6f)), 0, 0, 0, 0, 1); + let rotatedP = (rotMatZ * (rotMatX * vec4f(localP, 1f))).xyz; + let boxSize = vec3f(0.699999988079071); + let sphere1Offset = vec3f((cos((t * 2f)) * 0.8f), (sin((t * 3f)) * 0.3f), (sin((t * 2f)) * 0.8f)); + let sphere2Offset = vec3f((cos(((t * 2f) + 3.14f)) * 0.8f), (sin(((t * 3f) + 1.57f)) * 0.3f), (sin(((t * 2f) + 3.14f)) * 0.8f)); + let sphere1 = Shape(vec3f(0.4000000059604645, 0.5, 1), sdSphere((localP - sphere1Offset), 0.5f)); + let sphere2 = Shape(vec3f(1, 0.800000011920929, 0.20000000298023224), sdSphere((localP - sphere2Offset), 0.3f)); + let box = Shape(vec3f(1, 0.30000001192092896, 0.30000001192092896), sdBoxFrame3d(rotatedP, boxSize, 0.1f)); + let spheres = smoothShapeUnion(sphere1, sphere2, 0.1f); return smoothShapeUnion(spheres, box, 0.2f); } @group(0) @binding(1) var time: f32; fn checkerBoard(uv: vec2f) -> f32 { - var fuv = floor(uv); + let fuv = floor(uv); return (abs((fuv.x + fuv.y)) % 2f); } @@ -96,8 +92,8 @@ describe('ray-marching example', () => { } fn getSceneDist(p: vec3f) -> Shape { - var shape = getMorphingShape(p, time); - var floor_1 = Shape(mix(vec3f(1), vec3f(0.20000000298023224), checkerBoard((p.xz * 2f))), sdPlane(p, vec3f(0, 1, 0), 0f)); + let shape = getMorphingShape(p, time); + let floor_1 = Shape(mix(vec3f(1), vec3f(0.20000000298023224), checkerBoard((p.xz * 2f))), sdPlane(p, vec3f(0, 1, 0), 0f)); return shapeUnion(shape, floor_1); } @@ -105,8 +101,8 @@ describe('ray-marching example', () => { var dO = 0f; var result = Shape(vec3f(), 30f); for (var i = 0; (i < 1000i); i++) { - var p = (ro + (rd * dO)); - var scene = getSceneDist(p); + let p = (ro + (rd * dO)); + let scene = getSceneDist(p); dO += scene.dist; if (((dO > 30f) || (scene.dist < 1e-3f))) { result.dist = dO; @@ -120,7 +116,7 @@ describe('ray-marching example', () => { fn getNormal(p: vec3f) -> vec3f { let dist = getSceneDist(p).dist; const e = 0.01; - var n = vec3f((getSceneDist((p + vec3f(e, 0f, 0f))).dist - dist), (getSceneDist((p + vec3f(0f, e, 0f))).dist - dist), (getSceneDist((p + vec3f(0f, 0f, e))).dist - dist)); + let n = vec3f((getSceneDist((p + vec3f(e, 0f, 0f))).dist - dist), (getSceneDist((p + vec3f(0f, e, 0f))).dist - dist), (getSceneDist((p + vec3f(0f, 0f, e))).dist - dist)); return normalize(n); } @@ -148,24 +144,28 @@ describe('ray-marching example', () => { return res; } + struct fragmentMain_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentMain(_arg_0: fragmentMain_Input) -> @location(0) vec4f { var uv = ((_arg_0.uv * 2f) - 1f); uv.x *= (resolution.x / resolution.y); - var ro = vec3f(0, 2, 3); - var rd = normalize(vec3f(uv.x, uv.y, 1f)); - var march = rayMarch(ro, rd); + let ro = vec3f(0, 2, 3); + let rd = normalize(vec3f(uv.x, uv.y, 1f)); + let march = rayMarch(ro, rd); let fog = pow(min((march.dist / 30f), 1f), 0.7f); var p = (ro + (rd * march.dist)); - var n = getNormal(p); - var lightPos = getOrbitingLightPos(time); + let n = getNormal(p); + let lightPos = getOrbitingLightPos(time); var l = normalize((lightPos - p)); let diff = max(dot(n, l), 0f); let shadowRo = (&p); let shadowRd = (&l); let shadowDist = length((lightPos - p)); let shadow = softShadow((*shadowRo), (*shadowRd), 0.1f, shadowDist, 16f); - var litColor = (march.color * diff); - var finalColor = mix((litColor * 0.5f), litColor, shadow); + let litColor = (march.color * diff); + let finalColor = mix((litColor * 0.5f), litColor, shadow); return mix(vec4f(finalColor, 1f), vec4f(0.699999988079071, 0.800000011920929, 0.8999999761581421, 1), fog); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/ripple-cube.test.ts b/apps/typegpu-docs/tests/individual-example-tests/ripple-cube.test.ts index e73568d898..f49bb897bf 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/ripple-cube.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/ripple-cube.test.ts @@ -131,7 +131,7 @@ describe('ripple-cube example', () => { @group(0) @binding(2) var memoryBuffer: array; fn getJunctionGradient(pos: vec3i) -> vec3f { - var size_i = vec3i(128); + let size_i = vec3i(128); let x = (((pos.x % size_i.x) + size_i.x) % size_i.x); let y = (((pos.y % size_i.y) + size_i.y) % size_i.y); let z = (((pos.z % size_i.z) + size_i.z) % size_i.z); @@ -139,8 +139,8 @@ describe('ripple-cube example', () => { } fn dotProdGrid(pos: vec3f, junction: vec3f) -> f32 { - var relative = (pos - junction); - var gridVector = getJunctionGradient(vec3i(junction)); + let relative = (pos - junction); + let gridVector = getJunctionGradient(vec3i(junction)); return dot(relative, gridVector); } @@ -149,7 +149,7 @@ describe('ripple-cube example', () => { } fn sample(pos: vec3f) -> f32 { - var minJunction = floor(pos); + let minJunction = floor(pos); let xyz = dotProdGrid(pos, minJunction); let xyZ = dotProdGrid(pos, (minJunction + vec3f(0, 0, 1))); let xYz = dotProdGrid(pos, (minJunction + vec3f(0, 1, 0))); @@ -158,8 +158,8 @@ describe('ripple-cube example', () => { let XyZ = dotProdGrid(pos, (minJunction + vec3f(1, 0, 1))); let XYz = dotProdGrid(pos, (minJunction + vec3f(1, 1, 0))); let XYZ = dotProdGrid(pos, (minJunction + vec3f(1))); - var partial = (pos - minJunction); - var smoothPartial = quinticInterpolation(partial); + let partial = (pos - minJunction); + let smoothPartial = quinticInterpolation(partial); let xy = mix(xyz, xyZ, smoothPartial.z); let xY = mix(xYz, xYZ, smoothPartial.z); let Xy = mix(Xyz, XyZ, smoothPartial.z); @@ -175,11 +175,11 @@ describe('ripple-cube example', () => { let n3 = ((sample(((rd * 5f) + 150f)) * 0.5f) + 0.5f); let n4 = ((sample(((rd * 0.8f) + 300f)) * 0.5f) + 0.5f); let colorShift = ((sample(((rd * 0.5f) + 500f)) * 0.5f) + 0.5f); - var purple = (vec3f(0.6000000238418579, 0.10000000149011612, 0.800000011920929) * (pow(n1, 1.8f) * 0.5f)); - var blue = (vec3f(0.10000000149011612, 0.30000001192092896, 0.699999988079071) * (pow(n2, 2f) * 0.4f)); - var cyan = (vec3f(0.10000000149011612, 0.6000000238418579, 0.6000000238418579) * (pow((n3 * n4), 1.5f) * 0.3f)); - var pink = (vec3f(0.699999988079071, 0.20000000298023224, 0.4000000059604645) * ((pow((1f - n1), 3f) * n2) * 0.4f)); - var gold = (vec3f(0.800000011920929, 0.5, 0.10000000149011612) * (pow((n2 * n3), 3f) * 0.6f)); + let purple = (vec3f(0.6000000238418579, 0.10000000149011612, 0.800000011920929) * (pow(n1, 1.8f) * 0.5f)); + let blue = (vec3f(0.10000000149011612, 0.30000001192092896, 0.699999988079071) * (pow(n2, 2f) * 0.4f)); + let cyan = (vec3f(0.10000000149011612, 0.6000000238418579, 0.6000000238418579) * (pow((n3 * n4), 1.5f) * 0.3f)); + let pink = (vec3f(0.699999988079071, 0.20000000298023224, 0.4000000059604645) * ((pow((1f - n1), 3f) * n2) * 0.4f)); + let gold = (vec3f(0.800000011920929, 0.5, 0.10000000149011612) * (pow((n2 * n3), 3f) * 0.6f)); var color = (((vec3f(0.009999999776482582, 0.009999999776482582, 0.029999999329447746) + mix(purple, blue, colorShift)) + mix(pink, cyan, n4)) + gold); color = (color + (mix(vec3f(0.800000011920929, 0.4000000059604645, 1), vec3f(0.4000000059604645, 0.800000011920929, 1), colorShift) * (pow(((n1 * n2) * n3), 4f) * 2f))); return color; @@ -209,15 +209,15 @@ describe('ripple-cube example', () => { fn spaceBackground(rd: vec3f) -> vec3f { var color = spaceNebula(rd); - var starPos = (rd * 50f); + let starPos = (rd * 50f); randSeed3(floor(starPos)); - var starCenter = ((vec3f(randFloat01(), randFloat01(), randFloat01()) * 0.6f) + 0.2f); + let starCenter = ((vec3f(randFloat01(), randFloat01(), randFloat01()) * 0.6f) + 0.2f); let starDist = length((fract(starPos) - starCenter)); let starHash = randFloat01(); color = (color + (mix(vec3f(1, 0.8999999761581421, 0.800000011920929), vec3f(0.800000011920929, 0.8999999761581421, 1), starHash) * ((pow(max((1f - (starDist * 4f)), 0f), 4f) * step(0.85f, starHash)) * 3f))); - var bigStarPos = (rd * 20f); + let bigStarPos = (rd * 20f); randSeed3(floor(bigStarPos)); - var bigStarCenter = ((vec3f(randFloat01(), randFloat01(), randFloat01()) * 0.5f) + 0.25f); + let bigStarCenter = ((vec3f(randFloat01(), randFloat01(), randFloat01()) * 0.5f) + 0.25f); let bigStarDist = length((fract(bigStarPos) - bigStarCenter)); color = (color + (vec3f(1, 0.949999988079071, 0.8999999761581421) * ((pow(max((1f - (bigStarDist * 3f)), 0f), 3f) * step(0.95f, randFloat01())) * 8f))); return color; @@ -229,8 +229,8 @@ describe('ripple-cube example', () => { let u = ((((f32(x) + 0.5f) / 1024f) * 2f) - 1f); let v = ((((f32(y) + 0.5f) / 1024f) * 2f) - 1f); let basis = (&faceBasisUniform); - var direction = normalize((((*basis).forward + ((*basis).right * u)) + ((*basis).up * v))); - var color = spaceBackground(direction); + let direction = normalize((((*basis).forward + ((*basis).right * u)) + ((*basis).up * v))); + let color = spaceBackground(direction); textureStore(outputTexture, vec2u(x, y), vec4f(color, 1f)); } @@ -260,7 +260,7 @@ describe('ripple-cube example', () => { fn wrappedCallback(x: u32, y: u32, z: u32) { const cellSize = 0.0047169811320754715; - var p = ((vec3f(f32(x), f32(y), f32(z)) + 0.5f) * cellSize); + let p = ((vec3f(f32(x), f32(y), f32(z)) + 0.5f) * cellSize); let r = (timeUniform * 0.15f); let iterCount = select(5, 11, (extendedRippleUniform == 1u)); var shellD = 1e+10f; @@ -273,7 +273,7 @@ describe('ripple-cube example', () => { let qx = select((ox + p.x), (ox - p.x), ((ix % 2i) == 0i)); let qy = select((oy + p.y), (oy - p.y), ((iy % 2i) == 0i)); let qz = select((oz + p.z), (oz - p.z), ((iz % 2i) == 0i)); - var q = vec3f(qx, qy, qz); + let q = vec3f(qx, qy, qz); shellD = opSmoothUnion(shellD, (abs((length(q) - r)) - 5e-3f), blendFactorUniform); } } @@ -324,11 +324,11 @@ describe('ripple-cube example', () => { fn getRayForUV(uv: vec2f) -> Ray { let camera = (&cameraUniform); - var jitteredUV = (uv + jitterUniform); - var ndc = (((jitteredUV * 2f) - 1f) * vec2f(1, -1)); - var farView = ((*camera).projectionInverse * vec4f(ndc.xy, 1f, 1f)); - var farWorld = ((*camera).viewInverse * vec4f((farView.xyz / farView.w), 1f)); - var direction = normalize((farWorld.xyz - (*camera).position.xyz)); + let jitteredUV = (uv + jitterUniform); + let ndc = (((jitteredUV * 2f) - 1f) * vec2f(1, -1)); + let farView = ((*camera).projectionInverse * vec4f(ndc.xy, 1f, 1f)); + let farWorld = ((*camera).viewInverse * vec4f((farView.xyz / farView.w), 1f)); + let direction = normalize((farWorld.xyz - (*camera).position.xyz)); return Ray((*camera).position, vec4f(direction, 0f)); } @@ -337,13 +337,13 @@ describe('ripple-cube example', () => { @group(1) @binding(1) var sdfSampler: sampler; fn sdBox3d(point: vec3f, size: vec3f) -> f32 { - var d = (abs(point) - size); + let d = (abs(point) - size); return (length(max(d, vec3f())) + min(max(max(d.x, d.y), d.z), 0f)); } fn sdBoxFrame3d(point: vec3f, size: vec3f, thickness: f32) -> f32 { - var p1 = (abs(point) - size); - var q = (abs((p1 + thickness)) - vec3f(thickness)); + let p1 = (abs(point) - size); + let q = (abs((p1 + thickness)) - vec3f(thickness)); let d1 = (length(max(vec3f(p1.x, q.y, q.z), vec3f())) + min(max(p1.x, max(q.y, q.z)), 0f)); let d2 = (length(max(vec3f(q.x, p1.y, q.z), vec3f())) + min(max(q.x, max(p1.y, q.z)), 0f)); let d3 = (length(max(vec3f(q.x, q.y, p1.z), vec3f())) + min(max(q.x, max(q.y, p1.z)), 0f)); @@ -351,7 +351,7 @@ describe('ripple-cube example', () => { } fn sceneSDF(p: vec3f) -> f32 { - var uv = (abs(p) * 2f); + let uv = (abs(p) * 2f); let sdfValue = textureSampleLevel(sdfTexture, sdfSampler, uv, 0).x; let interior = max(sdBox3d(p, vec3f(0.5)), sdfValue); return min(sdBoxFrame3d(p, vec3f(0.5), 5e-3f), interior); @@ -404,26 +404,26 @@ describe('ripple-cube example', () => { } fn evaluateLight(p: vec3f, n: vec3f, v: vec3f, light: Light, material: Material, f0: vec3f) -> vec3f { - var toLight = (light.position - p); + let toLight = (light.position - p); let dist = length(toLight); - var l = normalize(toLight); - var h = normalize((v + l)); - var radiance = (light.color / pow(dist, 2f)); + let l = normalize(toLight); + let h = normalize((v + l)); + let radiance = (light.color / pow(dist, 2f)); let ndotl = max(dot(n, l), 0f); let ndoth = max(dot(n, h), 0f); let ndotv = max(dot(n, v), 1e-3f); let ndf = distributionGGX(ndoth, material.roughness); let g = geometrySmith(ndotv, ndotl, material.roughness); - var fresnel = fresnelSchlick(ndoth, f0); - var specular = ((fresnel * (ndf * g)) / (((4f * ndotv) * ndotl) + 1e-3f)); - var kd = ((1f - fresnel) * (1f - material.metallic)); + let fresnel = fresnelSchlick(ndoth, f0); + let specular = ((fresnel * (ndf * g)) / (((4f * ndotv) * ndotl) + 1e-3f)); + let kd = ((1f - fresnel) * (1f - material.metallic)); return (((((kd * material.albedo) / 3.141592653589793f) + specular) * radiance) * ndotl); } @group(0) @binding(7) var memoryBuffer: array; fn getJunctionGradient(pos: vec3i) -> vec3f { - var size_i = vec3i(32); + let size_i = vec3i(32); let x = (((pos.x % size_i.x) + size_i.x) % size_i.x); let y = (((pos.y % size_i.y) + size_i.y) % size_i.y); let z = (((pos.z % size_i.z) + size_i.z) % size_i.z); @@ -431,8 +431,8 @@ describe('ripple-cube example', () => { } fn dotProdGrid(pos: vec3f, junction: vec3f) -> f32 { - var relative = (pos - junction); - var gridVector = getJunctionGradient(vec3i(junction)); + let relative = (pos - junction); + let gridVector = getJunctionGradient(vec3i(junction)); return dot(relative, gridVector); } @@ -441,7 +441,7 @@ describe('ripple-cube example', () => { } fn sample(pos: vec3f) -> f32 { - var minJunction = floor(pos); + let minJunction = floor(pos); let xyz = dotProdGrid(pos, minJunction); let xyZ = dotProdGrid(pos, (minJunction + vec3f(0, 0, 1))); let xYz = dotProdGrid(pos, (minJunction + vec3f(0, 1, 0))); @@ -450,8 +450,8 @@ describe('ripple-cube example', () => { let XyZ = dotProdGrid(pos, (minJunction + vec3f(1, 0, 1))); let XYz = dotProdGrid(pos, (minJunction + vec3f(1, 1, 0))); let XYZ = dotProdGrid(pos, (minJunction + vec3f(1))); - var partial = (pos - minJunction); - var smoothPartial = quinticInterpolation(partial); + let partial = (pos - minJunction); + let smoothPartial = quinticInterpolation(partial); let xy = mix(xyz, xyZ, smoothPartial.z); let xY = mix(xYz, xYZ, smoothPartial.z); let Xy = mix(Xyz, XyZ, smoothPartial.z); @@ -463,7 +463,7 @@ describe('ripple-cube example', () => { fn shade(p: vec3f, n: vec3f, v: vec3f) -> vec3f { let material = (&materialUniform); - var f0 = mix(vec3f(0.03999999910593033), (*material).albedo, (*material).metallic); + let f0 = mix(vec3f(0.03999999910593033), (*material).albedo, (*material).metallic); var lo = vec3f(); // unrolled iteration #0 { @@ -473,33 +473,33 @@ describe('ripple-cube example', () => { { lo += evaluateLight(p, n, v, lightsUniform[1i], (*material), f0); } - var reflectDir = reflect(v, n); - var pScaled = (p * 50f); - var roughOffset = ((vec3f(sample(pScaled), sample((pScaled + 100f)), sample((pScaled + 200f))) * (*material).roughness) * 0.3f); - var blurredReflectDir = normalize((reflectDir + roughOffset)); - var envColor = textureSampleLevel(envMap, envSampler, blurredReflectDir, ((*material).roughness * 4f)); + let reflectDir = reflect(v, n); + let pScaled = (p * 50f); + let roughOffset = ((vec3f(sample(pScaled), sample((pScaled + 100f)), sample((pScaled + 200f))) * (*material).roughness) * 0.3f); + let blurredReflectDir = normalize((reflectDir + roughOffset)); + let envColor = textureSampleLevel(envMap, envSampler, blurredReflectDir, ((*material).roughness * 4f)); let ndotv = max(dot(n, v), 0f); - var fresnel = fresnelSchlick(ndotv, f0); - var reflectionTint = mix(vec3f(1), (*material).albedo, (*material).metallic); + let fresnel = fresnelSchlick(ndotv, f0); + let reflectionTint = mix(vec3f(1), (*material).albedo, (*material).metallic); let reflectionStrength = (1f - ((*material).roughness * 0.85f)); - var envContribution = (((envColor.rgb * fresnel) * reflectionTint) * reflectionStrength); - var ambient = ((*material).albedo * ((*material).ao * 0.05f)); - var color = ((ambient + lo) + envContribution); + let envContribution = (((envColor.rgb * fresnel) * reflectionTint) * reflectionStrength); + let ambient = ((*material).albedo * ((*material).ao * 0.05f)); + let color = ((ambient + lo) + envContribution); return pow((color / (color + 1f)), vec3f(0.4545454680919647)); } fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { randSeed2((vec2f(f32(x), f32(y)) + timeUniform)); - var textureSize = textureDimensions(writeView); - var uv = ((vec2f(f32(x), f32(y)) + 0.5f) / vec2f(textureSize)); - var ray = getRayForUV(uv); - var ro = ray.origin.xyz; - var rd = ray.direction.xyz; + let textureSize = textureDimensions(writeView); + let uv = ((vec2f(f32(x), f32(y)) + 0.5f) / vec2f(textureSize)); + let ray = getRayForUV(uv); + let ro = ray.origin.xyz; + let rd = ray.direction.xyz; var totalDist = 0f; var lastDist = 5f; var hit = false; for (var i = 0; (i < 48i); i++) { - var p = (ro + (rd * totalDist)); + let p = (ro + (rd * totalDist)); lastDist = sceneSDF(p); if ((lastDist < 1e-3f)) { hit = true; @@ -515,12 +515,12 @@ describe('ripple-cube example', () => { } var finalColor = textureSampleLevel(envMap, envSampler, rd, 0).rgb; if (hit) { - var p = (ro + (rd * totalDist)); - var n = getNormal(p); - var v = normalize((ro - p)); - var sceneColor = shade(p, n, v); + let p = (ro + (rd * totalDist)); + let n = getNormal(p); + let v = normalize((ro - p)); + let sceneColor = shade(p, n, v); let fog = exp((-(totalDist) * 0.05f)); - var fogColor = vec3f(0.019999999552965164, 0.019999999552965164, 0.03999999910593033); + let fogColor = vec3f(0.019999999552965164, 0.019999999552965164, 0.03999999910593033); finalColor = mix(fogColor, sceneColor, fog); } textureStore(writeView, vec2u(x, y), vec4f(finalColor, 1f)); @@ -542,34 +542,34 @@ describe('ripple-cube example', () => { @group(1) @binding(2) var outputTexture: texture_storage_2d; fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { - var coord = vec2i(i32(x), i32(y)); - var current = textureLoad(currentTexture, coord, 0); - var historyColor = textureLoad(historyTexture, coord, 0); + let coord = vec2i(i32(x), i32(y)); + let current = textureLoad(currentTexture, coord, 0); + let historyColor = textureLoad(historyTexture, coord, 0); var minColor = vec3f(9999); var maxColor = vec3f(-9999); // unrolled iteration #0 { // unrolled iteration #0 { - var sampleCoord = (coord + vec2i(-1)); - var clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - var neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + let sampleCoord = (coord + vec2i(-1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; minColor = min(minColor, neighbor); maxColor = max(maxColor, neighbor); } // unrolled iteration #1 { - var sampleCoord = (coord + vec2i(-1, 0)); - var clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - var neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + let sampleCoord = (coord + vec2i(-1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; minColor = min(minColor, neighbor); maxColor = max(maxColor, neighbor); } // unrolled iteration #2 { - var sampleCoord = (coord + vec2i(-1, 1)); - var clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - var neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + let sampleCoord = (coord + vec2i(-1, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; minColor = min(minColor, neighbor); maxColor = max(maxColor, neighbor); } @@ -578,25 +578,25 @@ describe('ripple-cube example', () => { { // unrolled iteration #0 { - var sampleCoord = (coord + vec2i(0, -1)); - var clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - var neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + let sampleCoord = (coord + vec2i(0, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; minColor = min(minColor, neighbor); maxColor = max(maxColor, neighbor); } // unrolled iteration #1 { - var sampleCoord = (coord + vec2i()); - var clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - var neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + let sampleCoord = (coord + vec2i()); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; minColor = min(minColor, neighbor); maxColor = max(maxColor, neighbor); } // unrolled iteration #2 { - var sampleCoord = (coord + vec2i(0, 1)); - var clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - var neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + let sampleCoord = (coord + vec2i(0, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; minColor = min(minColor, neighbor); maxColor = max(maxColor, neighbor); } @@ -605,31 +605,31 @@ describe('ripple-cube example', () => { { // unrolled iteration #0 { - var sampleCoord = (coord + vec2i(1, -1)); - var clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - var neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + let sampleCoord = (coord + vec2i(1, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; minColor = min(minColor, neighbor); maxColor = max(maxColor, neighbor); } // unrolled iteration #1 { - var sampleCoord = (coord + vec2i(1, 0)); - var clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - var neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + let sampleCoord = (coord + vec2i(1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; minColor = min(minColor, neighbor); maxColor = max(maxColor, neighbor); } // unrolled iteration #2 { - var sampleCoord = (coord + vec2i(1)); - var clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - var neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + let sampleCoord = (coord + vec2i(1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; minColor = min(minColor, neighbor); maxColor = max(maxColor, neighbor); } } - var clampedHistory = clamp(historyColor.rgb, minColor, maxColor); - var blended = mix(current.rgb, clampedHistory, 0.85f); + let clampedHistory = clamp(historyColor.rgb, minColor, maxColor); + let blended = mix(current.rgb, clampedHistory, 0.85f); textureStore(outputTexture, vec2u(x, y), vec4f(blended, 1f)); } @@ -647,7 +647,7 @@ describe('ripple-cube example', () => { @group(1) @binding(1) var outputTexture: texture_storage_2d; fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { - var color = textureLoad(inputTexture, vec2i(i32(x), i32(y)), 0); + let color = textureLoad(inputTexture, vec2i(i32(x), i32(y)), 0); textureStore(outputTexture, vec2u(x, y), color); } @@ -674,13 +674,13 @@ describe('ripple-cube example', () => { @group(0) @binding(1) var bloomUniform: BloomParams; fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { - var dimensions = textureDimensions(outputTexture); - var uv = ((vec2f(f32(x), f32(y)) + 0.5f) / vec2f(dimensions)); - var color = textureSampleLevel(inputTexture, sampler_1, uv, 0); + let dimensions = textureDimensions(outputTexture); + let uv = ((vec2f(f32(x), f32(y)) + 0.5f) / vec2f(dimensions)); + let color = textureSampleLevel(inputTexture, sampler_1, uv, 0); let brightness = dot(color.rgb, vec3f(0.2125999927520752, 0.7152000069618225, 0.0722000002861023)); let threshold = bloomUniform.threshold; let bright = (max((brightness - threshold), 0f) / max(brightness, 1e-4f)); - var bloomColor = (color.rgb * bright); + let bloomColor = (color.rgb * bright); textureStore(outputTexture, vec2u(x, y), vec4f(bloomColor, 1f)); } @@ -700,14 +700,14 @@ describe('ripple-cube example', () => { @group(1) @binding(1) var outputTexture: texture_storage_2d; fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { - var dimensions = textureDimensions(inputTexture); - var texelSize = (1f / vec2f(dimensions)); - var uv = ((vec2f(f32(x), f32(y)) + 0.5f) / vec2f(dimensions)); - var offsetDir = vec2f(1, 0); + let dimensions = textureDimensions(inputTexture); + let texelSize = (1f / vec2f(dimensions)); + let uv = ((vec2f(f32(x), f32(y)) + 0.5f) / vec2f(dimensions)); + let offsetDir = vec2f(1, 0); var result = vec3f(); var totalWeight = 0f; for (var i = -8; (i <= 8i); i++) { - var offset = ((offsetDir * f32(i)) * texelSize); + let offset = ((offsetDir * f32(i)) * texelSize); let weight = exp((-(f32((i * i))) / 16f)); result += (textureSampleLevel(inputTexture, sampler_1, (uv + offset), 0).rgb * weight); totalWeight += weight; @@ -731,14 +731,14 @@ describe('ripple-cube example', () => { @group(1) @binding(1) var outputTexture: texture_storage_2d; fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { - var dimensions = textureDimensions(inputTexture); - var texelSize = (1f / vec2f(dimensions)); - var uv = ((vec2f(f32(x), f32(y)) + 0.5f) / vec2f(dimensions)); - var offsetDir = vec2f(0, 1); + let dimensions = textureDimensions(inputTexture); + let texelSize = (1f / vec2f(dimensions)); + let uv = ((vec2f(f32(x), f32(y)) + 0.5f) / vec2f(dimensions)); + let offsetDir = vec2f(0, 1); var result = vec3f(); var totalWeight = 0f; for (var i = -8; (i <= 8i); i++) { - var offset = ((offsetDir * f32(i)) * texelSize); + let offset = ((offsetDir * f32(i)) * texelSize); let weight = exp((-(f32((i * i))) / 16f)); result += (textureSampleLevel(inputTexture, sampler_1, (uv + offset), 0).rgb * weight); totalWeight += weight; @@ -765,10 +765,6 @@ describe('ripple-cube example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct fragmentMain_Input { - @location(0) uv: vec2f, - } - @group(1) @binding(0) var colorTexture: texture_2d; @group(1) @binding(2) var sampler_1: sampler; @@ -782,11 +778,15 @@ describe('ripple-cube example', () => { @group(0) @binding(0) var bloomUniform: BloomParams; + struct fragmentMain_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentMain(_arg_0: fragmentMain_Input) -> @location(0) vec4f { - var color = textureSample(colorTexture, sampler_1, _arg_0.uv); - var bloomColor = textureSample(bloomTexture, sampler_1, _arg_0.uv); + let color = textureSample(colorTexture, sampler_1, _arg_0.uv); + let bloomColor = textureSample(bloomTexture, sampler_1, _arg_0.uv); var final_1 = (color.rgb + (bloomColor.rgb * bloomUniform.intensity)); - var centeredUV = ((_arg_0.uv - 0.5f) * 2f); + let centeredUV = ((_arg_0.uv - 0.5f) * 2f); let vignette = (1f - (dot(centeredUV, centeredUV) * 0.15f)); final_1 *= vignette; return vec4f(final_1, 1f); diff --git a/apps/typegpu-docs/tests/individual-example-tests/simple-shadow.test.ts b/apps/typegpu-docs/tests/individual-example-tests/simple-shadow.test.ts index f1f6775cc0..0eb1086769 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/simple-shadow.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/simple-shadow.test.ts @@ -47,8 +47,8 @@ describe('simple shadow example', () => { } @vertex fn shadowVert(@location(0) position: vec4f) -> shadowVert_Output { - var world = (instanceInfo.modelMatrix * position); - var clip = (lightSpaceUniform.viewProj * world); + let world = (instanceInfo.modelMatrix * position); + let clip = (lightSpaceUniform.viewProj * world); return shadowVert_Output(clip); } @@ -82,18 +82,13 @@ describe('simple shadow example', () => { @vertex fn mainVert(@location(0) position: vec4f, @location(1) normal: vec4f) -> mainVert_Output { let modelMatrixUniform = (&instanceInfo.modelMatrix); - var worldPos = ((*modelMatrixUniform) * position); - var viewPos = (cameraUniform.view * worldPos); - var clipPos = (cameraUniform.projection * viewPos); - var transformedNormal = ((*modelMatrixUniform) * normal); + let worldPos = ((*modelMatrixUniform) * position); + let viewPos = (cameraUniform.view * worldPos); + let clipPos = (cameraUniform.projection * viewPos); + let transformedNormal = ((*modelMatrixUniform) * normal); return mainVert_Output(clipPos, transformedNormal, worldPos.xyz); } - struct mainFrag_Input { - @location(0) normal: vec4f, - @location(1) worldPos: vec3f, - } - struct DirectionalLight { direction: vec3f, color: vec3f, @@ -118,14 +113,19 @@ describe('simple shadow example', () => { @group(0) @binding(3) var paramsUniform: VisParams; + struct mainFrag_Input { + @location(0) normal: vec4f, + @location(1) worldPos: vec3f, + } + @fragment fn mainFrag(_arg_0: mainFrag_Input) -> @location(0) vec4f { let instanceInfo_1 = (&instanceInfo); - var N = normalize(_arg_0.normal.xyz); - var L = normalize(-(light.direction)); - var V = normalize((cameraUniform.position - _arg_0.worldPos)); - var R = reflect(-(L), N); - var lp4 = (lightSpaceUniform.viewProj * vec4f(_arg_0.worldPos, 1f)); - var ndc = (lp4.xyz / lp4.w); + let N = normalize(_arg_0.normal.xyz); + let L = normalize(-(light.direction)); + let V = normalize((cameraUniform.position - _arg_0.worldPos)); + let R = reflect(-(L), N); + let lp4 = (lightSpaceUniform.viewProj * vec4f(_arg_0.worldPos, 1f)); + let ndc = (lp4.xyz / lp4.w); var uv = ((ndc.xy * 0.5f) + 0.5f); uv = vec2f(uv.x, (1f - uv.y)); let currentDepth = ndc.z; @@ -134,13 +134,13 @@ describe('simple shadow example', () => { if (!inBounds) { shadowFactor = 1f; } - var ambient = ((*instanceInfo_1).material.ambient * light.color); + let ambient = ((*instanceInfo_1).material.ambient * light.color); let diff = max(0f, dot(N, L)); - var diffuse = (((*instanceInfo_1).material.diffuse * light.color) * diff); + let diffuse = (((*instanceInfo_1).material.diffuse * light.color) * diff); let spec = pow(max(0f, dot(V, R)), (*instanceInfo_1).material.shininess); - var specular = (((*instanceInfo_1).material.specular * light.color) * spec); - var lit = ((diffuse + specular) * shadowFactor); - var finalColor = (ambient + lit); + let specular = (((*instanceInfo_1).material.specular * light.color) * spec); + let lit = ((diffuse + specular) * shadowFactor); + let finalColor = (ambient + lit); if ((paramsUniform.shadowOnly == 1f)) { return vec4f(vec3f(shadowFactor), 1f); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/slime-mold-3d.test.ts b/apps/typegpu-docs/tests/individual-example-tests/slime-mold-3d.test.ts index 16ec9b7e12..0acb522042 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/slime-mold-3d.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/slime-mold-3d.test.ts @@ -52,8 +52,8 @@ describe('slime mold 3d example', () => { fn randInUnitSphere() -> vec3f { let u = sample(); - var v = vec3f(randNormal(0f, 1f), randNormal(0f, 1f), randNormal(0f, 1f)); - var vNorm = normalize(v); + let v = vec3f(randNormal(0f, 1f), randNormal(0f, 1f), randNormal(0f, 1f)); + let vNorm = normalize(v); return (vNorm * pow(u, 0.33f)); } @@ -68,9 +68,9 @@ describe('slime mold 3d example', () => { fn wrappedCallback(x: u32, _arg_1: u32, _arg_2: u32) { randSeed((f32(x) / 8e+5f)); - var pos = ((randInUnitSphere() * 64f) + vec3f(128)); - var center = vec3f(128); - var dir = normalize((center - pos)); + let pos = ((randInUnitSphere() * 64f) + vec3f(128)); + let center = vec3f(128); + let dir = normalize((center - pos)); item[x] = Agent(pos, dir); item_1[x] = Agent(pos, dir); } @@ -104,11 +104,11 @@ describe('slime mold 3d example', () => { @group(1) @binding(1) var newState: texture_storage_3d; @compute @workgroup_size(4, 4, 4) fn blur(@builtin(global_invocation_id) gid: vec3u) { - var dims = textureDimensions(oldState); + let dims = textureDimensions(oldState); if ((((gid.x >= dims.x) || (gid.y >= dims.y)) || (gid.z >= dims.z))) { return; } - var uv = ((vec3f(gid) + 0.5f) / vec3f(dims)); + let uv = ((vec3f(gid) + 0.5f) / vec3f(dims)); var sum = 0f; sum += getSummand(uv, (vec3f(-1, 0, 0) / vec3f(dims))); sum += getSummand(uv, (vec3f(1, 0, 0) / vec3f(dims))); @@ -173,19 +173,19 @@ describe('slime mold 3d example', () => { } fn sense3D(pos: vec3f, direction: vec3f) -> SenseResult { - var dims = textureDimensions(oldState); - var dimsf = vec3f(dims); + let dims = textureDimensions(oldState); + let dimsf = vec3f(dims); var weightedDir = vec3f(); var totalWeight = 0f; - var perp1 = getPerpendicular(direction); - var perp2 = cross(direction, perp1); + let perp1 = getPerpendicular(direction); + let perp2 = cross(direction, perp1); // unrolled iteration #0 { const theta = 0.; - var coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); - var sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); - var sensorPos = (pos + (sensorDir * params.sensorDistance)); - var sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); + let coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); + let sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); + let sensorPos = (pos + (sensorDir * params.sensorDistance)); + let sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); let weight = textureLoad(oldState, sensorPosInt).x; weightedDir = (weightedDir + (sensorDir * weight)); totalWeight = (totalWeight + weight); @@ -193,10 +193,10 @@ describe('slime mold 3d example', () => { // unrolled iteration #1 { const theta = 0.7853981633974483; - var coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); - var sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); - var sensorPos = (pos + (sensorDir * params.sensorDistance)); - var sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); + let coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); + let sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); + let sensorPos = (pos + (sensorDir * params.sensorDistance)); + let sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); let weight = textureLoad(oldState, sensorPosInt).x; weightedDir = (weightedDir + (sensorDir * weight)); totalWeight = (totalWeight + weight); @@ -204,10 +204,10 @@ describe('slime mold 3d example', () => { // unrolled iteration #2 { const theta = 1.5707963267948966; - var coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); - var sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); - var sensorPos = (pos + (sensorDir * params.sensorDistance)); - var sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); + let coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); + let sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); + let sensorPos = (pos + (sensorDir * params.sensorDistance)); + let sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); let weight = textureLoad(oldState, sensorPosInt).x; weightedDir = (weightedDir + (sensorDir * weight)); totalWeight = (totalWeight + weight); @@ -215,10 +215,10 @@ describe('slime mold 3d example', () => { // unrolled iteration #3 { const theta = 2.356194490192345; - var coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); - var sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); - var sensorPos = (pos + (sensorDir * params.sensorDistance)); - var sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); + let coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); + let sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); + let sensorPos = (pos + (sensorDir * params.sensorDistance)); + let sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); let weight = textureLoad(oldState, sensorPosInt).x; weightedDir = (weightedDir + (sensorDir * weight)); totalWeight = (totalWeight + weight); @@ -226,10 +226,10 @@ describe('slime mold 3d example', () => { // unrolled iteration #4 { const theta = 3.141592653589793; - var coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); - var sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); - var sensorPos = (pos + (sensorDir * params.sensorDistance)); - var sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); + let coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); + let sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); + let sensorPos = (pos + (sensorDir * params.sensorDistance)); + let sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); let weight = textureLoad(oldState, sensorPosInt).x; weightedDir = (weightedDir + (sensorDir * weight)); totalWeight = (totalWeight + weight); @@ -237,10 +237,10 @@ describe('slime mold 3d example', () => { // unrolled iteration #5 { const theta = 3.9269908169872414; - var coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); - var sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); - var sensorPos = (pos + (sensorDir * params.sensorDistance)); - var sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); + let coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); + let sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); + let sensorPos = (pos + (sensorDir * params.sensorDistance)); + let sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); let weight = textureLoad(oldState, sensorPosInt).x; weightedDir = (weightedDir + (sensorDir * weight)); totalWeight = (totalWeight + weight); @@ -248,10 +248,10 @@ describe('slime mold 3d example', () => { // unrolled iteration #6 { const theta = 4.71238898038469; - var coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); - var sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); - var sensorPos = (pos + (sensorDir * params.sensorDistance)); - var sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); + let coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); + let sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); + let sensorPos = (pos + (sensorDir * params.sensorDistance)); + let sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); let weight = textureLoad(oldState, sensorPosInt).x; weightedDir = (weightedDir + (sensorDir * weight)); totalWeight = (totalWeight + weight); @@ -259,10 +259,10 @@ describe('slime mold 3d example', () => { // unrolled iteration #7 { const theta = 5.497787143782138; - var coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); - var sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); - var sensorPos = (pos + (sensorDir * params.sensorDistance)); - var sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); + let coneOffset = ((perp1 * cos(theta)) + (perp2 * sin(theta))); + let sensorDir = normalize((direction + (coneOffset * sin(params.sensorAngle)))); + let sensorPos = (pos + (sensorDir * params.sensorDistance)); + let sensorPosInt = vec3u(clamp(sensorPos, vec3f(), (dimsf - 1f))); let weight = textureLoad(oldState, sensorPosInt).x; weightedDir = (weightedDir + (sensorDir * weight)); totalWeight = (totalWeight + weight); @@ -288,7 +288,7 @@ describe('slime mold 3d example', () => { } fn randOnUnitHemisphere(normal: vec3f) -> vec3f { - var value = randOnUnitSphere(); + let value = randOnUnitSphere(); let alignment = dot(normal, value); return (sign(alignment) * value); } @@ -305,13 +305,13 @@ describe('slime mold 3d example', () => { fn randInUnitSphere() -> vec3f { let u = sample(); - var v = vec3f(randNormal(0f, 1f), randNormal(0f, 1f), randNormal(0f, 1f)); - var vNorm = normalize(v); + let v = vec3f(randNormal(0f, 1f), randNormal(0f, 1f), randNormal(0f, 1f)); + let vNorm = normalize(v); return (vNorm * pow(u, 0.33f)); } fn randInUnitHemisphere(normal: vec3f) -> vec3f { - var value = randInUnitSphere(); + let value = randInUnitSphere(); let alignment = dot(normal, value); return (sign(alignment) * value); } @@ -325,23 +325,23 @@ describe('slime mold 3d example', () => { return; } randSeed(((f32(gid.x) / 8e+5f) + 0.1f)); - var dims = textureDimensions(oldState); - var dimsf = vec3f(dims); + let dims = textureDimensions(oldState); + let dimsf = vec3f(dims); let agent = (&oldAgents[gid.x]); var direction = normalize((*agent).direction); - var senseResult = sense3D((*agent).position, direction); - var targetDirection = select(randOnUnitHemisphere(direction), normalize(senseResult.weightedDir), (senseResult.totalWeight > 0.01f)); + let senseResult = sense3D((*agent).position, direction); + let targetDirection = select(randOnUnitHemisphere(direction), normalize(senseResult.weightedDir), (senseResult.totalWeight > 0.01f)); direction = normalize((direction + ((targetDirection * params.turnSpeed) * params.deltaTime))); var newPos = ((*agent).position + ((direction * params.moveSpeed) * params.deltaTime)); - var center = (dimsf / 2f); + let center = (dimsf / 2f); if (((newPos.x < 0f) || (newPos.x >= dimsf.x))) { newPos.x = clamp(newPos.x, 0f, (dimsf.x - 1f)); var normal = vec3f(1, 0, 0); if ((newPos.x > 1f)) { normal = vec3f(-1, 0, 0); } - var randomDir = randInUnitHemisphere(normal); - var toCenter = normalize((center - newPos)); + let randomDir = randInUnitHemisphere(normal); + let toCenter = normalize((center - newPos)); direction = normalize(((randomDir * 0.3f) + (toCenter * 0.7f))); } if (((newPos.y < 0f) || (newPos.y >= dimsf.y))) { @@ -350,8 +350,8 @@ describe('slime mold 3d example', () => { if ((newPos.y > 1f)) { normal = vec3f(0, -1, 0); } - var randomDir = randInUnitHemisphere(normal); - var toCenter = normalize((center - newPos)); + let randomDir = randInUnitHemisphere(normal); + let toCenter = normalize((center - newPos)); direction = normalize(((randomDir * 0.3f) + (toCenter * 0.7f))); } if (((newPos.z < 0f) || (newPos.z >= dimsf.z))) { @@ -360,8 +360,8 @@ describe('slime mold 3d example', () => { if ((newPos.z > 1f)) { normal = vec3f(0, 0, -1); } - var randomDir = randInUnitHemisphere(normal); - var toCenter = normalize((center - newPos)); + let randomDir = randInUnitHemisphere(normal); + let toCenter = normalize((center - newPos)); direction = normalize(((randomDir * 0.3f) + (toCenter * 0.7f))); } newAgents[gid.x] = Agent(newPos, direction); @@ -382,10 +382,6 @@ describe('slime mold 3d example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct fragmentShader_Input { - @location(0) uv: vec2f, - } - var seed: vec2f; fn seed2(value: vec2f) { @@ -411,11 +407,11 @@ describe('slime mold 3d example', () => { } fn rayBoxIntersection(rayOrigin: vec3f, rayDir: vec3f, boxMin: vec3f, boxMax: vec3f) -> RayBoxResult { - var invDir = (1f / rayDir); - var t0 = ((boxMin - rayOrigin) * invDir); - var t1 = ((boxMax - rayOrigin) * invDir); - var tmin = min(t0, t1); - var tmax = max(t0, t1); + let invDir = (1f / rayDir); + let t0 = ((boxMin - rayOrigin) * invDir); + let t1 = ((boxMax - rayOrigin) * invDir); + let tmin = min(t0, t1); + let tmax = max(t0, t1); let tNear = max(max(tmin.x, tmin.y), tmin.z); let tFar = min(min(tmax.x, tmax.y), tmax.z); let hit = ((tFar >= tNear) && (tFar >= 0f)); @@ -438,19 +434,23 @@ describe('slime mold 3d example', () => { @group(0) @binding(1) var sampler_1: sampler; + struct fragmentShader_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentShader(_arg_0: fragmentShader_Input) -> @location(0) vec4f { randSeed2(_arg_0.uv); - var ndc = vec2f(((_arg_0.uv.x * 2f) - 1f), (1f - (_arg_0.uv.y * 2f))); - var ndcNear = vec4f(ndc, -1f, 1f); - var ndcFar = vec4f(ndc, 1f, 1f); - var worldNear = (cameraData.invViewProj * ndcNear); - var worldFar = (cameraData.invViewProj * ndcFar); - var rayOrigin = (worldNear.xyz / worldNear.w); - var rayEnd = (worldFar.xyz / worldFar.w); - var rayDir = normalize((rayEnd - rayOrigin)); - var boxMin = vec3f(); - var boxMax = vec3f(256); - var isect = rayBoxIntersection(rayOrigin, rayDir, boxMin, boxMax); + let ndc = vec2f(((_arg_0.uv.x * 2f) - 1f), (1f - (_arg_0.uv.y * 2f))); + let ndcNear = vec4f(ndc, -1f, 1f); + let ndcFar = vec4f(ndc, 1f, 1f); + let worldNear = (cameraData.invViewProj * ndcNear); + let worldFar = (cameraData.invViewProj * ndcFar); + let rayOrigin = (worldNear.xyz / worldNear.w); + let rayEnd = (worldFar.xyz / worldFar.w); + let rayDir = normalize((rayEnd - rayOrigin)); + let boxMin = vec3f(); + let boxMax = vec3f(256); + let isect = rayBoxIntersection(rayOrigin, rayDir, boxMin, boxMax); if (!isect.hit) { return vec4f(); } @@ -468,20 +468,20 @@ describe('slime mold 3d example', () => { const thresholdHi = 0.25f; const gamma = 1.399999976158142f; const sigmaT = 0.10000000149011612f; - var albedo = vec3f(0.5699999928474426, 0.4399999976158142, 0.9599999785423279); + let albedo = vec3f(0.5699999928474426, 0.4399999976158142, 0.9599999785423279); var transmittance = 1f; var accum = vec3f(); const TMin = 0.0010000000474974513f; var i = 0i; while (((i < numSteps) && (transmittance > TMin))) { let t = (tStart + ((f32(i) + 0.5f) * stepSize)); - var pos = (rayOrigin + (rayDir * t)); - var texCoord = (pos / vec3f(256)); + let pos = (rayOrigin + (rayDir * t)); + let texCoord = (pos / vec3f(256)); let sampleValue = textureSampleLevel(state, sampler_1, texCoord, 0).x; let d0 = smoothstep(thresholdLo, thresholdHi, sampleValue); let density = pow(d0, gamma); let alphaSrc = (1f - exp(((-(sigmaT) * density) * stepSize))); - var contrib = (albedo * alphaSrc); + let contrib = (albedo * alphaSrc); accum += (contrib * transmittance); transmittance = (transmittance * (1f - alphaSrc)); i += 1i; diff --git a/apps/typegpu-docs/tests/individual-example-tests/slime-mold.test.ts b/apps/typegpu-docs/tests/individual-example-tests/slime-mold.test.ts index 44d050241e..bd3763d8bd 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/slime-mold.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/slime-mold.test.ts @@ -55,7 +55,7 @@ describe('slime mold example', () => { fn wrappedCallback(x: u32, _arg_1: u32, _arg_2: u32) { randSeed(((f32(x) / 2e+5f) + 0.1f)); - var pos = ((randInUnitCircle() * 118f) + vec2f(128)); + let pos = ((randInUnitCircle() * 118f) + vec2f(128)); let angle = atan2((128f - pos.y), (128f - pos.x)); agentsData[x] = Agent(pos, angle); } @@ -82,7 +82,7 @@ describe('slime mold example', () => { @group(1) @binding(1) var newState: texture_storage_2d; @compute @workgroup_size(16, 16) fn blur(@builtin(global_invocation_id) gid: vec3u) { - var dims = textureDimensions(oldState); + let dims = textureDimensions(oldState); if (((gid.x >= dims.x) || (gid.y >= dims.y))) { return; } @@ -92,30 +92,30 @@ describe('slime mold example', () => { { // unrolled iteration #0 { - var samplePos = (vec2i(gid.xy) + vec2i(-1)); - var dimsi = vec2i(dims); + let samplePos = (vec2i(gid.xy) + vec2i(-1)); + let dimsi = vec2i(dims); if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - var color = textureLoad(oldState, vec2u(samplePos)).rgb; + let color = textureLoad(oldState, vec2u(samplePos)).rgb; sum += color; count += 1f; } } // unrolled iteration #1 { - var samplePos = (vec2i(gid.xy) + vec2i(0, -1)); - var dimsi = vec2i(dims); + let samplePos = (vec2i(gid.xy) + vec2i(0, -1)); + let dimsi = vec2i(dims); if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - var color = textureLoad(oldState, vec2u(samplePos)).rgb; + let color = textureLoad(oldState, vec2u(samplePos)).rgb; sum += color; count += 1f; } } // unrolled iteration #2 { - var samplePos = (vec2i(gid.xy) + vec2i(1, -1)); - var dimsi = vec2i(dims); + let samplePos = (vec2i(gid.xy) + vec2i(1, -1)); + let dimsi = vec2i(dims); if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - var color = textureLoad(oldState, vec2u(samplePos)).rgb; + let color = textureLoad(oldState, vec2u(samplePos)).rgb; sum += color; count += 1f; } @@ -125,30 +125,30 @@ describe('slime mold example', () => { { // unrolled iteration #0 { - var samplePos = (vec2i(gid.xy) + vec2i(-1, 0)); - var dimsi = vec2i(dims); + let samplePos = (vec2i(gid.xy) + vec2i(-1, 0)); + let dimsi = vec2i(dims); if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - var color = textureLoad(oldState, vec2u(samplePos)).rgb; + let color = textureLoad(oldState, vec2u(samplePos)).rgb; sum += color; count += 1f; } } // unrolled iteration #1 { - var samplePos = (vec2i(gid.xy) + vec2i()); - var dimsi = vec2i(dims); + let samplePos = (vec2i(gid.xy) + vec2i()); + let dimsi = vec2i(dims); if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - var color = textureLoad(oldState, vec2u(samplePos)).rgb; + let color = textureLoad(oldState, vec2u(samplePos)).rgb; sum += color; count += 1f; } } // unrolled iteration #2 { - var samplePos = (vec2i(gid.xy) + vec2i(1, 0)); - var dimsi = vec2i(dims); + let samplePos = (vec2i(gid.xy) + vec2i(1, 0)); + let dimsi = vec2i(dims); if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - var color = textureLoad(oldState, vec2u(samplePos)).rgb; + let color = textureLoad(oldState, vec2u(samplePos)).rgb; sum += color; count += 1f; } @@ -158,37 +158,37 @@ describe('slime mold example', () => { { // unrolled iteration #0 { - var samplePos = (vec2i(gid.xy) + vec2i(-1, 1)); - var dimsi = vec2i(dims); + let samplePos = (vec2i(gid.xy) + vec2i(-1, 1)); + let dimsi = vec2i(dims); if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - var color = textureLoad(oldState, vec2u(samplePos)).rgb; + let color = textureLoad(oldState, vec2u(samplePos)).rgb; sum += color; count += 1f; } } // unrolled iteration #1 { - var samplePos = (vec2i(gid.xy) + vec2i(0, 1)); - var dimsi = vec2i(dims); + let samplePos = (vec2i(gid.xy) + vec2i(0, 1)); + let dimsi = vec2i(dims); if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - var color = textureLoad(oldState, vec2u(samplePos)).rgb; + let color = textureLoad(oldState, vec2u(samplePos)).rgb; sum += color; count += 1f; } } // unrolled iteration #2 { - var samplePos = (vec2i(gid.xy) + vec2i(1)); - var dimsi = vec2i(dims); + let samplePos = (vec2i(gid.xy) + vec2i(1)); + let dimsi = vec2i(dims); if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - var color = textureLoad(oldState, vec2u(samplePos)).rgb; + let color = textureLoad(oldState, vec2u(samplePos)).rgb; sum += color; count += 1f; } } } - var blurred = (sum / count); - var newColor = saturate((blurred - params.evaporationRate)); + let blurred = (sum / count); + let newColor = saturate((blurred - params.evaporationRate)); textureStore(newState, gid.xy, vec4f(newColor, 1f)); } @@ -235,12 +235,12 @@ describe('slime mold example', () => { fn sense(pos: vec2f, angle: f32, sensorAngleOffset: f32) -> f32 { let sensorAngle = (angle + sensorAngleOffset); - var sensorDir = vec2f(cos(sensorAngle), sin(sensorAngle)); - var sensorPos = (pos + (sensorDir * params.sensorDistance)); - var dims = textureDimensions(oldState); - var dimsf = vec2f(dims); - var sensorPosInt = vec2u(clamp(sensorPos, vec2f(), (dimsf - 1f))); - var color = textureLoad(oldState, sensorPosInt).rgb; + let sensorDir = vec2f(cos(sensorAngle), sin(sensorAngle)); + let sensorPos = (pos + (sensorDir * params.sensorDistance)); + let dims = textureDimensions(oldState); + let dimsf = vec2f(dims); + let sensorPosInt = vec2u(clamp(sensorPos, vec2f(), (dimsf - 1f))); + let color = textureLoad(oldState, sensorPosInt).rgb; return ((color.x + color.y) + color.z); } @@ -253,7 +253,7 @@ describe('slime mold example', () => { return; } randSeed(((f32(gid.x) / 2e+5f) + 0.1f)); - var dims = textureDimensions(oldState); + let dims = textureDimensions(oldState); let agent = (&agentsData[gid.x]); let random = randFloat01(); let weightForward = sense((*agent).position, (*agent).angle, 0f); @@ -278,9 +278,9 @@ describe('slime mold example', () => { } } } - var dir = vec2f(cos(angle), sin(angle)); + let dir = vec2f(cos(angle), sin(angle)); var newPos = ((*agent).position + ((dir * params.moveSpeed) * deltaTime)); - var dimsf = vec2f(dims); + let dimsf = vec2f(dims); if (((((newPos.x < 0f) || (newPos.x > dimsf.x)) || (newPos.y < 0f)) || (newPos.y > dimsf.y))) { newPos = clamp(newPos, vec2f(), (dimsf - 1f)); if (((newPos.x <= 0f) || (newPos.x >= (dimsf.x - 1f)))) { @@ -292,8 +292,8 @@ describe('slime mold example', () => { angle += ((random - 0.5f) * 0.1f); } agentsData[gid.x] = Agent(newPos, angle); - var oldState_1 = textureLoad(oldState, vec2u(newPos)).rgb; - var newState = (oldState_1 + 1f); + let oldState_1 = textureLoad(oldState, vec2u(newPos)).rgb; + let newState = (oldState_1 + 1f); textureStore(newState_1, vec2u(newPos), vec4f(newState, 1f)); } @@ -303,19 +303,19 @@ describe('slime mold example', () => { } @vertex fn fullScreenTriangle(@builtin(vertex_index) _arg_vertexIndex: u32) -> fullScreenTriangle_Output { - var pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); - var uv = array(vec2f(0, 1), vec2f(2, 1), vec2f(0, -1)); + let pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); + let uv = array(vec2f(0, 1), vec2f(2, 1), vec2f(0, -1)); return fullScreenTriangle_Output(vec4f(pos[_arg_vertexIndex], 0f, 1f), uv[_arg_vertexIndex]); } - struct fragmentShader_Input { - @location(0) uv: vec2f, - } - @group(1) @binding(0) var state: texture_2d; @group(0) @binding(0) var filteringSampler: sampler; + struct fragmentShader_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentShader(_arg_0: fragmentShader_Input) -> @location(0) vec4f { return textureSample(state, filteringSampler, _arg_0.uv); }" diff --git a/apps/typegpu-docs/tests/individual-example-tests/smoky-triangle.test.ts b/apps/typegpu-docs/tests/individual-example-tests/smoky-triangle.test.ts index ab5a14973c..62d467d90a 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/smoky-triangle.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/smoky-triangle.test.ts @@ -101,7 +101,7 @@ describe('smoky triangle', () => { @group(0) @binding(1) var memoryBuffer: array; fn getJunctionGradient(pos: vec3i) -> vec3f { - var size_i = vec3i(32); + let size_i = vec3i(32); let x = (((pos.x % size_i.x) + size_i.x) % size_i.x); let y = (((pos.y % size_i.y) + size_i.y) % size_i.y); let z = (((pos.z % size_i.z) + size_i.z) % size_i.z); @@ -109,8 +109,8 @@ describe('smoky triangle', () => { } fn dotProdGrid(pos: vec3f, junction: vec3f) -> f32 { - var relative = (pos - junction); - var gridVector = getJunctionGradient(vec3i(junction)); + let relative = (pos - junction); + let gridVector = getJunctionGradient(vec3i(junction)); return dot(relative, gridVector); } @@ -119,7 +119,7 @@ describe('smoky triangle', () => { } fn sample(pos: vec3f) -> f32 { - var minJunction = floor(pos); + let minJunction = floor(pos); let xyz = dotProdGrid(pos, minJunction); let xyZ = dotProdGrid(pos, (minJunction + vec3f(0, 0, 1))); let xYz = dotProdGrid(pos, (minJunction + vec3f(0, 1, 0))); @@ -128,8 +128,8 @@ describe('smoky triangle', () => { let XyZ = dotProdGrid(pos, (minJunction + vec3f(1, 0, 1))); let XYz = dotProdGrid(pos, (minJunction + vec3f(1, 1, 0))); let XYZ = dotProdGrid(pos, (minJunction + vec3f(1))); - var partial = (pos - minJunction); - var smoothPartial = quinticInterpolation(partial); + let partial = (pos - minJunction); + let smoothPartial = quinticInterpolation(partial); let xy = mix(xyz, xyZ, smoothPartial.z); let xY = mix(xYz, xYZ, smoothPartial.z); let Xy = mix(Xyz, XyZ, smoothPartial.z); @@ -164,10 +164,10 @@ describe('smoky triangle', () => { @fragment fn fragment(_arg_0: FragmentIn) -> @location(0) vec4f { let params = (¶msUniform); let t = ((*params).time * 0.1f); - var ouv = ((_arg_0.uv * 5f) + vec2f(0f, -(t))); + let ouv = ((_arg_0.uv * 5f) + vec2f(0f, -(t))); var off = (vec2f(sample(vec3f(ouv, t)), (sample(vec3f((ouv * 2f), (t + 10f))) * 0.5f)) + -0.1f); off = tanhVec((off * (*params).sharpness)); - var p = (_arg_0.uv + (off * (*params).distortion)); + let p = (_arg_0.uv + (off * (*params).distortion)); var factor = 0f; if (((*params).polarCoords == 1u)) { factor = length(((p - vec2f(0.5, 0.30000001192092896)) * 2f)); diff --git a/apps/typegpu-docs/tests/individual-example-tests/square.test.ts b/apps/typegpu-docs/tests/individual-example-tests/square.test.ts index c1e9ec6fc5..b3d2254fc3 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/square.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/square.test.ts @@ -26,7 +26,7 @@ describe('square example', () => { } @vertex fn vertex(@builtin(vertex_index) idx: u32, @location(0) color: vec4f) -> vertex_Output { - var vertices = array(vec2f(-1), vec2f(1, -1), vec2f(1), vec2f(-1, 1)); + let vertices = array(vec2f(-1), vec2f(1, -1), vec2f(1), vec2f(-1, 1)); return vertex_Output(color, vec4f(vertices[idx], 0f, 1f)); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/stable-fluid.test.ts b/apps/typegpu-docs/tests/individual-example-tests/stable-fluid.test.ts index 0e97b0d9e9..0972af3eac 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/stable-fluid.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/stable-fluid.test.ts @@ -39,18 +39,18 @@ describe('stable-fluid example', () => { @group(0) @binding(3) var linSampler: sampler; @compute @workgroup_size(16, 16) fn advectFn(@builtin(global_invocation_id) _arg_gid: vec3u) { - var texSize = textureDimensions(src); - var pixelPos = _arg_gid.xy; + let texSize = textureDimensions(src); + let pixelPos = _arg_gid.xy; if (((((pixelPos.x >= (texSize.x - 1u)) || (pixelPos.y >= (texSize.y - 1u))) || (pixelPos.x <= 0u)) || (pixelPos.y <= 0u))) { textureStore(dst, pixelPos, vec4f(0, 0, 0, 1)); return; } - var velocity = textureLoad(src, pixelPos, 0); + let velocity = textureLoad(src, pixelPos, 0); let timeStep = simParams.dt; - var prevPos = (vec2f(pixelPos) - (timeStep * velocity.xy)); - var clampedPos = clamp(prevPos, vec2f(-0.5), (vec2f(texSize.xy) - 0.5f)); - var normalizedPos = ((clampedPos + 0.5f) / vec2f(texSize.xy)); - var prevVelocity = textureSampleLevel(src, linSampler, normalizedPos, 0); + let prevPos = (vec2f(pixelPos) - (timeStep * velocity.xy)); + let clampedPos = clamp(prevPos, vec2f(-0.5), (vec2f(texSize.xy) - 0.5f)); + let normalizedPos = ((clampedPos + 0.5f) / vec2f(texSize.xy)); + let prevVelocity = textureSampleLevel(src, linSampler, normalizedPos, 0); textureStore(dst, pixelPos, prevVelocity); } @@ -87,19 +87,19 @@ describe('stable-fluid example', () => { @group(0) @binding(1) var out: texture_storage_2d; @compute @workgroup_size(16, 16) fn diffusionFn(@builtin(global_invocation_id) _arg_gid: vec3u) { - var pixelPos = vec2i(_arg_gid.xy); - var texSize = vec2i(textureDimensions(in)); - var centerVal = textureLoad(in, pixelPos, 0); - var neighbors = getNeighbors(pixelPos, texSize); - var leftVal = textureLoad(in, neighbors[0i], 0); - var upVal = textureLoad(in, neighbors[1i], 0); - var rightVal = textureLoad(in, neighbors[2i], 0); - var downVal = textureLoad(in, neighbors[3i], 0); + let pixelPos = vec2i(_arg_gid.xy); + let texSize = vec2i(textureDimensions(in)); + let centerVal = textureLoad(in, pixelPos, 0); + let neighbors = getNeighbors(pixelPos, texSize); + let leftVal = textureLoad(in, neighbors[0i], 0); + let upVal = textureLoad(in, neighbors[1i], 0); + let rightVal = textureLoad(in, neighbors[2i], 0); + let downVal = textureLoad(in, neighbors[3i], 0); let timeStep = simParams.dt; let viscosity = simParams.viscosity; let diffuseRate = (viscosity * timeStep); let blendFactor = (1f / (4f + diffuseRate)); - var diffusedVal = (vec4f(blendFactor) * ((((leftVal + rightVal) + upVal) + downVal) + (centerVal * diffuseRate))); + let diffusedVal = (vec4f(blendFactor) * ((((leftVal + rightVal) + upVal) + downVal) + (centerVal * diffuseRate))); textureStore(out, pixelPos, diffusedVal); } @@ -129,13 +129,13 @@ describe('stable-fluid example', () => { @group(0) @binding(1) var div: texture_storage_2d; @compute @workgroup_size(16, 16) fn divergenceFn(@builtin(global_invocation_id) _arg_gid: vec3u) { - var pixelPos = vec2i(_arg_gid.xy); - var texSize = vec2i(textureDimensions(vel)); - var neighbors = getNeighbors(pixelPos, texSize); - var leftVel = textureLoad(vel, neighbors[0i], 0); - var upVel = textureLoad(vel, neighbors[1i], 0); - var rightVel = textureLoad(vel, neighbors[2i], 0); - var downVel = textureLoad(vel, neighbors[3i], 0); + let pixelPos = vec2i(_arg_gid.xy); + let texSize = vec2i(textureDimensions(vel)); + let neighbors = getNeighbors(pixelPos, texSize); + let leftVel = textureLoad(vel, neighbors[0i], 0); + let upVel = textureLoad(vel, neighbors[1i], 0); + let rightVel = textureLoad(vel, neighbors[2i], 0); + let downVel = textureLoad(vel, neighbors[3i], 0); let divergence = (0.5f * ((rightVel.x - leftVel.x) + (downVel.y - upVel.y))); textureStore(div, pixelPos, vec4f(divergence, 0f, 0f, 1f)); } @@ -168,13 +168,13 @@ describe('stable-fluid example', () => { @group(0) @binding(2) var out: texture_storage_2d; @compute @workgroup_size(16, 16) fn pressureFn(@builtin(global_invocation_id) _arg_gid: vec3u) { - var pixelPos = vec2i(_arg_gid.xy); - var texSize = vec2i(textureDimensions(x)); - var neighbors = getNeighbors(pixelPos, texSize); - var leftPressure = textureLoad(x, neighbors[0i], 0); - var upPressure = textureLoad(x, neighbors[1i], 0); - var rightPressure = textureLoad(x, neighbors[2i], 0); - var downPressure = textureLoad(x, neighbors[3i], 0); + let pixelPos = vec2i(_arg_gid.xy); + let texSize = vec2i(textureDimensions(x)); + let neighbors = getNeighbors(pixelPos, texSize); + let leftPressure = textureLoad(x, neighbors[0i], 0); + let upPressure = textureLoad(x, neighbors[1i], 0); + let rightPressure = textureLoad(x, neighbors[2i], 0); + let downPressure = textureLoad(x, neighbors[3i], 0); let divergence = textureLoad(b, pixelPos, 0).x; let newPressure = (0.25f * ((((leftPressure.x + rightPressure.x) + upPressure.x) + downPressure.x) - divergence)); textureStore(out, pixelPos, vec4f(newPressure, 0f, 0f, 1f)); @@ -208,16 +208,16 @@ describe('stable-fluid example', () => { @group(0) @binding(2) var out: texture_storage_2d; @compute @workgroup_size(16, 16) fn projectFn(@builtin(global_invocation_id) _arg_gid: vec3u) { - var pixelPos = vec2i(_arg_gid.xy); - var texSize = vec2i(textureDimensions(vel)); - var velocity = textureLoad(vel, pixelPos, 0); - var neighbors = getNeighbors(pixelPos, texSize); - var leftPressure = textureLoad(p, neighbors[0i], 0); - var upPressure = textureLoad(p, neighbors[1i], 0); - var rightPressure = textureLoad(p, neighbors[2i], 0); - var downPressure = textureLoad(p, neighbors[3i], 0); - var pressureGrad = vec2f((0.5f * (rightPressure.x - leftPressure.x)), (0.5f * (downPressure.x - upPressure.x))); - var projectedVel = (velocity.xy - pressureGrad); + let pixelPos = vec2i(_arg_gid.xy); + let texSize = vec2i(textureDimensions(vel)); + let velocity = textureLoad(vel, pixelPos, 0); + let neighbors = getNeighbors(pixelPos, texSize); + let leftPressure = textureLoad(p, neighbors[0i], 0); + let upPressure = textureLoad(p, neighbors[1i], 0); + let rightPressure = textureLoad(p, neighbors[2i], 0); + let downPressure = textureLoad(p, neighbors[3i], 0); + let pressureGrad = vec2f((0.5f * (rightPressure.x - leftPressure.x)), (0.5f * (downPressure.x - upPressure.x))); + let projectedVel = (velocity.xy - pressureGrad); textureStore(out, pixelPos, vec4f(projectedVel, 0f, 1f)); } @@ -237,14 +237,14 @@ describe('stable-fluid example', () => { @group(0) @binding(2) var dst: texture_storage_2d; @compute @workgroup_size(16, 16) fn advectInkFn(@builtin(global_invocation_id) _arg_gid: vec3u) { - var texSize = textureDimensions(src); - var pixelPos = _arg_gid.xy; - var velocity = textureLoad(vel, pixelPos, 0).xy; + let texSize = textureDimensions(src); + let pixelPos = _arg_gid.xy; + let velocity = textureLoad(vel, pixelPos, 0).xy; let timeStep = simParams.dt; - var prevPos = (vec2f(pixelPos) - (timeStep * velocity)); - var clampedPos = clamp(prevPos, vec2f(-0.5), (vec2f(texSize.xy) - vec2f(0.5))); - var normalizedPos = ((clampedPos + 0.5f) / vec2f(texSize.xy)); - var inkVal = textureSampleLevel(src, linSampler, normalizedPos, 0); + let prevPos = (vec2f(pixelPos) - (timeStep * velocity)); + let clampedPos = clamp(prevPos, vec2f(-0.5), (vec2f(texSize.xy) - vec2f(0.5))); + let normalizedPos = ((clampedPos + 0.5f) / vec2f(texSize.xy)); + let inkVal = textureSampleLevel(src, linSampler, normalizedPos, 0); textureStore(dst, pixelPos, inkVal); } @@ -254,21 +254,21 @@ describe('stable-fluid example', () => { } @vertex fn renderFn(@builtin(vertex_index) _arg_idx: u32) -> renderFn_Output { - var vertices = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); - var texCoords = array(vec2f(), vec2f(2, 0), vec2f(0, 2)); + let vertices = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); + let texCoords = array(vec2f(), vec2f(2, 0), vec2f(0, 2)); return renderFn_Output(vec4f(vertices[_arg_idx], 0f, 1f), texCoords[_arg_idx]); } - struct fragmentImageFn_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var result: texture_2d; @group(0) @binding(2) var linSampler: sampler; @group(0) @binding(1) var background: texture_2d; + struct fragmentImageFn_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentImageFn(_arg_0: fragmentImageFn_Input) -> @location(0) vec4f { const pixelStep = 0.001953125f; let leftSample = textureSample(result, linSampler, vec2f((_arg_0.uv.x - pixelStep), _arg_0.uv.y)).x; @@ -278,9 +278,9 @@ describe('stable-fluid example', () => { let gradientX = (rightSample - leftSample); let gradientY = (upSample - downSample); const distortStrength = 0.8; - var distortVector = vec2f(gradientX, gradientY); - var distortedUV = (_arg_0.uv + (distortVector * vec2f(distortStrength, -(distortStrength)))); - var outputColor = textureSample(background, linSampler, vec2f(distortedUV.x, (1f - distortedUV.y))); + let distortVector = vec2f(gradientX, gradientY); + let distortedUV = (_arg_0.uv + (distortVector * vec2f(distortStrength, -(distortStrength)))); + let outputColor = textureSample(background, linSampler, vec2f(distortedUV.x, (1f - distortedUV.y))); return vec4f(outputColor.rgb, 1f); }" `); diff --git a/apps/typegpu-docs/tests/individual-example-tests/stencil.test.ts b/apps/typegpu-docs/tests/individual-example-tests/stencil.test.ts index 5d18a11d52..48bb4050f8 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/stencil.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/stencil.test.ts @@ -36,7 +36,7 @@ describe('stencil example', () => { @vertex fn vertexFn(@builtin(vertex_index) vid: u32) -> vertexFn_Output { let pos = vertices[vid]; let uv = uvs[vid]; - var rotatedPos = (rotationUniform * pos); + let rotatedPos = (rotationUniform * pos); return vertexFn_Output(vec4f(rotatedPos, 0f, 1f), uv); } @@ -54,7 +54,7 @@ describe('stencil example', () => { @vertex fn vertexFn(@builtin(vertex_index) vid: u32) -> vertexFn_Output { let pos = vertices[vid]; let uv = uvs[vid]; - var rotatedPos = (rotationUniform * pos); + let rotatedPos = (rotationUniform * pos); return vertexFn_Output(vec4f(rotatedPos, 0f, 1f), uv); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/tgsl-parsing-test.test.ts b/apps/typegpu-docs/tests/individual-example-tests/tgsl-parsing-test.test.ts index 00d7e99d0e..996fd3e99e 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/tgsl-parsing-test.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/tgsl-parsing-test.test.ts @@ -33,7 +33,7 @@ describe('tgsl parsing test example', () => { } fn negateStruct(input: Schema) -> Schema { - var result = Schema(!(input.vec2b), !(input.vec4b), !(input.vec3b), !input.bool); + let result = Schema(!(input.vec2b), !(input.vec4b), !(input.vec3b), !input.bool); return result; } @@ -63,10 +63,10 @@ describe('tgsl parsing test example', () => { s = (s && true); s = (s && true); s = (s && true); - var vec = vec3(true, false, true); + let vec = vec3(true, false, true); s = (s && all(!(vec) == negate(vec))); - var inputStruct = Schema(vec2(false, true), vec4(false, true, false, true), vec3(true, true, false), true); - var resultStruct = negateStruct(inputStruct); + let inputStruct = Schema(vec2(false, true), vec4(false, true, false, true), vec3(true, true, false), true); + let resultStruct = negateStruct(inputStruct); s = (s && all(!(inputStruct.vec2b) == resultStruct.vec2b)); s = (s && all(!(inputStruct.vec4b) == resultStruct.vec4b)); s = (s && all(!(inputStruct.vec3b) == resultStruct.vec3b)); @@ -126,40 +126,40 @@ describe('tgsl parsing test example', () => { fn arrayAndStructConstructorsTest() -> bool { var s = true; - var defaultComplexStruct = ComplexStruct(); + let defaultComplexStruct = ComplexStruct(); s = (s && (2 == 2i)); s = (s && (defaultComplexStruct.arr[0i] == 0i)); s = (s && (defaultComplexStruct.arr[1i] == 0i)); - var defaultComplexArray = array(); + let defaultComplexArray = array(); s = (s && (3 == 3i)); s = (s && all(defaultComplexArray[0i].vec == vec2f())); s = (s && all(defaultComplexArray[1i].vec == vec2f())); s = (s && all(defaultComplexArray[2i].vec == vec2f())); var simpleStruct = SimpleStruct(vec2f(1, 2)); - var clonedSimpleStruct = simpleStruct; + let clonedSimpleStruct = simpleStruct; s = (s && all(simpleStruct.vec == clonedSimpleStruct.vec)); simpleStruct.vec[1i] += 1f; s = (s && !all(simpleStruct.vec == clonedSimpleStruct.vec)); var simpleArray = array(3i, 4i); - var clonedSimpleArray = simpleArray; + let clonedSimpleArray = simpleArray; s = (s && (simpleArray[0i] == clonedSimpleArray[0i])); s = (s && (simpleArray[1i] == clonedSimpleArray[1i])); simpleArray[1i] += 1i; s = (s && !(simpleArray[1i] == clonedSimpleArray[1i])); var complexStruct = ComplexStruct(array(5i, 6i)); - var clonedComplexStruct = complexStruct; + let clonedComplexStruct = complexStruct; s = (s && (complexStruct.arr[0i] == clonedComplexStruct.arr[0i])); s = (s && (complexStruct.arr[1i] == clonedComplexStruct.arr[1i])); complexStruct.arr[1i] += 1i; s = (s && !(complexStruct.arr[1i] == clonedComplexStruct.arr[1i])); var complexArray = array(SimpleStruct(vec2f(7, 8)), SimpleStruct(vec2f(9, 10)), SimpleStruct(vec2f(11, 12))); - var clonedComplexArray = complexArray; + let clonedComplexArray = complexArray; s = (s && all(complexArray[2i].vec == clonedComplexArray[2i].vec)); complexArray[2i].vec[1i] += 1f; s = (s && !all(complexArray[2i].vec == clonedComplexArray[2i].vec)); - var indirectClonedStruct = complexArray[0i]; + let indirectClonedStruct = complexArray[0i]; s = (s && all(indirectClonedStruct.vec == complexArray[0i].vec)); - var indirectlyClonedArray = complexStruct.arr; + let indirectlyClonedArray = complexStruct.arr; s = (s && (indirectlyClonedArray[0i] == complexStruct.arr[0i])); s = (s && (indirectlyClonedArray[1i] == complexStruct.arr[1i])); return s; diff --git a/apps/typegpu-docs/tests/individual-example-tests/two-boxes.test.ts b/apps/typegpu-docs/tests/individual-example-tests/two-boxes.test.ts index 03e50a2c57..2f9ec7a8a8 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/two-boxes.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/two-boxes.test.ts @@ -41,7 +41,7 @@ describe('two boxes example', () => { } @vertex fn vertex(@location(0) _arg_position: vec4f, @location(1) _arg_color: vec4f) -> vertex_Output { - var pos = (camera.projection * (camera.view * (transform.model * _arg_position))); + let pos = (camera.projection * (camera.view * (transform.model * _arg_position))); return vertex_Output(pos, _arg_color); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/uniformity.test.ts b/apps/typegpu-docs/tests/individual-example-tests/uniformity.test.ts index 21ccd861f6..445bfbfd9b 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/uniformity.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/uniformity.test.ts @@ -35,10 +35,6 @@ describe('uniformity test example', () => { return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]); } - struct fragmentShader_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var canvasRatioUniform: f32; @group(0) @binding(1) var gridSizeUniform: f32; @@ -65,17 +61,17 @@ describe('uniformity test example', () => { return sample(); } + struct fragmentShader_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentShader(_arg_0: fragmentShader_Input) -> @location(0) vec4f { - var uv = (((_arg_0.uv + 1f) / 2f) * vec2f(canvasRatioUniform, 1f)); - var gridedUV = floor((uv * gridSizeUniform)); + let uv = (((_arg_0.uv + 1f) / 2f) * vec2f(canvasRatioUniform, 1f)); + let gridedUV = floor((uv * gridSizeUniform)); randSeed2(gridedUV); return vec4f(vec3f(randFloat01()), 1f); } - struct fragmentShader_Input_1 { - @location(0) uv: vec2f, - } - var seed_1: u32; fn seed2_1(value: vec2f) { @@ -102,9 +98,13 @@ describe('uniformity test example', () => { return sample_1(); } + struct fragmentShader_Input_1 { + @location(0) uv: vec2f, + } + @fragment fn fragmentShader_1(_arg_0: fragmentShader_Input_1) -> @location(0) vec4f { - var uv = (((_arg_0.uv + 1f) / 2f) * vec2f(canvasRatioUniform, 1f)); - var gridedUV = floor((uv * gridSizeUniform)); + let uv = (((_arg_0.uv + 1f) / 2f) * vec2f(canvasRatioUniform, 1f)); + let gridedUV = floor((uv * gridSizeUniform)); randSeed2_1(gridedUV); return vec4f(vec3f(randFloat01_1()), 1f); }" diff --git a/apps/typegpu-docs/tests/individual-example-tests/vaporrave.test.ts b/apps/typegpu-docs/tests/individual-example-tests/vaporrave.test.ts index d7834afa66..a9a5623a9a 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/vaporrave.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/vaporrave.test.ts @@ -74,15 +74,11 @@ describe('vaporrave example', () => { } @vertex fn vertexMain(@builtin(vertex_index) idx: u32) -> vertexMain_Output { - var pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); - var uv = array(vec2f(), vec2f(2, 0), vec2f(0, 2)); + let pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); + let uv = array(vec2f(), vec2f(2, 0), vec2f(0, 2)); return vertexMain_Output(vec4f(pos[idx], 0f, 1f), uv[idx]); } - struct fragmentMain_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var resolutionUniform: vec2f; struct Ray { @@ -95,9 +91,9 @@ describe('vaporrave example', () => { } fn circles(uv: vec2f, angle: f32) -> vec3f { - var uvRotated = (rotateXY(angle) * vec2f(uv.x, (uv.y - 12f))); - var uvNormalized = fract((vec2f(uvRotated.x, uvRotated.y) / 1.2f)); - var diff2 = pow((vec2f(0.5) - uvNormalized), vec2f(2)); + let uvRotated = (rotateXY(angle) * vec2f(uv.x, (uv.y - 12f))); + let uvNormalized = fract((vec2f(uvRotated.x, uvRotated.y) / 1.2f)); + let diff2 = pow((vec2f(0.5) - uvNormalized), vec2f(2)); let distO = pow((diff2.x + diff2.y), 0.5f); return mix(vec3f(), vec3f(0.9200000166893005, 0.20999999344348907, 0.9599999785423279), exp((-5f * distO))); } @@ -123,7 +119,7 @@ describe('vaporrave example', () => { @group(0) @binding(2) var memoryBuffer: array; fn getJunctionGradient(pos: vec3i) -> vec3f { - var size_i = vec3i(7); + let size_i = vec3i(7); let x = (((pos.x % size_i.x) + size_i.x) % size_i.x); let y = (((pos.y % size_i.y) + size_i.y) % size_i.y); let z = (((pos.z % size_i.z) + size_i.z) % size_i.z); @@ -131,8 +127,8 @@ describe('vaporrave example', () => { } fn dotProdGrid(pos: vec3f, junction: vec3f) -> f32 { - var relative = (pos - junction); - var gridVector = getJunctionGradient(vec3i(junction)); + let relative = (pos - junction); + let gridVector = getJunctionGradient(vec3i(junction)); return dot(relative, gridVector); } @@ -141,7 +137,7 @@ describe('vaporrave example', () => { } fn sample(pos: vec3f) -> f32 { - var minJunction = floor(pos); + let minJunction = floor(pos); let xyz = dotProdGrid(pos, minJunction); let xyZ = dotProdGrid(pos, (minJunction + vec3f(0, 0, 1))); let xYz = dotProdGrid(pos, (minJunction + vec3f(0, 1, 0))); @@ -150,8 +146,8 @@ describe('vaporrave example', () => { let XyZ = dotProdGrid(pos, (minJunction + vec3f(1, 0, 1))); let XYz = dotProdGrid(pos, (minJunction + vec3f(1, 1, 0))); let XYZ = dotProdGrid(pos, (minJunction + vec3f(1))); - var partial = (pos - minJunction); - var smoothPartial = quinticInterpolation(partial); + let partial = (pos - minJunction); + let smoothPartial = quinticInterpolation(partial); let xy = mix(xyz, xyZ, smoothPartial.z); let xY = mix(xYz, xYZ, smoothPartial.z); let Xy = mix(Xyz, XyZ, smoothPartial.z); @@ -162,10 +158,10 @@ describe('vaporrave example', () => { } fn getSphere(p: vec3f, sphereColor: vec3f, sphereCenter: vec3f, angle: f32) -> Ray { - var localP = (p - sphereCenter); - var rotMatZ = rotateAroundZ((-(angle) * 0.3f)); - var rotMatX = rotateAroundX((-(angle) * 0.7f)); - var rotatedP = ((localP * rotMatZ) * rotMatX); + let localP = (p - sphereCenter); + let rotMatZ = rotateAroundZ((-(angle) * 0.3f)); + let rotMatX = rotateAroundX((-(angle) * 0.7f)); + let rotatedP = ((localP * rotMatZ) * rotMatX); let radius = (3f + sin(angle)); let rawDist = sdSphere(rotatedP, radius); var noise = 0f; @@ -184,8 +180,8 @@ describe('vaporrave example', () => { } fn getSceneRay(p: vec3f) -> Ray { - var floor_1 = Ray(circles(p.xz, floorAngleUniform), sdPlane(p, vec3f(0, 1, 0), 1f)); - var sphere = getSphere(p, sphereColorUniform, vec3f(0, 6, 12), sphereAngleUniform); + let floor_1 = Ray(circles(p.xz, floorAngleUniform), sdPlane(p, vec3f(0, 1, 0), 1f)); + let sphere = getSphere(p, sphereColorUniform, vec3f(0, 6, 12), sphereAngleUniform); return rayUnion(floor_1, sphere); } @@ -199,9 +195,9 @@ describe('vaporrave example', () => { var result = Ray(vec3f(), 19f); var glow = vec3f(); for (var i = 0; (i < 1000i); i++) { - var p = ((rd * distOrigin) + ro); - var scene = getSceneRay(p); - var sphereDist = getSphere(p, sphereColorUniform, vec3f(0, 6, 12), sphereAngleUniform); + let p = ((rd * distOrigin) + ro); + let scene = getSceneRay(p); + let sphereDist = getSphere(p, sphereColorUniform, vec3f(0, 6, 12), sphereAngleUniform); glow += (sphereColorUniform * exp(-(sphereDist.dist))); distOrigin += scene.dist; if ((distOrigin > 19f)) { @@ -219,14 +215,18 @@ describe('vaporrave example', () => { @group(0) @binding(5) var glowIntensityUniform: f32; + struct fragmentMain_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentMain(_arg_0: fragmentMain_Input) -> @location(0) vec4f { var uv = ((_arg_0.uv * 2f) - 1f); uv.x *= (resolutionUniform.x / resolutionUniform.y); - var ro = vec3f(0, 2, -1); - var rd = normalize(vec3f(uv.x, uv.y, 1f)); - var march = rayMarch(ro, rd); + let ro = vec3f(0, 2, -1); + let rd = normalize(vec3f(uv.x, uv.y, 1f)); + let march = rayMarch(ro, rd); let y = (((rd.y * march.ray.dist) + ro.y) - 2f); - var sky = mix(vec4f(0.10000000149011612, 0, 0.20000000298023224, 1), vec4f(0.2800000011920929, 0, 0.5400000214576721, 1), (y / 19f)); + let sky = mix(vec4f(0.10000000149011612, 0, 0.20000000298023224, 1), vec4f(0.2800000011920929, 0, 0.5400000214576721, 1), (y / 19f)); let fog = min((march.ray.dist / 19f), 1f); return mix(mix(vec4f(march.ray.color, 1f), sky, fog), vec4f(march.glow, 1f), glowIntensityUniform); }" diff --git a/apps/typegpu-docs/tests/individual-example-tests/wgsl-resolution.test.ts b/apps/typegpu-docs/tests/individual-example-tests/wgsl-resolution.test.ts index 315d8404b9..a7456be9e5 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/wgsl-resolution.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/wgsl-resolution.test.ts @@ -40,10 +40,10 @@ describe('wgsl resolution example', () => { @vertex fn vertex_shader(@location(0) _arg_v: vec2f, @location(1) _arg_center: vec2f, @location(2) _arg_velocity: vec2f) -> vertex_shader_Output { let angle = get_rotation_from_velocity_util(_arg_velocity); - var rotated = rotate_util(_arg_v, angle); - var pos = vec4f((rotated.x + _arg_center.x), (rotated.y + _arg_center.y), 0f, 1f); + let rotated = rotate_util(_arg_v, angle); + let pos = vec4f((rotated.x + _arg_center.x), (rotated.y + _arg_center.y), 0f, 1f); let colorPalette = (&colorPalette_1); - var color = vec4f(((sin((angle + (*colorPalette).x)) * 0.45f) + 0.45f), ((sin((angle + (*colorPalette).y)) * 0.45f) + 0.45f), ((sin((angle + (*colorPalette).z)) * 0.45f) + 0.45f), 1f); + let color = vec4f(((sin((angle + (*colorPalette).x)) * 0.45f) + 0.45f), ((sin((angle + (*colorPalette).y)) * 0.45f) + 0.45f), ((sin((angle + (*colorPalette).z)) * 0.45f) + 0.45f), 1f); return vertex_shader_Output(pos, color); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/xor-dev-centrifuge-2.test.ts b/apps/typegpu-docs/tests/individual-example-tests/xor-dev-centrifuge-2.test.ts index 9abffaf6b8..8438e76d59 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/xor-dev-centrifuge-2.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/xor-dev-centrifuge-2.test.ts @@ -26,14 +26,10 @@ describe('xor dev centrifuge example', () => { } @vertex fn vertexMain(@builtin(vertex_index) _arg_vertexIndex: u32) -> vertexMain_Output { - var pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); + let pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); return vertexMain_Output(vec4f(pos[_arg_vertexIndex], 0f, 1f), pos[_arg_vertexIndex]); } - struct fragmentMain_Input { - @location(0) uv: vec2f, - } - struct Params { time: f32, aspectRatio: f32, @@ -51,18 +47,22 @@ describe('xor dev centrifuge example', () => { return select(tanh(v), sign(v), (abs(v) > vec3f(10))); } + struct fragmentMain_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentMain(_arg_0: fragmentMain_Input) -> @location(0) vec4f { let params = (¶msUniform); - var ratio = vec2f((*params).aspectRatio, 1f); - var dir = normalize(vec3f((_arg_0.uv * ratio), -1f)); + let ratio = vec2f((*params).aspectRatio, 1f); + let dir = normalize(vec3f((_arg_0.uv * ratio), -1f)); var z = 0f; var acc = vec3f(); for (var i = 0; (i < (*params).tunnelDepth); i++) { var p = (dir * z); p.x += (*params).cameraPos.x; p.y += (*params).cameraPos.y; - var coords = vec3f(((atan2(p.y, p.x) * (*params).bigStrips) + (*params).time), ((p.z * (*params).dollyZoom) - (5f * (*params).time)), (length(p.xy) - 11f)); - var coords2 = (cos((coords + cos((coords * (*params).smallStrips)))) - 1f); + let coords = vec3f(((atan2(p.y, p.x) * (*params).bigStrips) + (*params).time), ((p.z * (*params).dollyZoom) - (5f * (*params).time)), (length(p.xy) - 11f)); + let coords2 = (cos((coords + cos((coords * (*params).smallStrips)))) - 1f); let dd = ((length(vec4f(coords.z, coords2)) * 0.5f) - 0.1f); acc += ((1.2f - cos(((*params).color * p.z))) / dd); z += dd; diff --git a/apps/typegpu-docs/tests/individual-example-tests/xor-dev-runner.test.ts b/apps/typegpu-docs/tests/individual-example-tests/xor-dev-runner.test.ts index 419c95807c..7544091949 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/xor-dev-runner.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/xor-dev-runner.test.ts @@ -30,14 +30,10 @@ describe('xor dev runner example', () => { } @vertex fn vertexMain(@builtin(vertex_index) _arg_vertexIndex: u32) -> vertexMain_Output { - var pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); + let pos = array(vec2f(-1), vec2f(3, -1), vec2f(-1, 3)); return vertexMain_Output(vec4f(pos[_arg_vertexIndex], 0f, 1f), pos[_arg_vertexIndex]); } - struct fragmentMain_Input { - @location(0) uv: vec2f, - } - @group(0) @binding(0) var colorUniform: vec3f; struct Camera { @@ -58,9 +54,9 @@ describe('xor dev runner example', () => { fn getRayForUV(uv: vec2f) -> Ray { let camera = (&cameraUniform); - var farView = ((*camera).projectionInverse * vec4f(uv, 1f, 1f)); - var farWorld = ((*camera).viewInverse * vec4f((farView.xyz / farView.w), 1f)); - var direction = normalize((farWorld.xyz - (*camera).pos.xyz)); + let farView = ((*camera).projectionInverse * vec4f(uv, 1f, 1f)); + let farWorld = ((*camera).viewInverse * vec4f((farView.xyz / farView.w), 1f)); + let direction = normalize((farWorld.xyz - (*camera).pos.xyz)); return Ray((*camera).pos, vec4f(direction, 0f)); } @@ -82,13 +78,17 @@ describe('xor dev runner example', () => { return select(tanh(v), sign(v), (abs(v) > 10f)); } + struct fragmentMain_Input { + @location(0) uv: vec2f, + } + @fragment fn fragmentMain(_arg_0: fragmentMain_Input) -> @location(0) vec4f { - var icolor = (colorUniform * 4f); - var ray = getRayForUV(_arg_0.uv); + let icolor = (colorUniform * 4f); + let ray = getRayForUV(_arg_0.uv); var acc = vec3f(); var z = 0f; for (var l = 0; (l < 30i); l++) { - var p = ((((vec3f(3, 0, 3) + controlsOffsetUniform) + autoMoveOffsetUniform) + ray.origin.xyz) + (ray.direction.xyz * z)); + let p = ((((vec3f(3, 0, 3) + controlsOffsetUniform) + autoMoveOffsetUniform) + ray.origin.xyz) + (ray.direction.xyz * z)); var q = p; var prox = p.y; for (var i = 40.1; (i > 0.01f); i *= 0.2f) { diff --git a/packages/typegpu/src/core/buffer/bufferUsage.ts b/packages/typegpu/src/core/buffer/bufferUsage.ts index 24f28dcbca..d8a1028e78 100644 --- a/packages/typegpu/src/core/buffer/bufferUsage.ts +++ b/packages/typegpu/src/core/buffer/bufferUsage.ts @@ -118,7 +118,7 @@ class TgpuFixedBufferImpl implements TgpuConst, } [$resolve](ctx: ResolutionCtx): ResolvedSnippet { - const id = ctx.getUniqueName(this); + const id = ctx.makeUniqueIdentifier(getName(this), 'global'); const resolvedDataType = ctx.resolve(this.dataType).value; const resolvedValue = ctx.resolve(this.#value, this.dataType).value; diff --git a/packages/typegpu/src/core/function/autoIO.ts b/packages/typegpu/src/core/function/autoIO.ts index 6feece51d5..b35a092b1a 100644 --- a/packages/typegpu/src/core/function/autoIO.ts +++ b/packages/typegpu/src/core/function/autoIO.ts @@ -85,7 +85,7 @@ export class AutoFragmentFn implements SelfResolvable { if (!getName(impl)) { setName(impl, 'fragmentFn'); } - this.#core = createFnCore(impl, '@fragment '); + this.#core = createFnCore(impl, 'fragment'); this.autoIn = new AutoStruct({ ...builtinFragmentIn, ...varyings }, undefined, locations); setName(this.autoIn, 'FragmentIn'); this.autoOut = new AutoStruct(builtinFragmentOut, vec4f); @@ -131,7 +131,7 @@ export class AutoVertexFn implements SelfResolvable { if (!getName(impl)) { setName(impl, 'vertexFn'); } - this.#core = createFnCore(impl, '@vertex '); + this.#core = createFnCore(impl, 'vertex'); this.autoIn = new AutoStruct({ ...builtinVertexIn, ...attribs }, undefined, locations); setName(this.autoIn, 'VertexIn'); this.autoOut = new AutoStruct(builtinVertexOut, undefined); diff --git a/packages/typegpu/src/core/function/entryInputRouter.ts b/packages/typegpu/src/core/function/entryInputRouter.ts index 8ba6669372..b756366c4b 100644 --- a/packages/typegpu/src/core/function/entryInputRouter.ts +++ b/packages/typegpu/src/core/function/entryInputRouter.ts @@ -1,12 +1,7 @@ -import { undecorate } from '../../data/dataTypes.ts'; -import { snip, type Snippet } from '../../data/snippet.ts'; +import { type Snippet } from '../../data/snippet.ts'; import { $internal, $repr } from '../../shared/symbols.ts'; import { type BaseData, isWgslStruct } from '../../data/wgslTypes.ts'; - -interface PositionalArgEntry { - argName: string; - type: BaseData; -} +import type { FunctionArgumentAccess } from '../../types.ts'; /** * Routes `(input) => { input.x }` style property access to the correct WGSL @@ -18,38 +13,32 @@ export class EntryInputRouter implements BaseData { readonly type = 'entry-input-router' as const; // Type-token only, not present at runtime: declare readonly [$repr]: never; - readonly structArgName: string; - readonly dataSchema: BaseData | undefined; + + readonly structArg: FunctionArgumentAccess | undefined; /** Maps schemaKey → { WGSL arg name, type } */ - readonly positionalArgsMap: Map; + readonly positionalArgsMap: Map; constructor( - structArgName: string, - dataSchema: BaseData | undefined, - positionalArgs: { schemaKey: string; argName: string; type: BaseData }[], + structArg: FunctionArgumentAccess | undefined, + positionalArgs: { schemaKey: string; arg: FunctionArgumentAccess }[], ) { - this.structArgName = structArgName; - this.dataSchema = dataSchema; - this.positionalArgsMap = new Map( - positionalArgs.map((a) => [a.schemaKey, { argName: a.argName, type: a.type }]), - ); + this.structArg = structArg; + this.positionalArgsMap = new Map(positionalArgs.map((a) => [a.schemaKey, a.arg])); } toString(): string { return 'entry-input-router'; } - accessProp(propName: string): Snippet | undefined { + accessProp(propName: string): Snippet | { target: Snippet; prop: string } | undefined { const positionalEntry = this.positionalArgsMap.get(propName); if (positionalEntry) { - return snip(positionalEntry.argName, positionalEntry.type, 'argument'); + return positionalEntry(); } - if (this.dataSchema && isWgslStruct(this.dataSchema)) { - const propType = this.dataSchema.propTypes[propName]; - if (propType) { - return snip(`${this.structArgName}.${propName}`, undecorate(propType), 'argument'); - } + const structSnippet = this.structArg?.(); + if (structSnippet && isWgslStruct(structSnippet.dataType)) { + return { target: structSnippet, prop: propName }; } return undefined; diff --git a/packages/typegpu/src/core/function/fnCore.ts b/packages/typegpu/src/core/function/fnCore.ts index 66429067e5..513000f199 100644 --- a/packages/typegpu/src/core/function/fnCore.ts +++ b/packages/typegpu/src/core/function/fnCore.ts @@ -3,9 +3,10 @@ import { undecorate } from '../../data/dataTypes.ts'; import { type ResolvedSnippet, snip } from '../../data/snippet.ts'; import { type BaseData, isWgslData, isWgslStruct, Void } from '../../data/wgslTypes.ts'; import { MissingLinksError } from '../../errors.ts'; +import { isValidIdentifier } from '../../nameUtils.ts'; import { getMetaData, getName } from '../../shared/meta.ts'; import { $getNameForward } from '../../shared/symbols.ts'; -import type { ResolutionCtx } from '../../types.ts'; +import type { ResolutionCtx, TgpuShaderStage } from '../../types.ts'; import { applyExternals, type ExternalMap, replaceExternalsInWgsl } from '../resolve/externals.ts'; import { extractArgs } from './extractArgs.ts'; import type { Implementation, SeparatedEntryArgs } from './fnTypes.ts'; @@ -32,7 +33,11 @@ export interface FnCore { ): ResolvedSnippet; } -export function createFnCore(implementation: Implementation, fnAttribute = ''): FnCore { +export function createFnCore( + implementation: Implementation, + functionType: 'normal' | TgpuShaderStage, + workgroupSize?: number[], +): FnCore { /** * External application has to be deferred until resolution because * some externals can reference the owner function which has not been @@ -57,25 +62,38 @@ export function createFnCore(implementation: Implementation, fnAttribute = ''): ): ResolvedSnippet { const externalMap: ExternalMap = {}; + let attributes = ''; + if (functionType === 'compute') { + attributes = `@compute @workgroup_size(${workgroupSize?.join(', ')}) `; + } else if (functionType === 'vertex') { + attributes = `@vertex `; + } else if (functionType === 'fragment') { + attributes = `@fragment `; + } + for (const externals of externalsToApply) { applyExternals(externalMap, externals); } - const id = ctx.getUniqueName(this); + const id = ctx.makeUniqueIdentifier(getName(this), 'global'); if (typeof implementation === 'string') { if (!returnType) { throw new Error('Explicit return type is required for string implementation'); } - const validArgNames = entryInput - ? Object.fromEntries( - entryInput.positionalArgs.map((a) => [a.schemaKey, ctx.makeNameValid(a.schemaKey)]), - ) - : undefined; + if (entryInput) { + for (const arg of entryInput.positionalArgs) { + if (!isValidIdentifier(arg.schemaKey)) { + throw new Error(`Invalid argument name: ${arg.schemaKey}`); + } + } - if (validArgNames && Object.keys(validArgNames).length > 0) { - applyExternals(externalMap, { in: validArgNames }); + applyExternals(externalMap, { + in: Object.fromEntries( + entryInput.positionalArgs.map((a) => [a.schemaKey, a.schemaKey]), + ), + }); } const replacedImpl = replaceExternalsInWgsl(ctx, externalMap, implementation); @@ -83,15 +101,15 @@ export function createFnCore(implementation: Implementation, fnAttribute = ''): let header = ''; let body = ''; - if (fnAttribute !== '' && entryInput && validArgNames) { + if (functionType !== 'normal' && entryInput) { const { dataSchema, positionalArgs } = entryInput; const parts: string[] = []; if (dataSchema && isArgUsedInBody('in', replacedImpl)) { parts.push(`in: ${ctx.resolve(dataSchema).value}`); } for (const a of positionalArgs) { - const argName = validArgNames[a.schemaKey] ?? ''; - if (argName !== '' && isArgUsedInBody(argName, replacedImpl)) { + const argName = a.schemaKey; + if (isArgUsedInBody(argName, replacedImpl)) { parts.push(`${getAttributesString(a.type)}${argName}: ${ctx.resolve(a.type).value}`); } } @@ -140,7 +158,8 @@ export function createFnCore(implementation: Implementation, fnAttribute = ''): body = replacedImpl.slice(providedArgs.range.end); } - ctx.addDeclaration(`${fnAttribute}fn ${id}${header}${body}`); + ctx.addDeclaration(`${attributes}fn ${id}${header}${body}`); + return snip(id, returnType, /* origin */ 'runtime'); } @@ -178,7 +197,7 @@ export function createFnCore(implementation: Implementation, fnAttribute = ''): // If an entrypoint implementation has a second argument, it represents the output schema. // We look at the identifier chosen by the user and add it to externals. const maybeSecondArg = ast.params[1]; - if (maybeSecondArg && maybeSecondArg.type === 'i' && fnAttribute !== '') { + if (maybeSecondArg && maybeSecondArg.type === 'i' && functionType !== 'normal') { applyExternals(externalMap, { // oxlint-disable-next-line typescript/no-non-null-assertion -- entry functions cannot be shellless [maybeSecondArg.name]: undecorate(returnType!), @@ -187,18 +206,8 @@ export function createFnCore(implementation: Implementation, fnAttribute = ''): // generate wgsl string - const { - head, - body, - returnType: actualReturnType, - } = ctx.fnToWgsl({ - functionType: fnAttribute.includes('@compute') - ? 'compute' - : fnAttribute.includes('@vertex') - ? 'vertex' - : fnAttribute.includes('@fragment') - ? 'fragment' - : 'normal', + const { code, returnType: actualReturnType } = ctx.fnToWgsl({ + functionType, argTypes, entryInput, params: ast.params, @@ -207,9 +216,7 @@ export function createFnCore(implementation: Implementation, fnAttribute = ''): externalMap, }); - ctx.addDeclaration( - `${fnAttribute}fn ${id}${ctx.resolve(head).value}${ctx.resolve(body).value}`, - ); + ctx.addDeclaration(`${attributes}fn ${id}${code}`); return snip(id, actualReturnType, /* origin */ 'runtime'); }, diff --git a/packages/typegpu/src/core/function/shelllessImpl.ts b/packages/typegpu/src/core/function/shelllessImpl.ts index 23b60bdde1..9263303a31 100644 --- a/packages/typegpu/src/core/function/shelllessImpl.ts +++ b/packages/typegpu/src/core/function/shelllessImpl.ts @@ -31,7 +31,7 @@ export function createShelllessImpl( argTypes: BaseData[], implementation: (...args: never[]) => unknown, ): ShelllessImpl { - const core = createFnCore(implementation, ''); + const core = createFnCore(implementation, 'normal'); return { [$internal]: true, diff --git a/packages/typegpu/src/core/function/tgpuComputeFn.ts b/packages/typegpu/src/core/function/tgpuComputeFn.ts index 6f48cbe643..9cef2d49cc 100644 --- a/packages/typegpu/src/core/function/tgpuComputeFn.ts +++ b/packages/typegpu/src/core/function/tgpuComputeFn.ts @@ -114,10 +114,7 @@ function createComputeFn>( [$getNameForward]: FnCore; }; - const core = createFnCore( - implementation, - `@compute @workgroup_size(${workgroupSize.join(', ')}) `, - ); + const core = createFnCore(implementation, 'compute', workgroupSize); const result: This = { shell, diff --git a/packages/typegpu/src/core/function/tgpuFn.ts b/packages/typegpu/src/core/function/tgpuFn.ts index 65ea52de65..40f6548922 100644 --- a/packages/typegpu/src/core/function/tgpuFn.ts +++ b/packages/typegpu/src/core/function/tgpuFn.ts @@ -173,7 +173,7 @@ function createFn( implementation = _implementation; } - const core = createFnCore(implementation as Implementation, ''); + const core = createFnCore(implementation as Implementation, 'normal'); const fnBase = { shell, diff --git a/packages/typegpu/src/core/function/tgpuFragmentFn.ts b/packages/typegpu/src/core/function/tgpuFragmentFn.ts index 631617bcdc..cb3b4c990f 100644 --- a/packages/typegpu/src/core/function/tgpuFragmentFn.ts +++ b/packages/typegpu/src/core/function/tgpuFragmentFn.ts @@ -183,7 +183,7 @@ function createFragmentFn( [$getNameForward]: FnCore; }; - const core = createFnCore(implementation, '@fragment '); + const core = createFnCore(implementation, 'fragment'); const outputType = shell.returnType; if (typeof implementation === 'string') { addReturnTypeToExternals(implementation, outputType, (externals) => diff --git a/packages/typegpu/src/core/function/tgpuVertexFn.ts b/packages/typegpu/src/core/function/tgpuVertexFn.ts index a261634b3d..8c5b230891 100644 --- a/packages/typegpu/src/core/function/tgpuVertexFn.ts +++ b/packages/typegpu/src/core/function/tgpuVertexFn.ts @@ -158,7 +158,7 @@ function createVertexFn( [$getNameForward]: FnCore; }; - const core = createFnCore(implementation, '@vertex '); + const core = createFnCore(implementation, 'vertex'); const entryInput: SeparatedEntryArgs = separateAllAsPositional(shell.in ?? {}); const result: This = { diff --git a/packages/typegpu/src/core/resolve/namespace.ts b/packages/typegpu/src/core/resolve/namespace.ts index f112cd4fb0..90fcba08f7 100644 --- a/packages/typegpu/src/core/resolve/namespace.ts +++ b/packages/typegpu/src/core/resolve/namespace.ts @@ -1,6 +1,5 @@ import type { ResolvedSnippet } from '../../data/snippet.ts'; -import { type NameRegistry, RandomNameRegistry, StrictNameRegistry } from '../../nameRegistry.ts'; -import { getName } from '../../shared/meta.ts'; +import { bannedTokens, builtins } from '../../nameUtils.ts'; import { $internal } from '../../shared/symbols.ts'; import { ShelllessRepository } from '../../tgsl/shellless.ts'; import type { TgpuLazy, TgpuSlot } from '../slot/slotTypes.ts'; @@ -8,8 +7,9 @@ import type { TgpuLazy, TgpuSlot } from '../slot/slotTypes.ts'; type SlotToValueMap = Map, unknown>; export interface NamespaceInternal { - readonly nameRegistry: NameRegistry; + readonly takenGlobalIdentifiers: Set; readonly shelllessRepo: ShelllessRepository; + readonly strategy: 'random' | 'strict'; memoizedResolves: WeakMap< // WeakMap because if the item does not exist anymore, @@ -24,73 +24,32 @@ export interface NamespaceInternal { TgpuLazy, { slotToValueMap: SlotToValueMap; result: unknown }[] >; - - listeners: { - [K in keyof NamespaceEventMap]: Set<(event: NamespaceEventMap[K]) => void>; - }; } -type NamespaceEventMap = { - name: { target: object; name: string }; -}; - -type DetachListener = () => void; - export interface Namespace { readonly [$internal]: NamespaceInternal; - - on( - event: TEvent, - listener: (event: NamespaceEventMap[TEvent]) => void, - ): DetachListener; } class NamespaceImpl implements Namespace { readonly [$internal]: NamespaceInternal; - constructor(nameRegistry: NameRegistry) { + constructor(strategy: 'random' | 'strict') { this[$internal] = { - nameRegistry, + strategy, + takenGlobalIdentifiers: new Set([...bannedTokens, ...builtins]), shelllessRepo: new ShelllessRepository(), memoizedResolves: new WeakMap(), memoizedLazy: new WeakMap(), - listeners: { - name: new Set(), - }, }; } - - on( - event: TEvent, - listener: (event: NamespaceEventMap[TEvent]) => void, - ): DetachListener { - if (event === 'name') { - const listeners = this[$internal].listeners.name; - listeners.add(listener); - - return () => listeners.delete(listener); - } - - throw new Error(`Unsupported event: ${event}`); - } } export interface NamespaceOptions { names?: 'random' | 'strict' | undefined; } -export function getUniqueName(namespace: NamespaceInternal, resource: object): string { - const name = namespace.nameRegistry.makeUnique(getName(resource), true); - for (const listener of namespace.listeners.name) { - listener({ target: resource, name }); - } - return name; -} - export function namespace(options?: NamespaceOptions): Namespace { const { names = 'strict' } = options ?? {}; - return new NamespaceImpl( - names === 'strict' ? new StrictNameRegistry() : new RandomNameRegistry(), - ); + return new NamespaceImpl(names); } diff --git a/packages/typegpu/src/core/resolve/resolveData.ts b/packages/typegpu/src/core/resolve/resolveData.ts index 19e5da347d..bc5320c80d 100644 --- a/packages/typegpu/src/core/resolve/resolveData.ts +++ b/packages/typegpu/src/core/resolve/resolveData.ts @@ -38,6 +38,7 @@ import type { WgslArray, WgslStruct, } from '../../data/wgslTypes.ts'; +import { getName } from '../../shared/meta.ts'; import { $internal } from '../../shared/symbols.ts'; import { assertExhaustive } from '../../shared/utilityTypes.ts'; import type { ResolutionCtx } from '../../types.ts'; @@ -127,7 +128,7 @@ function resolveStruct(ctx: ResolutionCtx, struct: WgslStruct) { if (struct[$internal].isAbstruct) { throw new Error('Cannot resolve abstract struct types to WGSL.'); } - const id = ctx.getUniqueName(struct); + const id = ctx.makeUniqueIdentifier(getName(struct), 'global'); ctx.addDeclaration(`\ struct ${id} { @@ -155,7 +156,7 @@ ${Object.entries(struct.propTypes) * ``` */ function resolveUnstruct(ctx: ResolutionCtx, unstruct: Unstruct) { - const id = ctx.getUniqueName(unstruct); + const id = ctx.makeUniqueIdentifier(getName(unstruct), 'global'); ctx.addDeclaration(`\ struct ${id} { diff --git a/packages/typegpu/src/core/sampler/sampler.ts b/packages/typegpu/src/core/sampler/sampler.ts index 4daaf1c917..adf10ee8ce 100644 --- a/packages/typegpu/src/core/sampler/sampler.ts +++ b/packages/typegpu/src/core/sampler/sampler.ts @@ -99,7 +99,7 @@ export class TgpuLaidOutSamplerImpl< } [$resolve](ctx: ResolutionCtx): ResolvedSnippet { - const id = ctx.getUniqueName(this); + const id = ctx.makeUniqueIdentifier(getName(this), 'global'); const group = ctx.allocateLayoutEntry(this.#membership.layout); ctx.addDeclaration( @@ -186,7 +186,7 @@ class TgpuFixedSamplerImpl } [$resolve](ctx: ResolutionCtx): ResolvedSnippet { - const id = ctx.getUniqueName(this); + const id = ctx.makeUniqueIdentifier(getName(this), 'global'); const { group, binding } = ctx.allocateFixedEntry( this.schema.type === 'sampler_comparison' diff --git a/packages/typegpu/src/core/texture/externalTexture.ts b/packages/typegpu/src/core/texture/externalTexture.ts index c9d457c48b..78ae4cd582 100644 --- a/packages/typegpu/src/core/texture/externalTexture.ts +++ b/packages/typegpu/src/core/texture/externalTexture.ts @@ -37,7 +37,7 @@ export class TgpuExternalTextureImpl implements TgpuExternalTexture, SelfResolva } [$resolve](ctx: ResolutionCtx): ResolvedSnippet { - const id = ctx.getUniqueName(this); + const id = ctx.makeUniqueIdentifier(getName(this), 'global'); const group = ctx.allocateLayoutEntry(this.#membership.layout); ctx.addDeclaration( diff --git a/packages/typegpu/src/core/texture/texture.ts b/packages/typegpu/src/core/texture/texture.ts index 27923995d6..fbe7295d83 100644 --- a/packages/typegpu/src/core/texture/texture.ts +++ b/packages/typegpu/src/core/texture/texture.ts @@ -600,7 +600,7 @@ class TgpuFixedTextureViewImpl } [$resolve](ctx: ResolutionCtx): ResolvedSnippet { - const id = ctx.getUniqueName(this); + const id = ctx.makeUniqueIdentifier(getName(this), 'global'); const { group, binding } = ctx.allocateFixedEntry( isWgslStorageTexture(this.schema) ? { @@ -642,7 +642,7 @@ export class TgpuLaidOutTextureViewImpl } [$resolve](ctx: ResolutionCtx): ResolvedSnippet { - const id = ctx.getUniqueName(this); + const id = ctx.makeUniqueIdentifier(getName(this), 'global'); const pre = `var<${this.#scope}> ${id}: ${ctx.resolve(this.#dataType).value}`; if (this.#initialValue) { diff --git a/packages/typegpu/src/data/autoStruct.ts b/packages/typegpu/src/data/autoStruct.ts index 647d13b79c..c227b565fe 100644 --- a/packages/typegpu/src/data/autoStruct.ts +++ b/packages/typegpu/src/data/autoStruct.ts @@ -1,5 +1,5 @@ import { createIoSchema } from '../core/function/ioSchema.ts'; -import { isValidProp } from '../nameRegistry.ts'; +import { isValidProp } from '../nameUtils.ts'; import { getName, setName } from '../shared/meta.ts'; import { $internal, $repr, $resolve } from '../shared/symbols.ts'; import type { ResolutionCtx, SelfResolvable } from '../types.ts'; diff --git a/packages/typegpu/src/data/snippet.ts b/packages/typegpu/src/data/snippet.ts index fe658ef99d..9c2e954f0d 100644 --- a/packages/typegpu/src/data/snippet.ts +++ b/packages/typegpu/src/data/snippet.ts @@ -74,14 +74,9 @@ export interface Snippet { readonly origin: Origin; } -export interface ResolvedSnippet { +export interface ResolvedSnippet extends Snippet { readonly value: string; - /** - * The type that `value` is assignable to (not necessary exactly inferred as). - * E.g. `1.1` is assignable to `f32`, but `1.1` itself is an abstract float - */ readonly dataType: BaseData; - readonly origin: Origin; } export type MapValueToSnippet = { [K in keyof T]: Snippet }; diff --git a/packages/typegpu/src/data/struct.ts b/packages/typegpu/src/data/struct.ts index c044da5f8f..c2d024acc3 100644 --- a/packages/typegpu/src/data/struct.ts +++ b/packages/typegpu/src/data/struct.ts @@ -1,4 +1,4 @@ -import { isValidProp } from '../nameRegistry.ts'; +import { isValidProp } from '../nameUtils.ts'; import { getName, setName } from '../shared/meta.ts'; import { $internal } from '../shared/symbols.ts'; import { schemaCallWrapper } from './schemaCallWrapper.ts'; diff --git a/packages/typegpu/src/nameRegistry.ts b/packages/typegpu/src/nameUtils.ts similarity index 58% rename from packages/typegpu/src/nameRegistry.ts rename to packages/typegpu/src/nameUtils.ts index aa2cd1ada0..f66bfbb79a 100644 --- a/packages/typegpu/src/nameRegistry.ts +++ b/packages/typegpu/src/nameUtils.ts @@ -1,6 +1,4 @@ -import { invariant } from './errors.ts'; - -const bannedTokens = new Set([ +export const bannedTokens = new Set([ // keywords 'alias', 'break', @@ -181,7 +179,7 @@ const bannedTokens = new Set([ 'storage', ]); -const builtins = new Set([ +export const builtins = new Set([ // constructors 'array', 'bool', @@ -361,37 +359,8 @@ const builtins = new Set([ 'quadSwapY', ]); -export interface NameRegistry { - /** - * Creates a valid WGSL identifier, each guaranteed to be unique - * in the lifetime of a single resolution process - * (excluding non-global identifiers from popped scopes). - * Should append "_" to primer, followed by some id. - * @param primer Used in the generation process, makes the identifier more recognizable. - * @param global Whether the name should be registered in the global scope (true), or in the current function scope (false) - */ - makeUnique(primer: string | undefined, global: boolean): string; - - /** - * Creates a valid WGSL identifier. - * Renames identifiers that are WGSL reserved words. - * @param primer Used in the generation process. - * - * @example - * makeValid("notAKeyword"); // "notAKeyword" - * makeValid("struct"); // makeUnique("struct") - * makeValid("struct_1"); // makeUnique("struct_1") (to avoid potential name collisions) - * makeValid("_"); // ERROR (too difficult to make valid to care) - */ - makeValid(primer: string): string; - - pushFunctionScope(): void; - popFunctionScope(): void; - pushBlockScope(): void; - popBlockScope(): void; -} - -function sanitizePrimer(primer: string | undefined) { +/*#__NO_SIDE_EFFECTS__*/ +export function sanitizePrimer(primer: string | undefined) { if (primer) { // sanitizing return primer @@ -411,7 +380,8 @@ function sanitizePrimer(primer: string | undefined) { * isValidIdentifier("_"); // ERROR * isValidIdentifier("my variable"); // ERROR */ -function isValidIdentifier(ident: string): boolean { +/*#__NO_SIDE_EFFECTS__*/ +export function isValidIdentifier(ident: string): boolean { if (ident === '_' || ident.startsWith('__') || /\s/.test(ident)) { throw new Error( `Invalid identifier '${ident}'. Choose an identifier without whitespaces or leading underscores.`, @@ -424,6 +394,7 @@ function isValidIdentifier(ident: string): boolean { /** * Same as `isValidIdentifier`, except does not check for builtin clashes. */ +/*#__NO_SIDE_EFFECTS__*/ export function isValidProp(ident: string): boolean { if (ident === '_' || ident.startsWith('__') || /\s/.test(ident)) { throw new Error( @@ -433,126 +404,3 @@ export function isValidProp(ident: string): boolean { const prefix = ident.split('_')[0] as string; return !bannedTokens.has(prefix); } -type FunctionScopeLayer = { - type: 'functionScope'; -}; - -type BlockScopeLayer = { - type: 'blockScope'; - usedBlockScopeNames: Set; -}; - -type ScopeLayer = FunctionScopeLayer | BlockScopeLayer; - -abstract class NameRegistryImpl implements NameRegistry { - abstract getUniqueVariant(base: string): string; - - readonly #usedNames: Set; - readonly #scopeStack: ScopeLayer[]; - - constructor() { - this.#usedNames = new Set([...bannedTokens, ...builtins]); - this.#scopeStack = []; - } - - get #usedBlockScopeNames(): Set | undefined { - return (this.#scopeStack[this.#scopeStack.length - 1] as BlockScopeLayer | undefined) - ?.usedBlockScopeNames; - } - - makeUnique(primer: string | undefined, global: boolean): string { - const sanitizedPrimer = sanitizePrimer(primer); - const name = this.getUniqueVariant(sanitizedPrimer); - - if (global) { - this.#usedNames.add(name); - } else { - this.#usedBlockScopeNames?.add(name); - } - - return name; - } - - #isUsedInBlocksBefore(name: string): boolean { - const functionScopeIndex = this.#scopeStack.findLastIndex( - (scope) => scope.type === 'functionScope', - ); - return this.#scopeStack - .slice(functionScopeIndex + 1) - .some((scope) => (scope as BlockScopeLayer).usedBlockScopeNames.has(name)); - } - - makeValid(primer: string): string { - if ( - isValidIdentifier(primer) && - !this.#usedNames.has(primer) && - !this.#isUsedInBlocksBefore(primer) - ) { - this.#usedBlockScopeNames?.add(primer); - return primer; - } - return this.makeUnique(primer, false); - } - - isUsed(name: string): boolean { - return this.#usedNames.has(name) || this.#isUsedInBlocksBefore(name); - } - - pushFunctionScope(): void { - this.#scopeStack.push({ type: 'functionScope' }); - this.#scopeStack.push({ - type: 'blockScope', - usedBlockScopeNames: new Set(), - }); - } - - popFunctionScope(): void { - const functionScopeIndex = this.#scopeStack.findLastIndex( - (scope) => scope.type === 'functionScope', - ); - - if (functionScopeIndex === -1) { - throw new Error('Tried to pop function scope when no scope was present.'); - } - - this.#scopeStack.splice(functionScopeIndex); - } - - pushBlockScope(): void { - this.#scopeStack.push({ - type: 'blockScope', - usedBlockScopeNames: new Set(), - }); - } - popBlockScope(): void { - invariant( - this.#scopeStack[this.#scopeStack.length - 1]?.type === 'blockScope', - 'Tried to pop block scope, but it is not present', - ); - this.#scopeStack.pop(); - } -} - -export class RandomNameRegistry extends NameRegistryImpl { - #lastUniqueId = 0; - - getUniqueVariant(base: string): string { - let name = `${base}_${this.#lastUniqueId++}`; - while (this.isUsed(name)) { - name = `${base}_${this.#lastUniqueId++}`; - } - return name; - } -} - -export class StrictNameRegistry extends NameRegistryImpl { - getUniqueVariant(base: string): string { - let index = 0; - let name = base; - while (this.isUsed(name)) { - index++; - name = `${base}_${index}`; - } - return name; - } -} diff --git a/packages/typegpu/src/resolutionCtx.ts b/packages/typegpu/src/resolutionCtx.ts index 5b3daa0067..800b2f50c3 100644 --- a/packages/typegpu/src/resolutionCtx.ts +++ b/packages/typegpu/src/resolutionCtx.ts @@ -1,5 +1,5 @@ import { isTgpuFn } from './core/function/tgpuFn.ts'; -import { getUniqueName, type Namespace, type NamespaceInternal } from './core/resolve/namespace.ts'; +import type { Namespace, NamespaceInternal } from './core/resolve/namespace.ts'; import { stitch } from './core/resolve/stitch.ts'; import { ConfigurableImpl } from './core/root/configurableImpl.ts'; import type { Configurable, ExperimentalTgpuRoot } from './core/root/rootTypes.ts'; @@ -12,10 +12,9 @@ import { type TgpuLazy, type TgpuSlot, } from './core/slot/slotTypes.ts'; -import { getAttributesString } from './data/attributes.ts'; -import { isData, undecorate, UnknownData } from './data/dataTypes.ts'; +import { isData, UnknownData } from './data/dataTypes.ts'; import { bool } from './data/numeric.ts'; -import { type ResolvedSnippet, snip, type Snippet } from './data/snippet.ts'; +import { type Origin, type ResolvedSnippet, snip, type Snippet } from './data/snippet.ts'; import { type BaseData, isPtr, isWgslArray, isWgslStruct, Void } from './data/wgslTypes.ts'; import { invariant, MissingSlotValueError, ResolutionError, WgslTypeError } from './errors.ts'; import { provideCtx, topLevelState } from './execMode.ts'; @@ -38,9 +37,11 @@ import { coerceToSnippet, concretize, numericLiteralToSnippet } from './tgsl/gen import type { ShaderGenerator } from './tgsl/shaderGenerator.ts'; import wgslGenerator from './tgsl/wgslGenerator.ts'; import type { + BlockScopeLayer, ExecMode, ExecState, FnToWgslOptions, + FunctionArgumentAccess, FunctionScopeLayer, ItemLayer, ItemStateStack, @@ -58,6 +59,8 @@ import { createIoSchema } from './core/function/ioSchema.ts'; import type { IOData } from './core/function/fnTypes.ts'; import { AutoStruct } from './data/autoStruct.ts'; import { EntryInputRouter } from './core/function/entryInputRouter.ts'; +import type { FunctionArgument } from './tgsl/shaderGenerator_members.ts'; +import { isValidIdentifier, sanitizePrimer } from './nameUtils.ts'; /** * Inserted into bind group entry definitions that belong @@ -98,6 +101,10 @@ class ItemStateStackImpl implements ItemStateStack { return this._stack.findLast((e) => e.type === 'functionScope'); } + get topBlockScope(): BlockScopeLayer | undefined { + return this._stack.findLast((e) => e.type === 'blockScope'); + } + pushItem() { this._itemDepth++; this._stack.push({ @@ -115,19 +122,19 @@ class ItemStateStackImpl implements ItemStateStack { pushFunctionScope( functionType: 'normal' | TgpuShaderStage, - args: Snippet[], - argAliases: Record, + argAccess: Record, returnType: BaseData | undefined, externalMap: Record, ): FunctionScopeLayer { const scope: FunctionScopeLayer = { type: 'functionScope', functionType, - args, - argAliases, + argAccess, returnType, externalMap, reportedReturnTypes: new Set(), + placeholderForVariable: new Map(), + modifiedVariables: new Set(), }; this._stack.push(scope); @@ -137,6 +144,7 @@ class ItemStateStackImpl implements ItemStateStack { pushBlockScope() { this._stack.push({ type: 'blockScope', + takenLocalIdentifiers: new Set(), declarations: new Map(), externals: new Map(), }); @@ -184,13 +192,9 @@ class ItemStateStackImpl implements ItemStateStack { const layer = this._stack[i]; if (layer?.type === 'functionScope') { - const arg = layer.args.find((a) => a.value === id); - if (arg !== undefined) { - return arg; - } - - if (layer.argAliases[id]) { - return layer.argAliases[id]; + const access = layer.argAccess[id]; + if (access) { + return access(); } const external = layer.externalMap[id]; @@ -218,6 +222,26 @@ class ItemStateStackImpl implements ItemStateStack { return undefined; } + isIdentifierTakenLocally(id: string): boolean { + for (let i = this._stack.length - 1; i >= 0; --i) { + const layer = this._stack[i]; + + if (layer?.type === 'functionScope') { + // Since functions cannot access resources from the calling scope, we + // return early here. + return false; + } + + if (layer?.type === 'blockScope') { + if (layer.takenLocalIdentifiers.has(id)) { + return true; + } + } + } + + return false; + } + defineBlockVariable(id: string, snippet: Snippet): void { if (snippet.dataType === UnknownData) { throw Error(`Tried to define variable '${id}' of unknown type`); @@ -311,6 +335,39 @@ interface FixedBindingConfig { resource: object; } +function createArgument( + name: string, + type: BaseData, + origin: Origin = 'argument', +): FunctionArgument { + let used = false; + + return { + name, + access: () => { + used = true; + return snip(name, type, origin); + }, + decoratedType: type, + get used() { + return used; + }, + }; +} + +function createArgumentPropAccess( + argAccess: FunctionArgumentAccess, + prop: string, +): FunctionArgumentAccess { + return () => { + const argSnippet = argAccess(); + if (!argSnippet) { + return undefined; + } + return accessProp(argSnippet, prop); + }; +} + export class ResolutionCtxImpl implements ResolutionCtx { readonly #namespaceInternal: NamespaceInternal; @@ -347,6 +404,11 @@ export class ResolutionCtxImpl implements ResolutionCtx { public readonly enableExtensions: WgslExtension[] | undefined; public expectedType: BaseData | undefined; + /** + * A counter used to generate unique identifiers for globally-scoped definitions in the 'random' strategy. + */ + #lastUniqueId = 0; + constructor(opts: ResolutionCtxImplOptions) { this.enableExtensions = opts.enableExtensions; this.gen = opts.shaderGenerator ?? wgslGenerator; @@ -354,12 +416,42 @@ export class ResolutionCtxImpl implements ResolutionCtx { this.#namespaceInternal = opts.namespace[$internal]; } - getUniqueName(resource: object): string { - return getUniqueName(this.#namespaceInternal, resource); + isIdentifierTaken(name: string): boolean { + return ( + this.#namespaceInternal.takenGlobalIdentifiers.has(name) || + this._itemStateStack.isIdentifierTakenLocally(name) + ); + } + + makeUniqueIdentifier(primer: string = 'item', scope: 'global' | 'block'): string { + if (scope === 'block' && isValidIdentifier(primer) && !this.isIdentifierTaken(primer)) { + // Preserving local definitions as they are, provided they are valid and not already taken. + this.reserveIdentifier(primer, 'block'); + return primer; + } + + const base = sanitizePrimer(primer); + let index = 0; + const random = this.#namespaceInternal.strategy === 'random'; + let name = random ? `${base}_${this.#lastUniqueId++}` : base; + while (this.isIdentifierTaken(name)) { + name = random ? `${base}_${this.#lastUniqueId++}` : `${base}_${++index}`; + } + + this.reserveIdentifier(name, scope); + return name; } - makeNameValid(name: string): string { - return this.#namespaceInternal.nameRegistry.makeValid(name); + reserveIdentifier(name: string, scope: 'global' | 'block'): void { + if (scope === 'block') { + const blockScope = this._itemStateStack.topBlockScope; + if (blockScope) { + blockScope.takenLocalIdentifiers.add(name); + return; + } + // Fall through if no block scope is present, treating as global. + } + this.#namespaceInternal.takenGlobalIdentifiers.add(name); } get pre(): string { @@ -413,12 +505,10 @@ export class ResolutionCtxImpl implements ResolutionCtx { } pushBlockScope() { - this.#namespaceInternal.nameRegistry.pushBlockScope(); this._itemStateStack.pushBlockScope(); } popBlockScope() { - this.#namespaceInternal.nameRegistry.popBlockScope(); this._itemStateStack.pop('blockScope'); } @@ -438,28 +528,29 @@ export class ResolutionCtxImpl implements ResolutionCtx { return this.#logGenerator.logResources; } - fnToWgsl(options: FnToWgslOptions): { head: Wgsl; body: Wgsl; returnType: BaseData } { - let fnScopePushed = false; - + fnToWgsl(options: FnToWgslOptions): { code: string; returnType: BaseData } { try { - this.#namespaceInternal.nameRegistry.pushFunctionScope(); - const args: Snippet[] = []; - const argAliases: [string, Snippet][] = []; - // For entry functions: collect pending header entries to be filtered after body generation. - const pendingHeaderEntries: { argName: string; header: string }[] = []; + const scope = this._itemStateStack.pushFunctionScope( + options.functionType, + {}, + options.returnType, + options.externalMap, + ); + // Pushing a block scope as well, so that any identifiers declared at this point will be scoped to the function body. + this._itemStateStack.pushBlockScope(); + + const args: FunctionArgument[] = []; if (options.entryInput) { const { dataSchema, positionalArgs } = options.entryInput; const firstParam = options.params[0]; - const structArgName = this.makeNameValid('_arg_0'); - const structArg = dataSchema ? snip(structArgName, dataSchema, 'argument') : undefined; + const structArg = dataSchema + ? createArgument(this.makeUniqueIdentifier('_arg_0', 'block'), dataSchema) + : undefined; + if (structArg) { args.push(structArg); - pendingHeaderEntries.push({ - argName: structArgName, - header: `${structArgName}: ${this.resolve(dataSchema).value}`, - }); } if (firstParam?.type === FuncParameterType.destructuredObject) { @@ -467,45 +558,31 @@ export class ResolutionCtxImpl implements ResolutionCtx { for (const { name, alias } of firstParam.props) { const argInfo = positionalArgs.find((a) => a.schemaKey === name); if (argInfo) { - const argName = this.makeNameValid(alias); - const argSnippet = snip(argName, argInfo.type, 'argument'); - args.push(argSnippet); - argAliases.push([alias, argSnippet]); - pendingHeaderEntries.push({ - argName, - header: `${getAttributesString(argInfo.type)}${argName}: ${this.resolve(undecorate(argInfo.type)).value}`, - }); + const arg = createArgument(this.makeUniqueIdentifier(alias, 'block'), argInfo.type); + args.push(arg); + scope.argAccess[alias] = arg.access; } else if (structArg) { - const propSnippet = accessProp(structArg, name); - if (propSnippet) { - argAliases.push([alias, propSnippet]); - } + scope.argAccess[alias] = createArgumentPropAccess(structArg.access, name); } } } else if (firstParam?.type === FuncParameterType.identifier) { // Create named arg snippets, then a proxy for property access routing. - const proxyEntries: Array<{ schemaKey: string; argName: string; type: BaseData }> = []; + const proxyEntries: Array<{ schemaKey: string; arg: FunctionArgumentAccess }> = []; for (const a of positionalArgs) { - const argName = this.makeNameValid(`_arg_${a.schemaKey}`); - const s = snip(argName, a.type, 'argument'); - args.push(s); - proxyEntries.push({ schemaKey: a.schemaKey, argName, type: a.type }); - pendingHeaderEntries.push({ - argName, - header: `${getAttributesString(a.type)}${argName}: ${this.resolve(undecorate(a.type)).value}`, - }); + const argName = this.makeUniqueIdentifier(`_arg_${a.schemaKey}`, 'block'); + const arg = createArgument(argName, a.type); + args.push(arg); + proxyEntries.push({ schemaKey: a.schemaKey, arg: arg.access }); } - const router = new EntryInputRouter(structArgName, dataSchema, proxyEntries); - argAliases.push([firstParam.name, snip(firstParam.name, router, 'argument')]); + const router = new EntryInputRouter(structArg?.access, proxyEntries); + scope.argAccess[firstParam.name] = () => snip('N/A', router, 'argument'); } else { // No first param: push positional args with schema key names. for (const a of positionalArgs) { - const argName = this.makeNameValid(`_arg_${a.schemaKey}`); - args.push(snip(argName, a.type, 'argument')); - pendingHeaderEntries.push({ - argName, - header: `${getAttributesString(a.type)}${argName}: ${this.resolve(undecorate(a.type)).value}`, - }); + const argName = this.makeUniqueIdentifier(`_arg_${a.schemaKey}`, 'block'); + const arg = createArgument(argName, a.type); + args.push(arg); + scope.argAccess[argName] = arg.access; } } } else { @@ -528,22 +605,25 @@ export class ResolutionCtxImpl implements ResolutionCtx { switch (astParam?.type) { case FuncParameterType.identifier: { - const rawName = astParam.name; - const snippet = snip(this.makeNameValid(rawName), argType, origin); - args.push(snippet); - if (snippet.value !== rawName) { - argAliases.push([rawName, snippet]); - } + const arg = createArgument( + this.makeUniqueIdentifier(astParam.name, 'block'), + argType, + origin, + ); + args.push(arg); + scope.argAccess[astParam.name] = arg.access; break; } case FuncParameterType.destructuredObject: { - const objSnippet = snip(`_arg_${i}`, argType, origin); - args.push(objSnippet); - argAliases.push( - ...astParam.props.map( - ({ name, alias }) => [alias, accessProp(objSnippet, name)] as [string, Snippet], - ), + const objArg = createArgument( + this.makeUniqueIdentifier(`_arg_${i}`, 'block'), + argType, + origin, ); + args.push(objArg); + for (const { name, alias } of astParam.props) { + scope.argAccess[alias] = createArgumentPropAccess(objArg.access, name); + } break; } case undefined: { @@ -551,84 +631,86 @@ export class ResolutionCtxImpl implements ResolutionCtx { // If we're not using an auto-struct, it's not going to // have any properties anyway. if (!(argType instanceof AutoStruct)) { - args.push(snip(`_arg_${i}`, argType, origin)); + args.push({ + name: this.makeUniqueIdentifier(`_arg_${i}`, 'block'), + access: () => { + throw new Error( + `Unreachable: Accessing an argument that wasn't named in the function signature`, + ); + }, + decoratedType: argType, + used: false, + }); } } } } } - const scope = this._itemStateStack.pushFunctionScope( - options.functionType, - args, - Object.fromEntries(argAliases), - options.returnType, - options.externalMap, - ); - fnScopePushed = true; + let returnType: BaseData | undefined; - const body = this.gen.functionDefinition(options.body); - - let returnType = options.returnType; - if (returnType instanceof AutoStruct) { - // We're expecting an "auto" return type, so if there were structs returned, - // we accept the struct, otherwise we let the rest of the code unify on a - // primitive type. - if (isWgslStruct(scope.reportedReturnTypes.values().next().value)) { - returnType = returnType.completeStruct; - } else { - returnType = undefined; - } - } + const code = this.gen.functionDefinition({ + functionType: options.functionType, + args, + body: options.body, + determineReturnType: () => { + if (returnType) { + // Already determined + return returnType; + } - if (!returnType) { - const returnTypes = [...scope.reportedReturnTypes]; - if (returnTypes.length === 0) { - returnType = Void; - } else { - const conversion = getBestConversion(returnTypes); - if (conversion && !conversion.hasImplicitConversions) { - returnType = conversion.targetType; + returnType = options.returnType; + if (returnType instanceof AutoStruct) { + // We're expecting an "auto" return type, so if there were structs returned, + // we accept the struct, otherwise we let the rest of the code unify on a + // primitive type. + if (isWgslStruct(scope.reportedReturnTypes.values().next().value)) { + returnType = returnType.completeStruct; + } else { + returnType = undefined; + } } - } - if (!returnType) { - throw new Error( - `Expected function to have a single return type, got [${returnTypes.join( - ', ', - )}]. Cast explicitly to the desired type.`, - ); - } + if (!returnType) { + const returnTypes = [...scope.reportedReturnTypes]; + if (returnTypes.length === 0) { + returnType = Void; + } else { + const conversion = getBestConversion(returnTypes); + if (conversion && !conversion.hasImplicitConversions) { + returnType = conversion.targetType; + } + } - returnType = concretize(returnType); + if (!returnType) { + throw new Error( + `Expected function to have a single return type, got [${returnTypes.join( + ', ', + )}]. Cast explicitly to the desired type.`, + ); + } - if (options.functionType === 'vertex' || options.functionType === 'fragment') { - returnType = createIoSchema(returnType as IOData); - } - } + returnType = concretize(returnType); - if (options.entryInput) { - const headerParts = pendingHeaderEntries - .filter(({ argName }) => isArgUsedInBody(argName, body)) - .map(({ header }) => header); - const argList = headerParts.join(', '); - const returnStr = - returnType.type !== 'void' - ? `-> ${getAttributesString(returnType)}${this.resolve(returnType).value} ` - : ''; - return { head: `(${argList}) ${returnStr}`, body, returnType }; + if (options.functionType === 'vertex' || options.functionType === 'fragment') { + returnType = createIoSchema(returnType as IOData); + } + } + return returnType; + }, + }); + + if (!returnType) { + throw new Error(`Failed to determine return type`); } return { - head: resolveFunctionHeader(this, args, returnType), - body, + code, returnType, }; } finally { - if (fnScopePushed) { - this._itemStateStack.pop('functionScope'); - } - this.#namespaceInternal.nameRegistry.popFunctionScope(); + this._itemStateStack.pop('blockScope'); + this._itemStateStack.pop('functionScope'); } } @@ -1079,17 +1161,3 @@ export function resolve(item: Wgsl, options: ResolutionCtxImplOptions): Resoluti logResources: ctx.logResources, }; } - -function isArgUsedInBody(argName: string, body: string): boolean { - return new RegExp(`\\b${argName}\\b`).test(body); -} - -function resolveFunctionHeader(ctx: ResolutionCtx, args: Snippet[], returnType: BaseData) { - const argList = args - .map((arg) => `${arg.value}: ${ctx.resolve(arg.dataType as BaseData).value}`) - .join(', '); - - return returnType.type !== 'void' - ? `(${argList}) -> ${getAttributesString(returnType)}${ctx.resolve(returnType).value} ` - : `(${argList}) `; -} diff --git a/packages/typegpu/src/tgsl/accessProp.ts b/packages/typegpu/src/tgsl/accessProp.ts index b264a154ba..3410d3e383 100644 --- a/packages/typegpu/src/tgsl/accessProp.ts +++ b/packages/typegpu/src/tgsl/accessProp.ts @@ -10,7 +10,7 @@ import { } from '../data/dataTypes.ts'; import { abstractInt, bool, f16, f32, i32, u32 } from '../data/numeric.ts'; import { derefSnippet } from '../data/ref.ts'; -import { isEphemeralSnippet, snip, type Snippet } from '../data/snippet.ts'; +import { isEphemeralSnippet, isSnippet, snip, type Snippet } from '../data/snippet.ts'; import { vec2b, vec2f, @@ -160,7 +160,14 @@ export function accessProp(target: Snippet, propName: string): Snippet | undefin } if (target.dataType instanceof EntryInputRouter) { - return target.dataType.accessProp(propName); + const result = target.dataType.accessProp(propName); + if (isSnippet(result)) { + return result; + } + if (result) { + return accessProp(result.target, result.prop); + } + return undefined; } if (isPtr(target.dataType)) { diff --git a/packages/typegpu/src/tgsl/conversion.ts b/packages/typegpu/src/tgsl/conversion.ts index f410e53e6d..e01ce0700b 100644 --- a/packages/typegpu/src/tgsl/conversion.ts +++ b/packages/typegpu/src/tgsl/conversion.ts @@ -241,6 +241,10 @@ function applyActionToSnippet( targetType: BaseData, ): Snippet { if (action.action === 'none') { + if (targetType === snippet.dataType) { + return snippet; + } + return snip( snippet.value, targetType, @@ -308,7 +312,7 @@ export function convertToCommonType( if ((TEST || DEV) && verbose && conversion.hasImplicitConversions) { console.warn( `Implicit conversions from [\n${values - .map((v) => ` ${v.value}: ${safeStringify(v.dataType)}`) + .map((v) => ` ${ctx.resolveSnippet(v).value}: ${safeStringify(v.dataType)}`) .join(',\n')}\n] to ${conversion.targetType.type} are supported, but not recommended. Consider using explicit conversions instead.`, ); diff --git a/packages/typegpu/src/tgsl/shaderGenerator.ts b/packages/typegpu/src/tgsl/shaderGenerator.ts index e482b03cc8..adde48bf00 100644 --- a/packages/typegpu/src/tgsl/shaderGenerator.ts +++ b/packages/typegpu/src/tgsl/shaderGenerator.ts @@ -1,7 +1,7 @@ -import type { Block } from 'tinyest'; import type { BaseData } from '../data/wgslTypes.ts'; import type { GenerationCtx } from './generationHelpers.ts'; import type { ResolvedSnippet, Snippet } from '../data/snippet.ts'; +import type { FunctionDefinitionOptions } from './shaderGenerator_members.ts'; /** * **NOTE: This is an unstable API and may change in the future.** @@ -12,7 +12,7 @@ import type { ResolvedSnippet, Snippet } from '../data/snippet.ts'; export interface ShaderGenerator { initGenerator(ctx: GenerationCtx): void; - functionDefinition(body: Block): string; + functionDefinition(options: FunctionDefinitionOptions): string; typeInstantiation(schema: BaseData, args: readonly Snippet[]): ResolvedSnippet; typeAnnotation(schema: BaseData): string; } diff --git a/packages/typegpu/src/tgsl/shaderGenerator_members.ts b/packages/typegpu/src/tgsl/shaderGenerator_members.ts index 1eb11ae0c9..38ad393c2d 100644 --- a/packages/typegpu/src/tgsl/shaderGenerator_members.ts +++ b/packages/typegpu/src/tgsl/shaderGenerator_members.ts @@ -1,6 +1,18 @@ +import type { Block } from 'tinyest'; +import type { BaseData } from '../data/wgslTypes.ts'; +import type { FunctionArgument, TgpuShaderStage } from '../types.ts'; + export { UnknownData } from '../data/dataTypes.ts'; // types -export type { ResolutionCtx } from '../types.ts'; +export type { ResolutionCtx, FunctionArgument } from '../types.ts'; export type { Snippet } from '../data/snippet.ts'; export type { Origin } from '../data/snippet.ts'; + +export interface FunctionDefinitionOptions { + readonly functionType: 'normal' | TgpuShaderStage; + readonly args: readonly FunctionArgument[]; + readonly body: Block; + + determineReturnType(): BaseData; +} diff --git a/packages/typegpu/src/tgsl/wgslGenerator.ts b/packages/typegpu/src/tgsl/wgslGenerator.ts index 38d2a2ee44..c020422cae 100644 --- a/packages/typegpu/src/tgsl/wgslGenerator.ts +++ b/packages/typegpu/src/tgsl/wgslGenerator.ts @@ -41,9 +41,9 @@ import { accessProp } from './accessProp.ts'; import type { ShaderGenerator } from './shaderGenerator.ts'; import { resolveData } from '../core/resolve/resolveData.ts'; import { createPtrFromOrigin, implicitFrom, ptrFn } from '../data/ptr.ts'; -import { RefOperator } from '../data/ref.ts'; +import { _ref, RefOperator } from '../data/ref.ts'; import { constant } from '../core/constant/tgpuConstant.ts'; -import { UnrollableIterable } from '../core/unroll/tgpuUnroll.ts'; +import { unroll, UnrollableIterable } from '../core/unroll/tgpuUnroll.ts'; import { isGenericFn } from '../core/function/tgpuFn.ts'; import type { AnyFn } from '../core/function/fnTypes.ts'; import { AutoStruct } from '../data/autoStruct.ts'; @@ -51,6 +51,8 @@ import { mathToStd } from './math.ts'; import type { ExternalMap } from '../core/resolve/externals.ts'; import * as forOfUtils from './forOfUtils.ts'; import { isTgpuRange } from '../std/range.ts'; +import type { FunctionDefinitionOptions } from './shaderGenerator_members.ts'; +import { getAttributesString } from '../data/attributes.ts'; const { NodeTypeCatalog: NODE } = tinyest; @@ -239,8 +241,12 @@ ${this.ctx.pre}}`; } } + public _blockStatement(block: tinyest.Block, externalMap?: ExternalMap): string { + return `${this.ctx.pre}${this._block(block, externalMap)}`; + } + public refVariable(id: string, dataType: wgsl.StorableData): string { - const varName = this.ctx.makeNameValid(id); + const varName = this.ctx.makeUniqueIdentifier(id, 'block'); const ptrType = ptrFn(dataType); const snippet = snip( new RefOperator(snip(varName, dataType, 'function'), ptrType), @@ -252,7 +258,7 @@ ${this.ctx.pre}}`; } public blockVariable( - varType: 'var' | 'let' | 'const', + varType: 'var' | 'let' | 'const' | undefined, id: string, dataType: wgsl.BaseData | UnknownData, origin: Origin, @@ -278,14 +284,22 @@ ${this.ctx.pre}}`; varOrigin = 'runtime'; } - const snippet = snip(this.ctx.makeNameValid(id), dataType, /* origin */ varOrigin); + const snippet = snip( + this.ctx.makeUniqueIdentifier(id, 'block'), + dataType, + /* origin */ varOrigin, + ); this.ctx.defineVariable(id, snippet); return snippet; } + /** + * Creates a variable declaration string. + * `keyword` may be a placeholder filled in later. + */ protected emitVarDecl( pre: string, - keyword: 'var' | 'let' | 'const', + keyword: string, name: string, _dataType: wgsl.BaseData | UnknownData, rhsStr: string, @@ -450,6 +464,8 @@ ${this.ctx.pre}}`; ); } + this.tryMarkModified(lhs); + // Compound assignment operators are okay, e.g. +=, -=, *=, /=, ... if ( op === '=' && @@ -489,6 +505,8 @@ ${this.ctx.pre}}`; const argExpr = this._expression(arg); const argStr = this.ctx.resolve(argExpr.value, argExpr.dataType).value; + this.tryMarkModified(arg); + // Result of an operation, so not a reference to anything return snip(`${argStr}${op}`, argExpr.dataType, /* origin */ 'runtime'); } @@ -673,6 +691,10 @@ ${this.ctx.pre}}`; ); } + if ((callee.value === _ref || callee.value === unroll) && argNodes[0]) { + this.tryMarkModified(argNodes[0]); + } + if (isGPUCallable(callee.value)) { const callable = callee.value[$gpuCallable]; const strictSignature = callable.strictSignature; @@ -887,8 +909,44 @@ ${this.ctx.pre}}`; assertExhaustive(expression); } - public functionDefinition(body: tinyest.Block): string { - return this._block(body); + public functionDefinition(options: FunctionDefinitionOptions): string { + // Function body + let body = this._block(options.body); + const scope = this.ctx.topFunctionScope; + invariant(scope, 'Expected function scope to be present'); + const replacements = Object.fromEntries( + scope.placeholderForVariable + .entries() + .map(([variable, placeholder]) => [ + placeholder, + scope.modifiedVariables.has(variable) ? 'var' : 'let', + ]), + ); + if (Object.keys(replacements).length > 0) { + const regex = new RegExp(Object.keys(replacements).join('|'), 'gi'); + body = body.replace( + regex, + (match) => replacements[match as keyof typeof replacements] ?? '#ERR', + ); + } + + // Function header + const returnType = options.determineReturnType(); + + const argList = options.args + // Stripping out unused arguments in entry functions + .filter((arg) => arg.used || options.functionType === 'normal') + .map((arg) => { + return `${getAttributesString(arg.decoratedType)}${arg.name}: ${this.ctx.resolve(arg.decoratedType).value}`; + }) + .join(', '); + + const head = + returnType.type !== 'void' + ? `(${argList}) -> ${getAttributesString(returnType)}${this.ctx.resolve(returnType).value} ` + : `(${argList}) `; + + return `${head}${body}`; } /** @@ -1017,7 +1075,7 @@ Try 'return ${typeStr}(${str});' instead. return this._statement(node); } // simplify 'if (true) {A} else {B}' to '{A}' - return `${this.ctx.pre}${this._block(blockifySingleStatement(node))}`; + return this._blockStatement(blockifySingleStatement(node)); } const consequent = this._block(blockifySingleStatement(consNode)); @@ -1033,7 +1091,7 @@ ${this.ctx.pre}else ${alternate}`; } if (statement[0] === NODE.let || statement[0] === NODE.const) { - let varType: 'var' | 'let' | 'const' = 'var'; + let varType: 'var' | 'let' | 'const' | undefined; const [stmtType, rawId, rawValue] = statement; const eq = rawValue !== undefined ? this._expression(rawValue) : undefined; @@ -1105,6 +1163,7 @@ ${this.ctx.pre}else ${alternate}`; // If what we're assigning is something preceded by `&`, then it's a value // created using `d.ref()`. Otherwise, it's an implicit pointer dataType = implicitFrom(dataType as wgsl.Ptr); + this.tryMarkModified(rawValue); } } } else { @@ -1140,9 +1199,18 @@ ${this.ctx.pre}else ${alternate}`; const snippet = this.blockVariable(varType, rawId, concretize(dataType), eq.origin); const rhsSnippet = tryConvertSnippet(this.ctx, eq, dataType, false); const rhsStr = this.ctx.resolve(rhsSnippet.value, rhsSnippet.dataType).value; + + let emittedVarType: string | undefined = varType; + if (emittedVarType === undefined) { + const scope = this.ctx.topFunctionScope; + invariant(scope, `Expected function scope to be present for ${rawId}`); + emittedVarType = `#VAR_${scope.placeholderForVariable.size}#`; + scope.placeholderForVariable.set(snippet, emittedVarType); + } + return this.emitVarDecl( this.ctx.pre, - varType, + emittedVarType, snippet.value as string, concretize(dataType), rhsStr, @@ -1150,7 +1218,7 @@ ${this.ctx.pre}else ${alternate}`; } if (statement[0] === NODE.block) { - return `${this.ctx.pre}${this._block(statement)}`; + return this._blockStatement(statement); } if (statement[0] === NODE.for) { @@ -1201,6 +1269,8 @@ ${this.ctx.pre}else ${alternate}`; throw new WgslTypeError('Only `for (const ... of ... )` loops are supported'); } + this.tryMarkModified(iterable); // overly-defensive, but let's not tempt fate + let ctxIndent = false; const prevUnrollingFlag = this.#unrolling; @@ -1246,12 +1316,9 @@ ${this.ctx.pre}else ${alternate}`; const blocks = elements.map( (e, i) => - `${this.ctx.pre}// unrolled iteration #${i}\n${this.ctx.pre}${this._block( - blockified, - { - [originalLoopVarName]: e, - }, - )}`, + `${this.ctx.pre}// unrolled iteration #${i}\n${this._blockStatement(blockified, { + [originalLoopVarName]: e, + })}`, ); return blocks.join('\n'); @@ -1259,7 +1326,7 @@ ${this.ctx.pre}else ${alternate}`; this.#unrolling = false; - const index = this.ctx.makeNameValid('i'); + const index = this.ctx.makeUniqueIdentifier('i', 'block'); const forHeaderStr = stitch`${this.ctx.pre}for (var ${index} = ${range.start}; ${index} ${range.comparison} ${range.end}; ${index} += ${range.step})`; @@ -1272,7 +1339,7 @@ ${this.ctx.pre}else ${alternate}`; } else { this.ctx.indent(); ctxIndent = true; - const loopVarName = this.ctx.makeNameValid(originalLoopVarName); + const loopVarName = this.ctx.makeUniqueIdentifier(originalLoopVarName, 'block'); const elementSnippet = forOfUtils.getElementSnippet( iterableSnippet, snip(index, u32, 'runtime'), @@ -1286,7 +1353,7 @@ ${this.ctx.pre}else ${alternate}`; false, )};`; - bodyStr = `{\n${loopVarDeclStr}\n${this.ctx.pre}${this._block(blockified, { + bodyStr = `{\n${loopVarDeclStr}\n${this._blockStatement(blockified, { [originalLoopVarName]: snip(loopVarName, elementType, elementSnippet.origin), })}\n`; this.ctx.dedent(); @@ -1323,6 +1390,32 @@ ${this.ctx.pre}else ${alternate}`; // oxlint-disable-next-line typescript/no-base-to-string return resolved ? `${this.ctx.pre}${resolved};` : ''; } + + /** + * Attempts a member access lookup to mark a variable as modified. + * @example + * // given `let a; a = 1;` + * tryMarkModified('a') // `a` is marked in the function scope + * + * // given `const obj; obj.prop = 1;` + * tryMarkModified('obj.prop') // `obj` is marked in the function scope + * + * // given `this.buffer.$;` + * tryMarkModified('this.buffer.$') // `this` is not marked, since there is no placeholder for it + */ + private tryMarkModified(expr?: tinyest.Expression) { + if (!expr) { + return; + } + const maybeObject = extractObject(expr); + if (maybeObject !== undefined) { + const snippet = this.ctx.getById(maybeObject); + const scope = this.ctx.topFunctionScope; + if (snippet && scope && scope.placeholderForVariable.has(snippet)) { + scope.modifiedVariables.add(snippet); + } + } + } } function assertExhaustive(value: never): never { @@ -1349,5 +1442,18 @@ function blockifySingleStatement(statement: tinyest.Statement): tinyest.Block { : statement; } +function extractObject(expr: tinyest.Expression): string | undefined { + let object = expr; + while ( + Array.isArray(object) && + (object[0] === NODE.memberAccess || object[0] === NODE.indexAccess) + ) { + object = object[1]; + } + if (typeof object === 'string') { + return object; + } +} + const wgslGenerator: WgslGenerator = new WgslGenerator(); export default wgslGenerator; diff --git a/packages/typegpu/src/types.ts b/packages/typegpu/src/types.ts index 1c92f8a43f..0d5e488bb3 100644 --- a/packages/typegpu/src/types.ts +++ b/packages/typegpu/src/types.ts @@ -99,11 +99,19 @@ export type ItemLayer = { usedSlots: Set>; }; +export type FunctionArgumentAccess = () => Snippet | undefined; + +export interface FunctionArgument { + name: string; + access: FunctionArgumentAccess; + decoratedType: BaseData; + used: boolean; +} + export type FunctionScopeLayer = { type: 'functionScope'; functionType: 'normal' | 'compute' | 'vertex' | 'fragment'; - args: Snippet[]; - argAliases: Record; + argAccess: Record; externalMap: Record; /** * The return type of the function. If undefined, the type should be inferred @@ -114,6 +122,14 @@ export type FunctionScopeLayer = { * All types used in `return` statements. */ reportedReturnTypes: Set; + /** + * Maps variables to their modifier placeholders + */ + placeholderForVariable: Map; + /** + * Local variables that need `var` modifier. + */ + modifiedVariables: Set; }; export type SlotBindingLayer = { @@ -123,6 +139,7 @@ export type SlotBindingLayer = { export type BlockScopeLayer = { type: 'blockScope'; + takenLocalIdentifiers: Set; declarations: Map; externals: Map; }; @@ -132,14 +149,14 @@ export type StackLayer = ItemLayer | SlotBindingLayer | FunctionScopeLayer | Blo export interface ItemStateStack { readonly itemDepth: number; readonly topItem: ItemLayer; + readonly topBlockScope: BlockScopeLayer | undefined; readonly topFunctionScope: FunctionScopeLayer | undefined; pushItem(): void; pushSlotBindings(pairs: SlotValuePair[]): void; pushFunctionScope( functionType: 'normal' | TgpuShaderStage, - args: Snippet[], - argAliases: Record, + argAccess: Record, /** * The return type of the function. If undefined, the type should be inferred * from the implementation (relevant for shellless functions). @@ -305,8 +322,7 @@ export interface ResolutionCtx { resolveSnippet(snippet: Snippet): ResolvedSnippet; fnToWgsl(options: FnToWgslOptions): { - head: Wgsl; - body: Wgsl; + code: string; returnType: BaseData; }; @@ -324,8 +340,27 @@ export interface ResolutionCtx { */ withRenamed(item: object, name: string | undefined, callback: () => T): T; - getUniqueName(resource: object): string; - makeNameValid(name: string): string; + /** + * @param primer The basis for the unique identifier. Depending on the strategy, or + * the names already taken, this may be modified to ensure uniqueness. + * @param scope The scope in which to generate the identifier. 'global' means + * the identifier is meant to be unique across the entire program, while + * 'block' means it cannot shadow any existing identifiers visible from + * within the current block. After the block is popped, any identifiers + * defined within it are no longer visible. + * @returns an identifier that is unique within the given scope + */ + makeUniqueIdentifier(primer: string | undefined, scope: 'global' | 'block'): string; + + isIdentifierTaken(name: string): boolean; + + /** + * Makes sure the given identifier cannot be generated by {@link makeUniqueIdentifier} + * within the given scope. + * @param name The name to reserve + * @param scope See {@link makeUniqueIdentifier} for a description of the scope parameter. + */ + reserveIdentifier(name: string, scope: 'global' | 'block'): void; } /** diff --git a/packages/typegpu/tests/accessor.test.ts b/packages/typegpu/tests/accessor.test.ts index 851263eb88..12c83520da 100644 --- a/packages/typegpu/tests/accessor.test.ts +++ b/packages/typegpu/tests/accessor.test.ts @@ -162,9 +162,9 @@ describe('tgpu.accessor', () => { } fn main() { - var color = vec3f(1, 0, 0); + let color = vec3f(1, 0, 0); let color2 = (&redUniform); - var color3 = getColor(); + let color3 = getColor(); const colorX = 1f; let color2X = redUniform.x; let color3X = getColor().x; @@ -234,7 +234,7 @@ describe('tgpu.accessor', () => { } fn main() { - var pixel = getPixel(0i, 0i); + let pixel = getPixel(0i, 0i); }" `); }); @@ -276,8 +276,8 @@ describe('tgpu.accessor', () => { } fn main() { - var foo = getColor(); - var bar = getColor_1(); + let foo = getColor(); + let bar = getColor_1(); }" `); }); @@ -309,7 +309,7 @@ describe('tgpu.accessor', () => { } fn main() { - var foo = getColor(); + let foo = getColor(); }" `); }); @@ -358,7 +358,7 @@ describe('tgpu.accessor', () => { } fn main() { - var pixel = getPixel(0i, 0i); + let pixel = getPixel(0i, 0i); }" `); }); diff --git a/packages/typegpu/tests/array.test.ts b/packages/typegpu/tests/array.test.ts index 0eb30bbd72..fccd3ba623 100644 --- a/packages/typegpu/tests/array.test.ts +++ b/packages/typegpu/tests/array.test.ts @@ -184,7 +184,7 @@ describe('array', () => { expect(tgpu.resolve([testFunction])).toMatchInlineSnapshot(` "fn testFunction() { - var defaultValue = array, 2>(); + let defaultValue = array, 2>(); }" `); }); @@ -207,12 +207,12 @@ describe('array', () => { expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` "fn f(arr: array) { - var clone = arr; + let clone = arr; } fn testFn() { - var myArray = array(10u); - var myClone = myArray; + let myArray = array(10u); + let myClone = myArray; f(myArray); return; }" @@ -230,8 +230,8 @@ describe('array', () => { expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` "fn testFn() { - var myArrays = array, 1>(array(10i)); - var myClone = myArrays[0i]; + let myArrays = array, 1>(array(10i)); + let myClone = myArrays[0i]; return; }" `); @@ -246,7 +246,7 @@ describe('array', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { - var arr = array(6f, 7f); + let arr = array(6f, 7f); return; }" `); @@ -270,11 +270,11 @@ describe('array', () => { "fn f(v: vec4f) { var v2 = vec4f(3); let v3 = (&v2); - var arr = array(v, v2, (*v3)); + let arr = array(v, v2, (*v3)); } fn main() { - var v1 = vec4f(7); + let v1 = vec4f(7); f(v1); return; }" @@ -290,7 +290,7 @@ describe('array', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { - var arr = array(5f, 6.7f, 8f); + let arr = array(5f, 6.7f, 8f); return; }" `); @@ -303,7 +303,7 @@ describe('array', () => { expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` "fn foo() { - var result = array(); + let result = array(); }" `); }); @@ -315,7 +315,7 @@ describe('array', () => { expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` "fn foo() { - var result = array(); + let result = array(); }" `); }); @@ -350,7 +350,7 @@ describe('array', () => { expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` "fn foo() { - var result = array(1f, 2f, 3f, 4f); + let result = array(1f, 2f, 3f, 4f); }" `); }); @@ -362,7 +362,7 @@ describe('array', () => { expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` "fn foo() { - var result = array(4f, 3f, 2f, 1f); + let result = array(4f, 3f, 2f, 1f); }" `); }); @@ -376,7 +376,7 @@ describe('array', () => { expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` "fn foo() { - var result = array(4f, 3f, 2f, 1f); + let result = array(4f, 3f, 2f, 1f); }" `); }); @@ -392,7 +392,7 @@ describe('array', () => { expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` "fn foo() { - var result = array(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f); + let result = array(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f); }" `); }); @@ -439,7 +439,7 @@ describe('array', () => { expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` "fn foo(n: u32) { const m = 1u; - var result = array(1u, n, m); + let result = array(1u, n, m); }" `); }); diff --git a/packages/typegpu/tests/computePipeline.test.ts b/packages/typegpu/tests/computePipeline.test.ts index 6fadc72872..3cbea14d08 100644 --- a/packages/typegpu/tests/computePipeline.test.ts +++ b/packages/typegpu/tests/computePipeline.test.ts @@ -453,7 +453,7 @@ describe('TgpuComputePipeline', () => { enable subgroups; @compute @workgroup_size(1) fn fn_1() { - var a = array(); + let a = array(); }" `); }); diff --git a/packages/typegpu/tests/indent.test.ts b/packages/typegpu/tests/indent.test.ts index f3e7d4ef7d..3430183cde 100644 --- a/packages/typegpu/tests/indent.test.ts +++ b/packages/typegpu/tests/indent.test.ts @@ -28,8 +28,8 @@ describe('indents', () => { } fn updateParicle(particle: Particle, gravity: vec3f, deltaTime: f32) -> Particle { - var newVelocity = ((particle.velocity * gravity) * deltaTime); - var newPosition = (particle.position + (newVelocity * deltaTime)); + let newVelocity = ((particle.velocity * gravity) * deltaTime); + let newPosition = (particle.position + (newVelocity * deltaTime)); return Particle(newPosition, newVelocity); }" `); @@ -90,8 +90,8 @@ describe('indents', () => { @group(0) @binding(0) var systemData: SystemData; fn updateParicle(particle: Particle, gravity: vec3f, deltaTime: f32) -> Particle { - var newVelocity = ((particle.velocity * gravity) * deltaTime); - var newPosition = (particle.position + (newVelocity * deltaTime)); + let newVelocity = ((particle.velocity * gravity) * deltaTime); + let newPosition = (particle.position + (newVelocity * deltaTime)); return Particle(newPosition, newVelocity); } @@ -207,9 +207,9 @@ describe('indents', () => { fn updateParticle(particle: Particle, gravity: vec3f, deltaTime: f32) -> Particle { let density = getDensityAt(particle.physics.position); - var force = (gravity * density); - var newVelocity = (particle.physics.velocity + (force * deltaTime)); - var newPosition = (particle.physics.position + (newVelocity * deltaTime)); + let force = (gravity * density); + let newVelocity = (particle.physics.velocity + (force * deltaTime)); + let newPosition = (particle.physics.position + (newVelocity * deltaTime)); return Particle(particle.id, PhysicsData(particle.physics.weight, newVelocity, newPosition)); } @@ -375,16 +375,16 @@ describe('indents', () => { @vertex fn someVertex(@location(0) _arg_position: vec4f, @location(1) _arg_something: vec4f) -> someVertex_Output { let uniBoid = (&boids); for (var i = 0u; (i < 1u); i++) { - var sampled_1 = textureSample(sampled, sampler_1, vec2f(0.5), i); - var someVal = textureLoad(smoothRender, vec2i(), 0); + let sampled_1 = textureSample(sampled, sampler_1, vec2f(0.5), i); + let someVal = textureLoad(smoothRender, vec2i(), 0); if (((someVal.x + sampled_1.x) > 0.5f)) { - var newPos = ((*uniBoid).position + vec4f(1, 2, 3, 4)); + let newPos = ((*uniBoid).position + vec4f(1, 2, 3, 4)); } else { while (true) { - var newPos = ((*uniBoid).position + vec4f(1, 2, 3, 4)); + let newPos = ((*uniBoid).position + vec4f(1, 2, 3, 4)); if ((newPos.x > 0f)) { - var evenNewer = (newPos + _arg_position); + let evenNewer = (newPos + _arg_position); } } } diff --git a/packages/typegpu/tests/lazy.test.ts b/packages/typegpu/tests/lazy.test.ts index 5058c537e2..5f06e809d3 100644 --- a/packages/typegpu/tests/lazy.test.ts +++ b/packages/typegpu/tests/lazy.test.ts @@ -152,7 +152,7 @@ describe('TgpuLazy', () => { @group(0) @binding(0) var boid: Boid; fn func() { - var pos = vec3f(2, 4, 6); + let pos = vec3f(2, 4, 6); const posX = 2f; let vel = (&boid.vel); let velX = boid.vel.x; @@ -237,11 +237,11 @@ describe('TgpuLazy', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn foo() { - var array_1 = array(); + let array_1 = array(); } fn foo_1() { - var array_1 = array(); + let array_1 = array(); } fn main() { diff --git a/packages/typegpu/tests/mutabilityTracking.test.ts b/packages/typegpu/tests/mutabilityTracking.test.ts new file mode 100644 index 0000000000..8a74ba4ec2 --- /dev/null +++ b/packages/typegpu/tests/mutabilityTracking.test.ts @@ -0,0 +1,620 @@ +import { describe, expect, it } from 'vitest'; +import * as d from '../src/data/index.ts'; +import tgpu, { std } from '../src/index.js'; + +const fnShell = tgpu.fn([d.vec4u], d.u32); + +describe('mutability tracking', () => { + describe('resolves unmodified to let', () => { + it('resolves unmodified primitive const', () => { + const fn = fnShell((arg) => { + 'use gpu'; + const a = arg.x; + return a; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + let a = arg.x; + return a; + }" + `); + expect(resolved).toContain('let a = arg.x'); + }); + + it('resolves unmodified primitive let', () => { + const fn = fnShell((arg) => { + 'use gpu'; + let a = arg.x; + return a; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + let a = arg.x; + return a; + }" + `); + expect(resolved).toContain('let a = arg.x'); + }); + + it('resolves unmodified reference const', () => { + const fn = fnShell((arg) => { + 'use gpu'; + const a = d.vec4u(arg); + return a.x; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + let a = arg; + return a.x; + }" + `); + expect(resolved).toContain('let a = arg'); + }); + + it('resolves unmodified reference let', () => { + const fn = fnShell((arg) => { + 'use gpu'; + let a = d.vec4u(arg); + return a.x; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + let a = arg; + return a.x; + }" + `); + expect(resolved).toContain('let a = arg'); + }); + + it('resolves reassigned in pruned branch', () => { + const myAccess = tgpu.accessor(d.bool); + const fn = () => { + 'use gpu'; + let a = 0; + if (myAccess.$) { + a = 1; + } + return a; + }; + + const resolved = tgpu.resolve([tgpu.fn(fn).with(myAccess, false)]); + expect(resolved).toMatchInlineSnapshot(` + "fn fn_1() -> i32 { + let a = 0; + return a; + }" + `); + expect(resolved).toContain('let a = 0'); + }); + }); + + describe('resolves modified to var', () => { + it('resolves reassigned primitive let', () => { + const fn = fnShell((arg) => { + 'use gpu'; + let a = arg.x; + a = 1; + return a; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + var a = arg.x; + a = 1u; + return a; + }" + `); + expect(resolved).toContain('var a = arg.x'); + }); + + it('resolves conditionally reassigned primitive let', () => { + const fn = fnShell((arg) => { + 'use gpu'; + let a = arg.x; + if (a < 1) { + a = 1; + } else { + } + return a; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + var a = arg.x; + if ((a < 1u)) { + a = 1u; + } + else { + + } + return a; + }" + `); + expect(resolved).toContain('var a = arg.x'); + }); + + it('resolves mutated primitive let', () => { + const fn = fnShell((arg) => { + 'use gpu'; + let a = arg.x; + a += 1; + return a; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + var a = arg.x; + a += 1u; + return a; + }" + `); + expect(resolved).toContain('var a = arg.x'); + }); + + it('resolves incremented primitive let', () => { + const fn = fnShell((arg) => { + 'use gpu'; + let a = arg.x; + a++; + return a; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + var a = arg.x; + a++; + return a; + }" + `); + expect(resolved).toContain('var a = arg.x'); + }); + + it('resolves incremented reference const', () => { + const fn = fnShell((arg) => { + 'use gpu'; + const a = d.vec4u(arg); + a.x++; + return a.x; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + var a = arg; + a.x++; + return a.x; + }" + `); + expect(resolved).toContain('var a = arg'); + }); + + it('resolves modified reference const', () => { + const fn = fnShell((arg) => { + 'use gpu'; + const a = d.vec4u(arg); + a.x = 1; + return a.x; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + var a = arg; + a.x = 1u; + return a.x; + }" + `); + expect(resolved).toContain('var a = arg'); + }); + + it('resolves modified reference let', () => { + const fn = fnShell((arg) => { + 'use gpu'; + let a = d.vec4u(arg); + a.x = 1; + return a.x; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + var a = arg; + a.x = 1u; + return a.x; + }" + `); + expect(resolved).toContain('var a = arg'); + }); + + it('resolves reassigned reference let', () => { + const fn = fnShell((arg) => { + 'use gpu'; + let a = d.vec4u(arg); + a = d.vec4u(); + return a.x; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + var a = arg; + a = vec4u(); + return a.x; + }" + `); + expect(resolved).toContain('var a = arg'); + }); + + it('resolves index-accessed reference const', () => { + const fn = fnShell((arg) => { + 'use gpu'; + const a = [1, 2, 3]; + + a[0] = 1; + + return a[0]; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + var a = array(1, 2, 3); + a[0i] = 1i; + return u32(a[0i]); + }" + `); + expect(resolved).toContain('var a ='); + }); + + it('resolves for loops', () => { + const fn = fnShell((arg) => { + 'use gpu'; + + for (const i of std.range(3)) { + } + for (let j = 0; j < 3; j++) {} + + return 0; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + for (var i = 0u; i < 3u; i += 1u) { + + } + for (var j = 0; (j < 3i); j++) { + + } + return 0u; + }" + `); + }); + + it('resolves deeply nested struct modification', () => { + const Struct = d.struct({ + a: d.arrayOf(d.struct({ b: d.struct({ c: d.vec4f }) }), 4), + }); + const fn = fnShell((arg) => { + 'use gpu'; + const struct = Struct(); + struct.a[0]!.b.c.x += 1; + return 0; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "struct b { + c: vec4f, + } + + struct item_1 { + b: b, + } + + struct Struct { + a: array, + } + + fn item(arg: vec4u) -> u32 { + var struct_1 = Struct(); + struct_1.a[0i].b.c.x += 1f; + return 0u; + }" + `); + expect(resolved).toContain('var struct_1 = Struct()'); + }); + }); + + it('resolves shadowed variables correctly', () => { + const fn = fnShell((arg) => { + 'use gpu'; + const a = d.vec4u(arg); + { + const a = d.vec4u(arg); + a.x = 2; + } + return a.x; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + let a = arg; + { + var a_1 = arg; + a_1.x = 2u; + } + return a.x; + }" + `); + expect(resolved).toContain('let a = arg'); + expect(resolved).toContain('var a_1 = arg'); + }); + + describe('d.ref and pointers', () => { + it('resolves a primitive variable used with d.ref', () => { + const fn = () => { + 'use gpu'; + const a = d.ref(0); + return a.$; + }; + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn fn_1() -> i32 { + var a = 0; + return a; + }" + `); + expect(resolved).toContain('var a = 0'); + }); + + it('resolves a referential variable used with d.ref', () => { + const fn = () => { + 'use gpu'; + const a = d.ref(d.vec4u()); + return a.$.x; + }; + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn fn_1() -> u32 { + var a = vec4u(); + return a.x; + }" + `); + expect(resolved).toContain('var a = vec4u()'); + }); + + it('resolves pointed variable', () => { + const modify = tgpu.fn([d.ptrFn(d.u32), d.ptrFn(d.vec4u)])((num, vec) => { + 'use gpu'; + num.$ += 1; + vec.$ += 1; + }); + + const fn = fnShell((arg) => { + 'use gpu'; + let a = d.ref(d.u32(arg.x)); + const b = d.vec4u(arg); + + modify(a, d.ref(b)); + + return a.$; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn modify(num: ptr, vec: ptr) { + (*num) += 1u; + (*vec) += 1; + } + + fn item(arg: vec4u) -> u32 { + var a = arg.x; + var b = arg; + modify((&a), (&b)); + return a; + }" + `); + expect(resolved).toContain('var a = arg.x'); + expect(resolved).toContain('var b = arg'); + }); + + it('resolves d.ref to a struct prop', () => { + const Struct = d.struct({ prop: d.vec4u }); + + const modify = tgpu.fn([d.ptrFn(d.vec4u)])((vec) => { + 'use gpu'; + vec.$ += 1; + }); + + const fn = fnShell((arg) => { + 'use gpu'; + const struct = Struct(); + + modify(d.ref(struct.prop)); + + return struct.prop.x; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "struct Struct { + prop: vec4u, + } + + fn modify(vec: ptr) { + (*vec) += 1; + } + + fn item(arg: vec4u) -> u32 { + var struct_1 = Struct(); + modify((&struct_1.prop)); + return struct_1.prop.x; + }" + `); + expect(resolved).toContain('var struct_1 = Struct()'); + }); + + it('resolves a referenced reference', () => { + const fn = () => { + 'use gpu'; + const a = d.vec4f(); + const b = a; + }; + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn fn_1() { + var a = vec4f(); + let b = (&a); + }" + `); + expect(resolved).toContain('var a = vec4f()'); + }); + + it('resolves a struct with its prop referenced', () => { + const Struct = d.struct({ prop: d.vec4f }); + const fn = () => { + 'use gpu'; + const struct = Struct(); + const prop = struct.prop; + }; + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "struct Struct { + prop: vec4f, + } + + fn fn_1() { + var struct_1 = Struct(); + let prop = (&struct_1.prop); + }" + `); + expect(resolved).toContain('var struct_1 = Struct()'); + }); + + it('resolves an array with its element referenced', () => { + const fn = fnShell((arg) => { + 'use gpu'; + const t = [d.vec2u()]; + const e = t[0]!; + return e.x; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + var t = array(vec2u()); + let e = (&t[0i]); + return (*e).x; + }" + `); + expect(resolved).toContain('var t = '); + }); + + it('resolves the weird unroll case', () => { + const fn = fnShell((arg) => { + 'use gpu'; + const a = d.vec2u(); + for (const e of tgpu.unroll([a])) { + a.x += 1; + } + return 0; + }); + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn item(arg: vec4u) -> u32 { + var a = vec2u(); + // unrolled iteration #0 + { + a.x += 1u; + } + return 0u; + }" + `); + expect(resolved).toContain('var a = '); + }); + + it('resolves a struct when its prop is only read', () => { + const Struct = d.struct({ prop: d.vec4f }); + const fn = () => { + 'use gpu'; + const struct = Struct(); + return struct.prop; + }; + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "struct Struct { + prop: vec4f, + } + + fn fn_1() -> vec4f { + let struct_1 = Struct(); + return struct_1.prop; + }" + `); + expect(resolved).toContain('let struct_1 = Struct()'); + }); + + it('resolves for..of on a referential array', () => { + const fn = () => { + 'use gpu'; + const t = [d.vec2f()]; + let result = d.vec2f(); + for (const v of t) { + result += v; + } + }; + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn fn_1() { + var t = array(vec2f()); + var result = vec2f(); + for (var i = 0u; i < 1u; i += 1u) { + let v = (&t[i]); + { + result += (*v); + } + } + }" + `); + expect(resolved).toContain('var t = '); + }); + + it('resolves tgpu.unroll() on a referential element', () => { + const fn = () => { + 'use gpu'; + const v = d.vec2f(); + const u = tgpu.unroll(v); + }; + + const resolved = tgpu.resolve([fn]); + expect(resolved).toMatchInlineSnapshot(` + "fn fn_1() { + var v = vec2f(); + let u = (&v); + }" + `); + expect(resolved).toContain('var v = '); + }); + }); +}); diff --git a/packages/typegpu/tests/namespace.test.ts b/packages/typegpu/tests/namespace.test.ts index ee6fe33099..7ac6407b43 100644 --- a/packages/typegpu/tests/namespace.test.ts +++ b/packages/typegpu/tests/namespace.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, vi } from 'vitest'; +import { describe, expect } from 'vitest'; import tgpu, { d } from '../src/index.js'; import { it } from 'typegpu-testing-utility'; @@ -71,34 +71,6 @@ describe('tgpu.namespace', () => { `); }); - it('fires "name" event', () => { - const Boid = d.struct({ - pos: d.vec3f, - }); - - const names = tgpu['~unstable'].namespace(); - - const listener = vi.fn((event) => {}); - names.on('name', listener); - - const code = tgpu.resolve([Boid], { names }); - - expect(listener).toHaveBeenCalledTimes(1); - expect(listener).toHaveBeenCalledWith({ name: 'Boid', target: Boid }); - - expect(code).toMatchInlineSnapshot(` - "struct Boid { - pos: vec3f, - }" - `); - - const code2 = tgpu.resolve([Boid], { names }); - - // No more events - expect(listener).toHaveBeenCalledTimes(1); - expect(code2).toMatchInlineSnapshot(`""`); - }); - it('handles name collision', () => { let code1: string, code2: string; const names = tgpu['~unstable'].namespace(); diff --git a/packages/typegpu/tests/pipeline-resolution.test.ts b/packages/typegpu/tests/pipeline-resolution.test.ts index 3d5272ae8f..5bbf9618ca 100644 --- a/packages/typegpu/tests/pipeline-resolution.test.ts +++ b/packages/typegpu/tests/pipeline-resolution.test.ts @@ -50,7 +50,7 @@ describe('resolve', () => { } @vertex fn vertexFn() -> vertexFn_Output { - var myBoid = Boid(); + let myBoid = Boid(); return vertexFn_Output(vec4f(myBoid.position, 0f, 1f), myBoid.color); } @@ -74,7 +74,7 @@ describe('resolve', () => { } @compute @workgroup_size(1, 1, 1) fn computeFn() { - var myBoid = Boid(vec2f(), vec4f(1, 0, 0, 1)); + let myBoid = Boid(vec2f(), vec4f(1, 0, 0, 1)); }" `); }); @@ -97,7 +97,7 @@ describe('resolve', () => { } fn wrappedCallback(x: u32, y: u32, z: u32) { - var myBoid = Boid(vec2f(), vec4f(f32(x), f32(y), f32(z), 1f)); + let myBoid = Boid(vec2f(), vec4f(f32(x), f32(y), f32(z), 1f)); } @compute @workgroup_size(8, 8, 4) fn mainCompute(@builtin(global_invocation_id) id: vec3u) { diff --git a/packages/typegpu/tests/renderPipeline.test.ts b/packages/typegpu/tests/renderPipeline.test.ts index 316f2d0e02..aa406650fe 100644 --- a/packages/typegpu/tests/renderPipeline.test.ts +++ b/packages/typegpu/tests/renderPipeline.test.ts @@ -277,13 +277,6 @@ describe('root.withVertex(...).withFragment(...)', () => { return vertexMain_Output(vec3f(), vec3f(), vec3f(), 0f, 0u, vec4f()); } - struct fragmentMain_Input { - @location(3) baz3: u32, - @location(1) bar: vec3f, - @location(2) foo: vec3f, - @location(5) baz2: f32, - } - @fragment fn fragmentMain() -> @location(0) vec4f { return vec4f(); }" @@ -1463,7 +1456,7 @@ describe('root.createRenderPipeline', () => { } @vertex fn vertex(_arg_0: VertexIn) -> VertexOut { - var pos = array(vec2f(0, 0.5), vec2f(-0.5), vec2f(0.5, -0.5)); + let pos = array(vec2f(0, 0.5), vec2f(-0.5), vec2f(0.5, -0.5)); return VertexOut(vec4f(pos[_arg_0.vertexIndex], 0f, 1f), (pos[_arg_0.vertexIndex] + vec2f(0.5))); } @@ -1568,12 +1561,12 @@ describe('root.createRenderPipeline', () => { } struct VertexIn { - @builtin(vertex_index) vertexIndex: u32, @location(0) localPos: vec3f, + @builtin(vertex_index) vertexIndex: u32, } @vertex fn vertex(_arg_0: VertexIn) -> VertexOut { - var uv = array(vec2f(0.5, 1), vec2f(), vec2f(1, 0)); + let uv = array(vec2f(0.5, 1), vec2f(), vec2f(1, 0)); return VertexOut(vec4f(_arg_0.localPos, 1f), uv[_arg_0.vertexIndex]); } @@ -1712,18 +1705,13 @@ describe('root.createRenderPipeline', () => { { "arrayStride": 16, "attributes": [ - { - "format": "float32", - "offset": 12, - "shaderLocation": 0, - }, { "format": "float32x3", "offset": 0, - "shaderLocation": 1, + "shaderLocation": 0, }, ], - "stepMode": "instance", + "stepMode": "vertex", }, { "arrayStride": 16, @@ -1731,10 +1719,15 @@ describe('root.createRenderPipeline', () => { { "format": "float32x3", "offset": 0, + "shaderLocation": 1, + }, + { + "format": "float32", + "offset": 12, "shaderLocation": 2, }, ], - "stepMode": "vertex", + "stepMode": "instance", }, ], "module": "mockShaderModule", @@ -1751,10 +1744,10 @@ describe('root.createRenderPipeline', () => { { "destroy": [MockFunction], "getMappedRange": [MockFunction], - "label": "instanceBuffer", + "label": "vertexBuffer", "mapAsync": [MockFunction], "mapState": "unmapped", - "size": 16, + "size": 48, "unmap": [MockFunction], "usage": 44, }, @@ -1766,10 +1759,10 @@ describe('root.createRenderPipeline', () => { { "destroy": [MockFunction], "getMappedRange": [MockFunction], - "label": "vertexBuffer", + "label": "instanceBuffer", "mapAsync": [MockFunction], "mapState": "unmapped", - "size": 48, + "size": 16, "unmap": [MockFunction], "usage": 44, }, diff --git a/packages/typegpu/tests/resolve.test.ts b/packages/typegpu/tests/resolve.test.ts index 254730def2..83e8e1e787 100644 --- a/packages/typegpu/tests/resolve.test.ts +++ b/packages/typegpu/tests/resolve.test.ts @@ -1,6 +1,6 @@ import { describe, expect, vi } from 'vitest'; import tgpu, { d } from '../src/index.js'; -import { setName } from '../src/shared/meta.ts'; +import { getName, setName } from '../src/shared/meta.ts'; import { $gpuValueOf, $internal, $ownSnippet, $resolve } from '../src/shared/symbols.ts'; import type { ResolutionCtx } from '../src/types.ts'; import { it } from 'typegpu-testing-utility'; @@ -55,7 +55,7 @@ describe('tgpu resolve', () => { } as unknown as number, [$resolve](ctx: ResolutionCtx) { - const name = ctx.getUniqueName(this); + const name = ctx.makeUniqueIdentifier(getName(this), 'global'); ctx.addDeclaration(`@group(0) @binding(0) var ${name}: f32;`); return snip(name, d.f32, /* origin */ 'runtime'); }, diff --git a/packages/typegpu/tests/slot.test.ts b/packages/typegpu/tests/slot.test.ts index 8f1fd76175..8e6d38fb76 100644 --- a/packages/typegpu/tests/slot.test.ts +++ b/packages/typegpu/tests/slot.test.ts @@ -286,13 +286,13 @@ describe('tgpu.slot', () => { } fn func() { - var pos = vec3f(1, 2, 3); + let pos = vec3f(1, 2, 3); const posX = 1f; let vel = (&boid.vel); let velX = boid.vel.x; let vel_ = (&boid.vel); let velX_ = boid.vel.x; - var color = getColor(); + let color = getColor(); }" `); }); @@ -319,7 +319,7 @@ describe('tgpu.slot', () => { // Gamma Correction: OFF expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main(uv: vec2f) -> vec3f { - var color = vec3f(1, 0, 1); + let color = vec3f(1, 0, 1); return color; }" `); diff --git a/packages/typegpu/tests/std/boolean/not.test.ts b/packages/typegpu/tests/std/boolean/not.test.ts index 930c405ccd..8d4a3f2eb3 100644 --- a/packages/typegpu/tests/std/boolean/not.test.ts +++ b/packages/typegpu/tests/std/boolean/not.test.ts @@ -102,7 +102,7 @@ describe('not', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { - var v = vec4(false, false, true, false); + let v = vec4(false, false, true, false); }" `); }); @@ -142,7 +142,7 @@ describe('not', () => { "fn testFn(v: vec3f, a: atomic, p: ptr) { const _b0 = false; let _b1 = false; - var _b2 = !(vec3(v)); + let _b2 = !(vec3(v)); let _b3 = false; let _b4 = !bool(atomicLoad(&a)); let _b5 = false; @@ -233,7 +233,7 @@ describe('not', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { - var v = vec4(false, false, true, false); + let v = vec4(false, false, true, false); }" `); }); diff --git a/packages/typegpu/tests/std/matrix/rotate.test.ts b/packages/typegpu/tests/std/matrix/rotate.test.ts index 191aa4d3ab..2b6642afc4 100644 --- a/packages/typegpu/tests/std/matrix/rotate.test.ts +++ b/packages/typegpu/tests/std/matrix/rotate.test.ts @@ -16,7 +16,7 @@ describe('rotate', () => { expect(tgpu.resolve([rotateFn])).toMatchInlineSnapshot(` "fn rotateFn() { const angle = 4; - var resultExpression = (mat4x4f(1, 0, 0, 0, 0, cos(f32(angle)), sin(f32(angle)), 0, 0, -sin(f32(angle)), cos(f32(angle)), 0, 0, 0, 0, 1) * mat4x4f(1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1)); + let resultExpression = (mat4x4f(1, 0, 0, 0, 0, cos(f32(angle)), sin(f32(angle)), 0, 0, -sin(f32(angle)), cos(f32(angle)), 0, 0, 0, 0, 1) * mat4x4f(1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1)); }" `); }); @@ -32,7 +32,7 @@ describe('rotate', () => { expect(tgpu.resolve([rotateFn])).toMatchInlineSnapshot(` "fn rotateFn() { const angle = 4; - var resultExpression = (mat4x4f(cos(f32(angle)), 0, -sin(f32(angle)), 0, 0, 1, 0, 0, sin(f32(angle)), 0, cos(f32(angle)), 0, 0, 0, 0, 1) * mat4x4f(1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1)); + let resultExpression = (mat4x4f(cos(f32(angle)), 0, -sin(f32(angle)), 0, 0, 1, 0, 0, sin(f32(angle)), 0, cos(f32(angle)), 0, 0, 0, 0, 1) * mat4x4f(1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1)); }" `); }); @@ -48,7 +48,7 @@ describe('rotate', () => { expect(tgpu.resolve([rotateFn])).toMatchInlineSnapshot(` "fn rotateFn() { const angle = 4; - var resultExpression = (mat4x4f(cos(f32(angle)), sin(f32(angle)), 0, 0, -sin(f32(angle)), cos(f32(angle)), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) * mat4x4f(1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1)); + let resultExpression = (mat4x4f(cos(f32(angle)), sin(f32(angle)), 0, 0, -sin(f32(angle)), cos(f32(angle)), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) * mat4x4f(1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1)); }" `); }); diff --git a/packages/typegpu/tests/std/matrix/scale.test.ts b/packages/typegpu/tests/std/matrix/scale.test.ts index 89907e7ec8..706085a81f 100644 --- a/packages/typegpu/tests/std/matrix/scale.test.ts +++ b/packages/typegpu/tests/std/matrix/scale.test.ts @@ -21,7 +21,7 @@ describe('scale', () => { expect(tgpu.resolve([scaleFn])).toMatchInlineSnapshot(` "fn scaleFn() { - var resultExpression = mat4x4f(2, 0, 0, 1, 0, 2, 0, 0, 2, 0, 4, 0, 0, 2, 0, 1); + let resultExpression = mat4x4f(2, 0, 0, 1, 0, 2, 0, 0, 2, 0, 4, 0, 0, 2, 0, 1); }" `); }); diff --git a/packages/typegpu/tests/std/matrix/translate.test.ts b/packages/typegpu/tests/std/matrix/translate.test.ts index 20b3998551..bf46e6565a 100644 --- a/packages/typegpu/tests/std/matrix/translate.test.ts +++ b/packages/typegpu/tests/std/matrix/translate.test.ts @@ -21,7 +21,7 @@ describe('translate', () => { expect(tgpu.resolve([translateFn])).toMatchInlineSnapshot(` "fn translateFn() { - var resultExpression = mat4x4f(3, 2, 4, 1, 0, 1, 0, 0, 1, 0, 1, 0, 2, 3, 4, 1); + let resultExpression = mat4x4f(3, 2, 4, 1, 0, 1, 0, 0, 1, 0, 1, 0, 2, 3, 4, 1); }" `); }); diff --git a/packages/typegpu/tests/std/numeric/bitShift.test.ts b/packages/typegpu/tests/std/numeric/bitShift.test.ts index ce87d830c6..aecfb3cecf 100644 --- a/packages/typegpu/tests/std/numeric/bitShift.test.ts +++ b/packages/typegpu/tests/std/numeric/bitShift.test.ts @@ -64,10 +64,10 @@ describe('bit shift', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { - var shift = vec3u(4); - var x = vec3i(256); - var y = (x << shift); - var z = (x >> shift); + let shift = vec3u(4); + let x = vec3i(256); + let y = (x << shift); + let z = (x >> shift); }" `); }); @@ -83,10 +83,10 @@ describe('bit shift', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { - var shift = vec3u(4); - var x = vec3i(256); - var y = (x << shift); - var z = (x >> shift); + let shift = vec3u(4); + let x = vec3i(256); + let y = (x << shift); + let z = (x >> shift); }" `); }); @@ -103,9 +103,9 @@ describe('bit shift', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { const shift = 4u; - var x = vec3i(256); - var y = (x << vec3u(shift)); - var z = (x >> vec3u(shift)); + let x = vec3i(256); + let y = (x << vec3u(shift)); + let z = (x >> vec3u(shift)); }" `); }); @@ -138,8 +138,8 @@ describe('bit shift', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> vec3i { - var shift = vec3u(4); - var x = vec3i(256); + let shift = vec3u(4); + let x = vec3i(256); return (x << shift); }" `); @@ -156,7 +156,7 @@ describe('bit shift', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { - var shift = vec3u(4); + let shift = vec3u(4); var x = vec3i(256); x >>= shift; }" diff --git a/packages/typegpu/tests/std/range.test.ts b/packages/typegpu/tests/std/range.test.ts index d51e5971ed..8e0c8a95f1 100644 --- a/packages/typegpu/tests/std/range.test.ts +++ b/packages/typegpu/tests/std/range.test.ts @@ -70,7 +70,7 @@ describe('on the GPU', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() -> array { - var result = array(0f, 2f, 4f, 6f); + let result = array(0f, 2f, 4f, 6f); return result; }" `); @@ -85,7 +85,7 @@ describe('on the GPU', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() -> array { - var result = array(0f, 2f, 4f, 6f); + let result = array(0f, 2f, 4f, 6f); return result; }" `); diff --git a/packages/typegpu/tests/std/texture/textureGather.test.ts b/packages/typegpu/tests/std/texture/textureGather.test.ts index 902cc8ae4e..d341c1f105 100644 --- a/packages/typegpu/tests/std/texture/textureGather.test.ts +++ b/packages/typegpu/tests/std/texture/textureGather.test.ts @@ -82,16 +82,16 @@ describe('textureGather', () => { @group(0) @binding(5) var texdepth2d_array: texture_depth_2d_array; fn testFn() { - var uv2d = vec2f(0.5); - var uv3d = vec3f(0.5, 0.5, 0); + let uv2d = vec2f(0.5); + let uv3d = vec3f(0.5, 0.5, 0); const idx = 1.2000000476837158f; const component = 0i; - var gather2d = textureGather(component, tex2d, sampler_1, uv2d); - var gather2d_u32 = textureGather(component, tex2d_u32, sampler_1, uv2d); - var gather2d_array = textureGather(component, tex2d_array, sampler_1, uv2d, u32(idx)); - var gathercube_array = textureGather(component, texcube_array, sampler_1, uv3d, u32(idx)); - var gatherdepth2d = textureGather(texdepth2d, sampler_1, uv2d); - var gatherdepth2d_array = textureGather(texdepth2d_array, sampler_1, uv2d, u32(idx)); + let gather2d = textureGather(component, tex2d, sampler_1, uv2d); + let gather2d_u32 = textureGather(component, tex2d_u32, sampler_1, uv2d); + let gather2d_array = textureGather(component, tex2d_array, sampler_1, uv2d, u32(idx)); + let gathercube_array = textureGather(component, texcube_array, sampler_1, uv3d, u32(idx)); + let gatherdepth2d = textureGather(texdepth2d, sampler_1, uv2d); + let gatherdepth2d_array = textureGather(texdepth2d_array, sampler_1, uv2d, u32(idx)); }" `); }); diff --git a/packages/typegpu/tests/std/texture/textureLoad.test.ts b/packages/typegpu/tests/std/texture/textureLoad.test.ts index ff498b7e05..af44f4b706 100644 --- a/packages/typegpu/tests/std/texture/textureLoad.test.ts +++ b/packages/typegpu/tests/std/texture/textureLoad.test.ts @@ -85,18 +85,18 @@ describe('textureLoad', () => { fn testFn() { const coord1d = 0i; - var coord2d = vec2i(); - var coord3d = vec3i(); + let coord2d = vec2i(); + let coord3d = vec3i(); const level = 0i; const arrayIndex = 0i; const sampleIndex = 0i; - var load1d = textureLoad(tex1d, coord1d, level); - var load2d = textureLoad(tex2d, coord2d, level); - var load2d_u32 = textureLoad(tex2d_u32, coord2d, level); - var load2d_i32 = textureLoad(tex2d_i32, coord2d, level); - var load2d_array = textureLoad(tex2d_array, coord2d, arrayIndex, level); - var load3d = textureLoad(tex3d, coord3d, level); - var loadms2d = textureLoad(texms2d, coord2d, sampleIndex); + let load1d = textureLoad(tex1d, coord1d, level); + let load2d = textureLoad(tex2d, coord2d, level); + let load2d_u32 = textureLoad(tex2d_u32, coord2d, level); + let load2d_i32 = textureLoad(tex2d_i32, coord2d, level); + let load2d_array = textureLoad(tex2d_array, coord2d, arrayIndex, level); + let load3d = textureLoad(tex3d, coord3d, level); + let loadms2d = textureLoad(texms2d, coord2d, sampleIndex); let loaddepth2d = textureLoad(texdepth2d, coord2d, level); let loaddepth2d_array = textureLoad(texdepth2d_array, coord2d, arrayIndex, level); let loaddepthms2d = textureLoad(texdepthms2d, coord2d, sampleIndex); @@ -152,15 +152,15 @@ describe('textureLoad', () => { fn testFn() { const coord1d = 0i; - var coord2d = vec2i(); - var coord3d = vec3i(); + let coord2d = vec2i(); + let coord3d = vec3i(); const arrayIndex = 0i; - var loadStore1d = textureLoad(store1d, coord1d); - var loadStore2d = textureLoad(store2d, coord2d); - var loadStore2d_uint = textureLoad(store2d_uint, coord2d); - var loadStore2d_sint = textureLoad(store2d_sint, coord2d); - var loadStore2d_array = textureLoad(store2d_array, coord2d, arrayIndex); - var loadStore3d = textureLoad(store3d, coord3d); + let loadStore1d = textureLoad(store1d, coord1d); + let loadStore2d = textureLoad(store2d, coord2d); + let loadStore2d_uint = textureLoad(store2d_uint, coord2d); + let loadStore2d_sint = textureLoad(store2d_sint, coord2d); + let loadStore2d_array = textureLoad(store2d_array, coord2d, arrayIndex); + let loadStore3d = textureLoad(store3d, coord3d); }" `); }); @@ -184,8 +184,8 @@ describe('textureLoad', () => { "@group(0) @binding(0) var texExternal: texture_external; fn testFn() { - var coord2d = vec2i(); - var loadExternal = textureLoad(texExternal, coord2d); + let coord2d = vec2i(); + let loadExternal = textureLoad(texExternal, coord2d); }" `); }); diff --git a/packages/typegpu/tests/struct.test.ts b/packages/typegpu/tests/struct.test.ts index 14dc0984aa..1e3341b59b 100644 --- a/packages/typegpu/tests/struct.test.ts +++ b/packages/typegpu/tests/struct.test.ts @@ -315,7 +315,7 @@ describe('struct', () => { } fn testFunction() { - var defaultValue = Outer(); + let defaultValue = Outer(); }" `); }); @@ -339,8 +339,8 @@ describe('struct', () => { } fn testFn() { - var myStruct = TestStruct(1u, 2f); - var myClone = myStruct; + let myStruct = TestStruct(1u, 2f); + let myClone = myStruct; return; }" `); @@ -365,8 +365,8 @@ describe('struct', () => { } fn testFn() { - var myStructs = array(TestStruct(1u, 2f)); - var myClone = myStructs[0i]; + let myStructs = array(TestStruct(1u, 2f)); + let myClone = myStructs[0i]; return; }" `); @@ -467,7 +467,7 @@ describe('abstruct', () => { expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` "fn testFn(x: f32) -> f32 { - var result = frexp(x); + let result = frexp(x); return f32(result.exp); }" `); diff --git a/packages/typegpu/tests/tgsl/codeGen.test.ts b/packages/typegpu/tests/tgsl/codeGen.test.ts index 38f48adc6e..b5db914b79 100644 --- a/packages/typegpu/tests/tgsl/codeGen.test.ts +++ b/packages/typegpu/tests/tgsl/codeGen.test.ts @@ -32,7 +32,7 @@ describe('codeGen', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() -> f32 { - var size = vec3f(1, 2, 3); + let size = vec3f(1, 2, 3); return ((size.x * size.y) * size.z); }" `); diff --git a/packages/typegpu/tests/tgsl/consoleLog.test.ts b/packages/typegpu/tests/tgsl/consoleLog.test.ts index c3fe5c7189..b2ae1f8fb3 100644 --- a/packages/typegpu/tests/tgsl/consoleLog.test.ts +++ b/packages/typegpu/tests/tgsl/consoleLog.test.ts @@ -618,7 +618,7 @@ describe('wgslGenerator with console.log', () => { } @compute @workgroup_size(1) fn fn_1() { - var complexStruct = ComplexStruct(vec3f(1, 2, 3), array(SimpleStruct(0u, array(9u, 8u, 7u, 6u)), SimpleStruct(1u, array(8u, 7u, 6u, 5u)), SimpleStruct(2u, array(7u, 6u, 5u, 4u)))); + let complexStruct = ComplexStruct(vec3f(1, 2, 3), array(SimpleStruct(0u, array(9u, 8u, 7u, 6u)), SimpleStruct(1u, array(8u, 7u, 6u, 5u)), SimpleStruct(2u, array(7u, 6u, 5u, 4u)))); log1(complexStruct); }" `); diff --git a/packages/typegpu/tests/tgsl/extensionEnabled.test.ts b/packages/typegpu/tests/tgsl/extensionEnabled.test.ts index 727e9fed70..58150fbee5 100644 --- a/packages/typegpu/tests/tgsl/extensionEnabled.test.ts +++ b/packages/typegpu/tests/tgsl/extensionEnabled.test.ts @@ -17,14 +17,14 @@ describe('extension based pruning', () => { }); expect(tgpu.resolve([someFn], { enableExtensions: ['f16'] })).toMatchInlineSnapshot(` - "enable f16; + "enable f16; - fn someFn() -> f32 { - { - return 6.599609375f; - } - }" - `); + fn someFn() -> f32 { + { + return 6.599609375f; + } + }" + `); expect(tgpu.resolve([someFn])).toMatchInlineSnapshot(` "fn someFn() -> f32 { diff --git a/packages/typegpu/tests/tgsl/infixOperators.test.ts b/packages/typegpu/tests/tgsl/infixOperators.test.ts index 2e18ed3331..73a4ec5223 100644 --- a/packages/typegpu/tests/tgsl/infixOperators.test.ts +++ b/packages/typegpu/tests/tgsl/infixOperators.test.ts @@ -14,11 +14,11 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` "fn testFn() { - var v1 = vec4f(1); - var v2 = vec3f(3, 4, 5); - var v3 = vec2f(6); - var m1 = mat2x2f(0, 0, 0, 0); - var m2 = mat3x3f(0, 0, 0, 0, 0, 0, 0, 0, 0); + let v1 = vec4f(1); + let v2 = vec3f(3, 4, 5); + let v3 = vec2f(6); + let m1 = mat2x2f(0, 0, 0, 0); + let m2 = mat3x3f(0, 0, 0, 0, 0, 0, 0, 0, 0); }" `); }); @@ -34,11 +34,11 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` "fn testFn() { - var v1 = vec4f(-1); - var v2 = vec3f(-1, -2, -3); - var v3 = vec2f(); - var m1 = mat2x2f(0, 0, 0, 0); - var m2 = mat3x3f(0, 0, 0, 0, 0, 0, 0, 0, 0); + let v1 = vec4f(-1); + let v2 = vec3f(-1, -2, -3); + let v3 = vec2f(); + let m1 = mat2x2f(0, 0, 0, 0); + let m2 = mat3x3f(0, 0, 0, 0, 0, 0, 0, 0, 0); }" `); }); @@ -58,14 +58,14 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` "fn testFn() { - var v1 = vec2f(6); - var v2 = vec3f(4, 6, 8); - var v3 = vec4f(); - var v4 = vec3f(); - var m1 = mat2x2f(0, 0, 0, 0); - var m2 = vec3f(); - var m3 = mat4x4f(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - var m4 = mat2x2f(0, 0, 0, 0); + let v1 = vec2f(6); + let v2 = vec3f(4, 6, 8); + let v3 = vec4f(); + let v4 = vec3f(); + let m1 = mat2x2f(0, 0, 0, 0); + let m2 = vec3f(); + let m3 = mat4x4f(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + let m4 = mat2x2f(0, 0, 0, 0); }" `); }); @@ -90,7 +90,7 @@ describe('wgslGenerator', () => { } fn testFn() { - var v1 = (getVec() * getVec()); + let v1 = (getVec() * getVec()); }" `); }); @@ -110,8 +110,8 @@ describe('wgslGenerator', () => { } fn testFn() { - var s = Struct(vec3f()); - var v1 = (s.vec * s.vec); + let s = Struct(vec3f()); + let v1 = (s.vec * s.vec); }" `); }); @@ -125,9 +125,9 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` "fn testFn() { - var v1 = vec4f(0.5); - var v2 = vec3f(6, 3, 2); - var v3 = vec2f(0.25); + let v1 = vec4f(0.5); + let v2 = vec3f(6, 3, 2); + let v3 = vec2f(0.25); }" `); }); @@ -140,8 +140,8 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` "fn testFn() { - var v1 = vec4f(1); - var v2 = vec3f(0.5, 1.5, 3.5); + let v1 = vec4f(1); + let v2 = vec3f(0.5, 1.5, 3.5); }" `); }); @@ -162,9 +162,9 @@ describe('wgslGenerator', () => { @group(0) @binding(1) var barUniform: vec3f; fn testFn() { - var v1 = (fooUniform + 2f); - var v2 = (vec3f(1, 2, 3) + barUniform); - var v3 = (fooUniform + barUniform); + let v1 = (fooUniform + 2f); + let v2 = (vec3f(1, 2, 3) + barUniform); + let v3 = (fooUniform + barUniform); }" `); }); @@ -177,8 +177,8 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` "fn testFn() { - var v1 = vec3f(6, 7, 8); - var v2 = vec3f(4); + let v1 = vec3f(6, 7, 8); + let v2 = vec3f(4); }" `); }); diff --git a/packages/typegpu/tests/tgsl/multiplication.test.ts b/packages/typegpu/tests/tgsl/multiplication.test.ts index 30b3b589c8..1a1e335463 100644 --- a/packages/typegpu/tests/tgsl/multiplication.test.ts +++ b/packages/typegpu/tests/tgsl/multiplication.test.ts @@ -31,7 +31,7 @@ test('multiplying i32 with a float literal should implicitly convert to an f32', [ [ "Implicit conversions from [ - 1: i32 + 1i: i32 ] to f32 are supported, but not recommended. Consider using explicit conversions instead.", ], @@ -43,7 +43,7 @@ test('multiplying i32 with a float literal should implicitly convert to an f32', ], [ "Implicit conversions from [ - 1: i32 + 1i: i32 ] to f32 are supported, but not recommended. Consider using explicit conversions instead.", ], @@ -78,7 +78,7 @@ test('multiplying u32 with a float literal should implicitly convert to an f32', [ [ "Implicit conversions from [ - 10: u32 + 10u: u32 ] to f32 are supported, but not recommended. Consider using explicit conversions instead.", ], @@ -90,7 +90,7 @@ test('multiplying u32 with a float literal should implicitly convert to an f32', ], [ "Implicit conversions from [ - 1: u32 + 1u: u32 ] to f32 are supported, but not recommended. Consider using explicit conversions instead.", ], diff --git a/packages/typegpu/tests/tgsl/nameClashes.test.ts b/packages/typegpu/tests/tgsl/nameClashes.test.ts index 86167245ed..586e8e3bf1 100644 --- a/packages/typegpu/tests/tgsl/nameClashes.test.ts +++ b/packages/typegpu/tests/tgsl/nameClashes.test.ts @@ -223,14 +223,14 @@ test('should allow duplicate name after block end', () => { }; expect(tgpu.resolve([main])).toMatchInlineSnapshot(` - "fn main() -> u32 { - for (var i = 0; (i < 3i); i++) { - let foo = (i + 1i); - } - const foo = 7u; - return foo; - }" - `); + "fn main() -> u32 { + for (var i = 0; (i < 3i); i++) { + let foo = (i + 1i); + } + const foo = 7u; + return foo; + }" + `); }); test('should give declarations new names when they are shadowed', () => { diff --git a/packages/typegpu/tests/tgsl/operatorOverloads.test.ts b/packages/typegpu/tests/tgsl/operatorOverloads.test.ts index a351fefcb4..3e39e99f4a 100644 --- a/packages/typegpu/tests/tgsl/operatorOverloads.test.ts +++ b/packages/typegpu/tests/tgsl/operatorOverloads.test.ts @@ -129,7 +129,7 @@ test('+= refOfVec3f', () => { "const constant: vec3f = vec3f(-10); fn foo(arg: vec3f) -> vec3f { - var local = vec3f(100, 10, 1); + let local = vec3f(100, 10, 1); var result = vec3f(); result += local; result += arg; @@ -154,7 +154,7 @@ describe('num op', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() -> vec3f { - var result = vec3f(2, 3, 4); + let result = vec3f(2, 3, 4); return result; }" `); @@ -171,7 +171,7 @@ describe('num op', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() -> vec3f { - var result = vec3f(0, -1, -2); + let result = vec3f(0, -1, -2); return result; }" `); @@ -188,7 +188,7 @@ describe('num op', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() -> vec3f { - var result = vec3f(2, 4, 6); + let result = vec3f(2, 4, 6); return result; }" `); @@ -205,7 +205,7 @@ describe('num op', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() -> vec3f { - var result = vec3f(3, 2, 1); + let result = vec3f(3, 2, 1); return result; }" `); diff --git a/packages/typegpu/tests/tgsl/ternaryOperator.test.ts b/packages/typegpu/tests/tgsl/ternaryOperator.test.ts index fd37903d12..c41cc6b27c 100644 --- a/packages/typegpu/tests/tgsl/ternaryOperator.test.ts +++ b/packages/typegpu/tests/tgsl/ternaryOperator.test.ts @@ -18,14 +18,14 @@ describe('ternary operator', () => { myFn.with(mySlot, false).$name('falseFn'), ]), ).toMatchInlineSnapshot(` - "fn trueFn() -> u32 { - return 10u; - } - - fn falseFn() -> u32 { - return 20u; - }" - `); + "fn trueFn() -> u32 { + return 10u; + } + + fn falseFn() -> u32 { + return 20u; + }" + `); }); it('should work for different comptime known expressions', () => { @@ -72,22 +72,22 @@ describe('ternary operator', () => { myFn.with(mySlot, 3).$name('threeFn'), ]), ).toMatchInlineSnapshot(` - "fn myFn() -> u32 { - return -1u; - } - - fn oneFn() -> u32 { - return 10u; - } - - fn twoFn() -> u32 { - return 20u; - } - - fn threeFn() -> u32 { - return 30u; - }" - `); + "fn myFn() -> u32 { + return -1u; + } + + fn oneFn() -> u32 { + return 10u; + } + + fn twoFn() -> u32 { + return 20u; + } + + fn threeFn() -> u32 { + return 30u; + }" + `); }); it('should not include unused dependencies', ({ root }) => { @@ -103,20 +103,20 @@ describe('ternary operator', () => { }); expect(tgpu.resolve([myFn.with(mySlot, true).$name('trueFn')])).toMatchInlineSnapshot(` - "@group(0) @binding(0) var myUniform: u32; + "@group(0) @binding(0) var myUniform: u32; - fn trueFn() -> u32 { - return myUniform; - }" - `); + fn trueFn() -> u32 { + return myUniform; + }" + `); expect(tgpu.resolve([myFn.with(mySlot, false).$name('falseFn')])).toMatchInlineSnapshot(` - "@group(0) @binding(0) var myReadonly: u32; + "@group(0) @binding(0) var myReadonly: u32; - fn falseFn() -> u32 { - return myReadonly; - }" - `); + fn falseFn() -> u32 { + return myReadonly; + }" + `); }); it('should handle undefined', ({ root }) => { diff --git a/packages/typegpu/tests/tgsl/typeInference.test.ts b/packages/typegpu/tests/tgsl/typeInference.test.ts index 10c6c81726..3e9ca4eb9e 100644 --- a/packages/typegpu/tests/tgsl/typeInference.test.ts +++ b/packages/typegpu/tests/tgsl/typeInference.test.ts @@ -34,7 +34,7 @@ describe('wgsl generator type inference', () => { } fn myFn() { - var myStruct = Outer(Inner(vec2f())); + let myStruct = Outer(Inner(vec2f())); }" `); }); @@ -101,10 +101,10 @@ describe('wgsl generator type inference', () => { expect(tgpu.resolve([myFn])).toMatchInlineSnapshot(` "fn myFn() { - var myArrayF32 = array(1f, 2f); - var myArrayF16 = array(3h, 4h); - var myArrayI32 = array(5i, 6i); - var myArrayU32 = array(7u, 8u); + let myArrayF32 = array(1f, 2f); + let myArrayF16 = array(3h, 4h); + let myArrayI32 = array(5i, 6i); + let myArrayU32 = array(7u, 8u); }" `); }); @@ -143,7 +143,7 @@ describe('wgsl generator type inference', () => { } fn myFn() { - var myStructArray = array(Struct(vec2f(1, 2)), Struct(vec2f(3, 4))); + let myStructArray = array(Struct(vec2f(1, 2)), Struct(vec2f(3, 4))); }" `); }); @@ -167,7 +167,7 @@ describe('wgsl generator type inference', () => { } fn myFn() { - var myBoid = id(Boid(vec2f(1), vec2f())); + let myBoid = id(Boid(vec2f(1), vec2f())); }" `); }); @@ -359,7 +359,7 @@ describe('wgsl generator js type inference', () => { expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` "fn foo() { - var result = array(1f, 2f, 3f); + let result = array(1f, 2f, 3f); }" `); }); @@ -411,7 +411,7 @@ describe('wgsl generator js type inference', () => { } fn myFn() { - var myStruct = Outer(Inner(vec2f())); + let myStruct = Outer(Inner(vec2f())); }" `); }); @@ -485,10 +485,10 @@ describe('wgsl generator js type inference', () => { expect(tgpu.resolve([myFn])).toMatchInlineSnapshot(` "fn myFn() { - var myArrayF32 = array(1f, 2f); - var myArrayF16 = array(3h, 4h); - var myArrayI32 = array(5i, 6i); - var myArrayU32 = array(7u, 8u); + let myArrayF32 = array(1f, 2f); + let myArrayF16 = array(3h, 4h); + let myArrayI32 = array(5i, 6i); + let myArrayU32 = array(7u, 8u); }" `); }); @@ -524,7 +524,7 @@ describe('wgsl generator js type inference', () => { } fn myFn() { - var myStructArray = array(Struct(vec2f(1, 2)), Struct(vec2f(3, 4))); + let myStructArray = array(Struct(vec2f(1, 2)), Struct(vec2f(3, 4))); }" `); }); @@ -549,7 +549,7 @@ describe('wgsl generator js type inference', () => { } fn myFn() { - var myBoid = id(Boid(vec2f(1), vec2f())); + let myBoid = id(Boid(vec2f(1), vec2f())); }" `); }); @@ -658,8 +658,8 @@ describe('wgsl generator js type inference', () => { } fn main() { - var foo = interpolate(0.1f, array(0., 0.5, 1.), array(100, 200, 100)); - var bar = interpolate_1(0.6f, array(0., 0.5), array(100., 40.5)); + let foo = interpolate(0.1f, array(0., 0.5, 1.), array(100, 200, 100)); + let bar = interpolate_1(0.6f, array(0., 0.5), array(100., 40.5)); }" `); }); diff --git a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts index e1129649ac..9c15d99ddf 100644 --- a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts +++ b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts @@ -3,19 +3,17 @@ import { beforeEach, describe, expect, vi } from 'vitest'; import { namespace } from '../../src/core/resolve/namespace.ts'; import * as d from '../../src/data/index.ts'; import { abstractFloat, abstractInt } from '../../src/data/numeric.ts'; -import { snip } from '../../src/data/snippet.ts'; -import { Void, type WgslArray } from '../../src/data/wgslTypes.ts'; +import { type WgslArray } from '../../src/data/wgslTypes.ts'; import { provideCtx } from '../../src/execMode.ts'; import tgpu from '../../src/index.js'; import { ResolutionCtxImpl } from '../../src/resolutionCtx.ts'; import { getMetaData } from '../../src/shared/meta.ts'; -import { $internal } from '../../src/shared/symbols.ts'; import * as std from '../../src/std/index.ts'; import wgslGenerator from '../../src/tgsl/wgslGenerator.ts'; import { CodegenState } from '../../src/types.ts'; import { it } from 'typegpu-testing-utility'; import { ArrayExpression } from '../../src/tgsl/generationHelpers.ts'; -import { extractSnippetFromFn } from '../utils/parseResolved.ts'; +import { expectDataTypeOf, extractSnippetFromFn } from '../utils/parseResolved.ts'; const { NodeTypeCatalog: NODE } = tinyest; @@ -40,19 +38,11 @@ describe('wgslGenerator', () => { return true; }; - const parsedBody = getMetaData(main)?.ast?.body as tinyest.Block; - - expect(JSON.stringify(parsedBody)).toMatchInlineSnapshot(`"[0,[[10,true]]]"`); - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope('normal', [], {}, d.bool, {}); - const gen = wgslGenerator.functionDefinition(parsedBody); - expect(gen).toMatchInlineSnapshot(` - "{ - return true; - }" - `); - }); + expect(tgpu.resolve([main])).toMatchInlineSnapshot(` + "fn main() -> bool { + return true; + }" + `); }); it('creates a function body', () => { @@ -63,23 +53,13 @@ describe('wgslGenerator', () => { return a; }; - const parsedBody = getMetaData(main)?.ast?.body as tinyest.Block; - - expect(JSON.stringify(parsedBody)).toMatchInlineSnapshot( - `"[0,[[12,"a",[5,"12"]],[2,"a","+=",[5,"21"]],[10,"a"]]]"`, - ); - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope('normal', [], {}, d.i32, {}); - const gen = wgslGenerator.functionDefinition(parsedBody); - expect(gen).toMatchInlineSnapshot(` - "{ - var a = 12; - a += 21i; - return a; - }" - `); - }); + expect(tgpu.resolve([main])).toMatchInlineSnapshot(` + "fn main() -> i32 { + var a = 12; + a += 21i; + return a; + }" + `); }); it('creates correct resources for numeric literals', () => { @@ -134,57 +114,22 @@ describe('wgslGenerator', () => { }); const testBuffer = root.createBuffer(TestStruct).$usage('storage'); - const testUsage = testBuffer.as('mutable'); - const testFn = tgpu.fn( - [], - d.u32, - )(() => { - return testUsage.$.a + testUsage.$.b.x; - }); - - const astInfo = getMetaData( - testFn[$internal].implementation as (...args: unknown[]) => unknown, - ); - if (!astInfo) { - throw new Error('Expected prebuilt AST to be present'); - } + expectDataTypeOf(() => { + 'use gpu'; + return testUsage.$.a; + }).toStrictEqual(d.u32); - expect(JSON.stringify(astInfo.ast?.body)).toMatchInlineSnapshot( - `"[0,[[10,[1,[7,[7,"testUsage","$"],"a"],"+",[7,[7,[7,"testUsage","$"],"b"],"x"]]]]]"`, - ); - ctx[$internal].itemStateStack.pushFunctionScope( - 'normal', - [], - {}, - d.u32, - (astInfo.externals as () => Record)() ?? {}, - ); + expectDataTypeOf(() => { + 'use gpu'; + return testUsage.$.b.x; + }).toStrictEqual(d.u32); - provideCtx(ctx, () => { - // Check for: return testUsage.$.a + testUsage.$.b.x; - // ^ this should be a u32 - const res1 = wgslGenerator._expression( - ((astInfo.ast?.body[1][0] as tinyest.Return)[1] as tinyest.BinaryExpression)[1], - ); - - expect(res1.dataType).toStrictEqual(d.u32); - - // Check for: return testUsage.$.a + testUsage.$.b.x; - // ^ this should be a u32 - const res2 = wgslGenerator._expression( - ((astInfo.ast?.body[1][0] as tinyest.Return)[1] as tinyest.BinaryExpression)[3], - ); - expect(res2.dataType).toStrictEqual(d.u32); - - // Check for: return testUsage.$.a + testUsage.$.b.x; - // ^ this should be a u32 - const sum = wgslGenerator._expression( - (astInfo.ast?.body[1][0] as tinyest.Return)[1] as tinyest.Expression, - ); - expect(sum.dataType).toStrictEqual(d.u32); - }); + expectDataTypeOf(() => { + 'use gpu'; + return testUsage.$.a + testUsage.$.b.x; + }).toStrictEqual(d.u32); }); it('generates correct resources for external resource array index access', ({ root }) => { @@ -192,42 +137,10 @@ describe('wgslGenerator', () => { const testUsage = testBuffer.as('uniform'); - const testFn = tgpu.fn( - [], - d.u32, - )(() => { - return testUsage.$[3] as number; - }); - - const astInfo = getMetaData( - testFn[$internal].implementation as (...args: unknown[]) => unknown, - ); - - if (!astInfo) { - throw new Error('Expected prebuilt AST to be present'); - } - - expect(JSON.stringify(astInfo.ast?.body)).toMatchInlineSnapshot( - `"[0,[[10,[8,[7,"testUsage","$"],[5,"3"]]]]]"`, - ); - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope( - 'normal', - [], - {}, - d.u32, - (astInfo.externals as () => Record)() ?? {}, - ); - - // Check for: return testUsage.$[3]; - // ^ this should be a u32 - const res = wgslGenerator._expression( - (astInfo.ast?.body[1][0] as tinyest.Return)[1] as tinyest.Expression, - ); - - expect(res.dataType).toStrictEqual(d.u32); - }); + expectDataTypeOf(() => { + 'use gpu'; + return testUsage.$[3]; + }).toStrictEqual(d.u32); }); it('generates correct resources for nested struct with atomics in a complex expression', ({ @@ -253,156 +166,29 @@ describe('wgslGenerator', () => { const testUsage = testBuffer.as('mutable'); - const testFn = tgpu.fn( - [d.u32], - d.vec4f, - )((idx) => { - const value = std.atomicLoad(testUsage.$.b.aa[idx]!.y); - const vec = std.mix(d.vec4f(), testUsage.$.a, value); - std.atomicStore(testUsage.$.b.aa[idx]!.x, vec.y); - return vec; - }); - - const astInfo = getMetaData( - testFn[$internal].implementation as (...args: unknown[]) => unknown, - ); - - if (!astInfo?.ast) { - throw new Error('Expected prebuilt AST to be present'); - } - - expect(JSON.stringify(astInfo.ast.body)).toMatchInlineSnapshot( - `"[0,[[13,"value",[6,[7,"std","atomicLoad"],[[7,[8,[7,[7,[7,"testUsage","$"],"b"],"aa"],"idx"],"y"]]]],[13,"vec",[6,[7,"std","mix"],[[6,[7,"d","vec4f"],[]],[7,[7,"testUsage","$"],"a"],"value"]]],[6,[7,"std","atomicStore"],[[7,[8,[7,[7,[7,"testUsage","$"],"b"],"aa"],"idx"],"x"],[7,"vec","y"]]],[10,"vec"]]]"`, - ); - - if (astInfo.ast.params.filter((arg) => arg.type !== 'i').length > 0) { - throw new Error('Expected arguments as identifier names in ast'); - } - - const args = astInfo.ast.params.map((arg) => - snip((arg as { type: 'i'; name: string }).name, d.u32, /* origin */ 'runtime'), - ); - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope( - 'normal', - args, - {}, - d.vec4f, - (astInfo.externals as () => Record)() ?? {}, - ); - - // Check for: const value = std.atomicLoad(testUsage.$.b.aa[idx]!.y); - // ^ this part should be a i32 - const res = wgslGenerator._expression( - (astInfo.ast?.body[1][0] as tinyest.Const)[2] as tinyest.Expression, - ); - - expect(res.dataType).toStrictEqual(d.i32); - - // Check for: const vec = std.mix(d.vec4f(), testUsage.$.a, value); - // ^ this part should be a vec4f - ctx[$internal].itemStateStack.pushBlockScope(); - wgslGenerator.blockVariable('var', 'value', d.i32, 'runtime'); - const res2 = wgslGenerator._expression( - (astInfo.ast?.body[1][1] as tinyest.Const)[2] as tinyest.Expression, - ); - ctx[$internal].itemStateStack.pop('blockScope'); - - expect(res2.dataType).toStrictEqual(d.vec4f); - - // Check for: std.atomicStore(testUsage.$.b.aa[idx]!.x, vec.y); - // ^ this part should be an atomic u32 - // ^ this part should be void - ctx[$internal].itemStateStack.pushBlockScope(); - wgslGenerator.blockVariable('var', 'vec', d.vec4f, 'function'); - const res3 = wgslGenerator._expression( - (astInfo.ast?.body[1][2] as tinyest.Call)[2][0] as tinyest.Expression, - ); - const res4 = wgslGenerator._expression(astInfo.ast?.body[1][2] as tinyest.Expression); - ctx[$internal].itemStateStack.pop('blockScope'); - - expect(res3.dataType).toStrictEqual(d.atomic(d.u32)); - expect(res4.dataType).toStrictEqual(Void); - }); - }); - - it('creates correct code for for statements', () => { - const main = () => { + // Check for: const value = std.atomicLoad(testUsage.$.b.aa[idx]!.y); + // ^ this part should be a i32 + expectDataTypeOf(() => { 'use gpu'; - for (let i = 0; i < 10; i += 1) { - continue; - } - }; - - const parsed = getMetaData(main)?.ast?.body as tinyest.Block; + const idx = d.u32(0); + return std.atomicLoad(testUsage.$.b.aa[idx]!.y); + }).toStrictEqual(d.i32); - expect(JSON.stringify(parsed)).toMatchInlineSnapshot( - `"[0,[[14,[12,"i",[5,"0"]],[1,"i","<",[5,"10"]],[2,"i","+=",[5,"1"]],[0,[[16]]]]]]"`, - ); - - const gen = provideCtx(ctx, () => wgslGenerator.functionDefinition(parsed)); - - expect(gen).toMatchInlineSnapshot(` - "{ - for (var i = 0; (i < 10i); i += 1i) { - continue; - } - }" - `); - }); - - it('creates correct code for for statements with outside init', () => { - const main = () => { + // Check for: const vec = std.mix(d.vec4f(), testUsage.$.a, value); + // ^ this part should be a vec4f + expectDataTypeOf(() => { 'use gpu'; - let i = 0; - for (; i < 10; i += 1) { - continue; - } - }; - - const parsed = getMetaData(main)?.ast?.body as tinyest.Block; - - expect(JSON.stringify(parsed)).toMatchInlineSnapshot( - `"[0,[[12,"i",[5,"0"]],[14,null,[1,"i","<",[5,"10"]],[2,"i","+=",[5,"1"]],[0,[[16]]]]]]"`, - ); - - const gen = provideCtx(ctx, () => wgslGenerator.functionDefinition(parsed)); + const value = std.atomicLoad(testUsage.$.b.aa[0]!.y); + return std.mix(d.vec4f(), testUsage.$.a, value); + }).toStrictEqual(d.vec4f); - expect(gen).toMatchInlineSnapshot(` - "{ - var i = 0; - for (; (i < 10i); i += 1i) { - continue; - } - }" - `); - }); - - it('creates correct code for while statements', () => { - const main = () => { + // Check for: std.atomicStore(testUsage.$.b.aa[idx]!.x, vec.y); + // ^ this part should be an atomic u32 + expectDataTypeOf(() => { 'use gpu'; - let i = 0; - while (i < 10) { - i += 1; - } - }; - - const parsed = getMetaData(main)?.ast?.body as tinyest.Block; - expect(JSON.stringify(parsed)).toMatchInlineSnapshot( - `"[0,[[12,"i",[5,"0"]],[15,[1,"i","<",[5,"10"]],[0,[[2,"i","+=",[5,"1"]]]]]]]"`, - ); - - const gen = provideCtx(ctx, () => wgslGenerator.functionDefinition(parsed)); - - expect(gen).toMatchInlineSnapshot(` - "{ - var i = 0; - while ((i < 10i)) { - i += 1i; - } - }" - `); + const idx = d.u32(0); + return testUsage.$.b.aa[idx]!.x; + }).toStrictEqual(d.atomic(d.u32)); }); it('parses correctly "for ... of ..." statements', () => { @@ -1003,6 +789,11 @@ describe('wgslGenerator', () => { }); it('creates correct resources for lazy values and slots', () => { + expectDataTypeOf(() => { + 'use gpu'; + return lazyV4u.$; + }).toStrictEqual(d.vec4u); + const testFn = tgpu.fn([], d.vec4u)(() => lazyV4u.$); expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` @@ -1010,76 +801,14 @@ describe('wgslGenerator', () => { return vec4u(44, 88, 132, 176); }" `); - - const astInfo = getMetaData( - testFn[$internal].implementation as (...args: unknown[]) => unknown, - ); - - if (!astInfo) { - throw new Error('Expected prebuilt AST to be present'); - } - - expect(JSON.stringify(astInfo.ast?.body)).toMatchInlineSnapshot( - `"[0,[[10,[7,"lazyV4u","$"]]]]"`, - ); - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope( - 'normal', - [], - {}, - d.vec4u, - (astInfo.externals as () => Record)() ?? {}, - ); - - wgslGenerator.initGenerator(ctx); - // Check for: return lazyV4u.$; - // ^ this should be a vec4u - const res = wgslGenerator._expression( - (astInfo.ast?.body[1][0] as tinyest.Return)[1] as tinyest.Expression, - ); - - expect(res.dataType).toStrictEqual(d.vec4u); - }); }); it('creates correct resources for indexing into a lazy value', () => { - const testFn = tgpu.fn( - [d.u32], - d.f32, - )((idx) => { - return lazyV2f.$[idx] as number; - }); - - const astInfo = getMetaData( - testFn[$internal].implementation as (...args: unknown[]) => unknown, - ); - - if (!astInfo) { - throw new Error('Expected prebuilt AST to be present'); - } - - expect(JSON.stringify(astInfo.ast?.body)).toMatchInlineSnapshot( - `"[0,[[10,[8,[7,"lazyV2f","$"],"idx"]]]]"`, - ); - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope( - 'normal', - [snip('idx', d.u32, /* origin */ 'runtime')], - {}, - d.f32, - (astInfo.externals as () => Record)() ?? {}, - ); - - // Check for: return lazyV2f.$[idx]; - // ^ this should be a f32 - const res = wgslGenerator._expression( - (astInfo.ast?.body[1][0] as tinyest.Return)[1] as tinyest.Expression, - ); - - expect(res.dataType).toStrictEqual(d.f32); - }); + expectDataTypeOf(() => { + 'use gpu'; + const idx = d.u32(0); + return lazyV2f.$[idx]; + }).toStrictEqual(d.f32); }); it('creates intermediate representation for array expression', () => { @@ -1105,44 +834,11 @@ describe('wgslGenerator', () => { }); expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` - "fn testFn() -> u32 { - var arr = array(1u, 2u, 3u); - return arr[1i]; - }" - `); - - const astInfo = getMetaData( - testFn[$internal].implementation as (...args: unknown[]) => unknown, - ); - - if (!astInfo) { - throw new Error('Expected prebuilt AST to be present'); - } - - expect(JSON.stringify(astInfo.ast?.body)).toMatchInlineSnapshot( - `"[0,[[13,"arr",[100,[[6,[7,"d","u32"],[[5,"1"]]],[5,"2"],[5,"3"]]]],[10,[8,"arr",[5,"1"]]]]]"`, - ); - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope( - 'normal', - [], - {}, - d.u32, - (astInfo.externals as () => Record)() ?? {}, - ); - - // Check for: const arr = [1, 2, 3] - // ^ this should be an array - wgslGenerator.initGenerator(ctx); - const res = wgslGenerator._expression( - (astInfo.ast?.body[1][0] as tinyest.Const)[2] as unknown as tinyest.Expression, - ); - - expect(d.isWgslArray(res.dataType)).toBe(true); - expect((res.dataType as unknown as WgslArray).elementCount).toBe(3); - expect((res.dataType as unknown as WgslArray).elementType).toBe(d.u32); - }); + "fn testFn() -> u32 { + let arr = array(1u, 2u, 3u); + return arr[1i]; + }" + `); }); it('generates correct code for complex array expressions', () => { @@ -1160,43 +856,10 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` "fn testFn() -> u32 { - var arr = array(vec2u(1, 2), vec2u(3, 4), vec2u(5, 6)); + let arr = array(vec2u(1, 2), vec2u(3, 4), vec2u(5, 6)); return arr[1i].x; }" `); - - const astInfo = getMetaData( - testFn[$internal].implementation as (...args: unknown[]) => unknown, - ); - - if (!astInfo) { - throw new Error('Expected prebuilt AST to be present'); - } - - expect(JSON.stringify(astInfo.ast?.body)).toMatchInlineSnapshot( - `"[0,[[13,"arr",[100,[[6,[7,"d","vec2u"],[[5,"1"],[5,"2"]]],[6,[7,"d","vec2u"],[[5,"3"],[5,"4"]]],[6,[7,"std","min"],[[6,[7,"d","vec2u"],[[5,"5"],[5,"8"]]],[6,[7,"d","vec2u"],[[5,"7"],[5,"6"]]]]]]]],[10,[7,[8,"arr",[5,"1"]],"x"]]]]"`, - ); - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope( - 'normal', - [], - {}, - d.u32, - (astInfo.externals as () => Record)() ?? {}, - ); - - // Check for: const arr = [1, 2, 3] - // ^ this should be an array - wgslGenerator.initGenerator(ctx); - const res = wgslGenerator._expression( - (astInfo.ast?.body[1][0] as tinyest.Const)[2] as unknown as tinyest.Expression, - ); - - expect(d.isWgslArray(res.dataType)).toBe(true); - expect((res.dataType as unknown as WgslArray).elementCount).toBe(3); - expect((res.dataType as unknown as WgslArray).elementType).toBe(d.vec2u); - }); }); it('does not autocast lhs of an assignment', () => { @@ -1242,43 +905,20 @@ describe('wgslGenerator', () => { } fn testFn() -> f32 { - var arr = array(TestStruct(1u, 2f), TestStruct(3u, 4f)); + let arr = array(TestStruct(1u, 2f), TestStruct(3u, 4f)); return arr[1i].y; }" `); - const astInfo = getMetaData( - testFn[$internal].implementation as (...args: unknown[]) => unknown, - ); - - if (!astInfo) { - throw new Error('Expected prebuilt AST to be present'); - } - - expect(JSON.stringify(astInfo.ast?.body)).toMatchInlineSnapshot( - `"[0,[[13,"arr",[100,[[6,"TestStruct",[[104,{"x":[5,"1"],"y":[5,"2"]}]]],[6,"TestStruct",[[104,{"x":[5,"3"],"y":[5,"4"]}]]]]]],[10,[7,[8,"arr",[5,"1"]],"y"]]]]"`, - ); - - const res = provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope( - 'normal', - [], - {}, - d.f32, - (astInfo.externals as () => Record)() ?? {}, - ); - - // Check for: const arr = [TestStruct({ x: 1, y: 2 }), TestStruct({ x: 3, y: 4 })]; - // ^ this should be an array - wgslGenerator.initGenerator(ctx); - return wgslGenerator._expression( - (astInfo.ast?.body[1][0] as tinyest.Const)[2] as tinyest.Expression, - ); + const arraySnippet = extractSnippetFromFn(() => { + 'use gpu'; + const arr = [TestStruct({ x: 1, y: 2 }), TestStruct({ x: 3, y: 4 })]; + return arr; }); - expect(d.isWgslArray(res.dataType)).toBe(true); - expect((res.dataType as unknown as WgslArray).elementCount).toBe(2); - expect((res.dataType as unknown as WgslArray).elementType).toBe(TestStruct); + expect(d.isWgslArray(arraySnippet.dataType)).toBe(true); + expect((arraySnippet.dataType as unknown as WgslArray).elementCount).toBe(2); + expect((arraySnippet.dataType as unknown as WgslArray).elementType).toBe(TestStruct); }); it('generates correct code for array expressions with lazy elements', () => { @@ -1292,41 +932,10 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([testFn])).toMatchInlineSnapshot(` "fn testFn() -> f32 { - var arr = array(vec2f(44, 88), vec2f(88, 176)); + let arr = array(vec2f(44, 88), vec2f(88, 176)); return arr[1i].y; }" `); - - const astInfo = getMetaData( - testFn[$internal].implementation as (...args: unknown[]) => unknown, - ); - - if (!astInfo) { - throw new Error('Expected prebuilt AST to be present'); - } - - expect(JSON.stringify(astInfo.ast?.body)).toMatchInlineSnapshot( - `"[0,[[13,"arr",[100,[[7,"lazyV2f","$"],[6,[7,"std","mul"],[[7,"lazyV2f","$"],[6,[7,"d","vec2f"],[[5,"2"],[5,"2"]]]]]]]],[10,[7,[8,"arr",[5,"1"]],"y"]]]]"`, - ); - - const res = provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope( - 'normal', - [], - {}, - d.f32, - (astInfo.externals as () => Record)() ?? {}, - ); - - wgslGenerator.initGenerator(ctx); - return wgslGenerator._expression( - (astInfo.ast?.body[1][0] as tinyest.Const)[2] as tinyest.Expression, - ); - }); - - expect(d.isWgslArray(res.dataType)).toBe(true); - expect((res.dataType as unknown as WgslArray).elementCount).toBe(2); - expect((res.dataType as unknown as WgslArray).elementType).toBe(d.vec2f); }); it('allows for member access on values returned from function calls', () => { @@ -1364,34 +973,10 @@ describe('wgslGenerator', () => { }" `); - const astInfo = getMetaData(fnTwo[$internal].implementation as (...args: unknown[]) => unknown); - - if (!astInfo) { - throw new Error('Expected prebuilt AST to be present'); - } - - expect(JSON.stringify(astInfo.ast?.body)).toMatchInlineSnapshot( - `"[0,[[10,[7,[7,[6,"fnOne",[]],"y"],"x"]]]]"`, - ); - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope( - 'normal', - [], - {}, - d.f32, - (astInfo.externals as () => Record)() ?? {}, - ); - - wgslGenerator.initGenerator(ctx); - // Check for: return fnOne().y.x; - // ^ this should be a f32 - const res = wgslGenerator._expression( - (astInfo.ast?.body[1][0] as tinyest.Return)[1] as tinyest.Expression, - ); - - expect(res.dataType).toStrictEqual(d.f32); - }); + expectDataTypeOf(() => { + 'use gpu'; + return fnOne().y.x; + }).toStrictEqual(d.f32); }); it('generates correct code for conditional with single statement', () => { @@ -1464,27 +1049,6 @@ describe('wgslGenerator', () => { `); }); - it('generates correct code for for loops with single statements', () => { - const main = () => { - 'use gpu'; - for (let i = 0; i < 10; i += 1) { - continue; - } - }; - - const gen = provideCtx(ctx, () => - wgslGenerator.functionDefinition(getMetaData(main)?.ast?.body as tinyest.Block), - ); - - expect(gen).toMatchInlineSnapshot(` - "{ - for (var i = 0; (i < 10i); i += 1i) { - continue; - } - }" - `); - }); - it('generates correct code for while loops with single statements', () => { const main = tgpu.fn([])(() => { let i = 0; @@ -1820,59 +1384,51 @@ describe('wgslGenerator', () => { it('block externals do not override identifiers', () => { const f = () => { 'use gpu'; - const y = 100; - const x = y; - return x; + const list = [1]; + for (const x of tgpu.unroll(list)) { + const y = 100; + const x = y; + return x; + } }; - const parsed = getMetaData(f)?.ast?.body as tinyest.Block; - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope('normal', [], {}, d.u32, {}); - - const res = wgslGenerator._block(parsed, { x: 42 }); - - expect(res).toMatchInlineSnapshot(` - "{ - const y = 100; - const x = y; - return u32(x); - }" - `); - }); + expect(tgpu.resolve([f])).toMatchInlineSnapshot(` + "fn f() -> i32 { + var list = array(1); + // unrolled iteration #0 + { + const y = 100; + const x = y; + return x; + } + }" + `); }); it('block externals are injected correctly', () => { const f = () => { 'use gpu'; - for (const x of []) { + for (const x of tgpu.unroll([1])) { const y = x; } }; - const parsed = getMetaData(f)?.ast?.body as tinyest.Block; - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope('normal', [], {}, d.Void, {}); - - const res = wgslGenerator._block((parsed[1][0] as tinyest.ForOf)[3] as tinyest.Block, { - x: 67, - }); - - expect(res).toMatchInlineSnapshot(` - "{ - const y = 67; - }" - `); - }); + expect(tgpu.resolve([f])).toMatchInlineSnapshot(` + "fn f() { + // unrolled iteration #0 + { + const y = 1; + } + }" + `); }); it('block externals are respected in nested blocks', () => { const f = () => { 'use gpu'; let result = d.i32(0); - const list = d.arrayOf(d.i32, 3)([1, 2, 3]); - for (const elem of list) { + const list = [1]; + for (const elem of tgpu.unroll(list)) { { // We use the `elem` in a nested block result += elem; @@ -1880,24 +1436,18 @@ describe('wgslGenerator', () => { } }; - const parsed = getMetaData(f)?.ast?.body as tinyest.Block; - - provideCtx(ctx, () => { - ctx[$internal].itemStateStack.pushFunctionScope('normal', [], {}, d.Void, {}); - - const res = wgslGenerator._block((parsed[1][2] as tinyest.ForOf)[3] as tinyest.Block, { - result: snip('result', d.i32, 'function'), - elem: 7, - }); - - expect(res).toMatchInlineSnapshot(` - "{ + expect(tgpu.resolve([f])).toMatchInlineSnapshot(` + "fn f() { + var result = 0i; + var list = array(1); + // unrolled iteration #0 + { { - result += 7i; + result += list[0u]; } - }" - `); - }); + } + }" + `); }); it('prunes comptime if/else', () => { @@ -2300,7 +1850,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> i32 { - var res = -1; + let res = -1; return res; }" `); @@ -2345,7 +1895,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> i32 { - var res = -1; + let res = -1; return res; }" `); diff --git a/packages/typegpu/tests/tgslFn.test.ts b/packages/typegpu/tests/tgslFn.test.ts index 529e9f0cfa..265634e9db 100644 --- a/packages/typegpu/tests/tgslFn.test.ts +++ b/packages/typegpu/tests/tgslFn.test.ts @@ -61,18 +61,18 @@ describe('TGSL tgpu.fn function', () => { expect(tgpu.resolve([getY])).toMatchInlineSnapshot(` "fn getColor() -> vec3f { - var color = vec3f(); - var color2 = vec3f(1, 2, 3); + let color = vec3f(); + let color2 = vec3f(1, 2, 3); return color; } fn getX() -> f32 { - var color = getColor(); + let color = getColor(); return 3f; } fn getY() -> f32 { - var c = getColor(); + let c = getColor(); return getX(); }" `); @@ -273,7 +273,7 @@ describe('TGSL tgpu.fn function', () => { } @vertex fn vertex_fn(@builtin(vertex_index) _arg_vi: u32, @builtin(instance_index) _arg_ii: u32, @location(0) _arg_color: vec4f) -> vertex_fn_Output { - var myOutput = vertex_fn_Output(vec4f(_arg_color.w, f32(_arg_ii), f32(_arg_vi), 1f), vec2f(_arg_color.w, f32(_arg_vi))); + let myOutput = vertex_fn_Output(vec4f(_arg_color.w, f32(_arg_ii), f32(_arg_vi), 1f), vec2f(_arg_color.w, f32(_arg_vi))); return myOutput; }" `); @@ -297,7 +297,7 @@ describe('TGSL tgpu.fn function', () => { let index = _arg_gid.x; const iterationF = 0f; const sign_1 = 0; - var change = vec4f(); + let change = vec4f(); }" `); }); @@ -320,7 +320,7 @@ describe('TGSL tgpu.fn function', () => { let index = gid.x; const iterationF = 0f; const sign_1 = 0; - var change = vec4f(); + let change = vec4f(); }" `); }); @@ -363,11 +363,7 @@ describe('TGSL tgpu.fn function', () => { }); expect(tgpu.resolve([fragmentFn])).toMatchInlineSnapshot(` - "struct fragmentFn_Input { - @location(0) uv: vec2f, - } - - struct fragmentFn_Output { + "struct fragmentFn_Output { @builtin(sample_mask) sampleMask: u32, @builtin(frag_depth) fragDepth: f32, @location(0) out: vec4f, @@ -410,11 +406,7 @@ describe('TGSL tgpu.fn function', () => { }); expect(tgpu.resolve([fragmentFn])).toMatchInlineSnapshot(` - "struct fragmentFn_Input { - @location(0) uv: vec2f, - } - - struct fragmentFn_Output { + "struct fragmentFn_Output { @builtin(sample_mask) sampleMask: u32, @builtin(frag_depth) fragDepth: f32, @location(0) out: vec4f, @@ -444,12 +436,8 @@ describe('TGSL tgpu.fn function', () => { }); expect(tgpu.resolve([fragmentFn])).toMatchInlineSnapshot(` - "struct fragmentFn_Input { - @location(0) uv: vec2f, - } - - @fragment fn fragmentFn() -> @location(0) vec4f { - var hmm = vec4f(1.25); + "@fragment fn fragmentFn() -> @location(0) vec4f { + let hmm = vec4f(1.25); return hmm; }" `); @@ -481,11 +469,7 @@ describe('TGSL tgpu.fn function', () => { }); expect(tgpu.resolve([fragmentFn])).toMatchInlineSnapshot(` - "struct fragmentFn_Input { - @location(0) uv: vec2f, - } - - struct fragmentFn_Output { + "struct fragmentFn_Output { @builtin(sample_mask) sampleMask: u32, @builtin(frag_depth) fragDepth: f32, @location(0) out: vec4f, @@ -583,7 +567,7 @@ describe('TGSL tgpu.fn function', () => { } @compute @workgroup_size(24) fn compute_fn() { - var testStruct = getTestStruct(); + let testStruct = getTestStruct(); }" `); }); @@ -662,7 +646,7 @@ describe('TGSL tgpu.fn function', () => { } fn fun(_arg_0: Input) { - var vector = vec2u(u32(_arg_0.value)); + let vector = vec2u(u32(_arg_0.value)); }" `); }); @@ -682,7 +666,7 @@ describe('TGSL tgpu.fn function', () => { } fn fun(input: Input) { - var vector = vec2u(u32(input.value)); + let vector = vec2u(u32(input.value)); }" `); }); @@ -702,7 +686,7 @@ describe('TGSL tgpu.fn function', () => { } fn fun(_arg_0: Input) { - var vector = vec2u(u32(_arg_0.value)); + let vector = vec2u(u32(_arg_0.value)); }" `); }); @@ -722,7 +706,7 @@ describe('TGSL tgpu.fn function', () => { } fn fun(_arg_0: Input, x: i32, _arg_2: Input) { - var vector = vec3u(u32(_arg_0.value), u32(x), u32(_arg_2.value)); + let vector = vec3u(u32(_arg_0.value), u32(x), u32(_arg_2.value)); }" `); }); diff --git a/packages/typegpu/tests/unroll.test.ts b/packages/typegpu/tests/unroll.test.ts index c35689684e..adfef7b0ef 100644 --- a/packages/typegpu/tests/unroll.test.ts +++ b/packages/typegpu/tests/unroll.test.ts @@ -30,7 +30,7 @@ describe('tgpu.unroll', () => { "@group(0) @binding(0) var arr_1: array; fn f() -> f32 { - var a = array(1, 2, 3); + let a = array(1, 2, 3); var v1 = vec2f(7); let v2 = (&v1); let arr = (&arr_1); @@ -80,7 +80,7 @@ describe('tgpu.unroll', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { - var foo = vec3f(6); + let foo = vec3f(6); // unrolled iteration #0 { const boo = 1; @@ -385,7 +385,7 @@ describe('tgpu.unroll', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> i32 { - var v = vec3f(7); + let v = vec3f(7); var res = 0; // unrolled iteration #0 { @@ -542,9 +542,9 @@ describe('tgpu.unroll', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> vec2f { - var v1 = vec2f(1); - var v2 = vec2f(8); - var v3 = vec2f(2); + let v1 = vec2f(1); + let v2 = vec2f(8); + let v3 = vec2f(2); var arr = array(v1, v2, v2, v3); var res = vec2f(); // unrolled iteration #0 @@ -600,8 +600,8 @@ describe('tgpu.unroll', () => { } fn f() -> vec2f { - var b1 = Boid(vec2i(1), vec2f(1)); - var b2 = Boid(vec2i(2), vec2f(2)); + let b1 = Boid(vec2i(1), vec2f(1)); + let b2 = Boid(vec2i(2), vec2f(2)); var arr = array(b1, b2); var res = vec2f(); // unrolled iteration #0 @@ -703,7 +703,7 @@ describe('tgpu.unroll', () => { `); expect(tgpu.resolve([tgpu.fn(f).with(unroll, false)])).toMatchInlineSnapshot(` "fn f() { - var arr = array(1, 2, 3); + let arr = array(1, 2, 3); var r = 0f; for (var i = 0u; i < 3u; i += 1u) { let foo = arr[i]; @@ -868,7 +868,7 @@ describe('tgpu.unroll', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> i32 { - var a = 0; + let a = 0; return a; }" `); diff --git a/packages/typegpu/tests/utils/parseResolved.ts b/packages/typegpu/tests/utils/parseResolved.ts index 7576fedc31..f6dffc8bdd 100644 --- a/packages/typegpu/tests/utils/parseResolved.ts +++ b/packages/typegpu/tests/utils/parseResolved.ts @@ -17,10 +17,10 @@ class ExtractingGenerator extends WgslGenerator { this.#fnDepth = 0; } - public functionDefinition(body: tinyest.Block): string { + public functionDefinition(options: ShaderGenerator.FunctionDefinitionOptions): string { this.#fnDepth++; try { - return super.functionDefinition(body); + return super.functionDefinition(options); } finally { this.#fnDepth--; } diff --git a/packages/typegpu/tests/vector.test.ts b/packages/typegpu/tests/vector.test.ts index 87149c62a0..c8700e4f55 100644 --- a/packages/typegpu/tests/vector.test.ts +++ b/packages/typegpu/tests/vector.test.ts @@ -828,10 +828,10 @@ describe('v3f', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() { - var planarPosLocal = vec2f(1, 2); - var one = vec3f(1, 2, 12); - var two = vec3f(planarPosLocal, 12f); - var three = vec3f(1, 2, 12); + let planarPosLocal = vec2f(1, 2); + let one = vec3f(1, 2, 12); + let two = vec3f(planarPosLocal, 12f); + let three = vec3f(1, 2, 12); }" `); }); @@ -875,10 +875,10 @@ describe('v4f', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() { - var green = vec3f(0, 1, 0); - var one = vec4f(0.125, 0.25, 0.375, 1); - var two = vec4f(green, 1f); - var three = vec4f(0, 0, 1, 1); + let green = vec3f(0, 1, 0); + let one = vec4f(0.125, 0.25, 0.375, 1); + let two = vec4f(green, 1f); + let three = vec4f(0, 0, 1, 1); }" `); }); @@ -904,10 +904,10 @@ describe('v4f', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() { - var fooLocal = vec3f(0.25, 0.5, 0.75); - var one = vec4f(0.25, 0.25, 0.5, 0.75); - var two = vec4f(0.1f, fooLocal); - var three = vec4f(0.125, 0.25, 0.5, 0.75); + let fooLocal = vec3f(0.25, 0.5, 0.75); + let one = vec4f(0.25, 0.25, 0.5, 0.75); + let two = vec4f(0.1f, fooLocal); + let three = vec4f(0.125, 0.25, 0.5, 0.75); }" `); }); @@ -959,10 +959,10 @@ describe('v4b', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() { - var vecLocal = vec3(true); - var one = vec4(true, false, true, true); - var two = vec4(vecLocal, false); - var three = vec4(false, false, true, true); + let vecLocal = vec3(true); + let one = vec4(true, false, true, true); + let two = vec4(vecLocal, false); + let three = vec4(false, false, true, true); }" `); }); @@ -1000,8 +1000,8 @@ describe('type predicates', () => { } fn main() { - var foo = ceil_1(vec3f(1, 2, 3)); - var bar = ceil_2(vec3i(1, 2, 3)); + let foo = ceil_1(vec3f(1, 2, 3)); + let bar = ceil_2(vec3i(1, 2, 3)); }" `); }); @@ -1203,7 +1203,7 @@ describe('RGBA swizzles', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() -> vec3f { - var color = vec4f(1, 0.5, 0.25, 1); + let color = vec4f(1, 0.5, 0.25, 1); return color.rgb; }" `); @@ -1220,7 +1220,7 @@ describe('RGBA swizzles', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() -> vec4f { - var color = vec4f(1, 0.5, 0.25, 1); + let color = vec4f(1, 0.5, 0.25, 1); return color.bgra; }" `); @@ -1252,7 +1252,7 @@ describe('RGBA swizzles', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn main() -> f32 { - var color = vec4f(1, 0.5, 0.25, 0.75); + let color = vec4f(1, 0.5, 0.25, 0.75); return color.a; }" `);