Skip to content

Commit 72059ee

Browse files
authored
NodeMaterialObserver: Add checking the lights (#1740)
* Update three.js * Add src * Update patch and delete src * Update declarations
1 parent f3f29de commit 72059ee

File tree

3 files changed

+91
-18
lines changed

3 files changed

+91
-18
lines changed

src-testing/changes.patch

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
diff --git a/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts b/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts
2-
index f2030fde..061cabf3 100644
2+
index b18f9a94..6cb70a74 100644
33
--- a/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts
44
+++ b/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts
5-
@@ -1,3 +1,11 @@
5+
@@ -1,3 +1,14 @@
66
+import NodeBuilder from '../../../nodes/core/NodeBuilder.js';
77
+import RenderObject from '../../../renderers/common/RenderObject.js';
88
+import { Matrix4 } from '../../../math/Matrix4.js';
99
+import { Material } from '../../Material.js';
1010
+import NodeFrame from '../../../nodes/core/NodeFrame.js';
1111
+import { BufferAttribute } from '../../../core/BufferAttribute.js';
1212
+import Renderer from '../../../renderers/common/Renderer.js';
13+
+import { Light } from '../../../lights/Light.js';
14+
+import { SpotLight } from '../../../lights/SpotLight.js';
15+
+import LightsNode from '../../../nodes/lighting/LightsNode.js';
1316
+
1417
const refreshUniforms = [
1518
'alphaMap',
1619
'alphaTest',
17-
@@ -53,7 +61,29 @@ const refreshUniforms = [
20+
@@ -53,7 +64,38 @@ const refreshUniforms = [
1821
'thickness',
1922
'transmission',
2023
'transmissionMap',
@@ -42,10 +45,28 @@ index f2030fde..061cabf3 100644
4245
+ worldMatrix: Matrix4;
4346
+ version?: number;
4447
+}
48+
+
49+
+interface LightData {
50+
+ map: number;
51+
+}
52+
+
53+
+interface LightsCacheData {
54+
+ renderId: number;
55+
+ lightsData: LightData[];
56+
+}
57+
58+
/**
59+
* A WeakMap to cache lights data for node materials.
60+
@@ -62,7 +104,7 @@ const refreshUniforms = [
61+
* @private
62+
* @type {WeakMap<LightsNode,Object>}
63+
*/
64+
-const _lightsCache = new WeakMap();
65+
+const _lightsCache = new WeakMap<LightsNode, LightsCacheData>();
4566

4667
/**
4768
* This class is used by {@link WebGPURenderer} as management component.
48-
@@ -61,12 +91,18 @@ const refreshUniforms = [
69+
@@ -70,12 +112,18 @@ const _lightsCache = new WeakMap();
4970
* refresh right before they are going to be rendered or not.
5071
*/
5172
class NodeMaterialObserver {
@@ -65,7 +86,7 @@ index f2030fde..061cabf3 100644
6586
/**
6687
* A node material can be used by more than one render object so the
6788
* monitor must maintain a list of render objects.
68-
@@ -111,7 +147,7 @@ class NodeMaterialObserver {
89+
@@ -120,7 +168,7 @@ class NodeMaterialObserver {
6990
* @param {RenderObject} renderObject - The render object.
7091
* @return {boolean} Whether the given render object is verified for the first time of this observer.
7192
*/
@@ -74,7 +95,7 @@ index f2030fde..061cabf3 100644
7495
const hasInitialized = this.renderObjects.has(renderObject);
7596

7697
if (hasInitialized === false) {
77-
@@ -129,7 +165,7 @@ class NodeMaterialObserver {
98+
@@ -138,7 +186,7 @@ class NodeMaterialObserver {
7899
* @param {Renderer} renderer - The renderer.
79100
* @return {boolean} Whether the current rendering produces motion vectors or not.
80101
*/
@@ -83,7 +104,7 @@ index f2030fde..061cabf3 100644
83104
const mrt = renderer.getMRT();
84105

85106
return mrt !== null && mrt.has('velocity');
86-
@@ -141,7 +177,7 @@ class NodeMaterialObserver {
107+
@@ -150,7 +198,7 @@ class NodeMaterialObserver {
87108
* @param {RenderObject} renderObject - The render object.
88109
* @return {Object} The monitoring data.
89110
*/
@@ -92,7 +113,7 @@ index f2030fde..061cabf3 100644
92113
let data = this.renderObjects.get(renderObject);
93114

94115
if (data === undefined) {
95-
@@ -190,8 +226,8 @@ class NodeMaterialObserver {
116+
@@ -201,8 +249,8 @@ class NodeMaterialObserver {
96117
* @param {Object} attributes - The geometry attributes.
97118
* @return {Object} An object for monitoring the versions of attributes.
98119
*/
@@ -103,7 +124,7 @@ index f2030fde..061cabf3 100644
103124

104125
for (const name in attributes) {
105126
const attribute = attributes[name];
106-
@@ -211,7 +247,7 @@ class NodeMaterialObserver {
127+
@@ -222,7 +270,7 @@ class NodeMaterialObserver {
107128
* @param {NodeBuilder} builder - The current node builder.
108129
* @return {boolean} Whether the node builder's material uses node properties or not.
109130
*/
@@ -112,7 +133,7 @@ index f2030fde..061cabf3 100644
112133
const material = builder.material;
113134

114135
for (const property in material) {
115-
@@ -234,8 +270,8 @@ class NodeMaterialObserver {
136+
@@ -245,8 +293,8 @@ class NodeMaterialObserver {
116137
* @param {Material} material - The material.
117138
* @return {Object} An object for monitoring material properties.
118139
*/
@@ -123,16 +144,47 @@ index f2030fde..061cabf3 100644
123144

124145
for (const property of this.refreshUniforms) {
125146
const value = material[property];
126-
@@ -262,7 +298,7 @@ class NodeMaterialObserver {
127-
* @param {RenderObject} renderObject - The render object.
147+
@@ -274,7 +322,7 @@ class NodeMaterialObserver {
148+
* @param {Array<Light>} lightsData - The current material lights.
128149
* @return {boolean} Whether the given render object has changed its state or not.
129150
*/
130-
- equals(renderObject) {
131-
+ equals(renderObject: RenderObject) {
151+
- equals(renderObject, lightsData) {
152+
+ equals(renderObject: RenderObject, lightsData: Light[]) {
132153
const { object, material, geometry } = renderObject;
133154

134155
const renderObjectData = this.getRenderObjectData(renderObject);
135-
@@ -413,7 +449,7 @@ class NodeMaterialObserver {
156+
@@ -434,14 +482,14 @@ class NodeMaterialObserver {
157+
* @param {Array<Light>} materialLights - The material lights.
158+
* @return {Array<Object>} The lights data for the given material lights.
159+
*/
160+
- getLightsData(materialLights) {
161+
- const lights = [];
162+
+ getLightsData(materialLights: Light[]) {
163+
+ const lights: LightData[] = [];
164+
165+
for (const light of materialLights) {
166+
- if (light.isSpotLight === true && light.map !== null) {
167+
+ if ((light as SpotLight).isSpotLight === true && (light as SpotLight).map !== null) {
168+
// only add lights that have a map
169+
170+
- lights.push({ map: light.map.version });
171+
+ lights.push({ map: (light as SpotLight).map!.version });
172+
}
173+
}
174+
175+
@@ -455,9 +503,9 @@ class NodeMaterialObserver {
176+
* @param {number} renderId - The render ID.
177+
* @return {Array} The lights for the given lights node and render ID.
178+
*/
179+
- getLights(lightsNode, renderId) {
180+
+ getLights(lightsNode: LightsNode, renderId: number) {
181+
if (_lightsCache.has(lightsNode)) {
182+
- const cached = _lightsCache.get(lightsNode);
183+
+ const cached = _lightsCache.get(lightsNode)!;
184+
185+
if (cached.renderId === renderId) {
186+
return cached.lightsData;
187+
@@ -478,7 +526,7 @@ class NodeMaterialObserver {
136188
* @param {NodeFrame} nodeFrame - The current node frame.
137189
* @return {boolean} Whether the given render object requires a refresh or not.
138190
*/
@@ -10217,7 +10269,7 @@ index 37784a05..7b08961a 100644
1021710269
+
1021810270
export default StandardNodeLibrary;
1021910271
diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts
10220-
index 40eff17c..e14f19f9 100644
10272+
index d6666b28..78ad6547 100644
1022110273
--- a/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts
1022210274
+++ b/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts
1022310275
@@ -10,7 +10,7 @@ import {

types/three/src/materials/nodes/manager/NodeMaterialObserver.d.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { BufferAttribute } from "../../../core/BufferAttribute.js";
2+
import { Light } from "../../../lights/Light.js";
23
import { Matrix4 } from "../../../math/Matrix4.js";
34
import NodeBuilder from "../../../nodes/core/NodeBuilder.js";
45
import NodeFrame from "../../../nodes/core/NodeFrame.js";
6+
import LightsNode from "../../../nodes/lighting/LightsNode.js";
57
import Renderer from "../../../renderers/common/Renderer.js";
68
import RenderObject from "../../../renderers/common/RenderObject.js";
79
import { Material } from "../../Material.js";
@@ -84,6 +86,9 @@ interface RenderObjectData {
8486
worldMatrix: Matrix4;
8587
version?: number;
8688
}
89+
interface LightData {
90+
map: number;
91+
}
8792
/**
8893
* This class is used by {@link WebGPURenderer} as management component.
8994
* It's primary purpose is to determine whether render objects require a
@@ -150,9 +155,25 @@ declare class NodeMaterialObserver {
150155
* Returns `true` if the given render object has not changed its state.
151156
*
152157
* @param {RenderObject} renderObject - The render object.
158+
* @param {Array<Light>} lightsData - The current material lights.
153159
* @return {boolean} Whether the given render object has changed its state or not.
154160
*/
155-
equals(renderObject: RenderObject): boolean;
161+
equals(renderObject: RenderObject, lightsData: Light[]): boolean;
162+
/**
163+
* Returns the lights data for the given material lights.
164+
*
165+
* @param {Array<Light>} materialLights - The material lights.
166+
* @return {Array<Object>} The lights data for the given material lights.
167+
*/
168+
getLightsData(materialLights: Light[]): LightData[];
169+
/**
170+
* Returns the lights for the given lights node and render ID.
171+
*
172+
* @param {LightsNode} lightsNode - The lights node.
173+
* @param {number} renderId - The render ID.
174+
* @return {Array} The lights for the given lights node and render ID.
175+
*/
176+
getLights(lightsNode: LightsNode, renderId: number): LightData[];
156177
/**
157178
* Checks if the given render object requires a refresh.
158179
*

0 commit comments

Comments
 (0)