How do I use `cond` and `switch` node in NodeMaterial?

I want to rewrite a ShaderMaterial to StandardNodeMaterial, here is the glsl segment code in ShaderMaterial.

float gridX = mod(uv.x, size.x + emptySize.x);
float gridY = mod(uv.y, size.y + emptySize.y);
if (gridX < size.x && gridY < size.y) {
    float modX = mod(uv.x + time * speed, size.x);
    if (modX < size.x * 0.5) {
        float a = (speed >= .0) ? (.5 - modX / size.x) : (modX / size.x);
        if (a < .0) {
            a = .0;
        }
        diffuseColor *= vec4(color, a);
    }
    else {
        if (flag > 0.) {
            discard;
        }
    }
}
else {
    discard;
}

Now, I have already use some Nodes to rewrite the codes above, however I cannot figure it out that how to replace if with cond(), and how to replace discard with discard()

const gridX = mod(uv().x, add(size.x, emptySize.x));
const gridY = mod(uv().y, add(size.y, emptySize.y));
cond(
    and(lessThan(gridX, size.x), lessThan(gridY, size.y)),
    (
        const modX = mod(add(uv().x, mul(time, speed)), size.x);
        cond(
            lessThan(modX, mul(size.x, 0.5)),
            (
                let a = cond(greaterThan(speed, .0), div(sub(.5, modX, size.x), div(modX, size.x));
                a = cond(lessThan(a, 0), 0, a);
                this.colorNode *= vec4(1.0, a);
            ),
            discard()
        )
    ),
    discard()
)

This kind of coding is even clearly fail with JavaScript pattern, but I have no idea how should I write the code. Hope some guy could help me.

@sunag Mister, can you help me? I really need this help! Thanks a looooot!

Hi @Bob_Lil. Try use in dev version this might help. I would recommend doing this implementation through a function, using tslFn() for example:

GLSL

void myFunction( vec3 color ) {

	float gridX = mod(uv.x, size.x + emptySize.x);
	float gridY = mod(uv.y, size.y + emptySize.y);
	if (gridX < size.x && gridY < size.y) {
		float modX = mod(uv.x + time * speed, size.x);
		if (modX < size.x * 0.5) {
			float a = (speed >= .0) ? (.5 - modX / size.x) : (modX / size.x);
			if (a < .0) {
				a = .0;
			}
			diffuseColor *= vec4(color, a);
		}
		else {
			if (flag > 0.) {
				discard;
			}
		}
	}
	else {
		discard;
	}

}

TSL

// Three.js Transpiler r159dev

import { vec3, uv, mod, float, cond, If, diffuseColor, color, vec4, discard, tslFn } from 'three/nodes';

const myFunction = tslFn( ( [ color_immutable ] ) => {

	const color = vec3( color_immutable ).toVar();
	const gridX = float( mod( uv.x, size.x.add( emptySize.x ) ) ).toVar();
	const gridY = float( mod( uv.y, size.y.add( emptySize.y ) ) ).toVar();

	If( gridX.lessThan( size.x ).and( gridY.lessThan( size.y ) ), () => {

		const modX = float( mod( uv.x.add( time.mul( speed ) ), size.x ) ).toVar();

		If( modX.lessThan( size.x.mul( 0.5 ) ), () => {

			const a = float( cond( speed.greaterThanEqual( .0 ), .5.sub( modX.div( size.x ) ), modX.div( size.x ) ) ).toVar();

			If( a.lessThan( .0 ), () => {

				a.assign( .0 );

			} );

			diffuseColor.mulAssign( vec4( color, a ) );

		} ).else( () => {

			If( flag.greaterThan( 0. ), () => {

				discard();

			} );

		} );

	} ).else( () => {

		discard();

	} );

} );

// layouts

myFunction.setLayout( {
	name: 'myFunction',
	type: 'void',
	inputs: [
		{ name: 'color', type: 'vec3' }
	]
} );

export { myFunction };

I think diffuseColor and color should both be arguments?

1 Like

@sunag Thanks a lot for your help! NodeMaterial is an excellent feature! I used to modify StandardMaterial in a wired way, like insert some code at pars, before_main, after_main, before_project, etc. which is hard to use. NodeMaterial’s coming saved me :slight_smile:

My current version is r158. Since you have said that the function is working at r159dev, I assume that will be work at r160? I will try this way when r160 is published, thanks again.

1 Like