Skip to content

Commit

Permalink
WebGPURenderer: Support to .backgroundNode (#24213)
Browse files Browse the repository at this point in the history
* beautify matrix columns

* add support to .onBeforeRender()

* add support to .backgroundNode

* add .backgroundNode to examples

* cleanup

* cleanup

* remove brightness, rename contrast to intensity

* fix get empty image[0]
  • Loading branch information
sunag authored Jun 9, 2022
1 parent 31730c1 commit f30599e
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 32 deletions.
3 changes: 2 additions & 1 deletion examples/jsm/nodes/utils/MaxMipLevelNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class MaxMipLevelNode extends UniformNode {

update() {

const image = this.texture.images && this.texture.images.length > 0 ? this.texture.images[ 0 ].image || this.texture.images[ 0 ] : this.texture.image;
const images = this.texture.images;
const image = ( images && images.length > 0 ) ? ( images[ 0 ]?.image || images[ 0 ] ) : this.texture.image;

if ( image?.width !== undefined ) {

Expand Down
43 changes: 40 additions & 3 deletions examples/jsm/renderers/webgpu/WebGPUBackground.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { GPULoadOp, GPUStoreOp } from './constants.js';
import { Color } from 'three';
import { Color, Mesh, BoxGeometry, BackSide } from 'three';
import { context, transformDirection, positionWorld, modelWorldMatrix } from 'three-nodes/Nodes.js';
import MeshBasicNodeMaterial from 'three-nodes/materials/MeshBasicNodeMaterial.js';

let _clearAlpha;
const _clearColor = new Color();
Expand All @@ -10,6 +12,8 @@ class WebGPUBackground {

this.renderer = renderer;

this.boxMesh = null;

this.forceClear = false;

}
Expand All @@ -20,10 +24,11 @@ class WebGPUBackground {

}

update( scene ) {
update( renderList, scene ) {

const renderer = this.renderer;
const background = ( scene.isScene === true ) ? scene.background : null;
const background = ( scene.isScene === true ) ? scene.backgroundNode || scene.background : null;

let forceClear = this.forceClear;

if ( background === null ) {
Expand All @@ -41,6 +46,38 @@ class WebGPUBackground {
_clearAlpha = 1;
forceClear = true;

} else if ( background.isNode === true ) {

_clearColor.copy( renderer._clearColor );
_clearAlpha = renderer._clearAlpha;

let boxMesh = this.boxMesh;

if ( boxMesh === null ) {

const colorNode = context( background, {
uvNode: transformDirection( positionWorld, modelWorldMatrix )
} );

const nodeMaterial = new MeshBasicNodeMaterial();
nodeMaterial.colorNode = colorNode;
nodeMaterial.side = BackSide;
nodeMaterial.depthTest = false;
nodeMaterial.depthWrite = false;
nodeMaterial.fog = false;

this.boxMesh = boxMesh = new Mesh( new BoxGeometry( 1, 1, 1 ), nodeMaterial );

boxMesh.onBeforeRender = function ( renderer, scene, camera ) {

this.matrixWorld.copyPosition( camera.matrixWorld );

};

}

renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null );

} else {

console.error( 'THREE.WebGPURenderer: Unsupported background configuration.', background );
Expand Down
14 changes: 8 additions & 6 deletions examples/jsm/renderers/webgpu/WebGPURenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ Matrix4.prototype.makeOrthographic = function ( left, right, top, bottom, near,
const y = ( top + bottom ) * h;
const z = near * p;

te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x;
te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y;
te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 1 * p; te[ 14 ] = - z;
te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1;
te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x;
te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y;
te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 1 * p; te[ 14 ] = - z;
te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1;

return this;

Expand Down Expand Up @@ -282,7 +282,7 @@ class WebGPURenderer {

//

this._background.update( scene );
this._background.update( this._currentRenderList, scene );

// start render pass

Expand Down Expand Up @@ -768,7 +768,9 @@ class WebGPURenderer {
// @TODO: Add support for multiple materials per object. This will require to extract
// the material from the renderItem object and pass it with its group data to _renderObject().

const object = renderItem.object;
const { object, geometry, material, group } = renderItem;

object.onBeforeRender( this, scene, camera, geometry, material, group );

object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
Expand Down
44 changes: 28 additions & 16 deletions examples/webgpu_cubemap_adjustments.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import * as THREE from 'three';
import * as Nodes from 'three-nodes/Nodes.js';

import { uniform, mix, cubeTexture, mul, reference, add, positionWorld, normalWorld, saturate, saturation, hue, reflectCube } from 'three-nodes/Nodes.js';
import { uniform, mix, cubeTexture, mul, reference, add, positionWorld, normalWorld, modelWorldMatrix, transformDirection, saturate, saturation, hue, reflectCube, context } from 'three-nodes/Nodes.js';

import WebGPU from './jsm/capabilities/WebGPU.js';
import WebGPURenderer from './jsm/renderers/webgpu/WebGPURenderer.js';
Expand Down Expand Up @@ -92,33 +92,41 @@
const adjustments = {
mix: 0,
procedural: 0,
brightness: 0,
contrast: 1,
intensity: 1,
hue: 0,
saturation: 1
};

const mixNode = reference( 'mix', 'float', adjustments );
const proceduralNode = reference( 'procedural', 'float', adjustments );
const brightnessNode = reference( 'brightness', 'float', adjustments );
const contrastNode = reference( 'contrast', 'float', adjustments );
const intensityNode = reference( 'intensity', 'float', adjustments );
const hueNode = reference( 'hue', 'float', adjustments );
const saturationNode = reference( 'saturation', 'float', adjustments );

const rotateY1Matrix = new THREE.Matrix4();
const rotateY2Matrix = new THREE.Matrix4();

const custom1UV = mul( reflectCube, uniform( rotateY1Matrix ) );
const custom2UV = mul( reflectCube, uniform( rotateY2Matrix ) );
const getEnvironmentNode = ( reflectNode ) => {

const mixCubeMaps = mix( cubeTexture( cube1Texture, custom1UV ), cubeTexture( cube2Texture, custom2UV ), saturate( add( positionWorld.y, mixNode ) ) );
const proceduralEnv = mix( mixCubeMaps, normalWorld, proceduralNode );
const brightnessFilter = add( proceduralEnv, brightnessNode );
const contrastFilter = mul( brightnessFilter, contrastNode );
const hueFilter = hue( contrastFilter, hueNode );
const saturationFilter = saturation( hueFilter, saturationNode );
const custom1UV = mul( reflectNode.xyz, uniform( rotateY1Matrix ) );
const custom2UV = mul( reflectNode.xyz, uniform( rotateY2Matrix ) );

scene.environmentNode = saturationFilter;
const mixCubeMaps = mix( cubeTexture( cube1Texture, custom1UV ), cubeTexture( cube2Texture, custom2UV ), saturate( add( positionWorld.y, mixNode ) ) );
const proceduralEnv = mix( mixCubeMaps, normalWorld, proceduralNode );
const intensityFilter = mul( proceduralEnv, intensityNode );
const hueFilter = hue( intensityFilter, hueNode );

return saturation( hueFilter, saturationNode );

}

const blurNode = uniform( 0 );

scene.environmentNode = getEnvironmentNode( reflectCube );

scene.backgroundNode = context( getEnvironmentNode( transformDirection( positionWorld, modelWorldMatrix ) ), {
levelNode : blurNode // @TODO: currently it uses mipmaps value, I think it should be replaced for [0,1]
} );

// scene objects

Expand Down Expand Up @@ -161,6 +169,11 @@

const gui = new GUI();

gui.add( { blurBackground: blurNode.value }, 'blurBackground', 0, 10, 0.01 ).onChange( value => {

blurNode.value = value;

} );
gui.add( { offsetCube1: 0 }, 'offsetCube1', 0, Math.PI * 2, 0.01 ).onChange( value => {

rotateY1Matrix.makeRotationY( value );
Expand All @@ -173,8 +186,7 @@
} );
gui.add( adjustments, 'mix', - 1, 2, 0.01 );
gui.add( adjustments, 'procedural', 0, 1, 0.01 );
gui.add( adjustments, 'brightness', 0, 1, 0.01 );
gui.add( adjustments, 'contrast', 0, 3, 0.01 );
gui.add( adjustments, 'intensity', 0, 5, 0.01 );
gui.add( adjustments, 'hue', 0, Math.PI * 2, 0.01 );
gui.add( adjustments, 'saturation', 0, 2, 0.01 );

Expand Down
14 changes: 9 additions & 5 deletions examples/webgpu_cubemap_mix.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import * as THREE from 'three';
import * as Nodes from 'three-nodes/Nodes.js';

import { mix, oscSine, timerLocal } from 'three-nodes/Nodes.js';
import { mix, oscSine, timerLocal, cubeTexture, context, float } from 'three-nodes/Nodes.js';

import WebGPU from './jsm/capabilities/WebGPU.js';
import WebGPURenderer from './jsm/renderers/webgpu/WebGPURenderer.js';
Expand Down Expand Up @@ -65,13 +65,13 @@
scene = new THREE.Scene();

const rgbmUrls = [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ];
const cubeTexture = new RGBMLoader()
const cube1Texture = new RGBMLoader()
.setMaxRange( 16 )
.setPath( './textures/cube/pisaRGBM16/' )
.loadCubemap( rgbmUrls );

cubeTexture.generateMipmaps = true;
cubeTexture.minFilter = THREE.LinearMipmapLinearFilter;
cube1Texture.generateMipmaps = true;
cube1Texture.minFilter = THREE.LinearMipmapLinearFilter;

const cube2Urls = [ 'dark-s_px.jpg', 'dark-s_nx.jpg', 'dark-s_py.jpg', 'dark-s_ny.jpg', 'dark-s_pz.jpg', 'dark-s_nz.jpg' ];
const cube2Texture = new THREE.CubeTextureLoader()
Expand All @@ -81,7 +81,11 @@
cube2Texture.generateMipmaps = true;
cube2Texture.minFilter = THREE.LinearMipmapLinearFilter;

scene.environmentNode = mix( new Nodes.CubeTextureNode( cube2Texture ), new Nodes.CubeTextureNode( cubeTexture ), oscSine( timerLocal( .1 ) ) );
scene.environmentNode = mix( cubeTexture( cube2Texture ), cubeTexture( cube1Texture ), oscSine( timerLocal( .1 ) ) );

scene.backgroundNode = context( scene.environmentNode, {
levelNode : float( 9 ) // @TODO: currently it uses mipmaps value, I think it should be replaced for [0,1]
} );

const loader = new GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' );
loader.load( 'DamagedHelmet.gltf', function ( gltf ) {
Expand Down
2 changes: 1 addition & 1 deletion examples/webgpu_loader_gltf.html
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@
cubeTexture.generateMipmaps = true;
cubeTexture.minFilter = THREE.LinearMipmapLinearFilter;

//scene.backgroundNode = texture;
scene.environmentNode = new Nodes.CubeTextureNode( cubeTexture );
scene.backgroundNode = scene.environmentNode;

const loader = new GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' );
loader.load( 'DamagedHelmet.gltf', function ( gltf ) {
Expand Down

0 comments on commit f30599e

Please sign in to comment.