123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- import { MathNode, GLSLNodeParser, NodeBuilder } from '../../../nodes/Nodes.js';
- const glslMethods = {
- [ MathNode.ATAN2 ]: 'atan'
- };
- const precisionLib = {
- low: 'lowp',
- medium: 'mediump',
- high: 'highp'
- };
- class GLSL1NodeBuilder extends NodeBuilder {
- constructor( object, renderer, scene = null ) {
- super( object, renderer, new GLSLNodeParser(), scene );
- }
- getMethod( method ) {
- return glslMethods[ method ] || method;
- }
- getTexture( texture, textureProperty, uvSnippet ) {
- if ( texture.isTextureCube ) {
- return `textureCube( ${textureProperty}, ${uvSnippet} )`;
- } else {
- return `texture2D( ${textureProperty}, ${uvSnippet} )`;
- }
- }
- getTextureBias( texture, textureProperty, uvSnippet, biasSnippet ) {
- if ( this.material.extensions !== undefined ) this.material.extensions.shaderTextureLOD = true;
- return `textureLod( ${textureProperty}, ${uvSnippet}, ${biasSnippet} )`;
- }
- getVars( shaderStage ) {
- const snippets = [];
- const vars = this.vars[ shaderStage ];
- for ( const variable of vars ) {
- snippets.push( `${ this.getVar( variable.type, variable.name ) };` );
- }
- return snippets.join( '\n\t' );
- }
- getUniforms( shaderStage ) {
- const uniforms = this.uniforms[ shaderStage ];
- let output = '';
- for ( const uniform of uniforms ) {
- let snippet = null;
- if ( uniform.type === 'texture' ) {
- snippet = `sampler2D ${uniform.name};\n`;
- } else if ( uniform.type === 'cubeTexture' ) {
- snippet = `samplerCube ${uniform.name};\n`;
- } else {
- const vectorType = this.getVectorType( uniform.type );
- snippet = `${vectorType} ${uniform.name};\n`;
- }
- const precision = uniform.node.precision;
- if ( precision !== null ) {
- snippet = 'uniform ' + precisionLib[ precision ] + ' ' + snippet;
- } else {
- snippet = 'uniform ' + snippet;
- }
- output += snippet;
- }
- return output;
- }
- getAttributes( shaderStage ) {
- let snippet = '';
- if ( shaderStage === 'vertex' ) {
- const attributes = this.attributes;
- for ( const attribute of attributes ) {
- snippet += `attribute ${attribute.type} ${attribute.name};\n`;
- }
- }
- return snippet;
- }
- getVaryings( shaderStage ) {
- let snippet = '';
- const varyings = this.varyings;
- if ( shaderStage === 'vertex' ) {
- for ( const varying of varyings ) {
- snippet += `${varying.needsInterpolation ? 'varying' : '/*varying*/'} ${varying.type} ${varying.name};\n`;
- }
- } else if ( shaderStage === 'fragment' ) {
- for ( const varying of varyings ) {
- if ( varying.needsInterpolation ) {
- snippet += `varying ${varying.type} ${varying.name};\n`;
- }
- }
- }
- return snippet;
- }
- getVertexIndex() {
- return 'gl_VertexID';
- }
- getFrontFacing() {
- return 'gl_FrontFacing';
- }
- getFragCoord() {
- return 'gl_FragCoord';
- }
- isFlipY() {
- return true;
- }
- _getGLSLVertexCode( shaderData ) {
- return `${ this.getSignature() }
- // uniforms
- ${shaderData.uniforms}
- // varyings
- ${shaderData.varyings}
- // attributes
- ${shaderData.attributes}
- // codes
- ${shaderData.codes}
- void main() {
- // vars
- ${shaderData.vars}
- // flow
- ${shaderData.flow}
- }
- `;
- }
- _getGLSLFragmentCode( shaderData ) {
- return `${ this.getSignature() }
- // precision
- precision highp float;
- precision highp int;
- // uniforms
- ${shaderData.uniforms}
- // varyings
- ${shaderData.varyings}
- // codes
- ${shaderData.codes}
- void main() {
- // vars
- ${shaderData.vars}
- // flow
- ${shaderData.flow}
- }
- `;
- }
- buildCode() {
- const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} };
- for ( const shaderStage in shadersData ) {
- let flow = '// code\n\n';
- flow += this.flowCode[ shaderStage ];
- const flowNodes = this.flowNodes[ shaderStage ];
- const mainNode = flowNodes[ flowNodes.length - 1 ];
- for ( const node of flowNodes ) {
- const flowSlotData = this.getFlowData( node/*, shaderStage*/ );
- const slotName = node.name;
- if ( slotName ) {
- if ( flow.length > 0 ) flow += '\n';
- flow += `\t// flow -> ${ slotName }\n\t`;
- }
- flow += `${ flowSlotData.code }\n\t`;
- if ( node === mainNode && shaderStage !== 'compute' ) {
- flow += '// result\n\t';
- if ( shaderStage === 'vertex' ) {
- flow += 'gl_Position = ';
- } else if ( shaderStage === 'fragment' ) {
- flow += 'gl_FragColor = ';
- }
- flow += `${ flowSlotData.result };`;
- }
- }
- const stageData = shadersData[ shaderStage ];
- stageData.uniforms = this.getUniforms( shaderStage );
- stageData.attributes = this.getAttributes( shaderStage );
- stageData.varyings = this.getVaryings( shaderStage );
- stageData.vars = this.getVars( shaderStage );
- stageData.codes = this.getCodes( shaderStage );
- stageData.flow = flow;
- }
- if ( this.material !== null ) {
- this.vertexShader = this._getGLSLVertexCode( shadersData.vertex );
- this.fragmentShader = this._getGLSLFragmentCode( shadersData.fragment );
- } else {
- console.warn( 'GLSLNodeBuilder: compute shaders are not supported.' );
- //this.computeShader = this._getGLSLComputeCode( shadersData.compute );
- }
- }
- }
- export default GLSL1NodeBuilder;
|