Skip to content

Commit e4f52b5

Browse files
committed
dont prompt on delete, it is annoyying. + bump node + remove annoying console log + getChildOfTYpe fixed + removed "world space" normal type & replaced trash code to use the proper tsl node + fix outlet prop to also check for other's ref not being empty
1 parent 15b9f75 commit e4f52b5

File tree

8 files changed

+153
-60
lines changed

8 files changed

+153
-60
lines changed

src/Editor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ export class Editor {
568568
const nodes2delete = this.selectedNodes.filter( node=>node.canBeDeleted );
569569

570570
if( !nodes2delete.length ) return;
571-
if( !confirm("Delete currently selected nodes?")) return;
571+
//if( !confirm("Delete currently selected nodes?")) return;
572572

573573
this.clearOutletSelection();
574574

src/EditorNodes.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { mathFunctions, mathOperations } from "./nodes/operators/list";
77
import { methodsDefinitions2NodeClassDefinitions } from "./nodes/operators/MethodCallNode";
88
import { MeshStandardNode } from "./nodes/shader/MeshStandardNode";
99
import { ImageTextureNode } from "./nodes/texture/ImageTextureNode";
10+
import { BumpMapNode } from "./nodes/vector/BumpMapNode";
1011
import { NormalMapNode } from "./nodes/vector/NormalMapNode";
1112

1213
// Define the type for class constructors that extend BaseType
@@ -63,7 +64,8 @@ export const NodeTypes : NodeGroupType[] = [
6364
group:"Vector",
6465
color:Theme.config.groupVector as string,
6566
nodes: [
66-
{ TypeClass:NormalMapNode, name: "Normal Map", id:"normal-map" }
67+
{ TypeClass:NormalMapNode, name: "Normal Map", id:"normal-map" },
68+
{ TypeClass:BumpMapNode, name: "Bump Map", id:"bump-map" },
6769
]
6870
}
6971
]

src/main.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Editor } from './Editor';
1+
//*/
2+
import { Editor } from './Editor';
23
import './style.css'
34

45
// Get the canvas and context
@@ -7,6 +8,11 @@ const canvas = document.getElementById('app') as HTMLCanvasElement;
78
const editor = new Editor(canvas);
89

910
editor.start();
11+
/*/
12+
import { test } from "./test.ts";
13+
14+
test();
15+
//*/
1016

1117

1218

src/nodes/Node.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ export class Node extends LayoutElement implements IScript {
106106
for (let i = 0; i < this._outlets.length; i++) {
107107
const outlet = this._outlets[i];
108108
const result = visitor( outlet, i );
109-
console.log("RESULT = ", result)
110109
if( result !== null && result !== undefined ) return result;
111110
}
112111
}

src/nodes/WinNode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class WinNode extends Node {
5454
}
5555

5656
protected getChildOfType<T>( constructor: new (...args: any[]) => T, pos=0 ): T | undefined {
57-
const matches = this.childs.filter((child) => child instanceof constructor);
57+
const matches = this.childs.filter((child) => Object.getPrototypeOf(child).constructor === constructor ) //child instanceof constructor);
5858
return matches[pos] as T | undefined;
5959
}
6060

src/nodes/vector/BumpMapNode.ts

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import { tslFn } from "three/tsl";
2+
import { Theme } from "../../colors/Theme";
3+
import { Script } from "../../export/Script";
4+
import { BasicInputProperty } from "../../properties/BasicInputProperty";
5+
import { ComboBoxProperty } from "../../properties/ComboBoxProperty";
6+
import { Input } from "../../properties/Input";
7+
import { InputOrValue } from "../../properties/InputOrValue";
8+
import { Output } from "../../properties/Output";
9+
import { WinNode } from "../WinNode";
10+
import { Fn } from "three/src/nodes/TSL.js";
11+
12+
export class BumpMapNode extends WinNode {
13+
14+
protected invert:ComboBoxProperty;
15+
protected strength:InputOrValue;
16+
//protected distance:InputOrValue;
17+
protected bumpHeight:BasicInputProperty;
18+
protected normal:BasicInputProperty;
19+
20+
constructor() {
21+
super("Bump Map", Theme.config.groupVector, [
22+
23+
new Output("Normal", 2),
24+
new ComboBoxProperty("Invert", [
25+
["", "---"],
26+
[".oneMinus()", "Invert Height"],
27+
]),
28+
29+
new InputOrValue(1, { label:"Strength", min:0, max:10, asBar:true, step:0.01, defaultValue:1 }),
30+
//new InputOrValue(1, { label:"Distance", step:0.01, defaultValue:0.1 }),
31+
new BasicInputProperty(1, "Height", ()=>"float(0.1)"),
32+
new BasicInputProperty(2, "Normal", ()=>""),
33+
]);
34+
35+
this.invert = this.getChildOfType(ComboBoxProperty)!;
36+
this.strength = this.getChildOfType(InputOrValue)!;
37+
//this.distance = this.getChildOfType(InputOrValue, 1)!;
38+
this.bumpHeight = this.getChildOfType(BasicInputProperty, 0)!;
39+
this.normal = this.getChildOfType(BasicInputProperty, 1)!;
40+
}
41+
42+
override writeScript(script: Script): string {
43+
44+
script.importModule("bumpMap");
45+
46+
47+
const bumpStrength = this.strength.writeScript( script );
48+
const bumpTexture = this.bumpHeight.writeScript( script ) + this.invert.value;
49+
50+
51+
let output = `bumpMap( ${ bumpTexture }, ${bumpStrength})`;
52+
53+
const normal = this.normal.writeScript( script );
54+
55+
/**
56+
* Taken from https://github.com/mrdoob/three.js/blob/dev/src/nodes/display/BumpMapNode.js
57+
* If anyone knows a cleaner way (not repeating/copy pasting code from the threejs source) let me know...
58+
*/
59+
if( normal!="" ) // Combine Normal map + bump map
60+
{
61+
script.importModule([
62+
"uv",
63+
"float",
64+
"vec2",
65+
"faceDirection",
66+
"positionView",
67+
"Fn"
68+
]);
69+
70+
// Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen
71+
// https://mmikk.github.io/papers3d/mm_sfgrad_bump.pdf
72+
const $dHdxy_fwd = script.define("dHdxy_fwd", `Fn( ( { textureNode, bumpScale } ) => {
73+
74+
// It's used to preserve the same TextureNode instance
75+
const sampleTexture = ( callback ) => textureNode.cache().context( { getUV: ( texNode ) => callback( texNode.uvNode || uv() ), forceUVContext: true } );
76+
77+
const Hll = float( sampleTexture( ( uvNode ) => uvNode ) );
78+
79+
return vec2(
80+
float( sampleTexture( ( uvNode ) => uvNode.add( uvNode.dFdx() ) ) ).sub( Hll ),
81+
float( sampleTexture( ( uvNode ) => uvNode.add( uvNode.dFdy() ) ) ).sub( Hll )
82+
).mul( bumpScale );
83+
84+
} );`);
85+
86+
const perturbNormalArb = script.define("perturbNormalArb", `Fn( ( inputs ) => {
87+
88+
const { surf_pos, surf_norm, dHdxy } = inputs;
89+
90+
// normalize is done to ensure that the bump map looks the same regardless of the texture's scale
91+
const vSigmaX = surf_pos.dFdx().normalize();
92+
const vSigmaY = surf_pos.dFdy().normalize();
93+
const vN = surf_norm; // normalized
94+
95+
const R1 = vSigmaY.cross( vN );
96+
const R2 = vN.cross( vSigmaX );
97+
98+
const fDet = vSigmaX.dot( R1 ).mul( faceDirection );
99+
100+
const vGrad = fDet.sign().mul( dHdxy.x.mul( R1 ).add( dHdxy.y.mul( R2 ) ) );
101+
102+
return fDet.abs().mul( surf_norm ).sub( vGrad ).normalize();
103+
104+
} );`);
105+
106+
//--
107+
return script.define(this.nodeName, `
108+
const dHdxy = ${$dHdxy_fwd}( { textureNode: ${ bumpTexture }, bumpScale: ${bumpStrength} } );
109+
110+
return ${perturbNormalArb}( {
111+
surf_pos: positionView,
112+
surf_norm: ${normal},
113+
dHdxy
114+
} );
115+
116+
`, true);
117+
//--
118+
119+
}
120+
else
121+
{
122+
return script.define( this.nodeName, output );
123+
}
124+
}
125+
}

src/nodes/vector/NormalMapNode.ts

Lines changed: 15 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ export class NormalMapNode extends WinNode {
1717

1818
const typeCombo = new ComboBox("Space", [
1919
"Tangent Space",
20-
"Object Space",
21-
"World Space"
20+
"Object Space"
2221
], v=>this.onTypeComboChange(v));
2322

2423
const strength = new InputOrValue(1, { label:"Stength", min:0, max:10, step:0.1, asBar:true, defaultValue:1 });
@@ -43,66 +42,28 @@ export class NormalMapNode extends WinNode {
4342
}
4443

4544
override writeScript(script: Script): string {
46-
// si es tangen space... usa el UV
47-
// else usa el object space o el world space tsl params
45+
46+
script.importModule("normalMap");
47+
4848
let map = this.color.writeScript(script);
49-
let node = "";
5049
let strength = this.strength.value;
5150

51+
let node = `
52+
const normalNode = normalMap( ${map}, ${strength});
53+
`;
54+
55+
// i will leave this as a switch just in case...
5256
switch( this.typeCombo.index )
5357
{
54-
case 1: //object space
55-
script.importModule("modelNormalMatrix");
56-
script.importModule("normalize");
57-
script.importModule("normalGeometry"); // Geometry normal in object space
58-
script.importModule("vec4");
59-
60-
node = `
61-
// object space normal map
62-
const mappedNormal = ${map}.xyz.mul(2).sub(1);
63-
const normalDiff = mappedNormal.sub(normalGeometry);
64-
const adjustedNormal = normalGeometry.add(normalDiff.mul(${strength}));
65-
66-
return normalize(modelNormalMatrix.mul(vec4(adjustedNormal, 0)).xyz);
67-
`;
68-
break;
69-
70-
case 2: // worlds space
71-
script.importModule("modelNormalMatrix");
72-
script.importModule("normalize");
73-
script.importModule("normalGeometry");
74-
script.importModule("vec4");
75-
76-
node = `
77-
// world's space normal
78-
const mappedNormal = ${map}.xyz.mul(2).sub(1);
79-
const normalDiff = mappedNormal.sub(normalGeometry);
80-
const adjustedNormal = normalGeometry.add(normalDiff.mul(${strength}));
81-
82-
return normalize((modelNormalMatrix.mul(vec4(adjustedNormal, 0))).xyz);
83-
`;
84-
85-
break;
86-
87-
default: // tangent space
88-
script.importModule("normalMap");
89-
script.importModule("TBNViewMatrix");
90-
script.importModule("normalGeometry");
91-
script.importModule("normalize");
92-
93-
node = `
94-
// tangent space normal
95-
const mappedNormal = ${map}.xyz.mul(2).sub(1);
96-
const normalDiff = mappedNormal.sub(normalGeometry);
97-
const adjustedNormal = normalGeometry.add(normalDiff.mul(${strength}));
98-
99-
return normalize(TBNViewMatrix.mul(adjustedNormal));
100-
//return normalMap( ${map} );
101-
`;
58+
case 1:
59+
//object space
60+
node += `
61+
normalNode.normalMapType = THREE.ObjectSpaceNormalMap;
62+
`;
10263
break;
10364
}
10465

105-
return script.define( this.nodeName, node, true );
66+
return script.define( this.nodeName, node+"\nreturn normalNode;", true );
10667

10768
}
10869
}

src/properties/OutletProperty.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export class OutletProperty extends LayoutElement implements IOutlet
133133
{
134134
otherNameRef = this.connectedTo.writeScript( script );
135135

136-
if( this.connectedTo.size!=this.size ) {
136+
if( otherNameRef && this.connectedTo.size!=this.size ) {
137137
otherNameRef += (this.size==1? ".toFloat" :
138138
".toVec"+this.size) + "()";
139139
}

0 commit comments

Comments
 (0)