-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
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
[WIP] Add CubeTexture blur #30165
base: dev
Are you sure you want to change the base?
[WIP] Add CubeTexture blur #30165
Conversation
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
const cubeUVsampler=Fn((envMap, sampleDirection)=>{ | ||
return bilinearCubeUV( envMap, sampleDirection, mipInt, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP ); | ||
}); | ||
material.fragmentNode = blur( { ...materialUniforms, latitudinal: latitudinal.equal( 1 ), sampler: cubeUVsampler } ); |
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.
This is the heart of the refactor I'm attempting - make the sampling function something that can be passed in so I can use different ones for a CubeUV texture vs an actual CubeTexture.
I can help with whatever you need :) |
Thanks @sunag - that got me unstuck for a bit. However, in my last commit I'm trying to pull in some of the #29900 changes but I hit a weird error,
I would guess this has something to do with my |
I pushed a commit to fix set uniform value, this happened because |
Ah, thank you again! I don't know how you manage to develop all this without TS. I have the actual blur function written now - I just need to test it. |
Okay, I might have this close to working, and I updated the new API with feedback from @mrdoob. However, upon trying to test it, I realized that |
@@ -6,6 +6,7 @@ export { default as Lighting } from './renderers/common/Lighting.js'; | |||
export { default as BundleGroup } from './renderers/common/BundleGroup.js'; | |||
export { default as QuadMesh } from './renderers/common/QuadMesh.js'; | |||
export { default as PMREMGenerator } from './renderers/common/extras/PMREMGenerator.js'; | |||
export { default as CubeRenderTarget } from './renderers/common/CubeRenderTarget.js'; |
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.
Not sure why this wasn't exported before for WebGPU - hopefully this is okay?
return envMap.sample( sampleDirection ); | ||
|
||
} ); | ||
blurMaterial.fragmentNode = blur( { n, latitudinal: latitudinal.equal( 1 ), poleAxis: vec3( poleAxis ), outputDirection: positionWorldDirection, weights, samples, dTheta, sampler: cubeSampler } ); |
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.
@sunag thanks for getting the PMREM version of this blur working - now this one is giving me trouble. I'm getting a lot of exceptions like getOutputNode( builder )
where builder
is undefined. Also this line device.queue.writeBuffer( bufferGPU, 0, buffer, 0 );
is giving me TypeError: Overload resolution failed.
which sounds pretty bad. I'm going to try to make a simpler repro in a three.js example instead of MV.
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.
Okay, I think this is just async issues with WebGPURenderer in MV.
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.
@@ -72,6 +72,12 @@ | |||
cube2Texture.generateMipmaps = true; | |||
cube2Texture.minFilter = THREE.LinearMipmapLinearFilter; | |||
|
|||
renderer = new THREE.WebGPURenderer( { antialias: true } ); | |||
await renderer.init(); |
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.
This was a quick fix to deal with an "uninitialized renderer" warning, which should maybe be an error since it just skips my shader entirely and makes a black texture? It also says I should use renderAsync
, but i'm using camera.update
, which doesn't seem to have an async version? Not sure why this hasn't been a problem for fromEquirectangularTexture
...
|
||
import { WebGLCubeRenderTarget } from '../../renderers/WebGLCubeRenderTarget.js'; | ||
import { Scene } from '../../scenes/Scene.js'; | ||
import { CubeCamera } from '../../cameras/CubeCamera.js'; | ||
import { BoxGeometry } from '../../geometries/BoxGeometry.js'; | ||
import { Mesh } from '../../objects/Mesh.js'; | ||
import { BackSide, NoBlending, LinearFilter, LinearMipmapLinearFilter } from '../../constants.js'; | ||
import { cubeTexture as TSL_CubeTexture } from '../../nodes/accessors/CubeTextureNode.js'; |
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.
This is weird - when I tried to have a local variable named cubeTexture
it didn't work - said it was a function instead (this one). Looks like it's getting properly renamed here, but apparently not? Is it somehow globally included somewhere?
return envMap.sample( sampleDirection ); | ||
|
||
} ); | ||
blurMaterial.fragmentNode = blur( { n, latitudinal: latitudinal.equal( 1 ), poleAxis: vec3( poleAxis ), outputDirection: positionWorldDirection, weights, samples, dTheta, sampler: cubeSampler } ); |
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.
Okay, I think this is just async issues with WebGPURenderer in MV.
|
||
const camera = new CubeCamera( 1, 10, this ); | ||
|
||
const width = cubeTex.source.data[0].width; |
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.
I've run into this issue before in Three (and complained about it) - this feels super fragile, but how am I supposed to find the size of a cubeTexture? Some have image
, some have source
, and I'm pretty sure if you generate one with a render target it has none? Seems like we're missing an API for this. Can we please just have a .size
?
samples.value = blurParams2.samples; | ||
dTheta.value = blurParams2.radiansPerPixel; | ||
|
||
camera.update( renderer, scene ); |
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.
Now that this function is finally running I'm getting an exception that comes from here (oddly not the first camera.update
call?): TypeError: Failed to execute 'writeBuffer' on 'GPUQueue': Overload resolution failed.
No idea what to do with that.
await renderer.init(); | ||
|
||
const cube2Blur = new THREE.CubeRenderTarget(cube2Texture.source.data[0].width); | ||
cube2Blur.fromCubeTexture(renderer, cube2Texture, 0.1); |
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.
I'm throwing in a fixed-size blur for now to test - to have it hooked up to the backgroundBlur
UI I believe we'll need some kind of cubeBlurNode
that works a bit like pmremNode
, automatically regenerating the texture as needed.
Since this is my last day at Google (and as a maintainer of MV, see google/model-viewer#4975) I don't think I'll get a chance to finish this PR. Hopefully it looks useful enough for someone else to pick up and push over the finish line. Thanks for all the help, @sunag! The TSL you've built is quite impressive, though hopefully by the time I play with it again it'll have a few more docs 😄. |
@elalish This news took me by surprise. You have done an incredible job over the years with MV and with all the improvements in physical-based materials, tone mapping, etc. I have always found your high level work and rich in detail, your work will certainly be missed by the community. I hope we can meet again on life's journey and I wish you all the best in your achievements. |
Thanks a lot @sunag! If you ever find yourself in New Zealand, come visit. |
The idea here is to make the PMREM cubemap blur function available as a generic public blur method for a
CubeTexture
. So far I only have a sketch, but this being my first attempt at using TSL, I've run into some early problems that I'd like to ask @sunag about.