Skip to content

Conversation

@donmccurdy
Copy link
Collaborator

@donmccurdy donmccurdy commented Jan 14, 2025

Step toward #29573. Adds an independent parameter allowing the user to configure a float16 drawing buffer on a WebGPU canvas. For WebGL backends this does nothing, but my understanding is that WebGL will eventually support higher bit depth output as well.

Example:

// default to device preference
const renderer = new WebGPURenderer();

// uint8
const renderer = new WebGPURenderer( { outputType: THREE.UnsignedByteType } );

// float16
const renderer = new WebGPURenderer( { outputType: THREE.HalfFloatType } );

A quick way to test the result is to modify the TSL editor example, widen the preview renderer to at least 800px x 200px, and draw a dark gradient:

const { uniform, vec3, vec4, uv } = await import( 'three/tsl' );

const l = uv().mul( 0.01 ).r;

output = vec4( l, l, l, 1.0 );

On a good monitor (for some unspecified definition of "good"; a modern Macbook Pro display will certainly do) you will see banding with outputType: UnsignedByteType, and the banding disappears with outputType: HalfFloatType.

EDIT: I removed the screenshot, as it's difficult to get a reliable capture of the difference. I thought I had one taken correctly, but the bands seem to have disappeared (under compression on upload to Github?).

@donmccurdy donmccurdy force-pushed the feat/webgpurenderer-canvastype branch from 98dcb94 to bfc0b70 Compare January 14, 2025 04:59
@github-actions
Copy link

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 339.52
79.1
339.52
79.1
+0 B
+0 B
WebGPU 490.85
136.4
490.96
136.42
+110 B
+23 B
WebGPU Nodes 490.32
136.29
490.43
136.31
+110 B
+23 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Before After Diff
WebGL 465.41
112.15
465.41
112.15
+0 B
+0 B
WebGPU 561.43
152.1
561.53
152.12
+108 B
+24 B
WebGPU Nodes 516.81
141.67
516.92
141.7
+108 B
+24 B

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Jan 14, 2025

The equivalent WebGPU terminology would be "canvas format", but (1) three.js uses "type" rather than "format" today, and (2) while I think the term "canvas" is fine, I somewhat prefer to keep alignment with the current .outputColorSpace property's prefix.

@Mugen87
Copy link
Collaborator

Mugen87 commented Jan 14, 2025

On a good monitor (for some unspecified definition of "good"; a modern Macbook Pro display will certainly do) you will see banding with outputType: UnsignedByteType, and the banding disappears with outputType: HalfFloatType.

Indeed! I can confirm on a Mac Studio Display that the banding disappears when using outputType: THREE.HalfFloatType 🎉 .

@Mugen87 Mugen87 added this to the r173 milestone Jan 14, 2025
@sunag sunag merged commit 53452d3 into mrdoob:dev Jan 14, 2025
12 checks passed
@donmccurdy donmccurdy deleted the feat/webgpurenderer-canvastype branch January 14, 2025 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants