From 3f440728fc8a94d59022bb545f418be049a1f1ba Mon Sep 17 00:00:00 2001 From: release-bot Date: Thu, 12 Feb 2026 18:11:14 +0100 Subject: [PATCH] feat: implement variable height for node shader --- .../graph-interface/helpers/nodeHelpers.ts | 2 - app/src/lib/graph-interface/node/Node.frag | 80 +++++++++++++------ app/src/lib/graph-interface/node/Node.svelte | 39 ++++++--- .../graph-interface/node/NodeParameter.svelte | 4 +- packages/ui/src/lib/app.css | 8 +- 5 files changed, 91 insertions(+), 42 deletions(-) diff --git a/app/src/lib/graph-interface/helpers/nodeHelpers.ts b/app/src/lib/graph-interface/helpers/nodeHelpers.ts index c214314..c66b907 100644 --- a/app/src/lib/graph-interface/helpers/nodeHelpers.ts +++ b/app/src/lib/graph-interface/helpers/nodeHelpers.ts @@ -38,7 +38,6 @@ export function getSocketPosition( const inputs = nodeType.inputs || {}; for (const inputKey in inputs) { const h = getParameterHeight(nodeType, inputKey) / 10; - console.log({ inputKey, h }); if (inputKey === index) { height += h / 2; break; @@ -61,7 +60,6 @@ export function getNodeHeight(node: NodeDefinition) { return 5; } let height = 5; - console.log('Get Node Height', node.id); for (const key in node.inputs) { const h = getParameterHeight(node, key) / 10; diff --git a/app/src/lib/graph-interface/node/Node.frag b/app/src/lib/graph-interface/node/Node.frag index 997ace1..46a6151 100644 --- a/app/src/lib/graph-interface/node/Node.frag +++ b/app/src/lib/graph-interface/node/Node.frag @@ -1,56 +1,88 @@ - varying vec2 vUv; uniform float uWidth; uniform float uHeight; +uniform float uZoom; uniform vec3 uColorDark; uniform vec3 uColorBright; - uniform vec3 uStrokeColor; -uniform float uStrokeWidth; + +const float uHeaderHeight = 5.0; +uniform float uSectionHeights[16]; +uniform int uNumSections; float msign(in float x) { return (x < 0.0) ? -1.0 : 1.0; } +float sdCircle(vec2 p, float r) { return length(p) - r; } vec4 roundedBoxSDF( in vec2 p, in vec2 b, in float r, in float s) { vec2 q = abs(p) - b + r; float l = b.x + b.y + 1.570796 * r; - float k1 = min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r; float k2 = ((q.x > 0.0) ? atan(q.y, q.x) : 1.570796); float k3 = 3.0 + 2.0 * msign(min(p.x, -p.y)) - msign(p.x); float k4 = msign(p.x * p.y); float k5 = r * k2 + max(-q.x, 0.0); - float ra = s * round(k1 / s); float l2 = l + 1.570796 * ra; - return vec4(k1 - ra, k3 * l2 + k4 * (b.y + ((q.y > 0.0) ? k5 + k2 * ra : q.y)), 4.0 * l2, k1); } void main(){ + float strokeWidth = mix(2.0, 0.5, uZoom); + + float borderRadius = 0.5; + float dentRadius = 0.8; - float y = (1.0-vUv.y) * uHeight; + float y = (1.0 - vUv.y) * uHeight; float x = vUv.x * uWidth; - vec2 size = vec2(uWidth, uHeight); - vec2 uv = (vUv - 0.5) * 2.0; + vec2 uvCenter = (vUv - 0.5) * 2.0; - float u_border_radius = 0.4; - vec4 distance = roundedBoxSDF(uv * size, size, u_border_radius*2.0, 0.0); + vec4 boxData = roundedBoxSDF(uvCenter * size, size, borderRadius * 2.0, 0.0); + float sceneSDF = boxData.w; - if (distance.w > 0.0 ) { - // outside - gl_FragColor = vec4(0.0,0.0,0.0, 0.0); - }else{ - if (distance.w > -uStrokeWidth || mod(y+5.0, 10.0) < uStrokeWidth/2.0) { - // draw the outer stroke - gl_FragColor = vec4(uStrokeColor, 1.0); - }else if (y<5.0){ - // draw the header - gl_FragColor = vec4(uColorBright, 1.0); - }else{ - gl_FragColor = vec4(uColorDark, 1.0); - } + vec2 headerDentPos = vec2(uWidth, uHeaderHeight * 0.5); + float headerDentDist = sdCircle(vec2(x, y) - headerDentPos, dentRadius); + sceneSDF = max(sceneSDF, -headerDentDist*2.0); + + float currentYBoundary = uHeaderHeight; + float previousYBoundary = uHeaderHeight; + + for (int i = 0; i < 16; i++) { + if (i >= uNumSections) break; + + float sectionHeight = uSectionHeights[i]; + currentYBoundary += sectionHeight; + + float centerY = previousYBoundary + (sectionHeight * 0.5); + vec2 circlePos = vec2(0.0, centerY); + float circleDist = sdCircle(vec2(x, y) - circlePos, dentRadius); + + sceneSDF = max(sceneSDF, -circleDist*2.0); + previousYBoundary = currentYBoundary; + } + + if (sceneSDF > 0.05) { + gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); + return; + } + + vec3 finalColor = (y < uHeaderHeight) ? uColorBright : uColorDark; + bool isDivider = false; + + float dividerY = uHeaderHeight; + if (abs(y - dividerY) < strokeWidth * 0.25) isDivider = true; + + for (int i = 0; i < 16; i++) { + if (i >= uNumSections - 1) break; + dividerY += uSectionHeights[i]; + if (abs(y - dividerY) < strokeWidth * 0.25) isDivider = true; + } + + if (sceneSDF > -strokeWidth || isDivider) { + gl_FragColor = vec4(uStrokeColor, 1.0); + } else { + gl_FragColor = vec4(finalColor, 1.0); } } diff --git a/app/src/lib/graph-interface/node/Node.svelte b/app/src/lib/graph-interface/node/Node.svelte index 81cfdfc..cba7fd7 100644 --- a/app/src/lib/graph-interface/node/Node.svelte +++ b/app/src/lib/graph-interface/node/Node.svelte @@ -5,7 +5,7 @@ import { type Mesh } from 'three'; import { getGraphState } from '../graph-state.svelte'; import { colors } from '../graph/colors.svelte'; - import { getNodeHeight } from '../helpers/nodeHelpers'; + import { getNodeHeight, getParameterHeight } from '../helpers/nodeHelpers'; import NodeFrag from './Node.frag'; import NodeVert from './Node.vert'; import NodeHtml from './NodeHTML.svelte'; @@ -15,9 +15,10 @@ type Props = { node: NodeInstance; inView: boolean; - z: number; }; - let { node = $bindable(), inView, z }: Props = $props(); + let { node = $bindable(), inView }: Props = $props(); + + const nodeType = $derived(node.state.type!); const isActive = $derived(graphState.activeNodeId === node.id); const isSelected = $derived(graphState.selectedNodes.has(node.id)); @@ -30,16 +31,29 @@ : colors.outline) ); + const sectionHeights = $derived( + Object + .keys(nodeType.inputs || {}) + .map(key => getParameterHeight(nodeType, key) / 10) + .filter(b => !!b) + ); + let meshRef: Mesh | undefined = $state(); const height = getNodeHeight(node.state.type!); + const zoom = $derived(graphState.cameraPosition[2]); + $effect(() => { if (meshRef && !node.state?.mesh) { node.state.mesh = meshRef; graphState.updateNodePosition(node); } }); + const zoomValue = $derived( + (Math.log(graphState.cameraPosition[2]) - Math.log(1)) / (Math.log(40) - Math.log(1)) + ); + // const zoomValue = (graphState.cameraPosition[2] - 1) / 39; - + diff --git a/app/src/lib/graph-interface/node/NodeParameter.svelte b/app/src/lib/graph-interface/node/NodeParameter.svelte index 56895d8..09decc9 100644 --- a/app/src/lib/graph-interface/node/NodeParameter.svelte +++ b/app/src/lib/graph-interface/node/NodeParameter.svelte @@ -43,7 +43,7 @@ const path = $derived( createNodePath({ depth: 6, - height: 1700 / height, + height: 2000 / height, y: 50.5, cornerBottom, leftBump, @@ -53,7 +53,7 @@ const pathHover = $derived( createNodePath({ depth: 7, - height: 2000 / height, + height: 2200 / height, y: 50.5, cornerBottom, leftBump, diff --git a/packages/ui/src/lib/app.css b/packages/ui/src/lib/app.css index 6758ef6..f1d64c8 100644 --- a/packages/ui/src/lib/app.css +++ b/packages/ui/src/lib/app.css @@ -3,10 +3,10 @@ prefix: "i"; } -@source inline("{hover:,}{bg-,outline-,text-,}layer-0"); -@source inline("{hover:,}{bg-,outline-,text-,}layer-1"); -@source inline("{hover:,}{bg-,outline-,text-,}layer-2"); -@source inline("{hover:,}{bg-,outline-,text-,}layer-3"); +@source inline("{hover:,}{bg-,outline-,text-,}layer-0{/30,/50,}"); +@source inline("{hover:,}{bg-,outline-,text-,}layer-1{/30,/50,}"); +@source inline("{hover:,}{bg-,outline-,text-,}layer-2{/30,/50,}"); +@source inline("{hover:,}{bg-,outline-,text-,}layer-3{/30,/50,}"); @source inline("{hover:,}{bg-,outline-,text-,}active"); @source inline("{hover:,}{bg-,outline-,text-,}selected"); @source inline("{hover:,}{bg-,outline-,text-,}outline{!,}");