www.xbdev.net
xbdev - software development
Wednesday January 15, 2025
Home | Contact | Support | WebGPU Graphics and Compute ...
     
 

WebGPU/WGSL Tutorials and Articles

Graphics and Compute ...

 


Procedural Textures


Generating textures using various algorithms - from wood and stone through to lava, dirt and fabrics.


Natural Materials
1. Wood Grain: Mimics the rings of a tree using sinusoidal and noise-based modulation.
2. Marble: Simulates marble veining with sine functions combined with turbulence.
3. Stone/Granite: Produces rugged surfaces using fractal noise with fine jitter.
4. Sand/Dirt: Grainy patterns with FBM (Fractal Brownian Motion) noise.
5. Water/Waves: Undulating wave patterns using layered sinusoids.
6. Fire/Flames: Animated turbulence with a fiery color gradient.
7. Clouds: Soft, billowy patterns from smooth FBM noise.


Geometric Patterns
8. Checkerboard: Alternating squares of contrasting colors.
9. Stripes: Horizontal or vertical repeating bands.
10. Polka Dots: Repeated circular patterns with uniform or random distribution.
11. Hexagonal Grid: Honeycomb-like tessellation.
12. Triangle Grid: Tessellated triangular arrangements.
13. Wave Patterns: Sinusoidal waves, optionally layered for complexity.
14. Concentric Circles: Expanding rings emanating from a center.
15. Radial Gradient: Smooth transitions radiating outward from a point.
16. Spiral: Coiled patterns created with polar coordinates.

Organic/Abstract Patterns
17. Veins/Cracks: Geological fault patterns using Voronoi noise.
18. Bubbles: Randomized circular shapes resembling foam.
19. Plasma: Swirling, colorful, and dynamic noise patterns.
20. Interference: Moiré effects from overlapping sine waves.
21. Growth Rings: Concentric patterns mimicking organic growth.
22. Lava: Animated molten rock textures with turbulent distortion.


Synthetic Textures
23. Metallic Brushed: Anisotropic noise for brushed metal effects.
24. Circuit Board: Geometric, grid-like patterns with fine detail.
25. Carbon Fiber: Woven, tight checkerboard patterns.
26. Brick Wall: Offset rectangular patterns for walls.
27. Fabric/Weave: Intersecting sine waves mimicking textile patterns.

Procedural Variations
28. Fractal Terrain: Mountain-like patterns with height maps.
29. Gaseous Nebula: Colorful, swirling patterns resembling space phenomena.
30. Stained Glass: Randomized Voronoi cells with bright colors.
31. Lightning: Jagged, branching patterns from fractal techniques.
32. Pebble Path: Coherent scatter of rounded shapes.
33. Grass: Thin, randomized lines simulating blades of grass.
34. Snowflakes: Geometric, fractal-like patterns for snow crystals.
35. Wood Bark: Ridged, layered noise for bark textures.

Mathematical Patterns
36. Mandelbrot Set: Complex fractal patterns with infinite detail.
37. Julia Set: Parameterized fractals similar to Mandelbrot.
38. Moire Patterns: Overlapping grids creating interference effects.
39. Sinusoidal Grids: Ripple-like patterns from intersecting sine waves.
40. Tiled Fractals: Fractal shapes repeated within a tile grid.

Animated/Temporal Patterns
41. Flow Fields: Simulates fluid-like directional motion.
42. Ripples: Expanding wave rings resembling raindrop ripples.
43. Pulsing Rings: Oscillating concentric circles.
44. Fading Stripes: Time-based transitions between stripe patterns.
45. Morphing Grid: Dynamically distorting grid patterns.

Color-Based Patterns
46. Rainbow Gradient: Smooth transitions across the color spectrum.
47. Heatmap: Gradient patterns similar to thermal imaging.
48. Fluorescent Glow: Radial gradients with a glowing effect.
49. Iridescence: Thin-film interference patterns.
50. Grayscale Noise: Monochrome noise for masking or blending.




For fun, lets put all the textures on a single image!
For fun, lets put all the textures on a single image!





Example Implementations


Obviously their is dozens of different ways to implement the texture algorithms - but to get you started and give you an idea the following gives you a simple example.



1. Wood Grain

// Default parameters: scale=10.0, grainIntensity=5.0
fn woodTexture(uvvec2<f32>, scalef32 10.0grainIntensityf32 5.0) -> vec3<f32> {
    
let rings scale uv.grainIntensity sin(scale uv.y);
    
let grain abs(sin(rings));
    return 
vec3<f32>(graingrain 0.5grain 0.2);
}



2. Marble

// Default parameters: scale=5.0, turbulence=2.0
fn marbleTexture(uvvec2<f32>, scalef32 5.0turbulencef32 2.0) -> vec3<f32> {
    
let veins sin(uv.scale turbulence sin(uv.scale));
    
let marble 0.5 0.5 veins;
    return 
vec3<f32>(marblemarblemarble 0.8);
}



3. Stone/Granite

// Default parameters: scale=8.0, roughness=0.5
fn stoneTexture(uvvec2<f32>, scalef32 8.0roughnessf32 0.5) -> vec3<f32> {
    
let noise fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    
let texture mix(1.0noiseroughness);
    return 
vec3<f32>(texture 0.7texture 0.6texture 0.4);
}



4. Sand/Dirt

// Default parameters: scale=10.0, noiseFactor=0.5
fn sandTexture(uvvec2<f32>, scalef32 10.0noiseFactorf32 0.5) -> vec3<f32> {
    
let noise fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    
let dirt mix(0.70.9noise noiseFactor);
    return 
vec3<f32>(dirtdirt 0.8dirt 0.5);
}



5. Water/Waves

// Default parameters: scale=1.0, frequency=5.0
fn waterRippleTexture(uvvec2<f32>, scalef32 1.0frequencyf32 5.0) -> vec3<f32> {
    
let ripple sin(uv.frequency uv.frequency);
    return 
vec3<f32>(0.00.5 0.5 ripple1.0);
}



6. Fire/Flames

// Default parameters: scale=2.0, turbulence=3.0
fn fireTexture(uvvec2<f32>, scalef32 2.0turbulencef32 3.0) -> vec3<f32> {
    
let flame abs(sin(uv.scale turbulence sin(uv.scale)));
    return 
vec3<f32>(flameflame 0.50.0);
}



7. Clouds

// Default parameters: scale=5.0, softness=0.6
fn cloudTexture(uvvec2<f32>, scalef32 5.0softnessf32 0.6) -> vec3<f32> {
    
let noise fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    
let clouds smoothstep(softness1.0noise);
    return 
vec3<f32>(clouds 0.8clouds 0.8clouds 0.9);
}




Geometric Patterns



8. Checkerboard

// Default parameters: scale=5.0
fn checkerboardTexture(uvvec2<f32>, scalef32 5.0) -> vec3<f32> {
    
let checker mod(floor(uv scale), 2.0);
    return 
vec3<f32>(checker.xchecker.y0.0);
}



9. Stripes

// Default parameters: scale=5.0, direction=1.0
fn stripeTexture(uvvec2<f32>, scalef32 5.0directionf32 1.0) -> vec3<f32> {
    
let stripe mod(floor(uv.scale direction), 2.0);
    return 
vec3<f32>(stripe0.00.0);
}



10. Polka Dots

// Default parameters: scale=10.0, radius=0.2
fn polkaDotTexture(uvvec2<f32>, scalef32 10.0radiusf32 0.2) -> vec3<f32> {
    
let center fract(uv scale);
    
let dist length(center 0.5);
    return 
vec3<f32>(step(distradius), 0.00.0);
}



11. Hexagonal Grid

// Default parameters: scale=10.0
fn hexagonalGrid(uvvec2<f32>, scalef32 10.0) -> vec3<f32> {
    
let hex mod(floor(uv scale), 2.0);
    return 
vec3<f32>(hex.xhex.y0.0);
}



12. Triangle Grid

// Default parameters: scale=10.0
fn triangleGrid(uvvec2<f32>, scalef32 10.0) -> vec3<f32> {
    
let tri mod(floor(uv scale), 2.0);
    return 
vec3<f32>(tri.x0.0tri.y);
}



13. Wave Patterns

// Default parameters: frequency=5.0
fn wavePattern(uvvec2<f32>, frequencyf32 5.0) -> vec3<f32> {
    
let wave sin(uv.frequency) + sin(uv.frequency);
    return 
vec3<f32>(wave 0.5 0.50.00.0);
}



14. Concentric Circles

// Default parameters: scale=5.0, center=0.5
fn concentricCircles(uvvec2<f32>, scalef32 5.0centerf32 0.5) -> vec3<f32> {
    
let dist length(uv vec2<f32>(centercenter)) * scale;
    
let rings sin(dist);
    return 
vec3<f32>(rings 0.5 0.5rings 0.3rings 0.1);
}



15. Radial Gradient

// Default parameters: scale=5.0
fn radialGradient(uvvec2<f32>, scalef32 5.0) -> vec3<f32> {
    
let dist length(uv 0.5) * scale;
    return 
vec3<f32>(distdist 0.5dist 0.2);
}



16. Spiral

// Default parameters: scale=5.0, turnCount=5.0
fn spiralTexture(uvvec2<f32>, scalef32 5.0turnCountf32 5.0) -> vec3<f32> {
    
let angle atan2(uv.0.5uv.0.5);
    
let radius length(uv 0.5) * scale;
    
let spiral sin(angle turnCount radius);
    return 
vec3<f32>(spiral 0.5 0.5spiral 0.4spiral 0.3);
}




Organic/Abstract Patterns



17. Veins/Cracks

// Default parameters: scale=5.0, roughness=1.0
fn veinsTexture(uvvec2<f32>, scalef32 5.0roughnessf32 1.0) -> vec3<f32> {
    
let veins fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    return 
vec3<f32>(veins roughnessveins roughness 0.60.0);
}



18. Bubbles

// Default parameters: scale=10.0, size=0.1
fn bubblesTexture(uvvec2<f32>, scalef32 10.0sizef32 0.1) -> vec3<f32> {
    
let dist length(fract(uv scale) - 0.5);
    return 
vec3<f32>(step(distsize), 0.51.0);
}



19. Plasma

// Default parameters: scale=5.0, turbulence=0.5
fn plasmaTexture(uvvec2<f32>, scalef32 5.0turbulencef32 0.5) -> vec3<f32> {
    
let noise sin(uv.scale turbulence cos(uv.scale));
    return 
vec3<f32>(noise 0.5 0.5noise 0.3 0.5noise 0.2 0.5);
}



20. Interference

// Default parameters: scale=5.0, amplitude=0.5
fn interferenceTexture(uvvec2<f32>, scalef32 5.0amplitudef32 0.5) -> vec3<f32> {
    
let interference sin(uv.scale uv.scale) * amplitude;
    return 
vec3<f32>(interferenceinterference 0.5interference 0.3);
}



21. Growth Rings

// Default parameters: scale=5.0, rings=10.0
fn growthRingsTexture(uvvec2<f32>, scalef32 5.0ringsf32 10.0) -> vec3<f32> {
    
let dist length(uv 0.5) * scale;
    
let ring sin(dist rings);
    return 
vec3<f32>(ring 0.8 0.2ring 0.6 0.4ring 0.4 0.2);
}



22. Lava

// Default parameters: scale=5.0, intensity=1.5
fn lavaTexture(uvvec2<f32>, scalef32 5.0intensityf32 1.5) -> vec3<f32> {
    
let noise fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    
let lava noise intensity;
    return 
vec3<f32>(lava 1.0lava 0.5lava 0.0);
}




Synthetic Textures




23. Metallic Brushed

// Default parameters: scale=5.0, roughness=0.3
fn metallicBrushedTexture(uvvec2<f32>, scalef32 5.0roughnessf32 0.3) -> vec3<f32> {
    
let noise fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    
let metallic mix(0.51.0noise roughness);
    return 
vec3<f32>(metallicmetallic 0.7metallic 0.4);
}



24. Circuit Board

// Default parameters: scale=10.0, lineThickness=0.02
fn circuitBoardTexture(uvvec2<f32>, scalef32 10.0lineThicknessf32 0.02) -> vec3<f32> {
    
let grid fract(uv scale);
    
let lines step(lineThicknessgrid);
    return 
vec3<f32>(lines.xlines.ylines.0.5);
}



25. Carbon Fiber

// Default parameters: scale=10.0, weaveSize=0.1
fn carbonFiberTexture(uvvec2<f32>, scalef32 10.0weaveSizef32 0.1) -> vec3<f32> {
    
let dist length(fract(uv scale) - 0.5);
    return 
vec3<f32>(step(distweaveSize), step(distweaveSize) * 0.7step(distweaveSize) * 0.5);
}



26. Brick Wall

// Default parameters: scale=1.0, brickHeight=0.2
fn brickWallTexture(uvvec2<f32>, scalef32 1.0brickHeightf32 0.2) -> vec3<f32> {
    
let brick mod(floor(uv.scale), 2.0);
    
let height mod(floor(uv.brickHeight), 2.0);
    return 
vec3<f32>(brickbrick 0.3height 0.3);
}



27. Fabric/Weave

// Default parameters: scale=10.0, weaveSize=0.1
fn fabricWeaveTexture(uvvec2<f32>, scalef32 10.0weaveSizef32 0.1) -> vec3<f32> {
    
let dist length(fract(uv scale) - 0.5);
    return 
vec3<f32>(step(distweaveSize), step(distweaveSize) * 0.7step(distweaveSize) * 0.5);
}




Procedural Variations




28. Fractal Terrain

// Default parameters: scale=5.0, roughness=0.6
fn fractalTerrainTexture(uvvec2<f32>, scalef32 5.0roughnessf32 0.6) -> vec3<f32> {
    
let noise fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    return 
vec3<f32>(noise roughnessnoise 0.7noise 0.3);
}



29. Gaseous Nebula

// Default parameters: scale=5.0, intensity=0.5
fn gaseousNebulaTexture(uvvec2<f32>, scalef32 5.0intensityf32 0.5) -> vec3<f32> {
    
let noise fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    return 
vec3<f32>(noise intensitynoise 0.8noise 0.6);
}



30. Stained Glass

// Default parameters: scale=5.0, colorVariance=0.2
fn stainedGlassTexture(uvvec2<f32>, scalef32 5.0colorVariancef32 0.2) -> vec3<f32> {
    
let cell fract(uv scale);
    return 
vec3<f32>(cell.colorVariancecell.colorVariance, (cell.cell.y) * 0.3);
}



31. Lightning

// Default parameters: scale=5.0, jaggedness=1.0
fn lightningTexture(uvvec2<f32>, scalef32 5.0jaggednessf32 1.0) -> vec3<f32> {
    
let noise fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    
let lightning abs(noise 0.5) * jaggedness;
    return 
vec3<f32>(lightninglightning 0.8lightning 0.4);
}



32. Pebble Path

// Default parameters: scale=10.0, pebbleSize=0.1
fn pebblePathTexture(uvvec2<f32>, scalef32 10.0pebbleSizef32 0.1) -> vec3<f32> {
    
let dist length(fract(uv scale) - 0.5);
    return 
vec3<f32>(step(distpebbleSize), 0.60.3);
}



33. Grass

// Default parameters: scale=10.0, bladeHeight=0.5
fn grassTexture(uvvec2<f32>, scalef32 10.0bladeHeightf32 0.5) -> vec3<f32> {
    
let blade step(0.2fract(uv.scale)) * bladeHeight;
    return 
vec3<f32>(0.2blade 0.80.2);
}



34. Snowflakes

// Default parameters: scale=5.0, fractalDetail=2.0
fn snowflakeTexture(uvvec2<f32>, scalef32 5.0fractalDetailf32 2.0) -> vec3<f32> {
    
let noise fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    
let snowflake smoothstep(fractalDetail1.0noise);
    return 
vec3<f32>(snowflake 0.9snowflake 0.9snowflake 1.0);
}



35. Wood Bark

// Default parameters: scale=5.0, ridges=5.0
fn woodBarkTexture(uvvec2<f32>, scalef32 5.0ridgesf32 5.0) -> vec3<f32> {
    
let bark sin(uv.scale uv.ridges);
    return 
vec3<f32>(bark 0.6 0.4bark 0.5 0.3bark 0.3 0.2);
}



36. Mandelbrot Set

// Default parameters: scale=5.0, iterations=50
fn mandelbrotSet(uvvec2<f32>, scalef32 5.0iterationsf32 50.0) -> vec3<f32> {
    
let c uv scale 1.0;
    var 
vec2<f32>(0.00.0);
    var 
countf32 0.0;
    for (var 
0uiterations1u) {
        
vec2<f32>(z.z.z.z.y2.0 z.z.y) + c;
        if (
length(z) > 2.0) {
            break;
        }
        
count count 1.0;
    }
    return 
vec3<f32>(count iterationscount iterationscount iterations);
}



37. Julia Set

// Default parameters: scale=1.0, iterations=50
fn juliaSet(uvvec2<f32>, scalef32 1.0iterationsf32 50.0) -> vec3<f32> {
    
let c vec2<f32>(0.3550.355); // Fixed Julia constant
    
var uv scale;
    var 
countf32 0.0;
    for (var 
0uiterations1u) {
        
vec2<f32>(z.z.z.z.y2.0 z.z.y) + c;
        if (
length(z) > 2.0) {
            break;
        }
        
count count 1.0;
    }
    return 
vec3<f32>(count iterationscount iterationscount iterations);
}



38. Moire Patterns

// Default parameters: scale=10.0, frequency=5.0
fn moirePatternsTexture(uvvec2<f32>, scalef32 10.0frequencyf32 5.0) -> vec3<f32> {
    
let grid1 fract(uv scale);
    
let grid2 fract(uv scale frequency);
    
let interference abs(grid1 grid2);
    return 
vec3<f32>(interferenceinterference 0.5interference 0.2);
}



39. Sinusoidal Grids

// Default parameters: scale=10.0, frequency=2.0
fn sinusoidalGridsTexture(uvvec2<f32>, scalef32 10.0frequencyf32 2.0) -> vec3<f32> {
    
let sinX sin(uv.frequency);
    
let sinY sin(uv.frequency);
    
let grid abs(sinX sinY);
    return 
vec3<f32>(gridgrid 0.5grid 0.2);
}



40. Tiled Fractals

// Default parameters: scale=5.0, fractalDetail=2.0
fn tiledFractalsTexture(uvvec2<f32>, scalef32 5.0fractalDetailf32 2.0) -> vec3<f32> {
    
let noise fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    
let fractal fract(noise fractalDetail);
    return 
vec3<f32>(fractalfractal 0.7fractal 0.5);
}



41. Flow Fields

// Default parameters: scale=10.0, speed=0.1
fn flowFieldsTexture(uvvec2<f32>, scalef32 10.0speedf32 0.1) -> vec3<f32> {
    
let flow sin(uv.scale speed sin(uv.scale));
    return 
vec3<f32>(flowflow 0.5flow 0.2);
}



42. Ripples

// Default parameters: scale=10.0, waveSpeed=0.5
fn ripplesTexture(uvvec2<f32>, scalef32 10.0waveSpeedf32 0.5) -> vec3<f32> {
    
let dist length(uv 0.5);
    
let ripples sin(dist scale waveSpeed);
    return 
vec3<f32>(ripples 0.5 0.5ripples 0.3 0.5ripples 0.1 0.5);
}



43. Pulsing Rings

// Default parameters: scale=10.0, pulseSpeed=1.0
fn pulsingRingsTexture(uvvec2<f32>, scalef32 10.0pulseSpeedf32 1.0) -> vec3<f32> {
    
let dist length(uv 0.5) * scale;
    
let pulse sin(dist pulseSpeed sin(dist));
    return 
vec3<f32>(pulse 0.5 0.5pulse 0.3 0.5pulse 0.2 0.5);
}



44. Fading Stripes

// Default parameters: scale=10.0, fadeSpeed=1.0
fn fadingStripesTexture(uvvec2<f32>, scalef32 10.0fadeSpeedf32 1.0) -> vec3<f32> {
    
let stripes mod(floor(uv.scale), 2.0);
    
let fade smoothstep(0.0fadeSpeedsin(uv.scale));
    return 
vec3<f32>(stripesstripes fadestripes 0.5);
}



45. Morphing Grid

// Default parameters: scale=10.0, time=0.0
fn morphingGridTexture(uvvec2<f32>, scalef32 10.0timef32 0.0) -> vec3<f32> {
    
let grid fract(uv scale time);
    return 
vec3<f32>(gridgrid 0.5grid 0.2);
}



46. Rainbow Gradient

// Default parameters: scale=10.0, offset=0.0
fn rainbowGradientTexture(uvvec2<f32>, scalef32 10.0offsetf32 0.0) -> vec3<f32> {
    
let rainbow mod(uv.scale offset1.0);
    return 
vec3<f32>(rainbow1.0 rainbow0.5);
}



47. Heatmap

// Default parameters: scale=10.0, intensity=0.8
fn heatmapTexture(uvvec2<f32>, scalef32 10.0intensityf32 0.8) -> vec3<f32> {
    
let heat smoothstep(0.0intensityuv.scale);
    return 
vec3<f32>(heat0.51.0 heat);
}



48. Fluorescent Glow

// Default parameters: scale=10.0, glowIntensity=1.0
fn fluorescentGlowTexture(uvvec2<f32>, scalef32 10.0glowIntensityf32 1.0) -> vec3<f32> {
    
let dist length(uv 0.5);
    
let glow smoothstep(0.0glowIntensitydist scale);
    return 
vec3<f32>(glowglow 0.5glow 1.0);
}



49. Iridescence

// Default parameters: scale=10.0, filmThickness=0.1
fn iridescenceTexture(uvvec2<f32>, scalef32 10.0filmThicknessf32 0.1) -> vec3<f32> {
    
let dist length(uv 0.5) * scale;
    
let iridescence smoothstep(0.0filmThicknessdist);
    return 
vec3<f32>(iridescenceiridescence 0.5iridescence 0.7);
}



50. Grayscale Noise

// Default parameters: scale=10.0, intensity=0.5
fn grayscaleNoiseTexture(uvvec2<f32>, scalef32 10.0intensityf32 0.5) -> vec3<f32> {
    
let noise fract(sin(dot(uvvec2<f32>(scalescale))) * 43758.5453);
    return 
vec3<f32>(noise intensitynoise intensitynoise intensity);
}



Things to Try


These functions are only the the start of procedural textures - but they provide examples of just how easy it is to create textures instead of loading them from a file.

Some things to try:

• Add more texture types
• Play around with the default parameters (maybe add an interface to control them)
• Mix and combine the textures (e.g., wood with dirt)
• Explore 3D textures - instead of just a 2d uv seed - you can use a 3d seed (extra depth value) - which should represent the changes of the texture as you slice away the layers (think of it like a piece of wood - if you cut away layers of the wood - you'll see the wooden grain texture change)
• Try other color mixes




Resources & Links


• All Texture Generation Examples (LINK)



















WebGPU Development Pixels - coding fragment shaders from post processing to ray tracing! WebGPU by Example: Fractals, Image Effects, Ray-Tracing, Procedural Geometry, 2D/3D, Particles, Simulations WebGPU Games WGSL 2d 3d interactive web-based fun learning WebGPU Compute WebGPU API - Owners WebGPU Development Cookbook - coding recipes for all your webgpu needs! WebGPU & WGSL Essentials: A Hands-On Approach to Interactive Graphics, Games, 2D Interfaces, 3D Meshes, Animation, Security and Production Kenwright graphics and animations using the webgpu api 12 week course kenwright learn webgpu api kenwright programming compute and graphics applications with html5 and webgpu api kenwright real-time 3d graphics with webgpu kenwright webgpu for dummies kenwright webgpu api develompent a quick start guide kenwright webgpu by example 2022 kenwright webgpu gems kenwright webgpu interactive compute and graphics visualization cookbook kenwright wgsl webgpu shading language cookbook kenwright WebGPU Shader Language Development: Vertex, Fragment, Compute Shaders for Programmers Kenwright wgsl webgpugems shading language cookbook kenwright WGSL Fundamentals book kenwright WebGPU Data Visualization Cookbook kenwright Special Effects Programming with WebGPU kenwright WebGPU Programming Guide: Interactive Graphics and Compute Programming with WebGPU & WGSL kenwright Ray-Tracing with WebGPU kenwright



 
Advert (Support Website)

 
 Visitor:
Copyright (c) 2002-2024 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.