feat: implement variable height for node shader
Some checks failed
🚀 Lint & Test & Deploy / release (pull_request) Failing after 1m3s

This commit is contained in:
release-bot
2026-02-12 18:11:14 +01:00
parent da09f8ba1e
commit 3f440728fc
5 changed files with 91 additions and 42 deletions

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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;
</script>
<T.Mesh
@@ -48,7 +62,7 @@
position.y={0.8}
rotation.x={-Math.PI / 2}
bind:ref={meshRef}
visible={inView && z < 7}
visible={inView && zoom < 7}
>
<T.PlaneGeometry args={[20, height]} radius={1} />
<T.ShaderMaterial
@@ -58,14 +72,19 @@
uniforms={{
uColorBright: { value: colors['layer-2'] },
uColorDark: { value: colors['layer-1'] },
uStrokeColor: { value: colors['layer-2'].clone() },
uStrokeWidth: { value: 1.0 },
uStrokeColor: { value: colors.outline.clone() },
uSectionHeights: { value: [5, 10] },
uNumSections: { value: 2 },
uWidth: { value: 20 },
uHeight: { value: height }
uHeight: { value: 200 },
uZoom: { value: 1.0 }
}}
uniforms.uStrokeColor.value={strokeColor.clone()}
uniforms.uStrokeWidth.value={(7 - z) / 3}
uniforms.uZoom.value={zoomValue}
uniforms.uHeight.value={height}
uniforms.uSectionHeights.value={sectionHeights}
uniforms.uNumSections.value={sectionHeights.length}
uniforms.uStrokeColor.value={strokeColor}
/>
</T.Mesh>
<NodeHtml bind:node {inView} {isActive} {isSelected} {z} />
<NodeHtml bind:node {inView} {isActive} {isSelected} z={zoom} />

View File

@@ -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,

View File

@@ -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{!,}");