Skip to content

Commit d4c3ea2

Browse files
authored
Merge pull request #21170 from sunag/nodematerial-webgpu
WebGPU: All UBOs and varys is generate by nodes
2 parents 5ad3317 + ce02271 commit d4c3ea2

33 files changed

+685
-384
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import Node from '../core/Node.js';
2+
import Vector3Node from '../inputs/Vector3Node.js';
3+
import Matrix4Node from '../inputs/Matrix4Node.js';
4+
import { NodeUpdateType } from '../core/constants.js';
5+
6+
class CameraNode extends Node {
7+
8+
static POSITION = 'position';
9+
static PROJECTION = 'projection';
10+
static VIEW = 'view';
11+
12+
constructor( scope = CameraNode.POSITION ) {
13+
14+
super();
15+
16+
this.updateType = NodeUpdateType.Frame;
17+
18+
this.scope = scope;
19+
20+
this._inputNode = null;
21+
22+
}
23+
24+
getType() {
25+
26+
const scope = this.scope;
27+
28+
if ( scope === CameraNode.PROJECTION || scope === CameraNode.VIEW ) {
29+
30+
return 'mat4';
31+
32+
}
33+
34+
return 'vec3';
35+
36+
}
37+
38+
update( frame ) {
39+
40+
const camera = frame.camera;
41+
const inputNode = this._inputNode;
42+
const scope = this.scope;
43+
44+
if ( scope === CameraNode.PROJECTION ) {
45+
46+
inputNode.value = camera.projectionMatrix;
47+
48+
} else if ( scope === CameraNode.VIEW ) {
49+
50+
inputNode.value = camera.matrixWorldInverse;
51+
52+
} else if ( scope === CameraNode.POSITION ) {
53+
54+
camera.getWorldPosition( inputNode.value );
55+
56+
}
57+
58+
}
59+
60+
generate( builder, output ) {
61+
62+
const nodeData = builder.getDataFromNode( this );
63+
64+
let inputNode = this._inputNode;
65+
66+
if ( nodeData.inputNode === undefined ) {
67+
68+
const scope = this.scope;
69+
70+
if ( scope === CameraNode.PROJECTION || scope === CameraNode.VIEW ) {
71+
72+
if ( inputNode === null || inputNode.isMatrix4Node !== true ) {
73+
74+
inputNode = new Matrix4Node( null );
75+
76+
}
77+
78+
} else if ( inputNode === null || inputNode.isVector3Node !== true ) {
79+
80+
inputNode = new Vector3Node();
81+
82+
}
83+
84+
this._inputNode = inputNode;
85+
86+
nodeData.inputNode = inputNode;
87+
88+
}
89+
90+
return inputNode.build( builder, output );
91+
92+
}
93+
94+
}
95+
96+
export default CameraNode;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import Node from '../core/Node.js';
2+
import CameraNode from '../accessors/CameraNode.js';
3+
import ModelNode from '../accessors/ModelNode.js';
4+
import OperatorNode from '../math/OperatorNode.js';
5+
import PositionNode from '../accessors/PositionNode.js';
6+
7+
class GLPositionNode extends Node {
8+
9+
constructor( position = new PositionNode() ) {
10+
11+
super( 'vec4' );
12+
13+
this.position = position;
14+
15+
this._mvpMatrix = new OperatorNode( '*', new CameraNode( CameraNode.PROJECTION ), new ModelNode( ModelNode.VIEW ) );
16+
17+
}
18+
19+
generate( builder, output ) {
20+
21+
const type = this.getType( builder );
22+
23+
const mvpSnipped = this._mvpMatrix.build( builder );
24+
const positionSnipped = this.position.build( builder, 'vec3' );
25+
26+
return builder.format( `( ${mvpSnipped} * vec4( ${positionSnipped}, 1.0 ) )`, type, output );
27+
28+
}
29+
30+
}
31+
32+
export default GLPositionNode;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import Node from '../core/Node.js';
2+
import Vector3Node from '../inputs/Vector3Node.js';
3+
import Matrix4Node from '../inputs/Matrix4Node.js';
4+
import { NodeUpdateType } from '../core/constants.js';
5+
6+
class ModelNode extends Node {
7+
8+
static VIEW = 'view';
9+
10+
constructor( scope = ModelNode.VIEW ) {
11+
12+
super( 'mat4' );
13+
14+
this.scope = scope;
15+
16+
this.updateType = NodeUpdateType.Object;
17+
18+
this._inputNode = new Matrix4Node( null );
19+
20+
}
21+
22+
update( frame ) {
23+
24+
const object = frame.object;
25+
const inputNode = this._inputNode;
26+
27+
inputNode.value = object.modelViewMatrix;
28+
29+
}
30+
31+
generate( builder, output ) {
32+
33+
return this._inputNode.build( builder, output );
34+
35+
}
36+
37+
}
38+
39+
export default ModelNode;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import Node from '../core/Node.js';
2+
import AttributeNode from '../core/AttributeNode.js';
3+
4+
class PositionNode extends Node {
5+
6+
static LOCAL = 'position';
7+
8+
constructor( scope = PositionNode.POSITION ) {
9+
10+
super( 'vec3' );
11+
12+
this.scope = scope;
13+
14+
}
15+
16+
generate( builder, output ) {
17+
18+
const type = this.getType( builder );
19+
const nodeData = builder.getDataFromNode( this, builder.shaderStage );
20+
21+
let positionNode = nodeData.positionNode;
22+
23+
if ( positionNode === undefined ) {
24+
25+
positionNode = new AttributeNode( 'position', 'vec3' );
26+
27+
nodeData.positionNode = positionNode;
28+
29+
}
30+
31+
const positionSnipped = positionNode.build( builder, type );
32+
33+
return builder.format( positionSnipped, type, output );
34+
35+
}
36+
37+
}
38+
39+
export default PositionNode;

examples/jsm/renderers/nodes/accessors/UVNode.js

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,15 @@ class UVNode extends AttributeNode {
44

55
constructor( index = 0 ) {
66

7-
super( 'vec2' );
7+
super( null, 'vec2' );
88

99
this.index = index;
1010

1111
}
1212

13-
getIndexProperty( prefix ) {
14-
15-
return prefix + ( this.index > 0 ? this.index + 1 : '' );
16-
17-
}
18-
1913
getAttributeName( /*builder*/ ) {
2014

21-
return this.getIndexProperty( 'uv' );
22-
23-
}
24-
25-
getAttributeProperty( builder ) {
26-
27-
// customize 'uv' property
28-
const property = this.getIndexProperty( 'vUv' );
29-
30-
this.setAttributeProperty( property );
31-
32-
return super.getAttributeProperty( builder );
15+
return 'uv' + ( this.index > 0 ? this.index + 1 : '' );
3316

3417
}
3518

examples/jsm/renderers/nodes/core/AttributeNode.js

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ import Node from './Node.js';
22

33
class AttributeNode extends Node {
44

5-
constructor( type, name = null, property = null ) {
5+
constructor( name, type ) {
66

77
super( type );
88

99
this.name = name;
10-
this.property = property;
1110

1211
}
1312

@@ -25,27 +24,36 @@ class AttributeNode extends Node {
2524

2625
}
2726

28-
setAttributeProperty( name ) {
27+
generate( builder, output ) {
2928

30-
this.property = name;
29+
const attributeName = this.getAttributeName( builder );
30+
const attributeType = this.getType( builder );
3131

32-
return this;
32+
const attribute = builder.getAttribute( attributeName, attributeType );
3333

34-
}
34+
if ( builder.isShaderStage( 'vertex' ) ) {
3535

36-
getAttributeProperty( builder ) {
36+
return builder.format( attribute.name, attribute.type, output );
3737

38-
const attribute = builder.getAttribute( this.getType( builder ), this.getAttributeName( builder ), this.property );
38+
} else {
3939

40-
return attribute.property;
40+
const nodeData = builder.getDataFromNode( this, builder.shaderStage );
4141

42-
}
42+
let nodeVary = nodeData.varyNode;
4343

44-
generate( builder, output ) {
44+
if ( nodeVary === undefined ) {
45+
46+
nodeVary = builder.getVaryFromNode( this, attribute.type, attributeName );
47+
48+
nodeData.nodeVary = nodeVary;
49+
50+
}
51+
52+
const varyName = builder.getPropertyName( nodeVary );
4553

46-
const attributeProperty = this.getAttributeProperty( builder );
54+
return builder.format( varyName, attribute.type, output );
4755

48-
return builder.format( attributeProperty, this.getType( builder ), output );
56+
}
4957

5058
}
5159

examples/jsm/renderers/nodes/core/Node.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1+
import { NodeUpdateType } from './constants.js';
2+
13
class Node {
24

35
constructor( type = null ) {
46

57
this.type = type;
68

7-
this.needsUpdate = false;
9+
this.updateType = NodeUpdateType.None;
810

911
Object.defineProperty( this, 'isNode', { value: true } );
1012

1113
}
1214

15+
getUpdateType( /*builder*/ ) {
16+
17+
return this.updateType;
18+
19+
}
20+
1321
getType( /*builder*/ ) {
1422

1523
return this.type;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class NodeAttribute {
2+
3+
constructor( name, type ) {
4+
5+
this.name = name;
6+
this.type = type;
7+
8+
Object.defineProperty( this, 'isNodeAttribute', { value: true } );
9+
10+
}
11+
12+
}
13+
14+
export default NodeAttribute;

0 commit comments

Comments
 (0)