Skip to content

Commit

Permalink
revision
Browse files Browse the repository at this point in the history
  • Loading branch information
sunag committed Oct 20, 2023
1 parent e8175c6 commit 25f73e5
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 76 deletions.
10 changes: 1 addition & 9 deletions examples/jsm/nodes/core/VarNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,7 @@ export default VarNode;

export const temp = nodeProxy( VarNode );

function toVar( node ) {

node = temp( node );
if ( getCurrentStack() ) getCurrentStack().add( node );
return node;

}

addNodeElement( 'temp', temp ); // @TODO: Will be removed in the future
addNodeElement( 'toVar', toVar );
addNodeElement( 'toVar', ( ...params ) => temp( ...params ).append() );

addNodeClass( 'VarNode', VarNode );
9 changes: 8 additions & 1 deletion examples/jsm/nodes/shadernode/ShaderNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,14 @@ export const setCurrentStack = stack => currentStack = stack;
export const getCurrentStack = () => currentStack;

export const If = ( ...params ) => currentStack.if( ...params );
export const append = ( ...params ) => currentStack.add( ...params );

export function append( node ) {

if ( currentStack ) currentStack.add( node );

return node;

}

addNodeElement( 'append', append );

Expand Down
15 changes: 15 additions & 0 deletions examples/jsm/nodes/transpiler/AST.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,20 @@ export class Expression {

}

export class Ternary {

constructor( cond, left, right ) {

this.cond = cond;
this.left = left;
this.right = right;

this.isTernary = true;

}

}

export class Operator {

constructor( type, left, right ) {
Expand All @@ -82,6 +96,7 @@ export class Operator {

}


export class Unary {

constructor( type, expression, after = false ) {
Expand Down
58 changes: 52 additions & 6 deletions examples/jsm/nodes/transpiler/GLSLDecoder.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Program, FunctionDeclaration, For, AccessorElements, DynamicElement, StaticElement, FunctionParameter, Unary, Conditional, VariableDeclaration, Operator, Number, FunctionCall, Return, Accessor } from './AST.js';
import { Program, FunctionDeclaration, For, AccessorElements, Ternary, DynamicElement, StaticElement, FunctionParameter, Unary, Conditional, VariableDeclaration, Operator, Number, FunctionCall, Return, Accessor } from './AST.js';

const unaryOperators = [
'+', '-', '~', '!', '++', '--'
Expand All @@ -16,6 +16,7 @@ const precedenceOperators = [
'&&',
'^^',
'||',
'?',
'=',
'+=', '-=', '*=', '/=', '%=', '^=', '&=', '|=', '<<=', '>>=',
','
Expand All @@ -26,7 +27,7 @@ const lineRegExp = /^\n+/;
const commentRegExp = /^\/\*[\s\S]*?\*\//;
const inlineCommentRegExp = /^\/\/.*?(\n|$)/;

const numberRegExp = /^((\.\d)|\d)((\w|e-?)*)(\.)?((\w|e-?)*)/;
const numberRegExp = /^((0x\w+)|(\.?\d+\.?\d*((e-?\d+)|\w)?))/;
const stringDoubleRegExp = /^(\"((?:[^"\\]|\\.)*)\")/;
const stringSingleRegExp = /^(\'((?:[^'\\]|\\.)*)\')/;
const literalRegExp = /^[A-Za-z](\w|\.)*/;
Expand Down Expand Up @@ -213,6 +214,17 @@ class GLSLDecoder {

this.index = 0;
this.tokenizer = null;
this.keywords = [];

this.addKeyword( 'gl_FragCoord', 'vec2 gl_FragCoord = vec2( viewportCoordinate.x, viewportCoordinate.y.oneMinus() );' );

}

addKeyword( name, polyfill ) {

this.keywords.push( { name, polyfill } );

return this;

}

Expand Down Expand Up @@ -293,10 +305,26 @@ class GLSLDecoder {

if ( groupIndex === 0 && token.str === operator ) {

const left = this.parseExpressionFromTokens( tokens.slice( 0, i ) );
const right = this.parseExpressionFromTokens( tokens.slice( i + 1, tokens.length ) );
if ( operator === '?' ) {

return new Operator( operator, left, right );
const conditionTokens = tokens.slice( 0, i );
const leftTokens = this.getTokensUntil( ':', tokens, i + 1 ).slice( 0, - 1 );
const rightTokens = tokens.slice( i + leftTokens.length + 2 );

const condition = this.parseExpressionFromTokens( conditionTokens );
const left = this.parseExpressionFromTokens( leftTokens );
const right = this.parseExpressionFromTokens( rightTokens );

return new Ternary( condition, left, right );

} else {

const left = this.parseExpressionFromTokens( tokens.slice( 0, i ) );
const right = this.parseExpressionFromTokens( tokens.slice( i + 1, tokens.length ) );

return new Operator( operator, left, right );

}

}

Expand Down Expand Up @@ -789,8 +817,26 @@ class GLSLDecoder {

parse( source ) {

let polyfill = '';

for ( const keyword of this.keywords ) {

if ( new RegExp( `(^|\\b)${ keyword.name }($|\\b)`, 'gm' ).test( source ) ) {

polyfill += keyword.polyfill + '\n';

}

}

if ( polyfill ) {

polyfill = '// Polyfills\n\n' + polyfill + '\n';

}

this.index = 0;
this.tokenizer = new Tokenizer( source ).tokenize();
this.tokenizer = new Tokenizer( polyfill + source ).tokenize();

const program = new Program();

Expand Down
36 changes: 5 additions & 31 deletions examples/jsm/nodes/transpiler/ShaderToyDecoder.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { Return, VariableDeclaration, Accessor } from './AST.js';
import GLSLDecoder from './GLSLDecoder.js';

const keywords = [
{ name: 'iTime', polyfill: 'float iTime = timerLocal();' },
{ name: 'iResolution', polyfill: 'vec2 iResolution = viewportResolution;' },
{ name: 'fragCoord', polyfill: 'vec2 fragCoord = vec2( viewportCoordinate.x, viewportCoordinate.y.oneMinus() );' }
];

class ShaderToyDecoder extends GLSLDecoder {

constructor() {

super();

this.addKeyword( 'iTime', 'float iTime = timerLocal();' );
this.addKeyword( 'iResolution', 'vec2 iResolution = viewportResolution;' );
this.addKeyword( 'fragCoord', 'vec2 fragCoord = vec2( viewportCoordinate.x, viewportCoordinate.y.oneMinus() );' );

}

parseFunction() {
Expand All @@ -21,7 +19,7 @@ class ShaderToyDecoder extends GLSLDecoder {

if ( node.name === 'mainImage' ) {

node.params = [];
node.params = []; // remove default parameters
node.type = 'vec4';
node.layout = false; // for now

Expand All @@ -46,30 +44,6 @@ class ShaderToyDecoder extends GLSLDecoder {

}

parse( source ) {

let polyfill = '';

for ( const keyword of keywords ) {

if ( new RegExp( `(^|\\b)${ keyword.name }($|\\b)`, 'gm' ).test( source ) ) {

polyfill += keyword.polyfill + '\n';

}

}

if ( polyfill ) {

polyfill = '// Polyfills\n\n' + polyfill + '\n';

}

return super.parse( polyfill + source );

}

}

export default ShaderToyDecoder;
44 changes: 39 additions & 5 deletions examples/jsm/nodes/transpiler/TSLEncoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,17 @@ class TSLEncoder {

} else if ( node.isNumber ) {

code = node.value;
if ( node.type === 'int' || node.type === 'uint' ) {

code = node.type + '( ' + node.value + ' )';

this.addImport( node.type );

} else {

code = node.value;

}

} else if ( node.isOperator ) {

Expand Down Expand Up @@ -178,6 +188,10 @@ class TSLEncoder {

code = this.emitVariables( node );

} else if ( node.isTernary ) {

code = this.emitTernary( node );

} else if ( node.isConditional ) {

code = this.emitConditional( node );
Expand Down Expand Up @@ -206,7 +220,7 @@ class TSLEncoder {

}

if ( ! code ) code = '// unknown statement';
if ( ! code ) code = '/* unknown statement */';

return code;

Expand Down Expand Up @@ -253,6 +267,18 @@ class TSLEncoder {

}

emitTernary( node ) {

const condStr = this.emitExpression( node.cond );
const leftStr = this.emitExpression( node.left );
const rightStr = this.emitExpression( node.right );

this.addImport( 'cond' );

return `cond( ${ condStr }, ${ leftStr }, ${ rightStr } )`;

}

emitConditional( node ) {

const condStr = this.emitExpression( node.cond );
Expand Down Expand Up @@ -305,10 +331,18 @@ ${ this.tab }} )`;

const start = this.emitExpression( node.initialization.value );
const end = this.emitExpression( node.condition.right );

const name = node.initialization.name;
const type = node.initialization.type;
const condition = node.condition.type;
const update = node.afterthought.type;

const nameParam = name !== 'i' ? `, name: '${ name }'` : '';
const typeParam = type !== 'int' ? `, type: '${ type }'` : '';
const conditionParam = condition !== '<' ? `, condition: '${ condition }'` : '';
const updateParam = update !== '++' ? `, update: '${ update }'` : '';

let loopStr = `loop( { start: ${ start }, end: ${ end + nameParam } }, ( { ${ name } } ) => {\n\n`;
let loopStr = `loop( { start: ${ start }, end: ${ end + nameParam + typeParam + conditionParam + updateParam } }, ( { ${ name } } ) => {\n\n`;

loopStr += this.emitBody( node.body ) + '\n\n';

Expand All @@ -325,8 +359,8 @@ ${ this.tab }} )`;
const { initialization, condition, afterthought } = node;

if ( ( initialization && initialization.isVariableDeclaration && initialization.next === null ) &&
( condition && condition.type === '<' && condition.left.isAccessor ) &&
( afterthought && afterthought.type === '++' ) &&
( condition && condition.left.isAccessor && condition.left.property === initialization.name ) &&
( afterthought && afterthought.isUnary ) &&
( initialization.name === condition.left.property ) &&
( initialization.name === afterthought.expression.property )
) {
Expand Down
Loading

0 comments on commit 25f73e5

Please sign in to comment.