Skip to content

Commit a39dbfa

Browse files
Mugen87sunag
andauthored
WebGPURenderer: Support rotation of env maps. (#30528)
* WebGPURenderer: Support rotation of env maps. * move `materialEnvIntensity` and `materialEnvRotation` to `MaterialProperties` * MaterialPropeties: Fix update. --------- Co-authored-by: sunag <[email protected]>
1 parent 4144826 commit a39dbfa

File tree

5 files changed

+70
-15
lines changed

5 files changed

+70
-15
lines changed

examples/webgpu_materials_envmaps.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@
107107
Refraction: false,
108108
backgroundRotationX: false,
109109
backgroundRotationY: false,
110-
backgroundRotationZ: false
110+
backgroundRotationZ: false,
111+
syncMaterial: false
111112
};
112113

113114
const gui = new GUI( { width: 300 } );
@@ -133,6 +134,7 @@
133134
gui.add( params, 'backgroundRotationX' );
134135
gui.add( params, 'backgroundRotationY' );
135136
gui.add( params, 'backgroundRotationZ' );
137+
gui.add( params, 'syncMaterial' );
136138
gui.open();
137139

138140
window.addEventListener( 'resize', onWindowResize );
@@ -170,6 +172,12 @@
170172

171173
}
172174

175+
if ( params.syncMaterial ) {
176+
177+
sphereMesh.material.envMapRotation.copy( scene.backgroundRotation );
178+
179+
}
180+
173181
camera.lookAt( scene.position );
174182
renderer.render( scene, camera );
175183

src/nodes/accessors/CubeTextureNode.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { reflectVector, refractVector } from './ReflectVector.js';
33
import { nodeProxy, vec3 } from '../tsl/TSLBase.js';
44

55
import { CubeReflectionMapping, CubeRefractionMapping, WebGPUCoordinateSystem } from '../../constants.js';
6+
import { materialEnvRotation } from './MaterialProperties.js';
67

78
/**
89
* This type of uniform node represents a cube texture.
@@ -101,14 +102,12 @@ class CubeTextureNode extends TextureNode {
101102

102103
if ( builder.renderer.coordinateSystem === WebGPUCoordinateSystem || ! texture.isRenderTargetTexture ) {
103104

104-
return vec3( uvNode.x.negate(), uvNode.yz );
105-
106-
} else {
107-
108-
return uvNode;
105+
uvNode = vec3( uvNode.x.negate(), uvNode.yz );
109106

110107
}
111108

109+
return materialEnvRotation.mul( uvNode );
110+
112111
}
113112

114113
/**
Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,59 @@
1+
import { Euler } from '../../math/Euler.js';
2+
import { Matrix4 } from '../../math/Matrix4.js';
13
import { uniform } from '../core/UniformNode.js';
24

5+
const _e1 = /*@__PURE__*/ new Euler();
6+
const _m1 = /*@__PURE__*/ new Matrix4();
7+
38
/**
49
* TSL object that represents the refraction ratio of the material used for rendering the current object.
510
*
611
* @tsl
712
* @type {UniformNode<float>}
813
*/
9-
export const materialRefractionRatio = /*@__PURE__*/ uniform( 0 ).onReference( ( { material } ) => material ).onRenderUpdate( ( { material } ) => material.refractionRatio );
14+
export const materialRefractionRatio = /*@__PURE__*/ uniform( 0 ).onReference( ( { material } ) => material ).onObjectUpdate( ( { material } ) => material.refractionRatio );
15+
16+
/**
17+
* TSL object that represents the intensity of environment maps of PBR materials.
18+
* When `material.envMap` is set, the value is `material.envMapIntensity` otherwise `scene.environmentIntensity`.
19+
*
20+
* @tsl
21+
* @type {Node<float>}
22+
*/
23+
export const materialEnvIntensity = /*@__PURE__*/ uniform( 1 ).onReference( ( { material } ) => material ).onObjectUpdate( function ( { material, scene } ) {
24+
25+
return material.envMap ? material.envMapIntensity : scene.environmentIntensity;
26+
27+
} );
28+
29+
/**
30+
* TSL object that represents the rotation of environment maps.
31+
* When `material.envMap` is set, the value is `material.envMapRotation`. `scene.environmentRotation` controls the
32+
* rotation of `scene.environment` instead.
33+
*
34+
* @tsl
35+
* @type {Node<mat4>}
36+
*/
37+
export const materialEnvRotation = /*@__PURE__*/ uniform( new Matrix4() ).onReference( function ( frame ) {
38+
39+
return frame.material;
40+
41+
} ).onObjectUpdate( function ( { material, scene } ) {
42+
43+
const rotation = ( scene.environment !== null && material.envMap === null ) ? scene.environmentRotation : material.envMapRotation;
44+
45+
if ( rotation ) {
46+
47+
_e1.copy( rotation );
48+
49+
_m1.makeRotationFromEuler( _e1 );
50+
51+
} else {
52+
53+
_m1.identity();
54+
55+
}
56+
57+
return _m1;
58+
59+
} );

src/nodes/lighting/EnvironmentNode.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import { cameraViewMatrix } from '../accessors/Camera.js';
55
import { transformedClearcoatNormalView, transformedNormalView, transformedNormalWorld } from '../accessors/Normal.js';
66
import { positionViewDirection } from '../accessors/Position.js';
77
import { float } from '../tsl/TSLBase.js';
8-
import { reference } from '../accessors/ReferenceNode.js';
98
import { transformedBentNormalView } from '../accessors/AccessorsUtils.js';
109
import { pmremTexture } from '../pmrem/PMREMNode.js';
10+
import { materialEnvIntensity } from '../accessors/MaterialProperties.js';
1111

1212
const _envNodeCache = new WeakMap();
1313

@@ -71,14 +71,11 @@ class EnvironmentNode extends LightingNode {
7171

7272
//
7373

74-
const envMap = material.envMap;
75-
const intensity = envMap ? reference( 'envMapIntensity', 'float', builder.material ) : reference( 'environmentIntensity', 'float', builder.scene ); // @TODO: Add materialEnvIntensity in MaterialNode
76-
7774
const useAnisotropy = material.useAnisotropy === true || material.anisotropy > 0;
7875
const radianceNormalView = useAnisotropy ? transformedBentNormalView : transformedNormalView;
7976

80-
const radiance = envNode.context( createRadianceContext( roughness, radianceNormalView ) ).mul( intensity );
81-
const irradiance = envNode.context( createIrradianceContext( transformedNormalWorld ) ).mul( Math.PI ).mul( intensity );
77+
const radiance = envNode.context( createRadianceContext( roughness, radianceNormalView ) ).mul( materialEnvIntensity );
78+
const irradiance = envNode.context( createIrradianceContext( transformedNormalWorld ) ).mul( Math.PI ).mul( materialEnvIntensity );
8279

8380
const isolateRadiance = cache( radiance );
8481
const isolateIrradiance = cache( irradiance );
@@ -95,7 +92,7 @@ class EnvironmentNode extends LightingNode {
9592

9693
if ( clearcoatRadiance ) {
9794

98-
const clearcoatRadianceContext = envNode.context( createRadianceContext( clearcoatRoughness, transformedClearcoatNormalView ) ).mul( intensity );
95+
const clearcoatRadianceContext = envNode.context( createRadianceContext( clearcoatRoughness, transformedClearcoatNormalView ) ).mul( materialEnvIntensity );
9996
const isolateClearcoatRadiance = cache( clearcoatRadianceContext );
10097

10198
clearcoatRadiance.addAssign( isolateClearcoatRadiance );

src/nodes/pmrem/PMREMNode.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { nodeProxy, vec3 } from '../tsl/TSLBase.js';
77

88
import { Texture } from '../../textures/Texture.js';
99
import PMREMGenerator from '../../renderers/common/extras/PMREMGenerator.js';
10+
import { materialEnvRotation } from '../accessors/MaterialProperties.js';
1011

1112
const _cache = new WeakMap();
1213

@@ -313,7 +314,7 @@ class PMREMNode extends TempNode {
313314

314315
//
315316

316-
uvNode = vec3( uvNode.x, uvNode.y.negate(), uvNode.z );
317+
uvNode = materialEnvRotation.mul( vec3( uvNode.x, uvNode.y.negate(), uvNode.z ) );
317318

318319
//
319320

0 commit comments

Comments
 (0)