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

ShadowNode: Ensure background does not influence shadow map. #1455

Merged
merged 5 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 71 additions & 53 deletions src-testing/changes.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts b/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts
index 6f0da365..95fd6f4f 100644
index a4dfe6b4..2d68722b 100644
--- a/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts
+++ b/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts
@@ -1,3 +1,10 @@
Expand All @@ -13,7 +13,7 @@ index 6f0da365..95fd6f4f 100644
const refreshUniforms = [
'alphaMap',
'alphaTest',
@@ -49,10 +56,33 @@ const refreshUniforms = [
@@ -49,7 +56,24 @@ const refreshUniforms = [
'thickness',
'transmission',
'transmissionMap',
Expand All @@ -37,80 +37,90 @@ index 6f0da365..95fd6f4f 100644
+ version?: number;
+}

/**
* This class is used by {@link WebGPURenderer} as management component.
@@ -57,12 +81,18 @@ const refreshUniforms = [
* refresh right before they are going to be rendered or not.
*/
class NodeMaterialObserver {
- constructor(builder) {
+ renderObjects: WeakMap<RenderObject, RenderObjectData>;
+ hasNode: boolean;
+ hasAnimation: boolean;
+ refreshUniforms: readonly RefreshUniform[];
+ renderId: number;
+
/**
* Constructs a new node material observer.
*
* @param {NodeBuilder} builder - The node builder.
*/
- constructor(builder) {
+ constructor(builder: NodeBuilder) {
this.renderObjects = new WeakMap();
this.hasNode = this.containsNode(builder);
this.hasAnimation = builder.object.isSkinnedMesh === true;
@@ -60,7 +90,7 @@ class NodeMaterialObserver {
this.renderId = 0;
}

/**
* A node material can be used by more than one render object so the
* monitor must maintain a list of render objects.
@@ -107,7 +137,7 @@ class NodeMaterialObserver {
* @param {RenderObject} renderObject - The render object.
* @return {Boolean} Whether the given render object is verified for the first time of this observer.
*/
- firstInitialization(renderObject) {
+ firstInitialization(renderObject: RenderObject) {
const hasInitialized = this.renderObjects.has(renderObject);

if (hasInitialized === false) {
@@ -72,7 +102,7 @@ class NodeMaterialObserver {
return false;
}

@@ -125,7 +155,7 @@ class NodeMaterialObserver {
* @param {RenderObject} renderObject - The render object.
* @return {Object} The monitoring data.
*/
- getRenderObjectData(renderObject) {
+ getRenderObjectData(renderObject: RenderObject) {
let data = this.renderObjects.get(renderObject);

if (data === undefined) {
@@ -113,8 +143,8 @@ class NodeMaterialObserver {
return data;
}

@@ -173,8 +203,8 @@ class NodeMaterialObserver {
* @param {Object} attributes - The geometry attributes.
* @return {Object} An object for monitoring the versions of attributes.
*/
- getAttributesData(attributes) {
- const attributesData = {};
+ getAttributesData(attributes: Record<string, BufferAttribute>) {
+ const attributesData: AttributesData = {};

for (const name in attributes) {
const attribute = attributes[name];
@@ -127,7 +157,7 @@ class NodeMaterialObserver {
return attributesData;
}

@@ -194,7 +224,7 @@ class NodeMaterialObserver {
* @param {NodeBuilder} builder - The current node builder.
* @return {Boolean} Whether the node builder's material uses node properties or not.
*/
- containsNode(builder) {
+ containsNode(builder: NodeBuilder) {
const material = builder.material;

for (const property in material) {
@@ -140,8 +170,8 @@ class NodeMaterialObserver {
return false;
}

@@ -214,8 +244,8 @@ class NodeMaterialObserver {
* @param {Material} material - The material.
* @return {Object} An object for monitoring material properties.
*/
- getMaterialData(material) {
- const data = {};
+ getMaterialData(material: Material) {
+ const data: MaterialData = {};

for (const property of this.refreshUniforms) {
const value = material[property];
@@ -162,7 +192,7 @@ class NodeMaterialObserver {
return data;
}

@@ -242,7 +272,7 @@ class NodeMaterialObserver {
* @param {RenderObject} renderObject - The render object.
* @return {Boolean} Whether the given render object has changed its state or not.
*/
- equals(renderObject) {
+ equals(renderObject: RenderObject) {
const { object, material, geometry } = renderObject;

const renderObjectData = this.getRenderObjectData(renderObject);
@@ -301,7 +331,7 @@ class NodeMaterialObserver {
return true;
}

@@ -388,7 +418,7 @@ class NodeMaterialObserver {
* @param {NodeFrame} nodeFrame - The current node frame.
* @return {Boolean} Whether the given render object requires a refresh or not.
*/
- needsRefresh(renderObject, nodeFrame) {
+ needsRefresh(renderObject: RenderObject, nodeFrame: NodeFrame) {
if (this.hasNode || this.hasAnimation || this.firstInitialization(renderObject)) return true;
Expand Down Expand Up @@ -7557,7 +7567,7 @@ index d2d92cb2..c022f814 100644
for (const uniform of this.uniforms) {
const node = uniform.nodeUniform.node;
diff --git a/src-testing/src/renderers/common/nodes/Nodes.ts b/src-testing/src/renderers/common/nodes/Nodes.ts
index fff9a80b..ab153bc4 100644
index ce2ea3f8..e89b2a0b 100644
--- a/src-testing/src/renderers/common/nodes/Nodes.ts
+++ b/src-testing/src/renderers/common/nodes/Nodes.ts
@@ -15,6 +15,7 @@ import {
Expand Down Expand Up @@ -7709,18 +7719,26 @@ index fff9a80b..ab153bc4 100644
return new NodeBuilderState(
nodeBuilder.vertexShader,
nodeBuilder.fragmentShader,
@@ -178,20 +239,20 @@ class Nodes extends DataMap {
@@ -178,7 +239,7 @@ class Nodes extends DataMap {
);
}

- getEnvironmentNode(scene) {
+ getEnvironmentNode(scene: Scene) {
return scene.environmentNode || this.get(scene).environmentNode || null;
let environmentNode = null;

if (scene.environmentNode && scene.environmentNode.isNode) {
@@ -194,7 +255,7 @@ class Nodes extends DataMap {
return environmentNode;
}

- getBackgroundNode(scene) {
+ getBackgroundNode(scene: Scene) {
return scene.backgroundNode || this.get(scene).backgroundNode || null;
let backgroundNode = null;

if (scene.backgroundNode && scene.backgroundNode.isNode) {
@@ -210,12 +271,12 @@ class Nodes extends DataMap {
return backgroundNode;
}

- getFogNode(scene) {
Expand All @@ -7735,7 +7753,7 @@ index fff9a80b..ab153bc4 100644
const callId = this.renderer.info.calls;

let cacheKeyData = this.callHashCache.get(chain);
@@ -219,7 +280,7 @@ class Nodes extends DataMap {
@@ -243,7 +304,7 @@ class Nodes extends DataMap {
return cacheKeyData.cacheKey;
}

Expand All @@ -7744,7 +7762,7 @@ index fff9a80b..ab153bc4 100644
this.updateEnvironment(scene);
this.updateFog(scene);
this.updateBackground(scene);
@@ -229,7 +290,7 @@ class Nodes extends DataMap {
@@ -253,7 +314,7 @@ class Nodes extends DataMap {
return this.renderer.getRenderTarget() ? false : true;
}

Expand All @@ -7753,7 +7771,7 @@ index fff9a80b..ab153bc4 100644
const sceneData = this.get(scene);
const background = scene.background;

@@ -242,7 +303,7 @@ class Nodes extends DataMap {
@@ -266,7 +327,7 @@ class Nodes extends DataMap {
let backgroundNode = null;

if (
Expand All @@ -7762,7 +7780,7 @@ index fff9a80b..ab153bc4 100644
background.mapping === EquirectangularReflectionMapping ||
background.mapping === EquirectangularRefractionMapping ||
background.mapping === CubeUVReflectionMapping
@@ -252,18 +313,18 @@ class Nodes extends DataMap {
@@ -276,18 +337,18 @@ class Nodes extends DataMap {
} else {
let envMap;

Expand All @@ -7787,7 +7805,7 @@ index fff9a80b..ab153bc4 100644
}

sceneData.backgroundNode = backgroundNode;
@@ -276,7 +337,7 @@ class Nodes extends DataMap {
@@ -300,7 +361,7 @@ class Nodes extends DataMap {
}
}

Expand All @@ -7796,7 +7814,7 @@ index fff9a80b..ab153bc4 100644
const sceneData = this.get(scene);
const sceneFog = scene.fog;

@@ -284,15 +345,15 @@ class Nodes extends DataMap {
@@ -308,15 +369,15 @@ class Nodes extends DataMap {
if (sceneData.fog !== sceneFog) {
let fogNode = null;

Expand All @@ -7819,7 +7837,7 @@ index fff9a80b..ab153bc4 100644

fogNode = fog(color, rangeFogFactor(near, far));
} else {
@@ -308,7 +369,7 @@ class Nodes extends DataMap {
@@ -332,7 +393,7 @@ class Nodes extends DataMap {
}
}

Expand All @@ -7828,7 +7846,7 @@ index fff9a80b..ab153bc4 100644
const sceneData = this.get(scene);
const environment = scene.environment;

@@ -316,7 +377,7 @@ class Nodes extends DataMap {
@@ -340,7 +401,7 @@ class Nodes extends DataMap {
if (sceneData.environment !== environment) {
let environmentNode = null;

Expand All @@ -7837,7 +7855,7 @@ index fff9a80b..ab153bc4 100644
environmentNode = cubeTexture(environment);
} else if (environment.isTexture === true) {
environmentNode = texture(environment);
@@ -333,7 +394,13 @@ class Nodes extends DataMap {
@@ -357,7 +418,13 @@ class Nodes extends DataMap {
}
}

Expand All @@ -7852,7 +7870,7 @@ index fff9a80b..ab153bc4 100644
const nodeFrame = this.nodeFrame;
nodeFrame.renderer = renderer;
nodeFrame.scene = scene;
@@ -344,7 +411,7 @@ class Nodes extends DataMap {
@@ -368,7 +435,7 @@ class Nodes extends DataMap {
return nodeFrame;
}

Expand All @@ -7861,7 +7879,7 @@ index fff9a80b..ab153bc4 100644
return this.getNodeFrame(
renderObject.renderer,
renderObject.scene,
@@ -360,24 +427,27 @@ class Nodes extends DataMap {
@@ -384,24 +451,27 @@ class Nodes extends DataMap {
return renderer.toneMapping + ',' + renderer.currentColorSpace;
}

Expand Down Expand Up @@ -7893,7 +7911,7 @@ index fff9a80b..ab153bc4 100644
const nodeBuilder = renderObject.getNodeBuilderState();

for (const node of nodeBuilder.updateBeforeNodes) {
@@ -387,7 +457,7 @@ class Nodes extends DataMap {
@@ -411,7 +481,7 @@ class Nodes extends DataMap {
}
}

Expand All @@ -7902,7 +7920,7 @@ index fff9a80b..ab153bc4 100644
const nodeBuilder = renderObject.getNodeBuilderState();

for (const node of nodeBuilder.updateAfterNodes) {
@@ -397,7 +467,7 @@ class Nodes extends DataMap {
@@ -421,7 +491,7 @@ class Nodes extends DataMap {
}
}

Expand All @@ -7911,7 +7929,7 @@ index fff9a80b..ab153bc4 100644
const nodeFrame = this.getNodeFrame();
const nodeBuilder = this.getForCompute(computeNode);

@@ -406,7 +476,7 @@ class Nodes extends DataMap {
@@ -430,7 +500,7 @@ class Nodes extends DataMap {
}
}

Expand All @@ -7920,7 +7938,7 @@ index fff9a80b..ab153bc4 100644
const nodeFrame = this.getNodeFrameForRender(renderObject);
const nodeBuilder = renderObject.getNodeBuilderState();

@@ -415,7 +485,7 @@ class Nodes extends DataMap {
@@ -439,7 +509,7 @@ class Nodes extends DataMap {
}
}

Expand Down
56 changes: 56 additions & 0 deletions types/three/src/materials/nodes/manager/NodeMaterialObserver.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,75 @@ interface RenderObjectData {
worldMatrix: Matrix4;
version?: number;
}
/**
* This class is used by {@link WebGPURenderer} as management component.
* It's primary purpose is to determine whether render objects require a
* refresh right before they are going to be rendered or not.
*/
declare class NodeMaterialObserver {
renderObjects: WeakMap<RenderObject, RenderObjectData>;
hasNode: boolean;
hasAnimation: boolean;
refreshUniforms: readonly RefreshUniform[];
renderId: number;
/**
* Constructs a new node material observer.
*
* @param {NodeBuilder} builder - The node builder.
*/
constructor(builder: NodeBuilder);
/**
* Returns `true` if the given render object is verified for the first time of this observer.
*
* @param {RenderObject} renderObject - The render object.
* @return {Boolean} Whether the given render object is verified for the first time of this observer.
*/
firstInitialization(renderObject: RenderObject): boolean;
/**
* Returns monitoring data for the given render object.
*
* @param {RenderObject} renderObject - The render object.
* @return {Object} The monitoring data.
*/
getRenderObjectData(renderObject: RenderObject): RenderObjectData;
/**
* Returns an attribute data structure holding the attributes versions for
* monitoring.
*
* @param {Object} attributes - The geometry attributes.
* @return {Object} An object for monitoring the versions of attributes.
*/
getAttributesData(attributes: Record<string, BufferAttribute>): AttributesData;
/**
* Returns `true` if the node builder's material uses
* node properties.
*
* @param {NodeBuilder} builder - The current node builder.
* @return {Boolean} Whether the node builder's material uses node properties or not.
*/
containsNode(builder: NodeBuilder): boolean;
/**
* Returns a material data structure holding the material property values for
* monitoring.
*
* @param {Material} material - The material.
* @return {Object} An object for monitoring material properties.
*/
getMaterialData(material: Material): MaterialData;
/**
* Returns `true` if the given render object has not changed its state.
*
* @param {RenderObject} renderObject - The render object.
* @return {Boolean} Whether the given render object has changed its state or not.
*/
equals(renderObject: RenderObject): boolean;
/**
* Checks if the given render object requires a refresh.
*
* @param {RenderObject} renderObject - The render object.
* @param {NodeFrame} nodeFrame - The current node frame.
* @return {Boolean} Whether the given render object requires a refresh or not.
*/
needsRefresh(renderObject: RenderObject, nodeFrame: NodeFrame): boolean;
}
export default NodeMaterialObserver;
Loading
Loading