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

WebGLRenderer: Add support for rotating env maps. #27758

Merged
merged 11 commits into from
Feb 20, 2024
5 changes: 5 additions & 0 deletions docs/api/en/materials/MeshBasicMaterial.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ <h3>[property:Integer combine]</h3>
<h3>[property:Texture envMap]</h3>
<p>The environment map. Default is null.</p>

<h3>[property:Euler envMapRotation]</h3>
<p>
The rotation of the environment map in radians. Default is `(0,0,0)`.
</p>

<h3>[property:Boolean fog]</h3>
<p>Whether the material is affected by fog. Default is `true`.</p>

Expand Down
5 changes: 5 additions & 0 deletions docs/api/en/materials/MeshLambertMaterial.html
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ <h3>[property:Float emissiveIntensity]</h3>
<h3>[property:Texture envMap]</h3>
<p>The environment map. Default is null.</p>

<h3>[property:Euler envMapRotation]</h3>
<p>
The rotation of the environment map in radians. Default is `(0,0,0)`.
</p>

<h3>[property:Boolean flatShading]</h3>
<p>
Define whether the material is rendered with flat shading. Default is
Expand Down
5 changes: 5 additions & 0 deletions docs/api/en/materials/MeshPhongMaterial.html
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ <h3>[property:Float emissiveIntensity]</h3>
<h3>[property:Texture envMap]</h3>
<p>The environment map. Default is null.</p>

<h3>[property:Euler envMapRotation]</h3>
<p>
The rotation of the environment map in radians. Default is `(0,0,0)`.
</p>

<h3>[property:Boolean flatShading]</h3>
<p>
Define whether the material is rendered with flat shading. Default is
Expand Down
5 changes: 5 additions & 0 deletions docs/api/en/materials/MeshStandardMaterial.html
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ <h3>[property:Texture envMap]</h3>
[page:PMREMGenerator]. Default is null.
</p>

<h3>[property:Euler envMapRotation]</h3>
<p>
The rotation of the environment map in radians. Default is `(0,0,0)`.
</p>

<h3>[property:Float envMapIntensity]</h3>
<p>Scales the effect of the environment map by multiplying its color.</p>

Expand Down
6 changes: 6 additions & 0 deletions docs/api/en/scenes/Scene.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ <h3>[property:Float backgroundIntensity]</h3>
textures. Default is `1`.
</p>

<h3>[property:Euler backgroundRotation]</h3>
<p>
The rotation of the background in radians. Only influences environment maps
assigned to [page:Scene.background]. Default is `(0,0,0)`.
</p>

<h3>[property:Texture environment]</h3>
<p>
Sets the environment map for all physical materials in the scene. However,
Expand Down
2 changes: 2 additions & 0 deletions src/materials/MeshBasicMaterial.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Material } from './Material.js';
import { MultiplyOperation } from '../constants.js';
import { Color } from '../math/Color.js';
import { Euler } from '../math/Euler.js';

class MeshBasicMaterial extends Material {

Expand All @@ -27,6 +28,7 @@ class MeshBasicMaterial extends Material {
this.alphaMap = null;

this.envMap = null;
this.envMapRotation = new Euler();
this.combine = MultiplyOperation;
this.reflectivity = 1;
this.refractionRatio = 0.98;
Expand Down
2 changes: 2 additions & 0 deletions src/materials/MeshLambertMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { MultiplyOperation, TangentSpaceNormalMap } from '../constants.js';
import { Material } from './Material.js';
import { Vector2 } from '../math/Vector2.js';
import { Color } from '../math/Color.js';
import { Euler } from '../math/Euler.js';

class MeshLambertMaterial extends Material {

Expand Down Expand Up @@ -43,6 +44,7 @@ class MeshLambertMaterial extends Material {
this.alphaMap = null;

this.envMap = null;
this.envMapRotation = new Euler();
this.combine = MultiplyOperation;
this.reflectivity = 1;
this.refractionRatio = 0.98;
Expand Down
2 changes: 2 additions & 0 deletions src/materials/MeshPhongMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { MultiplyOperation, TangentSpaceNormalMap } from '../constants.js';
import { Material } from './Material.js';
import { Vector2 } from '../math/Vector2.js';
import { Color } from '../math/Color.js';
import { Euler } from '../math/Euler.js';

class MeshPhongMaterial extends Material {

Expand Down Expand Up @@ -45,6 +46,7 @@ class MeshPhongMaterial extends Material {
this.alphaMap = null;

this.envMap = null;
this.envMapRotation = new Euler();
this.combine = MultiplyOperation;
this.reflectivity = 1;
this.refractionRatio = 0.98;
Expand Down
2 changes: 2 additions & 0 deletions src/materials/MeshStandardMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { TangentSpaceNormalMap } from '../constants.js';
import { Material } from './Material.js';
import { Vector2 } from '../math/Vector2.js';
import { Color } from '../math/Color.js';
import { Euler } from '../math/Euler.js';

class MeshStandardMaterial extends Material {

Expand Down Expand Up @@ -49,6 +50,7 @@ class MeshStandardMaterial extends Material {
this.alphaMap = null;

this.envMap = null;
this.envMapRotation = new Euler();
this.envMapIntensity = 1.0;

this.wireframe = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export default /* glsl */`

uniform float envMapIntensity;
uniform float flipEnvMap;
uniform mat3 envMapRotation;

#ifdef ENVMAP_TYPE_CUBE
uniform samplerCube envMap;
Expand Down
2 changes: 1 addition & 1 deletion src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default /* glsl */`

#ifdef ENVMAP_TYPE_CUBE

vec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
vec4 envColor = textureCube( envMap, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );

#else

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default /* glsl */`

vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );

vec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );
vec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );

return PI * envMapColor.rgb * envMapIntensity;

Expand All @@ -30,7 +30,7 @@ export default /* glsl */`

reflectVec = inverseTransformDirection( reflectVec, viewMatrix );

vec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );
vec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );

return envMapColor.rgb * envMapIntensity;

Expand Down
3 changes: 2 additions & 1 deletion src/renderers/shaders/ShaderLib.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ const ShaderLib = {
envMap: { value: null },
flipEnvMap: { value: - 1 },
backgroundBlurriness: { value: 0 },
backgroundIntensity: { value: 1 }
backgroundIntensity: { value: 1 },
backgroundRotation: { value: /*@__PURE__*/ new Matrix3() }
},

vertexShader: ShaderChunk.backgroundCube_vert,
Expand Down
5 changes: 3 additions & 2 deletions src/renderers/shaders/ShaderLib/backgroundCube.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const fragment = /* glsl */`
uniform float flipEnvMap;
uniform float backgroundBlurriness;
uniform float backgroundIntensity;
uniform mat3 backgroundRotation;

varying vec3 vWorldDirection;

Expand All @@ -39,11 +40,11 @@ void main() {

#ifdef ENVMAP_TYPE_CUBE

vec4 texColor = textureCube( envMap, vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );
vec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );

#elif defined( ENVMAP_TYPE_CUBE_UV )

vec4 texColor = textureCubeUV( envMap, vWorldDirection, backgroundBlurriness );
vec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );

#else

Expand Down
1 change: 1 addition & 0 deletions src/renderers/shaders/UniformsLib.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const UniformsLib = {
envmap: {

envMap: { value: null },
envMapRotation: { value: /*@__PURE__*/ new Matrix3() },
flipEnvMap: { value: - 1 },
reflectivity: { value: 1.0 }, // basic, lambert, phong
ior: { value: 1.5 }, // physical
Expand Down
18 changes: 18 additions & 0 deletions src/renderers/webgl/WebGLBackground.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import { PlaneGeometry } from '../../geometries/PlaneGeometry.js';
import { ShaderMaterial } from '../../materials/ShaderMaterial.js';
import { Color } from '../../math/Color.js';
import { ColorManagement } from '../../math/ColorManagement.js';
import { Euler } from '../../math/Euler.js';
import { Matrix4 } from '../../math/Matrix4.js';
import { Mesh } from '../../objects/Mesh.js';
import { ShaderLib } from '../shaders/ShaderLib.js';
import { cloneUniforms, getUnlitUniformColorSpace } from '../shaders/UniformsUtils.js';

const _rgb = { r: 0, b: 0, g: 0 };
const _e1 = /*@__PURE__*/ new Euler();
const _m1 = /*@__PURE__*/ new Matrix4();

function WebGLBackground( renderer, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha ) {

Expand Down Expand Up @@ -105,10 +109,24 @@ function WebGLBackground( renderer, cubemaps, cubeuvmaps, state, objects, alpha,

}

_e1.copy( scene.backgroundRotation );

_e1.x *= - 1;

if ( ( background.isCubeTexture && background.isRenderTargetTexture === true ) || background.mapping === CubeUVReflectionMapping ) {

// cube render targets and cubeUV maps (PMREM) need to reverse Y and Z rotation (which have a different conventions than normal cube textures, see flipEnvMap)

_e1.y *= - 1;
_e1.z *= - 1;

}
Mugen87 marked this conversation as resolved.
Show resolved Hide resolved

boxMesh.material.uniforms.envMap.value = background;
boxMesh.material.uniforms.flipEnvMap.value = ( background.isCubeTexture && background.isRenderTargetTexture === false ) ? - 1 : 1;
boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness;
boxMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity;
boxMesh.material.uniforms.backgroundRotation.value.setFromMatrix4( _m1.makeRotationFromEuler( _e1 ) );
boxMesh.material.toneMapped = ColorManagement.getTransfer( background.colorSpace ) !== SRGBTransfer;

if ( currentBackground !== background ||
Expand Down
22 changes: 21 additions & 1 deletion src/renderers/webgl/WebGLMaterials.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { BackSide } from '../../constants.js';
import { BackSide, CubeUVReflectionMapping } from '../../constants.js';
import { getUnlitUniformColorSpace } from '../shaders/UniformsUtils.js';
import { Euler } from '../../math/Euler.js';
import { Matrix4 } from '../../math/Matrix4.js';

const _e1 = /*@__PURE__*/ new Euler();
const _m1 = /*@__PURE__*/ new Matrix4();

function WebGLMaterials( renderer, properties ) {

Expand Down Expand Up @@ -215,6 +220,21 @@ function WebGLMaterials( renderer, properties ) {

uniforms.envMap.value = envMap;

_e1.copy( material.envMapRotation );

_e1.x *= - 1;

if ( ( envMap.isCubeTexture && envMap.isRenderTargetTexture === true ) || envMap.mapping === CubeUVReflectionMapping ) {

// cube render targets and cubeUV maps (PMREM) need to reverse Y and Z rotation (which have a different conventions than normal cube textures, see flipEnvMap)

_e1.y *= - 1;
_e1.z *= - 1;

}

uniforms.envMapRotation.value.setFromMatrix4( _m1.makeRotationFromEuler( _e1 ) );

uniforms.flipEnvMap.value = ( envMap.isCubeTexture && envMap.isRenderTargetTexture === false ) ? - 1 : 1;

uniforms.reflectivity.value = material.reflectivity;
Expand Down
2 changes: 2 additions & 0 deletions src/scenes/Scene.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Object3D } from '../core/Object3D.js';
import { Euler } from '../math/Euler.js';

class Scene extends Object3D {

Expand All @@ -16,6 +17,7 @@ class Scene extends Object3D {

this.backgroundBlurriness = 0;
this.backgroundIntensity = 1;
this.backgroundRotation = new Euler();

this.overrideMaterial = null;

Expand Down