diff --git a/webgpu/lessons/webgpu-optimization.md b/webgpu/lessons/webgpu-optimization.md index 8d696eb9..0eda2c32 100644 --- a/webgpu/lessons/webgpu-optimization.md +++ b/webgpu/lessons/webgpu-optimization.md @@ -274,14 +274,9 @@ const hsl = (h, s, l) => `hsl(${h * 360 | 0}, ${s * 100}%, ${l * 100 | 0}%)`; /** * Given hue, saturation, and luminance values in the range of 0 to 1 - * returns an array of values from 0 to 1 + * returns an array of 4 values from 0 to 1 */ const hslToRGBA = (h, s, l) => cssColorToRGBA(hsl(h, s, l)); -/** - * Given hue, saturation, and luminance values in the range of 0 to 1 - * returns an array of values from 0 to 255 - */ -const hslToRGBA8 = (h, s, l) => cssColorToRGBA8(hsl(h, s, l)); /** * Returns a random number between min and max. @@ -305,32 +300,31 @@ const randomArrayElement = arr => arr[Math.random() * arr.length | 0]; Hopefully they are all pretty straight forward. -Now let's make a texture and a sampler. The texture will -just be a 2x2 texel texture with 4 shades of gray. +Now let's make some textures and a sampler. We'll use +a canvas, draw an emoji on it, and then use our function +`createTextureFromSource` that we wrote in +[the article on importing textures](webgpu-importing-textures.html) +to create a texture from it. ```js - const texture = device.createTexture({ - size: [2, 2], - format: 'rgba8unorm', - usage: - GPUTextureUsage.TEXTURE_BINDING | - GPUTextureUsage.COPY_DST, + const textures = [ + '😂', '👾', '👍', '👀', '🌞', '🛟', + ].map(s => { + const size = 128; + const ctx = new OffscreenCanvas(size, size).getContext('2d'); + ctx.fillStyle = '#fff'; + ctx.fillRect(0, 0, size, size); + ctx.font = `${size * 0.9}px sans-serif`; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + ctx.fillText(s, size / 2, size / 2); + return createTextureFromSource(device, ctx.canvas, {mips: true}); }); - device.queue.writeTexture( - { texture }, - new Uint8Array([ - ...hslToRGBA8(0, 0, 1), - ...hslToRGBA8(0, 0, 0.5), - ...hslToRGBA8(0, 0, 0.75), - ...hslToRGBA8(0, 0, 0.25), - ]), - { bytesPerRow: 8, rowsPerImage: 2 }, - { width: 2, height: 2 }, - ); const sampler = device.createSampler({ - magFilter: 'nearest', - minFilter: 'nearest', + magFilter: 'linear', + minFilter: 'linear', + mipmapFilter: 'nearest', }); ``` @@ -350,7 +344,7 @@ We'll make 20 "materials" and then pick a material at random for each cube. materials.push({ color, shininess, - texture, + texture: randomArrayElement(textures), sampler, }); } @@ -1580,7 +1574,7 @@ Then we'll make a uniform buffer for each material. - color, - shininess, + materialUniformBuffer, - texture, + texture: randomArrayElement(textures), sampler, }); } diff --git a/webgpu/webgl-optimization-none-uniform-buffers.html b/webgpu/webgl-optimization-none-uniform-buffers.html index ab103c0d..56cafeee 100644 --- a/webgpu/webgl-optimization-none-uniform-buffers.html +++ b/webgpu/webgl-optimization-none-uniform-buffers.html @@ -145,14 +145,9 @@ /** * Given hue, saturation, and luminance values in the range of 0 to 1 - * returns an array of values from 0 to 1 + * returns an array of 4 values from 0 to 1 */ const hslToRGBA = (h, s, l) => cssColorToRGBA(hsl(h, s, l)); -/** - * Given hue, saturation, and luminance values in the range of 0 to 1 - * returns an array of values from 0 to 255 - */ -const hslToRGBA8 = (h, s, l) => cssColorToRGBA8(hsl(h, s, l)); /** * Returns a random number between min and max. @@ -278,17 +273,23 @@ gl.enable(gl.CULL_FACE); gl.enable(gl.DEPTH_TEST); - const texture = twgl.createTexture(gl, { - format: gl.RGBA, - width: 2, - src: new Uint8Array([ - ...hslToRGBA8(0, 0, 1), - ...hslToRGBA8(0, 0, 0.5), - ...hslToRGBA8(0, 0, 0.75), - ...hslToRGBA8(0, 0, 0.25), - ]), - minMag: gl.NEAREST, - wrap: gl.CLAMP_TO_EDGE, + const textures = [ + '😂', '👾', '👍', '👀', '🌞', '🛟', + ].map(s => { + const size = 128; + const ctx = new OffscreenCanvas(size, size).getContext('2d'); + ctx.fillStyle = '#fff'; + ctx.fillRect(0, 0, size, size); + ctx.font = `${size * 0.9}px sans-serif`; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + ctx.fillText(s, size / 2, size / 2); + return twgl.createTexture(gl, { + src: ctx.canvas, + wrap: gl.CLAMP_TO_EDGE, + min: gl.LINEAR_MIPMAP_NEAREST, + mag: gl.LINEAR, + }); }); const numMaterials = 20; @@ -299,7 +300,7 @@ materials.push({ color, shininess, - texture, + texture: randomArrayElement(textures), }); } @@ -315,7 +316,7 @@ const scale = rand(2, 10); const uniforms = { - diffuseTexture: texture, + diffuseTexture: randomArrayElement(textures), }; const uboInfo = twgl.createUniformBlockInfo(gl, prgInfo, 'Uniforms'); @@ -375,7 +376,6 @@ timingHelper.begin(); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - gl.useProgram(prgInfo.program); twgl.setBuffersAndAttributes(gl, prgInfo, bufferInfo); @@ -459,7 +459,6 @@ gpu : ${(gpuAverage.get() / 1000 / 1000).toFixed(1)}ms `; - requestAnimationFrame(render); } requestAnimationFrame(render); diff --git a/webgpu/webgl-optimization-none.html b/webgpu/webgl-optimization-none.html index 04c05c89..3148b3a4 100644 --- a/webgpu/webgl-optimization-none.html +++ b/webgpu/webgl-optimization-none.html @@ -145,14 +145,9 @@ /** * Given hue, saturation, and luminance values in the range of 0 to 1 - * returns an array of values from 0 to 1 + * returns an array of 4 values from 0 to 1 */ const hslToRGBA = (h, s, l) => cssColorToRGBA(hsl(h, s, l)); -/** - * Given hue, saturation, and luminance values in the range of 0 to 1 - * returns an array of values from 0 to 255 - */ -const hslToRGBA8 = (h, s, l) => cssColorToRGBA8(hsl(h, s, l)); /** * Returns a random number between min and max. @@ -273,17 +268,23 @@ gl.enable(gl.CULL_FACE); gl.enable(gl.DEPTH_TEST); - const texture = twgl.createTexture(gl, { - format: gl.RGBA, - width: 2, - src: new Uint8Array([ - ...hslToRGBA8(0, 0, 1), - ...hslToRGBA8(0, 0, 0.5), - ...hslToRGBA8(0, 0, 0.75), - ...hslToRGBA8(0, 0, 0.25), - ]), - minMag: gl.NEAREST, - wrap: gl.CLAMP_TO_EDGE, + const textures = [ + '😂', '👾', '👍', '👀', '🌞', '🛟', + ].map(s => { + const size = 128; + const ctx = new OffscreenCanvas(size, size).getContext('2d'); + ctx.fillStyle = '#fff'; + ctx.fillRect(0, 0, size, size); + ctx.font = `${size * 0.9}px sans-serif`; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + ctx.fillText(s, size / 2, size / 2); + return twgl.createTexture(gl, { + src: ctx.canvas, + wrap: gl.CLAMP_TO_EDGE, + min: gl.LINEAR_MIPMAP_NEAREST, + mag: gl.LINEAR, + }); }); const numMaterials = 20; @@ -294,7 +295,7 @@ materials.push({ color, shininess, - texture, + texture: randomArrayElement(textures), }); } @@ -317,7 +318,7 @@ viewWorldPosition: vec3.create(), color: new Float32Array(4), shininess: 0, - diffuseTexture: texture, + diffuseTexture: randomArrayElement(textures), }; objectInfos.push({ @@ -372,7 +373,6 @@ timingHelper.begin(); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - gl.useProgram(prgInfo.program); twgl.setBuffersAndAttributes(gl, prgInfo, bufferInfo); @@ -453,7 +453,6 @@ gpu : ${(gpuAverage.get() / 1000 / 1000).toFixed(1)}ms `; - requestAnimationFrame(render); } requestAnimationFrame(render); diff --git a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-16x16.html b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-16x16.html index 0f6b2715..ef7333da 100644 --- a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-16x16.html +++ b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-16x16.html @@ -116,7 +116,6 @@ `, }); - const histogramChunkPipeline = device.createComputePipeline({ label: 'histogram', layout: 'auto', @@ -222,7 +221,6 @@ console.log('sum:', sum); } - function showImageBitmap(imageBitmap) { const canvas = document.createElement('canvas'); diff --git a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more-gpu-draw-w-timing.html b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more-gpu-draw-w-timing.html index 49931638..85efbbd2 100644 --- a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more-gpu-draw-w-timing.html +++ b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more-gpu-draw-w-timing.html @@ -205,7 +205,6 @@ `, }); - const histogramChunkPipeline = device.createComputePipeline({ label: 'histogram', layout: 'auto', diff --git a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more-w-timing.html b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more-w-timing.html index c1e25c81..9dfdd6f4 100644 --- a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more-w-timing.html +++ b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more-w-timing.html @@ -124,7 +124,6 @@ `, }); - const histogramChunkPipeline = device.createComputePipeline({ label: 'histogram', layout: 'auto', diff --git a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more.html b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more.html index 40603853..384097c1 100644 --- a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more.html +++ b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-more.html @@ -115,7 +115,6 @@ `, }); - const histogramChunkPipeline = device.createComputePipeline({ label: 'histogram', layout: 'auto', diff --git a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-w-timing.html b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-w-timing.html index a4263826..f9d3cc91 100644 --- a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-w-timing.html +++ b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized-w-timing.html @@ -118,7 +118,6 @@ `, }); - const histogramChunkPipeline = device.createComputePipeline({ label: 'histogram', layout: 'auto', diff --git a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized.html b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized.html index a7c40469..e087a6b5 100644 --- a/webgpu/webgpu-compute-shaders-histogram-4ch-optimized.html +++ b/webgpu/webgpu-compute-shaders-histogram-4ch-optimized.html @@ -114,7 +114,6 @@ `, }); - const histogramChunkPipeline = device.createComputePipeline({ label: 'histogram', layout: 'auto', diff --git a/webgpu/webgpu-compute-shaders-histogram-optimized-16x16.html b/webgpu/webgpu-compute-shaders-histogram-optimized-16x16.html index ca9abbc5..51a6c35c 100644 --- a/webgpu/webgpu-compute-shaders-histogram-optimized-16x16.html +++ b/webgpu/webgpu-compute-shaders-histogram-optimized-16x16.html @@ -116,7 +116,6 @@ `, }); - const histogramChunkPipeline = device.createComputePipeline({ label: 'histogram', layout: 'auto', diff --git a/webgpu/webgpu-optimization-all.html b/webgpu/webgpu-optimization-all.html index 88471889..a30a814b 100644 --- a/webgpu/webgpu-optimization-all.html +++ b/webgpu/webgpu-optimization-all.html @@ -44,6 +44,9 @@