diff --git a/examples/files.json b/examples/files.json index 070955f2d4a3f3..f9c3ae92ef2431 100644 --- a/examples/files.json +++ b/examples/files.json @@ -397,7 +397,7 @@ "webgpu_materials_envmaps", "webgpu_materials_lightmap", "webgpu_materials_matcap", - "webgpu_materials_retroreflective", + "webgpu_materials_retroreflection", "webgpu_materials_sss", "webgpu_materials_texture_html", "webgpu_materials_texture_manualmipmap", diff --git a/examples/jsm/tsl/display/hashBlur.js b/examples/jsm/tsl/display/hashBlur.js index f781569d845ac9..540ccc560fc184 100644 --- a/examples/jsm/tsl/display/hashBlur.js +++ b/examples/jsm/tsl/display/hashBlur.js @@ -1,4 +1,4 @@ -import { float, Fn, vec2, uv, sin, rand, degrees, cos, Loop, vec4, premultiplyAlpha, unpremultiplyAlpha, convertToTexture, nodeObject } from 'three/tsl'; +import { float, Fn, vec2, uv, sin, rand, TWO_PI, cos, Loop, vec4, premultiplyAlpha, unpremultiplyAlpha, convertToTexture, nodeObject } from 'three/tsl'; /** * Applies a hash blur effect to the given texture node. @@ -41,7 +41,8 @@ export const hashBlur = /*#__PURE__*/ Fn( ( [ textureNode, bluramount = float( 0 Loop( { start: 0., end: repeats, type: 'float' }, ( { i } ) => { - const q = vec2( vec2( cos( degrees( i.div( repeats ).mul( 360. ) ) ), sin( degrees( i.div( repeats ).mul( 360. ) ) ) ).mul( rand( vec2( i, targetUV.x.add( targetUV.y ) ) ).add( bluramount ) ) ); + const angle = i.div( repeats ).mul( TWO_PI ).toConst(); + const q = vec2( cos( angle ), sin( angle ) ).mul( rand( vec2( i, targetUV.x.add( targetUV.y ) ) ).add( bluramount ) ); const uv2 = vec2( targetUV.add( q.mul( bluramount ) ) ); blurred_image.addAssign( tap( uv2 ) ); diff --git a/examples/jsm/webxr/WebGLXRFallback.js b/examples/jsm/webxr/WebGLXRFallback.js index 16df25631cfabb..c02cac6d829dc3 100644 --- a/examples/jsm/webxr/WebGLXRFallback.js +++ b/examples/jsm/webxr/WebGLXRFallback.js @@ -26,27 +26,13 @@ function setupWebGLXRFallback( renderer, createFallbackRenderer, onFallback = () } - if ( session !== null && renderer.backend.isWebGPUBackend === true && session.enabledFeatures.includes( 'webgpu' ) === false ) { + if ( session !== null && renderer.backend.isWebGPUBackend === true && typeof globalThis.XRGPUBinding === 'undefined' ) { return switchToFallbackRenderer( session, renderer ); } - try { - - return await setSession( session ); - - } catch ( error ) { - - if ( session === null || renderer.backend.isWebGPUBackend !== true ) { - - throw error; - - } - - return switchToFallbackRenderer( session, renderer ); - - } + return setSession( session ); }; diff --git a/examples/screenshots/webgpu_materials_retroreflection.jpg b/examples/screenshots/webgpu_materials_retroreflection.jpg new file mode 100644 index 00000000000000..e515892acee318 Binary files /dev/null and b/examples/screenshots/webgpu_materials_retroreflection.jpg differ diff --git a/examples/screenshots/webgpu_materials_retroreflective.jpg b/examples/screenshots/webgpu_materials_retroreflective.jpg deleted file mode 100644 index d8a4a881767e04..00000000000000 Binary files a/examples/screenshots/webgpu_materials_retroreflective.jpg and /dev/null differ diff --git a/examples/webgpu_materials_retroreflective.html b/examples/webgpu_materials_retroreflection.html similarity index 89% rename from examples/webgpu_materials_retroreflective.html rename to examples/webgpu_materials_retroreflection.html index 67024c56d021c6..36e88a55aa9640 100644 --- a/examples/webgpu_materials_retroreflective.html +++ b/examples/webgpu_materials_retroreflection.html @@ -1,12 +1,13 @@ - three.js webgpu - materials - retroreflective + three.js webgpu - materials - retroreflection - + - + + @@ -46,8 +47,8 @@ let frontLight, bandMaterial; const params = { - retroreflectivity: true, - retroreflective: 1.0, + retroreflective: true, + retroreflectivity: 1.0, frontLightIntensity: 5.0 }; @@ -95,8 +96,8 @@ controls.update(); const gui = new GUI(); - gui.add( params, 'retroreflectivity' ).name( 'retroreflectivity' ).onChange( updateMaterial ); - gui.add( params, 'retroreflective', 0, 1, 0.01 ).name( 'retroreflective' ).onChange( updateMaterial ); + gui.add( params, 'retroreflective' ).name( 'retroreflective' ).onChange( updateMaterial ); + gui.add( params, 'retroreflectivity', 0, 1, 0.01 ).name( 'retroreflectivity' ).onChange( updateMaterial ); gui.add( params, 'frontLightIntensity', 0, 30, 0.1 ).name( 'front light intensity' ).onChange( updateMaterial ); window.addEventListener( 'resize', onWindowResize ); @@ -120,7 +121,7 @@ color: 0xf7f0d6, roughness: 0.22, metalness: 0.0, - retroreflective: params.retroreflective + retroreflectivity: params.retroreflectivity } ); const base = new THREE.Mesh( @@ -167,7 +168,7 @@ function updateMaterial() { - bandMaterial.retroreflective = params.retroreflectivity ? params.retroreflective : 0; + bandMaterial.retroreflectivity = params.retroreflective ? params.retroreflectivity : 0; frontLight.intensity = params.frontLightIntensity; } diff --git a/src/Three.TSL.js b/src/Three.TSL.js index b2e4f301fdab08..76a0c83656e7d4 100644 --- a/src/Three.TSL.js +++ b/src/Three.TSL.js @@ -300,7 +300,7 @@ export const materialPointSize = TSL.materialPointSize; export const materialReference = TSL.materialReference; export const materialReflectivity = TSL.materialReflectivity; export const materialRefractionRatio = TSL.materialRefractionRatio; -export const materialRetroreflective = TSL.materialRetroreflective; +export const materialRetroreflectivity = TSL.materialRetroreflectivity; export const materialRotation = TSL.materialRotation; export const materialRoughness = TSL.materialRoughness; export const materialSheen = TSL.materialSheen; @@ -475,7 +475,7 @@ export const refract = TSL.refract; export const refractVector = TSL.refractVector; export const refractView = TSL.refractView; export const reinhardToneMapping = TSL.reinhardToneMapping; -export const retroreflective = TSL.retroreflective; +export const retroreflectivity = TSL.retroreflectivity; export const remap = TSL.remap; export const remapClamp = TSL.remapClamp; export const renderGroup = TSL.renderGroup; diff --git a/src/lights/LightShadow.js b/src/lights/LightShadow.js index 98fab479e3fea7..88b7d3b22bc844 100644 --- a/src/lights/LightShadow.js +++ b/src/lights/LightShadow.js @@ -333,6 +333,7 @@ class LightShadow { if ( this.bias !== 0 ) object.bias = this.bias; if ( this.normalBias !== 0 ) object.normalBias = this.normalBias; if ( this.radius !== 1 ) object.radius = this.radius; + if ( this.blurSamples !== 8 ) object.blurSamples = this.blurSamples; if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray(); object.camera = this.camera.toJSON( false ).object; diff --git a/src/lights/SpotLightShadow.js b/src/lights/SpotLightShadow.js index ba68595261d391..d7a5801b0f1fb8 100644 --- a/src/lights/SpotLightShadow.js +++ b/src/lights/SpotLightShadow.js @@ -70,11 +70,29 @@ class SpotLightShadow extends LightShadow { super.copy( source ); this.focus = source.focus; + this.aspect = source.aspect; return this; } + /** + * Serializes the light shadow into JSON. + * + * @return {Object} A JSON object representing the serialized light shadow. + * @see {@link ObjectLoader#parse} + */ + toJSON() { + + const object = super.toJSON(); + + if ( this.focus !== 1 ) object.focus = this.focus; + if ( this.aspect !== 1 ) object.aspect = this.aspect; + + return object; + + } + } export { SpotLightShadow }; diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 318df4e55bea06..6a0bd5b0769c57 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -1162,6 +1162,9 @@ class ObjectLoader extends Loader { if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias; if ( data.shadow.normalBias !== undefined ) object.shadow.normalBias = data.shadow.normalBias; if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius; + if ( data.shadow.blurSamples !== undefined ) object.shadow.blurSamples = data.shadow.blurSamples; + if ( data.shadow.focus !== undefined ) object.shadow.focus = data.shadow.focus; + if ( data.shadow.aspect !== undefined ) object.shadow.aspect = data.shadow.aspect; if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize ); if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera ); diff --git a/src/materials/Material.js b/src/materials/Material.js index b21e1658e91293..060a4e67fb26b4 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -1,9 +1,10 @@ import { Color } from '../math/Color.js'; import { EventDispatcher } from '../core/EventDispatcher.js'; -import { FrontSide, NormalBlending, LessEqualDepth, AddEquation, OneMinusSrcAlphaFactor, SrcAlphaFactor, AlwaysStencilFunc, KeepStencilOp } from '../constants.js'; +import { FrontSide, NormalBlending, LessEqualDepth, AddEquation, OneMinusSrcAlphaFactor, SrcAlphaFactor, AlwaysStencilFunc, KeepStencilOp, BasicDepthPacking } from '../constants.js'; import { generateUUID } from '../math/MathUtils.js'; import { warn } from '../utils.js'; import { Vector2 } from '../math/Vector2.js'; +import { Plane } from '../math/Plane.js'; let _materialId = 0; @@ -683,7 +684,7 @@ class Material extends EventDispatcher { } if ( this.dispersion !== undefined ) data.dispersion = this.dispersion; - if ( this.retroreflective !== undefined ) data.retroreflective = this.retroreflective; + if ( this.retroreflectivity !== undefined ) data.retroreflectivity = this.retroreflectivity; if ( this.iridescence !== undefined ) data.iridescence = this.iridescence; if ( this.iridescenceIOR !== undefined ) data.iridescenceIOR = this.iridescenceIOR; @@ -810,6 +811,15 @@ class Material extends EventDispatcher { if ( this.depthWrite === false ) data.depthWrite = this.depthWrite; if ( this.colorWrite === false ) data.colorWrite = this.colorWrite; + if ( Array.isArray( this.clippingPlanes ) && this.clippingPlanes.length > 0 ) { + + data.clippingPlanes = this.clippingPlanes.map( plane => plane.toJSON() ); + + } + + if ( this.clipIntersection === true ) data.clipIntersection = true; + if ( this.clipShadows === true ) data.clipShadows = true; + if ( this.stencilWriteMask !== 0xff ) data.stencilWriteMask = this.stencilWriteMask; if ( this.stencilFunc !== AlwaysStencilFunc ) data.stencilFunc = this.stencilFunc; if ( this.stencilRef !== 0 ) data.stencilRef = this.stencilRef; @@ -822,11 +832,16 @@ class Material extends EventDispatcher { // rotation (SpriteMaterial) if ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation; + // depthPacking (MeshDepthMaterial) + if ( this.depthPacking !== undefined && this.depthPacking !== BasicDepthPacking ) data.depthPacking = this.depthPacking; + if ( this.polygonOffset === true ) data.polygonOffset = true; if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor; if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits; if ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth; + if ( this.linecap !== undefined && this.linecap !== 'round' ) data.linecap = this.linecap; + if ( this.linejoin !== undefined && this.linejoin !== 'round' ) data.linejoin = this.linejoin; if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; if ( this.scale !== undefined ) data.scale = this.scale; @@ -912,7 +927,7 @@ class Material extends EventDispatcher { if ( json.clearcoat !== undefined ) this.clearcoat = json.clearcoat; if ( json.clearcoatRoughness !== undefined ) this.clearcoatRoughness = json.clearcoatRoughness; if ( json.dispersion !== undefined ) this.dispersion = json.dispersion; - if ( json.retroreflective !== undefined ) this.retroreflective = json.retroreflective; + if ( json.retroreflectivity !== undefined ) this.retroreflectivity = json.retroreflectivity; if ( json.iridescence !== undefined ) this.iridescence = json.iridescence; if ( json.iridescenceIOR !== undefined ) this.iridescenceIOR = json.iridescenceIOR; if ( json.iridescenceThicknessRange !== undefined ) this.iridescenceThicknessRange = json.iridescenceThicknessRange; @@ -936,6 +951,10 @@ class Material extends EventDispatcher { if ( json.depthTest !== undefined ) this.depthTest = json.depthTest; if ( json.depthWrite !== undefined ) this.depthWrite = json.depthWrite; if ( json.colorWrite !== undefined ) this.colorWrite = json.colorWrite; + if ( json.clippingPlanes !== undefined ) this.clippingPlanes = json.clippingPlanes.map( plane => new Plane().fromJSON( plane ) ); + if ( json.clipIntersection !== undefined ) this.clipIntersection = json.clipIntersection; + if ( json.clipShadows !== undefined ) this.clipShadows = json.clipShadows; + if ( json.depthPacking !== undefined ) this.depthPacking = json.depthPacking; if ( json.blendSrc !== undefined ) this.blendSrc = json.blendSrc; if ( json.blendDst !== undefined ) this.blendDst = json.blendDst; if ( json.blendEquation !== undefined ) this.blendEquation = json.blendEquation; @@ -961,6 +980,8 @@ class Material extends EventDispatcher { if ( json.rotation !== undefined ) this.rotation = json.rotation; if ( json.linewidth !== undefined ) this.linewidth = json.linewidth; + if ( json.linecap !== undefined ) this.linecap = json.linecap; + if ( json.linejoin !== undefined ) this.linejoin = json.linejoin; if ( json.dashSize !== undefined ) this.dashSize = json.dashSize; if ( json.gapSize !== undefined ) this.gapSize = json.gapSize; if ( json.scale !== undefined ) this.scale = json.scale; diff --git a/src/materials/MeshPhysicalMaterial.js b/src/materials/MeshPhysicalMaterial.js index 3d785961f506bd..d2523561152163 100644 --- a/src/materials/MeshPhysicalMaterial.js +++ b/src/materials/MeshPhysicalMaterial.js @@ -356,7 +356,7 @@ class MeshPhysicalMaterial extends MeshStandardMaterial { this._clearcoat = 0; this._dispersion = 0; this._iridescence = 0; - this._retroreflective = 0; + this._retroreflectivity = 0; this._sheen = 0.0; this._transmission = 0; @@ -473,21 +473,21 @@ class MeshPhysicalMaterial extends MeshStandardMaterial { * @type {number} * @default 0 */ - get retroreflective() { + get retroreflectivity() { - return this._retroreflective; + return this._retroreflectivity; } - set retroreflective( value ) { + set retroreflectivity( value ) { - if ( this._retroreflective > 0 !== value > 0 ) { + if ( this._retroreflectivity > 0 !== value > 0 ) { this.version ++; } - this._retroreflective = value; + this._retroreflectivity = value; } @@ -576,7 +576,7 @@ class MeshPhysicalMaterial extends MeshStandardMaterial { this.iridescenceThicknessRange = [ ...source.iridescenceThicknessRange ]; this.iridescenceThicknessMap = source.iridescenceThicknessMap; - this.retroreflective = source.retroreflective; + this.retroreflectivity = source.retroreflectivity; this.sheen = source.sheen; this.sheenColor.copy( source.sheenColor ); diff --git a/src/materials/nodes/MeshPhysicalNodeMaterial.js b/src/materials/nodes/MeshPhysicalNodeMaterial.js index 5accbc99db72cc..bd0b92411317ea 100644 --- a/src/materials/nodes/MeshPhysicalNodeMaterial.js +++ b/src/materials/nodes/MeshPhysicalNodeMaterial.js @@ -1,5 +1,5 @@ -import { clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness, specularColor, specularColorBlended, specularF90, diffuseColor, metalness, roughness, anisotropy, alphaT, anisotropyT, anisotropyB, ior, transmission, thickness, attenuationDistance, attenuationColor, dispersion, retroreflective } from '../../nodes/core/PropertyNode.js'; -import { materialClearcoat, materialClearcoatRoughness, materialClearcoatNormal, materialSheen, materialSheenRoughness, materialIridescence, materialIridescenceIOR, materialIridescenceThickness, materialSpecularIntensity, materialSpecularColor, materialAnisotropy, materialIOR, materialTransmission, materialThickness, materialAttenuationDistance, materialAttenuationColor, materialDispersion, materialRetroreflective } from '../../nodes/accessors/MaterialNode.js'; +import { clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness, specularColor, specularColorBlended, specularF90, diffuseColor, metalness, roughness, anisotropy, alphaT, anisotropyT, anisotropyB, ior, transmission, thickness, attenuationDistance, attenuationColor, dispersion, retroreflectivity } from '../../nodes/core/PropertyNode.js'; +import { materialClearcoat, materialClearcoatRoughness, materialClearcoatNormal, materialSheen, materialSheenRoughness, materialIridescence, materialIridescenceIOR, materialIridescenceThickness, materialSpecularIntensity, materialSpecularColor, materialAnisotropy, materialIOR, materialTransmission, materialThickness, materialAttenuationDistance, materialAttenuationColor, materialDispersion, materialRetroreflectivity } from '../../nodes/accessors/MaterialNode.js'; import { float, vec2, vec3, If } from '../../nodes/tsl/TSLBase.js'; import getRoughness from '../../nodes/functions/material/getRoughness.js'; import { TBNViewMatrix } from '../../nodes/accessors/AccessorsUtils.js'; @@ -253,16 +253,16 @@ class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial { /** * The retroreflective strength of physical materials is by default inferred from the - * `retroreflective` property. This node property allows to overwrite the default + * `retroreflectivity` property. This node property allows to overwrite the default * and define the retroreflective strength with a node instead. * * If you don't want to overwrite the retroreflective strength but modify the existing - * value instead, use {@link materialRetroreflective}. + * value instead, use {@link materialRetroreflectivity}. * * @type {?Node} * @default null */ - this.retroreflectiveNode = null; + this.retroreflectivityNode = null; /** * The anisotropy of physical materials is by default inferred from the @@ -361,9 +361,9 @@ class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial { * @type {boolean} * @default true */ - get useRetroreflective() { + get useRetroreflection() { - return this.retroreflective > 0 || this.retroreflectiveNode !== null; + return this.retroreflectivity > 0 || this.retroreflectivityNode !== null; } @@ -388,7 +388,7 @@ class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial { */ setupLightingModel( /*builder*/ ) { - return new PhysicalLightingModel( this.useClearcoat, this.useSheen, this.useIridescence, this.useAnisotropy, this.useTransmission, this.useDispersion, this.useRetroreflective ); + return new PhysicalLightingModel( this.useClearcoat, this.useSheen, this.useIridescence, this.useAnisotropy, this.useTransmission, this.useDispersion, this.useRetroreflection ); } @@ -425,13 +425,13 @@ class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial { } - // RETROREFLECTIVE + // RETROREFLECTION - if ( this.useRetroreflective ) { + if ( this.useRetroreflection ) { - const retroreflectiveNode = this.retroreflectiveNode ? float( this.retroreflectiveNode ) : materialRetroreflective; + const retroreflectivityNode = this.retroreflectivityNode ? float( this.retroreflectivityNode ) : materialRetroreflectivity; - retroreflective.assign( retroreflectiveNode ); + retroreflectivity.assign( retroreflectivityNode ); } diff --git a/src/materials/nodes/manager/NodeMaterialObserver.js b/src/materials/nodes/manager/NodeMaterialObserver.js index c64cd090139690..755d51b0e463af 100644 --- a/src/materials/nodes/manager/NodeMaterialObserver.js +++ b/src/materials/nodes/manager/NodeMaterialObserver.js @@ -38,7 +38,7 @@ const refreshUniforms = [ 'normalMap', 'normalScale', 'opacity', - 'retroreflective', + 'retroreflectivity', 'roughness', 'roughnessMap', 'sheen', diff --git a/src/math/Plane.js b/src/math/Plane.js index 95287da599362e..1cfe3ee8861352 100644 --- a/src/math/Plane.js +++ b/src/math/Plane.js @@ -363,6 +363,35 @@ class Plane { } + /** + * Returns a serialized structure of the plane. + * + * @return {Object} Serialized structure with fields representing the object state. + */ + toJSON() { + + return { + normal: this.normal.toArray(), + constant: this.constant + }; + + } + + /** + * Sets the plane properties from the given JSON. + * + * @param {Object} json - The serialized json to set the plane from. + * @return {Plane} A reference to this plane. + */ + fromJSON( json ) { + + this.normal.fromArray( json.normal ); + this.constant = json.constant; + + return this; + + } + } export { Plane }; diff --git a/src/nodes/accessors/MaterialNode.js b/src/nodes/accessors/MaterialNode.js index a02f8c579a2695..a813b85b81fff0 100644 --- a/src/nodes/accessors/MaterialNode.js +++ b/src/nodes/accessors/MaterialNode.js @@ -463,7 +463,7 @@ MaterialNode.LINE_WIDTH = 'linewidth'; MaterialNode.LINE_DASH_OFFSET = 'dashOffset'; MaterialNode.POINT_SIZE = 'size'; MaterialNode.DISPERSION = 'dispersion'; -MaterialNode.RETROREFLECTIVE = 'retroreflective'; +MaterialNode.RETROREFLECTIVITY = 'retroreflectivity'; MaterialNode.LIGHT_MAP = 'light'; MaterialNode.AO = 'ao'; @@ -771,7 +771,7 @@ export const materialDispersion = /*@__PURE__*/ nodeImmutable( MaterialNode, Mat * @tsl * @type {Node} */ -export const materialRetroreflective = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.RETROREFLECTIVE ); +export const materialRetroreflectivity = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.RETROREFLECTIVITY ); /** * TSL object that represents the light map of the current material. diff --git a/src/nodes/core/PropertyNode.js b/src/nodes/core/PropertyNode.js index b256399267e1ee..870782636336b6 100644 --- a/src/nodes/core/PropertyNode.js +++ b/src/nodes/core/PropertyNode.js @@ -404,12 +404,12 @@ export const attenuationColor = /*@__PURE__*/ nodeImmutable( PropertyNode, 'colo export const dispersion = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Dispersion' ); /** - * TSL object that represents the shader variable `Retroreflective`. + * TSL object that represents the shader variable `Retroreflectivity`. * * @tsl * @type {PropertyNode} */ -export const retroreflective = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Retroreflective' ); +export const retroreflectivity = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Retroreflectivity' ); /** * TSL object that represents the shader variable `AmbientOcclusion`. diff --git a/src/nodes/functions/PhysicalLightingModel.js b/src/nodes/functions/PhysicalLightingModel.js index 55a6922a93514e..4e2567f4b300cb 100644 --- a/src/nodes/functions/PhysicalLightingModel.js +++ b/src/nodes/functions/PhysicalLightingModel.js @@ -7,7 +7,7 @@ import Schlick_to_F0 from './BSDF/Schlick_to_F0.js'; import BRDF_Sheen from './BSDF/BRDF_Sheen.js'; import { LTC_Evaluate, LTC_Uv } from './BSDF/LTC.js'; import LightingModel from '../core/LightingModel.js'; -import { diffuseColor, diffuseContribution, specularColor, specularColorBlended, specularF90, roughness, metalness, clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness, ior, thickness, transmission, attenuationDistance, attenuationColor, dispersion, retroreflective } from '../core/PropertyNode.js'; +import { diffuseColor, diffuseContribution, specularColor, specularColorBlended, specularF90, roughness, metalness, clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness, ior, thickness, transmission, attenuationDistance, attenuationColor, dispersion, retroreflectivity } from '../core/PropertyNode.js'; import { normalView, clearcoatNormalView, normalWorld } from '../accessors/Normal.js'; import { positionViewDirection, positionView, positionWorld } from '../accessors/Position.js'; import { Fn, float, vec2, vec3, vec4, mat3, If } from '../tsl/TSLBase.js'; @@ -347,9 +347,9 @@ class PhysicalLightingModel extends LightingModel { * @param {boolean} [anisotropy=false] - Whether anisotropy is supported or not. * @param {boolean} [transmission=false] - Whether transmission is supported or not. * @param {boolean} [dispersion=false] - Whether dispersion is supported or not. - * @param {boolean} [retroreflective=false] - Whether retroreflection is supported or not. + * @param {boolean} [retroreflection=false] - Whether retroreflection is supported or not. */ - constructor( clearcoat = false, sheen = false, iridescence = false, anisotropy = false, transmission = false, dispersion = false, retroreflective = false ) { + constructor( clearcoat = false, sheen = false, iridescence = false, anisotropy = false, transmission = false, dispersion = false, retroreflection = false ) { super(); @@ -407,7 +407,7 @@ class PhysicalLightingModel extends LightingModel { * @type {boolean} * @default false */ - this.retroreflective = retroreflective; + this.retroreflection = retroreflection; /** * The clear coat radiance. @@ -655,7 +655,7 @@ class PhysicalLightingModel extends LightingModel { let specularBRDF = BRDF_GGX( { lightDirection, f0: specularColorBlended, f90: 1, roughness, f: this.iridescenceFresnel, USE_IRIDESCENCE: this.iridescence, USE_ANISOTROPY: this.anisotropy } ); - if ( this.retroreflective === true ) { + if ( this.retroreflection === true ) { // Minimal Retroreflective Microfacet Model: // https://jcgt.org/published/0015/01/04/ @@ -665,8 +665,8 @@ class PhysicalLightingModel extends LightingModel { const retroF = F_Schlick( { f0: specularColor, f90: specularF90, dotVH: dotRetroVH } ); const retroSpecularBRDF = BRDF_GGX( { lightDirection, viewDirection: retroViewDirection, f0: specularColorBlended, f90: 1, roughness, f: this.iridescenceFresnel, USE_IRIDESCENCE: this.iridescence, USE_ANISOTROPY: this.anisotropy } ); - F = mix( F, retroF, retroreflective.clamp() ); - specularBRDF = mix( specularBRDF, retroSpecularBRDF, retroreflective.clamp() ); + F = mix( F, retroF, retroreflectivity.clamp() ); + specularBRDF = mix( specularBRDF, retroSpecularBRDF, retroreflectivity.clamp() ); } diff --git a/src/renderers/common/Storage3DTexture.js b/src/renderers/common/Storage3DTexture.js index f17b4cdd150e65..c985ac36a38026 100644 --- a/src/renderers/common/Storage3DTexture.js +++ b/src/renderers/common/Storage3DTexture.js @@ -74,6 +74,22 @@ class Storage3DTexture extends Texture { } + /** + * Copies the values of the given texture to this instance. + * + * @param {Storage3DTexture} source - The texture to copy. + * @return {Storage3DTexture} A reference to this instance. + */ + copy( source ) { + + super.copy( source ); + + this.wrapR = source.wrapR; + + return this; + + } + /** * Sets the size of the storage 3d texture. * diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js index dbc1abdfd3acac..8ce14943dc980c 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js @@ -85,9 +85,9 @@ material.roughness = min( material.roughness, 1.0 ); #endif -#ifdef USE_RETROREFLECTIVE +#ifdef USE_RETROREFLECTION - material.retroreflective = retroreflective; + material.retroreflectivity = retroreflectivity; #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 374e17ef5392f4..6855001c80723d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js @@ -16,8 +16,8 @@ struct PhysicalMaterial { vec2 dfg; vec3 multiScatteringCompensation; - #ifdef USE_RETROREFLECTIVE - float retroreflective; + #ifdef USE_RETROREFLECTION + float retroreflectivity; #endif #ifdef USE_CLEARCOAT @@ -515,14 +515,14 @@ void RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geome vec3 specularBRDF = BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material ); - #ifdef USE_RETROREFLECTIVE + #ifdef USE_RETROREFLECTION // Minimal Retroreflective Microfacet Model: // https://jcgt.org/published/0015/01/04/ vec3 retroViewDir = reflect( - geometryViewDir, geometryNormal ); vec3 retroSpecularBRDF = BRDF_GGX( directLight.direction, retroViewDir, geometryNormal, material ); - specularBRDF = mix( specularBRDF, retroSpecularBRDF, saturate( material.retroreflective ) ); + specularBRDF = mix( specularBRDF, retroSpecularBRDF, saturate( material.retroreflectivity ) ); #endif @@ -533,13 +533,13 @@ void RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geome float dotVH = saturate( dot( geometryViewDir, halfDir ) ); vec3 F = F_Schlick( material.specularColor, material.specularF90, dotVH ); - #ifdef USE_RETROREFLECTIVE + #ifdef USE_RETROREFLECTION vec3 retroHalfDir = normalize( directLight.direction + retroViewDir ); float dotRetroVH = saturate( dot( retroViewDir, retroHalfDir ) ); vec3 retroF = F_Schlick( material.specularColor, material.specularF90, dotRetroVH ); - F = mix( F, retroF, saturate( material.retroreflective ) ); + F = mix( F, retroF, saturate( material.retroreflectivity ) ); #endif diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index ff768bc3fb8544..295581fa69c95b 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -316,7 +316,7 @@ ShaderLib.physical = { clearcoatRoughnessMap: { value: null }, clearcoatRoughnessMapTransform: { value: /*@__PURE__*/ new Matrix3() }, dispersion: { value: 0 }, - retroreflective: { value: 0 }, + retroreflectivity: { value: 0 }, iridescence: { value: 0 }, iridescenceMap: { value: null }, iridescenceMapTransform: { value: /*@__PURE__*/ new Matrix3() }, diff --git a/src/renderers/shaders/ShaderLib/meshphysical.glsl.js b/src/renderers/shaders/ShaderLib/meshphysical.glsl.js index c4a87fb4baec20..21403cce485bc0 100644 --- a/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +++ b/src/renderers/shaders/ShaderLib/meshphysical.glsl.js @@ -99,8 +99,8 @@ uniform float opacity; uniform float dispersion; #endif -#ifdef USE_RETROREFLECTIVE - uniform float retroreflective; +#ifdef USE_RETROREFLECTION + uniform float retroreflectivity; #endif #ifdef USE_IRIDESCENCE diff --git a/src/renderers/webgl/WebGLMaterials.js b/src/renderers/webgl/WebGLMaterials.js index ba1de8caf4e367..c41c1984d215e2 100644 --- a/src/renderers/webgl/WebGLMaterials.js +++ b/src/renderers/webgl/WebGLMaterials.js @@ -483,9 +483,9 @@ function WebGLMaterials( renderer, properties ) { } - if ( material.retroreflective > 0 ) { + if ( material.retroreflectivity > 0 ) { - uniforms.retroreflective.value = material.retroreflective; + uniforms.retroreflectivity.value = material.retroreflectivity; } diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 50a582235c339a..4d64b338ba5ee4 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -709,7 +709,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) { parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.dispersion ? '#define USE_DISPERSION' : '', - parameters.retroreflective ? '#define USE_RETROREFLECTIVE' : '', + parameters.retroreflection ? '#define USE_RETROREFLECTION' : '', parameters.iridescence ? '#define USE_IRIDESCENCE' : '', parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index 773a691f6d6c2b..b6a0fceaf49724 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -140,7 +140,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin const HAS_ANISOTROPY = material.anisotropy > 0; const HAS_CLEARCOAT = material.clearcoat > 0; const HAS_DISPERSION = material.dispersion > 0; - const HAS_RETROREFLECTIVE = material.retroreflective > 0; + const HAS_RETROREFLECTION = material.retroreflectivity > 0; const HAS_IRIDESCENCE = material.iridescence > 0; const HAS_SHEEN = material.sheen > 0; const HAS_TRANSMISSION = material.transmission > 0; @@ -241,7 +241,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin clearcoatRoughnessMap: HAS_CLEARCOAT_ROUGHNESSMAP, dispersion: HAS_DISPERSION, - retroreflective: HAS_RETROREFLECTIVE, + retroreflection: HAS_RETROREFLECTION, iridescence: HAS_IRIDESCENCE, iridescenceMap: HAS_IRIDESCENCEMAP, @@ -534,7 +534,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin _programLayers.enable( 18 ); if ( parameters.dispersion ) _programLayers.enable( 19 ); - if ( parameters.retroreflective ) + if ( parameters.retroreflection ) _programLayers.enable( 24 ); if ( parameters.batchingColor ) _programLayers.enable( 20 ); diff --git a/src/textures/CompressedArrayTexture.js b/src/textures/CompressedArrayTexture.js index 56205e36c8bc19..6a7c30e4a1ba17 100644 --- a/src/textures/CompressedArrayTexture.js +++ b/src/textures/CompressedArrayTexture.js @@ -60,6 +60,22 @@ class CompressedArrayTexture extends CompressedTexture { } + /** + * Copies the values of the given texture to this instance. + * + * @param {CompressedArrayTexture} source - The texture to copy. + * @return {CompressedArrayTexture} A reference to this instance. + */ + copy( source ) { + + super.copy( source ); + + this.wrapR = source.wrapR; + + return this; + + } + /** * Describes that a specific layer of the texture needs to be updated. * Normally when {@link Texture#needsUpdate} is set to `true`, the diff --git a/src/textures/Data3DTexture.js b/src/textures/Data3DTexture.js index e826b5261f5818..72fcd167afee0e 100644 --- a/src/textures/Data3DTexture.js +++ b/src/textures/Data3DTexture.js @@ -107,6 +107,22 @@ class Data3DTexture extends Texture { } + /** + * Copies the values of the given texture to this instance. + * + * @param {Data3DTexture} source - The texture to copy. + * @return {Data3DTexture} A reference to this instance. + */ + copy( source ) { + + super.copy( source ); + + this.wrapR = source.wrapR; + + return this; + + } + } export { Data3DTexture }; diff --git a/src/textures/DataArrayTexture.js b/src/textures/DataArrayTexture.js index 1e80e055e1eeed..1b17ac3a2a7dae 100644 --- a/src/textures/DataArrayTexture.js +++ b/src/textures/DataArrayTexture.js @@ -105,6 +105,22 @@ class DataArrayTexture extends Texture { } + /** + * Copies the values of the given texture to this instance. + * + * @param {DataArrayTexture} source - The texture to copy. + * @return {DataArrayTexture} A reference to this instance. + */ + copy( source ) { + + super.copy( source ); + + this.wrapR = source.wrapR; + + return this; + + } + /** * Describes that a specific layer of the texture needs to be updated. * Normally when {@link Texture#needsUpdate} is set to `true`, the diff --git a/test/unit/src/materials/MeshPhysicalMaterial.tests.js b/test/unit/src/materials/MeshPhysicalMaterial.tests.js index 81267b8c276d92..8a822a45a8d020 100644 --- a/test/unit/src/materials/MeshPhysicalMaterial.tests.js +++ b/test/unit/src/materials/MeshPhysicalMaterial.tests.js @@ -37,37 +37,37 @@ export default QUnit.module( 'Materials', () => { } ); - QUnit.test( 'retroreflective', ( assert ) => { + QUnit.test( 'retroreflectivity', ( assert ) => { const object = new MeshPhysicalMaterial(); - assert.strictEqual( object.retroreflective, 0, 'retroreflective defaults to 0.' ); + assert.strictEqual( object.retroreflectivity, 0, 'retroreflectivity defaults to 0.' ); - object.retroreflective = 0.75; - assert.strictEqual( object.retroreflective, 0.75, 'Can set retroreflective.' ); + object.retroreflectivity = 0.75; + assert.strictEqual( object.retroreflectivity, 0.75, 'Can set retroreflectivity.' ); } ); - QUnit.test( 'copy copies retroreflective', ( assert ) => { + QUnit.test( 'copy copies retroreflectivity', ( assert ) => { - const source = new MeshPhysicalMaterial( { retroreflective: 0.5 } ); + const source = new MeshPhysicalMaterial( { retroreflectivity: 0.5 } ); const object = new MeshPhysicalMaterial(); object.copy( source ); - assert.strictEqual( object.retroreflective, 0.5, 'copy() preserves retroreflective.' ); + assert.strictEqual( object.retroreflectivity, 0.5, 'copy() preserves retroreflectivity.' ); } ); - QUnit.test( 'fromJSON restores retroreflective', ( assert ) => { + QUnit.test( 'fromJSON restores retroreflectivity', ( assert ) => { - const source = new MeshPhysicalMaterial( { retroreflective: 0.25 } ); + const source = new MeshPhysicalMaterial( { retroreflectivity: 0.25 } ); const json = source.toJSON(); const object = new MeshPhysicalMaterial(); object.fromJSON( json ); - assert.strictEqual( json.retroreflective, 0.25, 'toJSON() serializes retroreflective.' ); - assert.strictEqual( object.retroreflective, 0.25, 'fromJSON() restores retroreflective.' ); + assert.strictEqual( json.retroreflectivity, 0.25, 'toJSON() serializes retroreflectivity.' ); + assert.strictEqual( object.retroreflectivity, 0.25, 'fromJSON() restores retroreflectivity.' ); } );