Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGPURenderer: Add .outputType backend parameter #30320

Merged
merged 1 commit into from
Jan 14, 2025

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?).

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