diff --git a/docs/api/en/materials/MeshPhysicalMaterial.html b/docs/api/en/materials/MeshPhysicalMaterial.html index e209528eb04051..625b6a41b580c1 100644 --- a/docs/api/en/materials/MeshPhysicalMaterial.html +++ b/docs/api/en/materials/MeshPhysicalMaterial.html @@ -133,10 +133,9 @@

[property:Float reflectivity]

This models the reflectivity of non-metallic materials. It has no effect when [page:MeshStandardMaterial.metalness metalness] is *1.0*

-

[property:Color sheen]

+

[property:Color sheenTint]

- If a color is assigned to this property, the material will use a special sheen BRDF intended for rendering cloth materials such as velvet. - The sheen color provides the ability to create two-tone specular materials. *null* by default. + Used for rendering materials such as velvet. It has no effect when set to black (0x000000). Default is black.

[property:Float transmission]

diff --git a/docs/api/en/math/Color.html b/docs/api/en/math/Color.html index adfdf427f88a46..210e49b124aa39 100644 --- a/docs/api/en/math/Color.html +++ b/docs/api/en/math/Color.html @@ -208,6 +208,9 @@

[method:Object getHSL]( [param:Object target] )

[method:String getStyle]()

Returns the value of this color as a CSS style string. Example: 'rgb(255,0,0)'.

+

[method:Boolean isBlack]()

+

Returns true if the [page:.r r], [page:.g g] and [page:.b b] components are zero, false otherwise.

+

[method:Color lerp]( [param:Color color], [param:Float alpha] )

[page:Color color] - color to converge on.
diff --git a/examples/jsm/nodes/materials/StandardNodeMaterial.js b/examples/jsm/nodes/materials/StandardNodeMaterial.js index 592cfe148b6228..16cb16f529e31e 100644 --- a/examples/jsm/nodes/materials/StandardNodeMaterial.js +++ b/examples/jsm/nodes/materials/StandardNodeMaterial.js @@ -34,7 +34,7 @@ NodeUtils.addShortcuts( StandardNodeMaterial.prototype, 'fragment', [ 'environment', 'mask', 'position', - 'sheen' + 'sheenTint' ] ); export { StandardNodeMaterial }; diff --git a/examples/jsm/nodes/materials/nodes/StandardNode.js b/examples/jsm/nodes/materials/nodes/StandardNode.js index 26b9fce2c336ad..1f4412db5ec89d 100644 --- a/examples/jsm/nodes/materials/nodes/StandardNode.js +++ b/examples/jsm/nodes/materials/nodes/StandardNode.js @@ -185,7 +185,7 @@ class StandardNode extends Node { } - if ( this.sheen ) this.sheen.analyze( builder ); + if ( this.sheenTint ) this.sheenTint.analyze( builder ); // build code @@ -230,7 +230,7 @@ class StandardNode extends Node { const clearcoatEnv = useClearcoat && environment ? this.environment.flow( builder, 'c', { cache: 'clearcoat', context: contextClearcoatEnvironment, slot: 'environment' } ) : undefined; - const sheen = this.sheen ? this.sheen.flow( builder, 'c' ) : undefined; + const sheenTint = this.sheenTint ? this.sheenTint.flow( builder, 'c' ) : undefined; builder.requires.transparent = alpha !== undefined; @@ -368,9 +368,9 @@ class StandardNode extends Node { } - if ( sheen ) { + if ( sheenTint ) { - output.push( 'material.sheenColor = ' + sheen.result + ';' ); + output.push( 'material.sheenTint = ' + sheenTint.result + ';' ); } @@ -547,7 +547,7 @@ class StandardNode extends Node { if ( source.environment ) this.environment = source.environment; - if ( source.sheen ) this.sheen = source.sheen; + if ( source.sheenTint ) this.sheenTint = source.sheenTint; return this; @@ -593,7 +593,7 @@ class StandardNode extends Node { if ( this.environment ) data.environment = this.environment.toJSON( meta ).uuid; - if ( this.sheen ) data.sheen = this.sheen.toJSON( meta ).uuid; + if ( this.sheenTint ) data.sheenTint = this.sheenTint.toJSON( meta ).uuid; } diff --git a/src/loaders/MaterialLoader.js b/src/loaders/MaterialLoader.js index 87ad254356c3a2..1a88bc44ed8e5b 100644 --- a/src/loaders/MaterialLoader.js +++ b/src/loaders/MaterialLoader.js @@ -74,7 +74,7 @@ class MaterialLoader extends Loader { if ( json.color !== undefined && material.color !== undefined ) material.color.setHex( json.color ); if ( json.roughness !== undefined ) material.roughness = json.roughness; if ( json.metalness !== undefined ) material.metalness = json.metalness; - if ( json.sheen !== undefined ) material.sheen = new Color().setHex( json.sheen ); + if ( json.sheenTint !== undefined ) material.sheenTint = new Color().setHex( json.sheenTint ); if ( json.emissive !== undefined && material.emissive !== undefined ) material.emissive.setHex( json.emissive ); if ( json.specular !== undefined && material.specular !== undefined ) material.specular.setHex( json.specular ); if ( json.specularIntensity !== undefined ) material.specularIntensity = json.specularIntensity; diff --git a/src/materials/Material.js b/src/materials/Material.js index 4b4c77155daf63..01ce2a792625fc 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -169,7 +169,7 @@ class Material extends EventDispatcher { if ( this.roughness !== undefined ) data.roughness = this.roughness; if ( this.metalness !== undefined ) data.metalness = this.metalness; - if ( this.sheen && this.sheen.isColor ) data.sheen = this.sheen.getHex(); + if ( this.sheenTint && this.sheenTint.isColor ) data.sheenTint = this.sheenTint.getHex(); if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; diff --git a/src/materials/MeshPhysicalMaterial.js b/src/materials/MeshPhysicalMaterial.js index ee4922e40845a2..b59f0cac35fd46 100644 --- a/src/materials/MeshPhysicalMaterial.js +++ b/src/materials/MeshPhysicalMaterial.js @@ -15,7 +15,7 @@ import * as MathUtils from '../math/MathUtils.js'; * ior: , * reflectivity: , * - * sheen: , + * sheenTint: , * * transmission: , * transmissionMap: new THREE.Texture( ), @@ -69,7 +69,7 @@ class MeshPhysicalMaterial extends MeshStandardMaterial { } } ); - this.sheen = null; // null will disable sheen bsdf + this.sheenTint = new Color( 0x000000 ); this.transmission = 0.0; this.transmissionMap = null; @@ -108,15 +108,7 @@ class MeshPhysicalMaterial extends MeshStandardMaterial { this.ior = source.ior; - if ( source.sheen ) { - - this.sheen = ( this.sheen || new Color() ).copy( source.sheen ); - - } else { - - this.sheen = null; - - } + this.sheenTint.copy( source.sheenTint ); this.transmission = source.transmission; this.transmissionMap = source.transmissionMap; diff --git a/src/math/Color.js b/src/math/Color.js index 295c60e1a1766b..ef752607c49ddf 100644 --- a/src/math/Color.js +++ b/src/math/Color.js @@ -546,6 +546,12 @@ class Color { } + isBlack() { + + return ( this.r === 0 ) && ( this.g === 0 ) && ( this.b === 0 ); + + } + fromArray( array, offset = 0 ) { this.r = array[ offset ]; diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js index 5ec23b7e238809..73f52811399f6f 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js @@ -73,7 +73,7 @@ material.roughness = min( material.roughness, 1.0 ); #ifdef USE_SHEEN - material.sheenColor = sheen; + material.sheenTint = sheenTint; #endif `; diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js index d14edd28942d10..c760a2e42997d7 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js @@ -11,7 +11,7 @@ struct PhysicalMaterial { float clearcoatRoughness; #endif #ifdef USE_SHEEN - vec3 sheenColor; + vec3 sheenTint; #endif }; @@ -157,7 +157,7 @@ void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricC material.roughness, directLight.direction, geometry, - material.sheenColor + material.sheenTint ); #else diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index cc3b7508fecf5c..188ba2a9a1636c 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -296,7 +296,7 @@ ShaderLib.physical = { clearcoatRoughnessMap: { value: null }, clearcoatNormalScale: { value: new Vector2( 1, 1 ) }, clearcoatNormalMap: { value: null }, - sheen: { value: new Color( 0x000000 ) }, + sheenTint: { value: new Color( 0x000000 ) }, transmission: { value: 0 }, transmissionMap: { value: null }, transmissionSamplerSize: { value: new Vector2() }, diff --git a/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js b/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js index b1077a6c31f0d7..a8dbf0b6ad5e74 100644 --- a/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js +++ b/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js @@ -36,7 +36,7 @@ uniform float opacity; #endif #ifdef USE_SHEEN - uniform vec3 sheen; + uniform vec3 sheenTint; #endif varying vec3 vViewPosition; diff --git a/src/renderers/webgl/WebGLMaterials.js b/src/renderers/webgl/WebGLMaterials.js index 00fe07a9b8878e..f5a982951dac1b 100644 --- a/src/renderers/webgl/WebGLMaterials.js +++ b/src/renderers/webgl/WebGLMaterials.js @@ -583,7 +583,7 @@ function WebGLMaterials( properties ) { uniforms.clearcoat.value = material.clearcoat; uniforms.clearcoatRoughness.value = material.clearcoatRoughness; - if ( material.sheen ) uniforms.sheen.value.copy( material.sheen ); + if ( material.sheenTint ) uniforms.sheenTint.value.copy( material.sheenTint ); if ( material.clearcoatMap ) { diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 8961a077127c9a..3694ed61971089 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -621,7 +621,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) { parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', - parameters.sheen ? '#define USE_SHEEN' : '', + parameters.sheenTint ? '#define USE_SHEEN' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index 7e5c563ace1414..20af4dfe12f6b0 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -46,7 +46,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities 'numDirLightShadows', 'numPointLightShadows', 'numSpotLightShadows', 'shadowMapEnabled', 'shadowMapType', 'toneMapping', 'physicallyCorrectLights', 'alphaTest', 'doubleSided', 'flipSided', 'numClippingPlanes', 'numClipIntersection', 'depthPacking', 'dithering', - 'sheen', 'transmission', 'transmissionMap', 'thicknessMap' + 'sheenTint', 'transmission', 'transmissionMap', 'thicknessMap' ]; function getMaxBones( object ) { @@ -204,7 +204,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities gradientMap: !! material.gradientMap, - sheen: !! material.sheen, + sheenTint: ( !! material.sheenTint && ! material.sheenTint.isBlack() ), transmission: material.transmission > 0, transmissionMap: !! material.transmissionMap,