-
-
Notifications
You must be signed in to change notification settings - Fork 36k
TSL Procedural Wood Example #31640
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
base: dev
Are you sure you want to change the base?
TSL Procedural Wood Example #31640
Conversation
Nice work @SeeleyLogan. But yeah, the compile times are brutal. @sunag do you have an idea on how to make this performant given they are all basically the same material, just different parameters? BTW what is really nice about this material is that it is fully 3D: ![]() |
My first suggestion is to use uniforms instead of constants for variable parameters, I didn't find any uniform in the code. The code also needs to follow the mrdoob code style, I would also suggest creating an extended material from I'm not sure if that would be enough, but I can continue the analysis as we progress. |
@sunag I'm having trouble with these uniforms. The value of the uniforms need to be different per-material... If I use the same uniform it either updates all the materials or everything gets cached so it uses the first material. |
|
||
export function GenerateWoodMaterial(params) | ||
{ | ||
const material = new THREE.MeshPhysicalMaterial(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use MeshPhysicalNodeMaterial
instead of MeshPhysicalMaterial
|
||
for (const key in params.wood_params) { | ||
if (key === 'dark_wood_color' || key === 'light_wood_color') { | ||
material.uniforms[key] = { value: new THREE.Color(params.wood_params[key]).convertLinearToSRGB() }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
material.uniforms[key]
it would be an old approach, necessary to use the uniform node https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language#uniform
If you use uniform for different materials and values, the final code will be the same, the node hierarchy too, so the system will not need to build and compile a new material/shader. |
This is a great example, and a good test case for compilation too, lol. Do the compilation issues relate to choosing .wgslFn over native TSL for certain functions? I don't see why this couldn't also work on the WebGL backend. @sunag Is the WGSLEncoder robust enough where he could plop these functions into the decoder and get the correct TSL out for his WGSL functions? |
@sunag I've updated the code to try to use uniforms. I think I did it correctly, but now all the woods are the same. ![]() (I've also formatted the code and changed variables/method names to be more in line with MrDoob style.) @WestLangley removed light and increased IBL intensity as well! |
@cmhhelgeson I used Though I don't see a reason why regular TSL Fn wouldn't work. |
For the sake of completeness and aligning with the rest of the examples, I think it would be best to port these over to TSL. That way the program can work with devices that aren't compatible with WebGPU or don't expose WebGPU functionality (though those are growing fewer by the year). Technically, it also would allow your code to run on whatever graphics backends arrive to the web in the future (WebGPU2, MetalWeb, DoobGPU, or any other hypothetical paradigm that would be prevalent enough to integrate into Threejs). If your initial source was GLSL, then you can port the GLSL code from Blender to TSL with the GLSLEncoder. The Threejs website provides an example that does this automatically: https://threejs.org/examples/?q=tsl#webgpu_tsl_transpiler. |
@sunag we fixed the pieces all looking the same by using MeshPhysicalNodeMaterial as you suggested. Yeah! ![]() Still pretty long loading time, but it is working now! CC: @SeeleyLogan |
Yes, this isn't a blocker for the PR. If we see shader aliasing here, could our TRAA save the day? |
@Mugen87 It looks like I've fixed the aliasing issue. As the camera moves away, the sharp wood rings get blurred and the cell structure becomes smaller. There are a couple distances where the anti-aliasing breaks down slightly; nothing too noticeable. |
Wow, much better! |
If the E2E screenshot makes troubles, I can try to regenerate it after the merge. |
I cached the @cmhhelgeson suggested using TSL functions instead of WGSL functions, which I also think is positive. The other point would be to create a Don't take this as a block if you want to do this in later PRs. |
@sunag The onObjectUpdate just creates a callback that updates the uniform whenever parameters on the material itself are changed, yes? |
I think incremental loading just covers the fact that compilation is slow, I'd opt for removing it and loading everything at the same time (as a typical application would do). We're also seeing very slow compile times with TSL (regular MeshPhysicalMaterial is ~50-100x slower to create and compile on WebGPURenderer vs. WebGLRenderer), so I think instead of covering it up this should stay as-is and compilation times hopefully improved at some point in the underlaying system. |
@cmhhelgeson I've converted all instances of |
Can you clarify what you mean by "WoodMaterial extended material instead of a function"? |
ProceduralWood should be a class that extends MeshPhysicalNodeMaterial, rather than a function that creates, modifies, and returns an instance of MeshPhysicalNodeMaterial. |
@hybridherbst wrote:
We are of course seeing that as well with this wood texture. It is incredibly slow on mobile devices. So much that I am scared to deploy it to production use. Should I create a Github issue for that? We could use this example as a test case. |
(cherry picked from commit d1813a2)
(cherry picked from commit 2a35725)
(cherry picked from commit 9ae3876)
(cherry picked from commit 6fd32bb)
(cherry picked from commit ade4e9d)
(cherry picked from commit eb5a62f)
(cherry picked from commit 9fad1ed)
(cherry picked from commit 7236e5e)
(cherry picked from commit 531d75c)
(cherry picked from commit dc8562d)
(cherry picked from commit e01ab4c)
(cherry picked from commit 4691579)
Fix code style. (cherry picked from commit bbbca28)
(cherry picked from commit 640fca8)
(cherry picked from commit 37abf5d)
(cherry picked from commit 8aa231d)
(cherry picked from commit 9119a50)
(cherry picked from commit e52cf02)
Extended StandardMeshNodeMaterial to create WoodNodeMaterial (cherry picked from commit 26f7487)
Converting voronoi3d to Fn caused frame drop and input lag. Merging e9f7c8b had no effect. (cherry picked from commit 72057d2)
(cherry picked from commit 5ee2693)
(cherry picked from commit 895ca13)
@mrdoob, I've fixed the PR to only have the key files included (cherrying picked all the important commits and force-pushed), refactored the example to make it cleaner and also demonstrate how to create custom wood materials, and not limit it to only presets. CC: @SeeleyLogan |
Description
This pull requests extends the ThreeJS examples library and adds an addon to JSM.
The addon provides a material generator for procedural wood textures. The addon includes preset wood parameters that can easily be exposed and changed.
The example creates a scene demonstrating each wood preset imported from the addon.
The math behind the wood texture is ported from a blender tutorial by Lance Phan.
Creating procedural materials can be time consuming. This contribution will allow developers to skip lower-level wood material design; instead focusing on high level customization.
Caveat
Each wood texture has the same node graph; different parameters. This caused ThreeJS to cache the first shader and ignore the parameters. I avoided this issue by bypassing the caching altogether, causing my example to compile each material individually (regardless of its parameters). This shouldn't be necessary and I believe I am doing something wrong on that end.
This contribution is funded by DriveCore