Skip to content

Commit b9a0cde

Browse files
committed
WebGL: NodeMaterial
1 parent 653de39 commit b9a0cde

File tree

2 files changed

+161
-0
lines changed

2 files changed

+161
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import NodeBuilder from '../../nodes/core/NodeBuilder.js';
2+
3+
import NodeSlot from '../../nodes/core/NodeSlot.js';
4+
5+
class WebGLNodeBuilder extends NodeBuilder {
6+
7+
constructor( material, renderer, properties ) {
8+
9+
super( material, renderer );
10+
11+
this.properties = properties;
12+
13+
this._parseMaterial();
14+
15+
}
16+
17+
_parseMaterial() {
18+
19+
const material = this.material;
20+
21+
// parse inputs
22+
23+
if ( material.colorNode !== undefined ) {
24+
25+
this.addSlot( 'fragment', new NodeSlot( material.colorNode, 'COLOR', 'vec4' ) );
26+
27+
}
28+
29+
}
30+
31+
getVaryFromNode( node, type ) {
32+
33+
const vary = super.getVaryFromNode( node, type );
34+
35+
if ( node.isUVNode ) {
36+
37+
vary.name = 'vUv';
38+
39+
}
40+
41+
return vary;
42+
43+
}
44+
45+
getTexture( textureProperty, uvSnippet ) {
46+
47+
return `sRGBToLinear( texture2D( ${textureProperty}, ${uvSnippet} ) )`;
48+
49+
}
50+
51+
getUniformsHeaderSnippet( shaderStage ) {
52+
53+
const uniforms = this.uniforms[ shaderStage ];
54+
55+
let snippet = '';
56+
57+
for ( let uniform of uniforms ) {
58+
59+
if ( uniform.type === 'texture' ) {
60+
61+
snippet += `uniform sampler2D ${uniform.name};`;
62+
63+
} else {
64+
65+
let vectorType = this.getVectorType( uniform.type );
66+
67+
snippet += `uniform ${vectorType} ${uniform.name};`;
68+
69+
}
70+
71+
}
72+
73+
return snippet;
74+
75+
}
76+
77+
getAttributesHeaderSnippet( /*shaderStage*/ ) {
78+
79+
}
80+
81+
getVarysHeaderSnippet( /*shaderStage*/ ) {
82+
83+
}
84+
85+
getVarysBodySnippet( /*shaderStage*/ ) {
86+
87+
}
88+
89+
composeUniforms() {
90+
91+
const uniforms = this.uniforms[ 'fragment' ];
92+
93+
for ( let uniform of uniforms ) {
94+
95+
this.properties.uniforms[ uniform.name ] = uniform;
96+
97+
}
98+
99+
}
100+
101+
build() {
102+
103+
super.build();
104+
105+
this.properties.defines['NODE_HEADER_UNIFORMS'] = this.defines['fragment']['NODE_HEADER_UNIFORMS'];
106+
this.properties.defines['NODE_COLOR'] = this.defines['fragment']['NODE_COLOR'];
107+
108+
this.composeUniforms();
109+
110+
return this;
111+
112+
}
113+
114+
}
115+
116+
export { WebGLNodeBuilder };
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { WebGLNodeBuilder } from './WebGLNodeBuilder.js';
2+
3+
import { Material } from '../../../../../build/three.module.js';
4+
5+
function addCodeAfterSnippet( source, snippet, code ) {
6+
7+
const index = source.indexOf( snippet );
8+
9+
if ( index !== -1 ) {
10+
11+
const start = source.substring( 0, index + snippet.length );
12+
const end = source.substring( index + snippet.length );
13+
14+
return `${start}\n${code}\n${end}`;
15+
16+
}
17+
18+
return source;
19+
20+
}
21+
22+
Material.prototype.onBeforeCompile = function( parameters, renderer ) {
23+
24+
const nodeBuilder = new WebGLNodeBuilder( this, renderer, parameters ).build();
25+
26+
let fragmentShader = parameters.fragmentShader;
27+
28+
fragmentShader = addCodeAfterSnippet( fragmentShader, '#include <color_pars_fragment>',
29+
`#ifdef NODE_HEADER_UNIFORMS
30+
31+
NODE_HEADER_UNIFORMS
32+
33+
#endif`);
34+
35+
fragmentShader = addCodeAfterSnippet( fragmentShader, '#include <color_fragment>',
36+
`#ifdef NODE_COLOR
37+
38+
diffuseColor *= NODE_COLOR;
39+
40+
#endif`);
41+
42+
parameters.fragmentShader = fragmentShader;
43+
44+
};
45+

0 commit comments

Comments
 (0)