Skip to content

Commit

Permalink
WebGPURenderer, CubeCamera: Add .activeMipmapLevel (#26770)
Browse files Browse the repository at this point in the history
* CubeCamera: Add .activeMipmapLevel

* Use CubeCamera

* WebGPURenderer:  Add .activeMipmapLevel for set .setRenderTarget()
  • Loading branch information
sunag authored Sep 18, 2023
1 parent 16eaae5 commit 18febaf
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 63 deletions.
28 changes: 25 additions & 3 deletions examples/jsm/renderers/common/Renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ class Renderer {
this._clearStencil = 0;

this._renderTarget = null;
this._currentActiveCubeFace = 0;
this._activeCubeFace = 0;
this._activeMipmapLevel = 0;

this._initialized = false;
this._initPromise = null;
Expand Down Expand Up @@ -187,6 +188,7 @@ class Renderer {
const renderTarget = this._renderTarget;
const renderContext = this._renderContexts.get( scene, camera, renderTarget );
const activeCubeFace = this._activeCubeFace;
const activeMipmapLevel = this._activeMipmapLevel;

this._currentRenderContext = renderContext;

Expand Down Expand Up @@ -238,12 +240,16 @@ class Renderer {
const maxDepth = ( viewport.maxDepth === undefined ) ? 1 : viewport.maxDepth;

renderContext.viewportValue.copy( viewport ).multiplyScalar( pixelRatio ).floor();
renderContext.viewportValue.width >>= activeMipmapLevel;
renderContext.viewportValue.height >>= activeMipmapLevel;
renderContext.viewportValue.minDepth = minDepth;
renderContext.viewportValue.maxDepth = maxDepth;
renderContext.viewport = renderContext.viewportValue.equals( _screen ) === false;

renderContext.scissorValue.copy( scissor ).multiplyScalar( pixelRatio ).floor();
renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals( _screen ) === false;
renderContext.scissorValue.width >>= activeMipmapLevel;
renderContext.scissorValue.height >>= activeMipmapLevel;

renderContext.depth = this.depth;
renderContext.stencil = this.stencil;
Expand Down Expand Up @@ -274,7 +280,7 @@ class Renderer {

if ( renderTarget !== null ) {

this._textures.updateRenderTarget( renderTarget );
this._textures.updateRenderTarget( renderTarget, activeMipmapLevel );

const renderTargetData = this._textures.get( renderTarget );

Expand All @@ -292,7 +298,10 @@ class Renderer {

}

renderContext.width >>= activeMipmapLevel;
renderContext.height >>= activeMipmapLevel;
renderContext.activeCubeFace = activeCubeFace;
renderContext.activeMipmapLevel = activeMipmapLevel;
renderContext.occlusionQueryCount = renderList.occlusionQueryCount;

//
Expand Down Expand Up @@ -333,6 +342,18 @@ class Renderer {

}

getActiveCubeFace() {

return this._activeCubeFace;

}

getActiveMipmapLevel() {

return this._activeMipmapLevel;

}

setAnimationLoop( callback ) {

if ( this._initialized === false ) this.init();
Expand Down Expand Up @@ -606,10 +627,11 @@ class Renderer {

}

setRenderTarget( renderTarget, activeCubeFace = 0 ) {
setRenderTarget( renderTarget, activeCubeFace = 0, activeMipmapLevel = 0 ) {

this._renderTarget = renderTarget;
this._activeCubeFace = activeCubeFace;
this._activeMipmapLevel = activeMipmapLevel;

}

Expand Down
19 changes: 13 additions & 6 deletions examples/jsm/renderers/common/Textures.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ class Textures extends DataMap {

}

updateRenderTarget( renderTarget ) {
updateRenderTarget( renderTarget, activeMipmapLevel = 0 ) {

const renderTargetData = this.get( renderTarget );

const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
const depthTextureMips = renderTargetData.depthTextureMips || ( renderTargetData.depthTextureMips = {} );

let texture, textures;

Expand All @@ -36,16 +38,21 @@ class Textures extends DataMap {

const size = this.getSize( texture );

let depthTexture = renderTarget.depthTexture || renderTargetData.depthTexture;
const mipWidth = size.width >> activeMipmapLevel;
const mipHeight = size.height >> activeMipmapLevel;

let depthTexture = renderTarget.depthTexture || depthTextureMips[ activeMipmapLevel ];
let textureNeedsUpdate = false;

if ( depthTexture === undefined ) {

depthTexture = new DepthTexture();
depthTexture.format = DepthStencilFormat;
depthTexture.type = UnsignedInt248Type;
depthTexture.image.width = size.width;
depthTexture.image.height = size.height;
depthTexture.image.width = mipWidth;
depthTexture.image.height = mipHeight;

depthTextureMips[ activeMipmapLevel ] = depthTexture;

}

Expand All @@ -54,8 +61,8 @@ class Textures extends DataMap {
textureNeedsUpdate = true;
depthTexture.needsUpdate = true;

depthTexture.image.width = size.width;
depthTexture.image.height = size.height;
depthTexture.image.width = mipWidth;
depthTexture.image.height = mipHeight;

}

Expand Down
2 changes: 1 addition & 1 deletion examples/jsm/renderers/webgpu/WebGPUBackend.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class WebGPUBackend extends Backend {
const textureData = this.get( textures[ i ] );

const textureView = textureData.texture.createView( {
baseMipLevel: 0,
baseMipLevel: renderContext.activeMipmapLevel,
mipLevelCount: 1,
baseArrayLayer: renderContext.activeCubeFace,
dimension: GPUTextureViewDimension.TwoD
Expand Down
53 changes: 8 additions & 45 deletions examples/webgl_materials_cubemap_render_to_mipmaps.html
Original file line number Diff line number Diff line change
Expand Up @@ -127,30 +127,6 @@

function renderToCubeTexture( cubeMapRenderTarget, sourceCubeTexture ) {

const cameras = [];

for ( let i = 0; i < 6; i ++ ) {

// negative fov is not an error
cameras.push( new THREE.PerspectiveCamera( - 90, 1, 1, 10 ) );

}

cameras[ 0 ].up.set( 0, 1, 0 );
cameras[ 0 ].lookAt( 1, 0, 0 );
cameras[ 1 ].up.set( 0, 1, 0 );
cameras[ 1 ].lookAt( - 1, 0, 0 );
cameras[ 2 ].up.set( 0, 0, - 1 );
cameras[ 2 ].lookAt( 0, 1, 0 );
cameras[ 3 ].up.set( 0, 0, 1 );
cameras[ 3 ].lookAt( 0, - 1, 0 );
cameras[ 4 ].up.set( 0, 1, 0 );
cameras[ 4 ].lookAt( 0, 0, 1 );
cameras[ 5 ].up.set( 0, 1, 0 );
cameras[ 5 ].lookAt( 0, 0, - 1 );

for ( let i = 0; i < 6; i ++ ) cameras[ i ].updateMatrixWorld();

const geometry = new THREE.BoxGeometry( 5, 5, 5 );

const material = new THREE.ShaderMaterial( {
Expand All @@ -165,34 +141,21 @@
material.uniforms.cubeTexture.value = sourceCubeTexture;

const mesh = new THREE.Mesh( geometry, material );
const cubeCamera = new THREE.CubeCamera( 1, 10, cubeMapRenderTarget );
const mipmapCount = Math.floor( Math.log2( Math.max( cubeMapRenderTarget.width, cubeMapRenderTarget.height ) ) );

const currentRenderTarget = renderer.getRenderTarget();
const currentXrEnabled = renderer.xr.enabled;
renderer.xr.enabled = false;

for ( let faceIndex = 0; faceIndex < 6; faceIndex ++ ) {
for ( let mipmap = 0; mipmap < mipmapCount; mipmap ++ ) {

let mipIndex = 0;
let mipSize = cubeMapRenderTarget.width;
material.uniforms.mipIndex.value = mipmap;
material.needsUpdate = true;

// Render to each texture mip level
while ( mipSize >= 1 ) {
cubeMapRenderTarget.viewport.set( 0, 0, cubeMapRenderTarget.width >> mipmap, cubeMapRenderTarget.height >> mipmap );

cubeMapRenderTarget.viewport.set( 0, 0, mipSize, mipSize );
renderer.setRenderTarget( cubeMapRenderTarget, faceIndex, mipIndex );
material.uniforms.mipIndex.value = mipIndex;
material.needsUpdate = true;
renderer.render( mesh, cameras[ faceIndex ] );
mipSize >>= 1;
mipIndex ++;

}
cubeCamera.activeMipmapLevel = mipmap;
cubeCamera.update( renderer, mesh );

}

renderer.setRenderTarget( currentRenderTarget );
renderer.xr.enabled = currentXrEnabled;

mesh.geometry.dispose();
mesh.material.dispose();

Expand Down
19 changes: 11 additions & 8 deletions src/cameras/CubeCamera.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class CubeCamera extends Object3D {

this.renderTarget = renderTarget;
this.coordinateSystem = null;
this.activeMipmapLevel = 0;

const cameraPX = new PerspectiveCamera( fov, aspect, near, far );
cameraPX.layers = this.layers;
Expand Down Expand Up @@ -112,7 +113,7 @@ class CubeCamera extends Object3D {

if ( this.parent === null ) this.updateMatrixWorld();

const renderTarget = this.renderTarget;
const { renderTarget, activeMipmapLevel } = this;

if ( this.coordinateSystem !== renderer.coordinateSystem ) {

Expand All @@ -125,6 +126,8 @@ class CubeCamera extends Object3D {
const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = this.children;

const currentRenderTarget = renderer.getRenderTarget();
const currentActiveCubeFace = renderer.getActiveCubeFace();
const currentActiveMipmapLevel = renderer.getActiveMipmapLevel();

const currentXrEnabled = renderer.xr.enabled;

Expand All @@ -134,30 +137,30 @@ class CubeCamera extends Object3D {

renderTarget.texture.generateMipmaps = false;

renderer.setRenderTarget( renderTarget, 0 );
renderer.setRenderTarget( renderTarget, 0, activeMipmapLevel );
renderer.render( scene, cameraPX );

renderer.setRenderTarget( renderTarget, 1 );
renderer.setRenderTarget( renderTarget, 1, activeMipmapLevel );
renderer.render( scene, cameraNX );

renderer.setRenderTarget( renderTarget, 2 );
renderer.setRenderTarget( renderTarget, 2, activeMipmapLevel );
renderer.render( scene, cameraPY );

renderer.setRenderTarget( renderTarget, 3 );
renderer.setRenderTarget( renderTarget, 3, activeMipmapLevel );
renderer.render( scene, cameraNY );

renderer.setRenderTarget( renderTarget, 4 );
renderer.setRenderTarget( renderTarget, 4, activeMipmapLevel );
renderer.render( scene, cameraPZ );

// mipmaps are generated during the last call of render()
// at this point, all sides of the cube render target are defined

renderTarget.texture.generateMipmaps = generateMipmaps;

renderer.setRenderTarget( renderTarget, 5 );
renderer.setRenderTarget( renderTarget, 5, activeMipmapLevel );
renderer.render( scene, cameraNZ );

renderer.setRenderTarget( currentRenderTarget );
renderer.setRenderTarget( currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel );

renderer.xr.enabled = currentXrEnabled;

Expand Down

0 comments on commit 18febaf

Please sign in to comment.