Skip to content
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

Prerender buffer for transmissive objects #22595

Closed
wants to merge 3 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 30 additions & 14 deletions src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ function WebGLRenderer( parameters = {} ) {

// transmission

let _transmissionRenderTarget = null;
let _transmissionRenderTarget = [];

// camera matrices cache

Expand Down Expand Up @@ -576,10 +576,10 @@ function WebGLRenderer( parameters = {} ) {
xr.removeEventListener( 'sessionstart', onXRSessionStart );
xr.removeEventListener( 'sessionend', onXRSessionEnd );

if ( _transmissionRenderTarget ) {
if ( _transmissionRenderTarget.length ) {
Mugen87 marked this conversation as resolved.
Show resolved Hide resolved

_transmissionRenderTarget.dispose();
_transmissionRenderTarget = null;
_transmissionRenderTarget.forEach( ( target ) => target.dispose() );
_transmissionRenderTarget = [];

}

Expand Down Expand Up @@ -1051,18 +1051,34 @@ function WebGLRenderer( parameters = {} ) {
if ( camera.isArrayCamera ) {

const cameras = camera.cameras;
const opaqueObjects = currentRenderList.opaque;
const transmissiveObjects = currentRenderList.transmissive;

if ( transmissiveObjects.length > 0 ) {

for ( let i = 0, l = cameras.length; i < l; i ++ ) {

const camera2 = cameras[ i ];

currentRenderState.setupLightsView( camera2 );

renderTransmissionPass( opaqueObjects, scene, camera2 );

}

}

for ( let i = 0, l = cameras.length; i < l; i ++ ) {

const camera2 = cameras[ i ];

renderScene( currentRenderList, scene, camera2, camera2.viewport );
renderScene( currentRenderList, scene, camera2, camera2.viewport, false );

}

} else {

renderScene( currentRenderList, scene, camera );
renderScene( currentRenderList, scene, camera, undefined, true );

}

Expand Down Expand Up @@ -1249,15 +1265,15 @@ function WebGLRenderer( parameters = {} ) {

}

function renderScene( currentRenderList, scene, camera, viewport ) {
function renderScene( currentRenderList, scene, camera, viewport, renderTransmissiveObjects ) {
Copy link
Collaborator

@Mugen87 Mugen87 Oct 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for pre-rendering the buffer for transmissive objects only for the XR code path? Couldn't the renderer always use this approach (so for non-XR setups, too).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No particular reason. I didn't want to change the non-xr path.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I see. I just wonder if the change becomes simpler if we have a uniform transmission code path.

@mrdoob What do you think?


const opaqueObjects = currentRenderList.opaque;
const transmissiveObjects = currentRenderList.transmissive;
const transparentObjects = currentRenderList.transparent;

currentRenderState.setupLightsView( camera );

if ( transmissiveObjects.length > 0 ) renderTransmissionPass( opaqueObjects, scene, camera );
if ( transmissiveObjects.length > 0 && renderTransmissiveObjects ) renderTransmissionPass( opaqueObjects, scene, camera );

if ( viewport ) state.viewport( _currentViewport.copy( viewport ) );

Expand All @@ -1269,12 +1285,12 @@ function WebGLRenderer( parameters = {} ) {

function renderTransmissionPass( opaqueObjects, scene, camera ) {

if ( _transmissionRenderTarget === null ) {
if ( _transmissionRenderTarget[ camera ] === undefined ) {

const needsAntialias = _antialias === true && capabilities.isWebGL2 === true;
const renderTargetType = needsAntialias ? WebGLMultisampleRenderTarget : WebGLRenderTarget;

_transmissionRenderTarget = new renderTargetType( 1024, 1024, {
_transmissionRenderTarget[ camera ] = new renderTargetType( 1024, 1024, {
generateMipmaps: true,
type: utils.convert( HalfFloatType ) !== null ? HalfFloatType : UnsignedByteType,
minFilter: LinearMipmapLinearFilter,
Expand All @@ -1286,7 +1302,7 @@ function WebGLRenderer( parameters = {} ) {
}

const currentRenderTarget = _this.getRenderTarget();
_this.setRenderTarget( _transmissionRenderTarget );
_this.setRenderTarget( _transmissionRenderTarget[ camera ] );
_this.clear();

// Turn off the features which can affect the frag color for opaque objects pass.
Expand All @@ -1298,8 +1314,8 @@ function WebGLRenderer( parameters = {} ) {

_this.toneMapping = currentToneMapping;

textures.updateMultisampleRenderTarget( _transmissionRenderTarget );
textures.updateRenderTargetMipmap( _transmissionRenderTarget );
textures.updateMultisampleRenderTarget( _transmissionRenderTarget[ camera ] );
textures.updateRenderTargetMipmap( _transmissionRenderTarget[ camera ] );

_this.setRenderTarget( currentRenderTarget );

Expand Down Expand Up @@ -1780,7 +1796,7 @@ function WebGLRenderer( parameters = {} ) {

}

materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget );
materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget[ camera ] );

WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );

Expand Down