-
-
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
Changes from all commits
deca60e
de3b18e
e87294d
1773a8f
05da83f
4c777e8
ad5cb2d
fe882ea
1981a27
5afa0c9
4346838
a5d3e89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,6 +72,12 @@ | |
cube2Texture.generateMipmaps = true; | ||
cube2Texture.minFilter = THREE.LinearMipmapLinearFilter; | ||
|
||
renderer = new THREE.WebGPURenderer( { antialias: true } ); | ||
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 commentThe 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 |
||
|
||
// nodes and environment | ||
|
||
const adjustments = { | ||
|
@@ -95,7 +101,7 @@ | |
|
||
const custom1UV = reflectNode.xyz.mul( uniform( rotateY1Matrix ) ); | ||
const custom2UV = reflectNode.xyz.mul( uniform( rotateY2Matrix ) ); | ||
const mixCubeMaps = mix( pmremTexture( cube1Texture, custom1UV ), pmremTexture( cube2Texture, custom2UV ), positionNode.y.add( mixNode ).clamp() ); | ||
const mixCubeMaps = mix( pmremTexture( cube1Texture, custom1UV ), pmremTexture( cube2Blur.texture, custom2UV ), positionNode.y.add( mixNode ).clamp() ); | ||
|
||
const proceduralEnv = mix( mixCubeMaps, normalWorld, proceduralNode ); | ||
|
||
|
@@ -133,7 +139,6 @@ | |
|
||
// renderer and controls | ||
|
||
renderer = new THREE.WebGPURenderer( { antialias: true } ); | ||
renderer.setPixelRatio( window.devicePixelRatio ); | ||
renderer.setSize( window.innerWidth, window.innerHeight ); | ||
renderer.toneMapping = THREE.LinearToneMapping; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 commentThe 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? |
||
export { default as PostProcessing } from './renderers/common/PostProcessing.js'; | ||
import * as PostProcessingUtils from './renderers/common/PostProcessingUtils.js'; | ||
export { PostProcessingUtils }; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,13 +2,19 @@ | |
import { texture as TSL_Texture } from '../../nodes/accessors/TextureNode.js'; | ||
import { positionWorldDirection } from '../../nodes/accessors/Position.js'; | ||
import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; | ||
import { blur, getBlurParams } from '../../nodes/pmrem/PMREMUtils.js'; | ||
import { uniform } from '../../nodes/core/UniformNode.js'; | ||
import { uniformArray } from '../../nodes/accessors/UniformArrayNode.js'; | ||
import { float, vec3, Fn } from '../../nodes/tsl/TSLBase.js'; | ||
|
||
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 commentThe reason will be displayed to describe this comment to others. Learn more. This is weird - when I tried to have a local variable named |
||
import { Vector3 } from '../../math/Vector3.js'; | ||
|
||
// @TODO: Consider rename WebGLCubeRenderTarget to just CubeRenderTarget | ||
|
||
|
@@ -72,6 +78,91 @@ | |
|
||
} | ||
|
||
fromCubeTexture( renderer, cubeTex, sigmaRadians = 0, poleAxis = new Vector3( 0, 1, 0 ) ) { | ||
|
||
const currentGenerateMipmaps = cubeTex.generateMipmaps; | ||
|
||
cubeTex.generateMipmaps = true; | ||
|
||
this.texture.type = cubeTex.type; | ||
this.texture.colorSpace = cubeTex.colorSpace; | ||
|
||
this.texture.generateMipmaps = cubeTex.generateMipmaps; | ||
this.texture.minFilter = cubeTex.minFilter; | ||
this.texture.magFilter = cubeTex.magFilter; | ||
|
||
// The maximum length of the blur for loop. Smaller sigmas will use fewer | ||
// samples and exit early, but not recompile the shader. | ||
const MAX_SAMPLES = 20; | ||
|
||
const blurMaterial = new NodeMaterial(); | ||
blurMaterial.side = BackSide; | ||
blurMaterial.depthTest = false; | ||
blurMaterial.depthWrite = false; | ||
blurMaterial.blending = NoBlending; | ||
|
||
const weights = uniformArray( new Array( MAX_SAMPLES ).fill( 0 ) ); | ||
const dTheta = uniform( 0 ); | ||
const n = float( MAX_SAMPLES ); | ||
const latitudinal = uniform( 0 ); // false, bool | ||
const samples = uniform( 1 ); // int | ||
const envMap = TSL_CubeTexture( null ); | ||
|
||
const cubeSampler = Fn( ( [ sampleDirection ] )=>{ | ||
|
||
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 commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 geometry = new BoxGeometry( 5, 5, 5 ); | ||
const mesh = new Mesh( geometry, blurMaterial ); | ||
|
||
const scene = new Scene(); | ||
scene.add( mesh ); | ||
|
||
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 commentThe 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 |
||
|
||
envMap.value = cubeTex; | ||
latitudinal.value = 1; | ||
const blurParams1 = getBlurParams( sigmaRadians, width, MAX_SAMPLES ); | ||
weights.value = blurParams1.weights; | ||
samples.value = blurParams1.samples; | ||
dTheta.value = blurParams1.radiansPerPixel; | ||
|
||
if ( sigmaRadians <= 0 ) { | ||
|
||
camera.update( renderer, scene ); | ||
|
||
} else { | ||
Check failure on line 139 in src/renderers/common/CubeRenderTarget.js GitHub Actions / Lint testing
|
||
|
||
const blurTarget = new CubeRenderTarget( Math.min( this.width, width ) ); | ||
camera.renderTarget = blurTarget; | ||
|
||
camera.update( renderer, scene ); | ||
|
||
camera.renderTarget = this; | ||
envMap.value = blurTarget.texture; | ||
latitudinal.value = 0; | ||
const blurParams2 = getBlurParams( sigmaRadians, blurTarget.width, MAX_SAMPLES ); | ||
weights.value = blurParams2.weights; | ||
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 commentThe 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 |
||
|
||
blurTarget.dispose(); | ||
|
||
} | ||
|
||
cubeTex.currentGenerateMipmaps = currentGenerateMipmaps; | ||
geometry.dispose(); | ||
blurMaterial.dispose(); | ||
|
||
} | ||
|
||
} | ||
|
||
export default CubeRenderTarget; |
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 usingcamera.update
, which doesn't seem to have an async version? Not sure why this hasn't been a problem forfromEquirectangularTexture
...