From 53875877baa4827348f6169ac9c5cb0c09889c1a Mon Sep 17 00:00:00 2001 From: Gregg Tavares Date: Tue, 18 Jun 2024 21:08:16 -0700 Subject: [PATCH] add textures --- webgpu/lessons/webgpu-optimization.md | 52 ++++++++----------- ...bgl-optimization-none-uniform-buffers.html | 41 +++++++-------- webgpu/webgl-optimization-none.html | 41 +++++++-------- ...shaders-histogram-4ch-optimized-16x16.html | 2 - ...-4ch-optimized-more-gpu-draw-w-timing.html | 1 - ...histogram-4ch-optimized-more-w-timing.html | 1 - ...-shaders-histogram-4ch-optimized-more.html | 1 - ...ders-histogram-4ch-optimized-w-timing.html | 1 - ...mpute-shaders-histogram-4ch-optimized.html | 1 - ...ute-shaders-histogram-optimized-16x16.html | 1 - webgpu/webgpu-optimization-all.html | 47 +++++++---------- webgpu/webgpu-optimization-none.html | 46 +++++++--------- ...n-step3-global-vs-per-object-uniforms.html | 46 +++++++--------- ...-optimization-step4-material-uniforms.html | 46 +++++++--------- ...ly-updated-uniform-buffers-pre-submit.html | 47 +++++++---------- ...er-frequently-updated-uniform-buffers.html | 47 +++++++---------- ...optimization-step5-use-buffer-offsets.html | 46 +++++++--------- ...-use-mapped-buffers-2-command-buffers.html | 46 +++++++--------- ...p6-use-mapped-buffers-dyanmic-offsets.html | 46 +++++++--------- ...ep6-use-mapped-buffers-math-w-offsets.html | 47 +++++++---------- ...optimization-step6-use-mapped-buffers.html | 46 +++++++--------- ...mization-step7-double-buffer-2-submit.html | 46 +++++++--------- ...on-step7-double-buffer-typedarray-set.html | 46 +++++++--------- ...bgpu-optimization-step7-double-buffer.html | 46 +++++++--------- 24 files changed, 342 insertions(+), 448 deletions(-) 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 @@