Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

BitcountNode - Add bitCount functions #31990

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

Open
cmhhelgeson wants to merge 11 commits into mrdoob:dev
base: dev
Choose a base branch
Loading
from cmhhelgeson:bit_count_functions

Conversation

@cmhhelgeson
Copy link
Contributor

@cmhhelgeson cmhhelgeson commented Sep 30, 2025
edited
Loading

Description

Add countTrailingZeros, countLeadingZeros, and countOneBits to TSL. Ideally, this functionality would also be accessible through the WebGLBackend, but I'm not sure what the status or likelihood is of the GLSL 3.1 functionality getting added to WebGL anytime in the future ( see KhronosGroup/WebGL#3714 ).

The impetus for implementing these functions is that they're notionally more concise and/or performant than equivalent operations ( log2, directly bit shifting, etc ).

I've also implemented each of these functions GLSL equivalents (findLSB, findMSB, bitCount) as aliases for the GLSL to TSL transpiration process. If it's preferred by the maintainers, we can get rid of the aliases and/or use the NodeBuilders to specify how the bitCount functions get constructed instead.

  • Add functionality to MathNode and/or separate BitCountNode
  • Add GLSL polyfills for functionality
  • Replace bitCount node in SSGI with TSL function and test output on WebGL/WebGPU backends
  • Validate that Transpiler produces correct output

Copy link

github-actions bot commented Sep 30, 2025
edited
Loading

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 350.11
84.81
350.11
84.81
+0 B
+0 B
WebGPU 604.15
169.43
607.19
170.38
+3.04 kB
+954 B
WebGPU Nodes 602.75
169.19
605.8
170.12
+3.04 kB
+924 B

🌳 Bundle size after tree-shaking

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

Before After Diff
WebGL 481.77
119.56
481.77
119.56
+0 B
+0 B
WebGPU 673.57
184.91
677.2
185.89
+3.63 kB
+981 B
WebGPU Nodes 615.56
168.12
619.19
169.14
+3.63 kB
+1.02 kB

Copy link
Collaborator

Mugen87 commented Oct 1, 2025

Related:

There is a custom bitCount() TSL function that I needed for the SSGI. The original Unity code used a built-in function but because of GLSL the code uses an implementation from https://graphics.stanford.edu/%7Eseander/bithacks.html.

const bitCount = Fn( ( [ value ] ) => {
const v = uint( value );
v.assign( v.sub( v.shiftRight( uint( 1 ) ).bitAnd( uint( 0x55555555 ) ) ) );
v.assign( v.bitAnd( uint( 0x33333333 ) ).add( v.shiftRight( uint( 2 ) ).bitAnd( uint( 0x33333333 ) ) ) );
return v.add( v.shiftRight( uint( 4 ) ) ).bitAnd( uint( 0xF0F0F0F ) ).mul( uint( 0x1010101 ) ).shiftRight( uint( 24 ) );
} ).setLayout( {
name: 'bitCount',
type: 'uint',
inputs: [
{ name: 'value', type: 'uint' }
]
} );

It's great to see WGSL support! How about providing a built-in bitCount() TSL function that fallbacks to the above code for the WebGL backend?

mrdoob and cmhhelgeson reacted with heart emoji

Copy link
Contributor Author

cmhhelgeson commented Oct 1, 2025
edited
Loading

It's great to see WGSL support! How about providing a built-in bitCount() TSL function that fallbacks to the above code for the WebGL backend?

In hindsight, I think it's possible to add polyfills for the other functions as well, so I will get on doing that. The link you provided should be useful in generating the necessary functions.

Copy link
Contributor Author

I'm going to fix the extant issues like documentation, but I'm also going to draft this PR so I can implement a polyfill approach. Basically, I'd be adding GLSL polyfills similar to how the WGSLNodeBuilder has polyfills for certain functions. Would this approach be desired, or would a different approach be preferred ( for instance, generating different nodes depending on the renderer's backend ). Personally, I'd prefer polyfilling in the GLSLNodeBuilder to keep the node code simpler for a simple mathematical operation.

Mugen87 reacted with thumbs up emoji

@cmhhelgeson cmhhelgeson marked this pull request as draft October 1, 2025 16:54
Copy link
Collaborator

Mugen87 commented Oct 1, 2025

Personally, I'd prefer polyfilling in the GLSLNodeBuilder to keep the node code simpler for a simple mathematical operation.

Then I suggest you start with that approach so we can see how it ends up in code.

cmhhelgeson reacted with thumbs up emoji

Copy link
Contributor Author

cmhhelgeson commented Oct 1, 2025
edited
Loading

(削除) I see that the bid twiddling hacks for counting bits mainly concern Uints, but the WGSL countOneBits function (GLSL bitCount equivalent), can also take in a signed integer or vectors. The vectors are trivial to implement, but are there any references for a signed integer equivalent of bitCount? (削除ここまで)

Nevermind, we can just case the i32 to a u32 using the GLSL bitcast functionality.

Copy link
Contributor Author

cmhhelgeson commented Oct 6, 2025
edited
Loading

Test Examples

  1. Validate functionality under WebGL backend

https://raw.githack.com/cmhhelgeson/three.js/bit_count_example/examples/webgpu_bitcount.html

  1. Validate SSGI functionality (the visuals seem off here but they match the existing representation of SSGI under the WebGL backend)

https://raw.githack.com/cmhhelgeson/three.js/bit_count_example/examples/webgpu_postprocessing_ssgi.html

Existing SSGI Example with forceWebGL set to true as example. Note how the existing SSGI implementation is significantly more noisy than the WebGPU example.

https://raw.githack.com/cmhhelgeson/three.js/ssgi_test/examples/webgpu_postprocessing_ssgi.html

Copy link
Collaborator

Mugen87 commented Oct 6, 2025

the visuals seem off here

What deviations are you seeing on your system?

@Mugen87 Mugen87 added this to the r182 milestone Oct 6, 2025
@cmhhelgeson cmhhelgeson changed the title (削除) MathNode - Add bitCount functions (削除ここまで) (追記) BitcountNode - Add bitCount functions (追記ここまで) Oct 6, 2025
@cmhhelgeson cmhhelgeson marked this pull request as ready for review October 6, 2025 20:51
Copy link
Contributor Author

Is it possible that #32091 is affecting the ability of displacementmap to pass its test? I'm not sure if the screenshots were updated before or after the light scattering PR, as that's the only reason I could think as to why materials_displacement is failing despite not activating the SSGINode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@Mugen87 Mugen87 Mugen87 left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

r182

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /