diff --git a/examples/webgl_materials_car.html b/examples/webgl_materials_car.html
index 1f5594f37c08004c7039ca0d289fe2699ca5d52d..03ac8fb95a30a3eb962645ec88f9378eff0842bf 100644
--- a/examples/webgl_materials_car.html
+++ b/examples/webgl_materials_car.html
@@ -70,6 +70,8 @@
var envMap = pmremGenerator.fromEquirectangular( texture ).texture;
pmremGenerator.dispose();
+ envMap.blurriness = 0.15;
+
scene.background = envMap;
scene.environment = envMap;
diff --git a/examples/webgl_materials_physical_clearcoat.html b/examples/webgl_materials_physical_clearcoat.html
index f5827bf460947666348024a47b87ad0695ef2d9a..8ab6b4960ab5bfaed028b4ed20062b0c6263f3b1 100644
--- a/examples/webgl_materials_physical_clearcoat.html
+++ b/examples/webgl_materials_physical_clearcoat.html
@@ -145,6 +145,8 @@
//
+ hdrCubeRenderTarget.texture.blurriness = 0.2;
+
scene.background = hdrCubeRenderTarget.texture;
scene.environment = hdrCubeRenderTarget.texture;
diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js
index 76f3496a6a43d5e085566f39333d210229fb9ba3..f0d1dbba96d375a5fccf5c771a96b7064d57d48b 100644
--- a/src/renderers/WebGLRenderer.js
+++ b/src/renderers/WebGLRenderer.js
@@ -2089,6 +2089,7 @@ function WebGLRenderer( parameters ) {
if ( envMap ) {
uniforms.envMap.value = envMap;
+ uniforms.envMapBlurriness.value = envMap.blurriness;
// don't flip CubeTexture envMaps, flip everything else:
// WebGLRenderTargetCube will be flipped for backwards compatibility
diff --git a/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js
index e57198dd9ae66491fb2525f489ff9456fa96c5b9..f7321507134ad5db263f385486fe556342735955 100644
--- a/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js
+++ b/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js
@@ -1,6 +1,7 @@
export default /* glsl */`
#ifdef USE_ENVMAP
+ uniform float envMapBlurriness;
uniform float envMapIntensity;
uniform float flipEnvMap;
uniform int maxMipLevel;
@@ -10,6 +11,6 @@ export default /* glsl */`
#else
uniform sampler2D envMap;
#endif
-
+
#endif
`;
diff --git a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js
index db216edb813f6a86ea24a1edea8523cf9d17be64..162ffc2fa1dafb1558c1d314f3232ee93e9f9d78 100644
--- a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js
+++ b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js
@@ -4,7 +4,7 @@ export default /* glsl */`
#ifdef ENV_WORLDPOS
vec3 cameraToFrag;
-
+
if ( isOrthographic ) {
cameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );
@@ -40,7 +40,7 @@ export default /* glsl */`
#elif defined( ENVMAP_TYPE_CUBE_UV )
- vec4 envColor = textureCubeUV( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), 0.0 );
+ vec4 envColor = textureCubeUV( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), envMapBlurriness );
#elif defined( ENVMAP_TYPE_EQUIREC )
diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js
index 9c0651d3c24eabd12fe139af0468d0b384793ea1..6944c2a7749f3bda907c62d85780dc2040e10dad 100644
--- a/src/renderers/shaders/UniformsLib.js
+++ b/src/renderers/shaders/UniformsLib.js
@@ -30,6 +30,7 @@ var UniformsLib = {
envmap: {
envMap: { value: null },
+ envMapBlurriness: { value: 0 },
flipEnvMap: { value: - 1 },
reflectivity: { value: 1.0 },
refractionRatio: { value: 0.98 },
diff --git a/src/renderers/webgl/WebGLBackground.js b/src/renderers/webgl/WebGLBackground.js
index 8020a3fdb52caef30a23eb624c41eeaf429f18c7..6b6c0fbae12bc6bf874f444f40fca21b6653987b 100644
--- a/src/renderers/webgl/WebGLBackground.js
+++ b/src/renderers/webgl/WebGLBackground.js
@@ -105,6 +105,7 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
var texture = background.isWebGLRenderTargetCube ? background.texture : background;
boxMesh.material.uniforms.envMap.value = texture;
+ boxMesh.material.uniforms.envMapBlurriness.value = texture.blurriness;
boxMesh.material.uniforms.flipEnvMap.value = texture.isCubeTexture ? - 1 : 1;
if ( currentBackground !== background ||
diff --git a/src/textures/Texture.js b/src/textures/Texture.js
index 6f816e6a59a89a71c7e3d259ea14d06590305231..3956c3e7477671bb5c983efb1b6ade197b6081ca 100644
--- a/src/textures/Texture.js
+++ b/src/textures/Texture.js
@@ -61,6 +61,8 @@ function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, ty
this.flipY = true;
this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
+ this.blurriness = 0;
+
// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
//
// Also changing the encoding after already used by a Material will not automatically make the Material