Skip to content

Commit

Permalink
[all] Implements depth in all node programs
Browse files Browse the repository at this point in the history
This commit is related to #1427.

Details:
- Updates depth management in sigma.ts to clarify the difference between
  zIndex and depth in nodes and edges data
- Adds depth management in all node programs
- Adds depth management in createNodeCompoundProgram
  • Loading branch information
jacomyal committed Jul 22, 2024
1 parent d64f763 commit afb4de4
Show file tree
Hide file tree
Showing 19 changed files with 176 additions and 80 deletions.
23 changes: 14 additions & 9 deletions packages/node-border/src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,11 @@ export default function getNodeBorderProgram<
};
const { borders } = options;

const UNIFORMS = [
"u_sizeRatio",
"u_correctionRatio",
"u_matrix",
...borders.flatMap(({ color }, i) => ("value" in color ? [`u_borderColor_${i + 1}`] : [])),
];

return class NodeBorderProgram<
N extends Attributes = Attributes,
E extends Attributes = Attributes,
G extends Attributes = Attributes,
> extends NodeProgram<(typeof UNIFORMS)[number], N, E, G> {
> extends NodeProgram<string, N, E, G> {
static readonly ANGLE_1 = 0;
static readonly ANGLE_2 = (2 * Math.PI) / 3;
static readonly ANGLE_3 = (4 * Math.PI) / 3;
Expand All @@ -42,10 +35,17 @@ export default function getNodeBorderProgram<
VERTEX_SHADER_SOURCE: getVertexShader(options),
FRAGMENT_SHADER_SOURCE: getFragmentShader(options),
METHOD: WebGLRenderingContext.TRIANGLES,
UNIFORMS,
UNIFORMS: [
"u_sizeRatio",
"u_correctionRatio",
"u_matrix",
...borders.flatMap(({ color }, i) => ("value" in color ? [`u_borderColor_${i + 1}`] : [])),
...(this.hasDepth ? ["u_maxZIndex"] : []),
],
ATTRIBUTES: [
{ name: "a_position", size: 2, type: FLOAT },
{ name: "a_id", size: 4, type: UNSIGNED_BYTE, normalized: true },
...(this.hasDepth ? [{ name: "a_zIndex", size: 1, type: FLOAT }] : []),
{ name: "a_size", size: 1, type: FLOAT },
...borders.flatMap(({ color }, i) =>
"attribute" in color
Expand All @@ -67,6 +67,9 @@ export default function getNodeBorderProgram<
array[startIndex++] = data.x;
array[startIndex++] = data.y;
array[startIndex++] = nodeIndex;
if (this.hasDepth) {
array[startIndex++] = data.depth;
}
array[startIndex++] = data.size;
borders.forEach(({ color }) => {
if ("attribute" in color)
Expand All @@ -91,6 +94,8 @@ export default function getNodeBorderProgram<
gl.uniform4f(location, r / 255, g / 255, b / 255, a / 255);
}
});

if (this.hasDepth) gl.uniform1f(uniformLocations.u_maxZIndex, params.maxNodesDepth);
}
};
}
6 changes: 4 additions & 2 deletions packages/node-border/src/shader-frag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,10 @@ ${borders
return res.join("\n");
})
.join("\n")}
if (dist > adjustedBorderSize_0) {
gl_FragColor = borderColor_0;
if (dist > v_radius) {
#ifdef HAS_DEPTH
discard;
#endif
} else ${borders
.map(
(_, i) => `if (dist > adjustedBorderSize_${i} - aaBorder) {
Expand Down
9 changes: 9 additions & 0 deletions packages/node-border/src/shader-vert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ ${borders
.join("\n")}
#endif
#ifdef HAS_DEPTH
attribute float a_zIndex;
uniform float u_maxZIndex;
#endif
const float bias = 255.0 / 254.0;
const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0);
Expand All @@ -46,6 +51,10 @@ void main() {
v_radius = size / 2.0;
v_diffVector = diffVector;
#ifdef HAS_DEPTH
gl_Position.z = a_zIndex / u_maxZIndex;
#endif
#ifdef PICKING_MODE
v_color = a_id;
#else
Expand Down
41 changes: 23 additions & 18 deletions packages/node-image/src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,6 @@ const DEFAULT_CREATE_NODE_IMAGE_OPTIONS: CreateNodeImageProgramOptions<Attribute
imageAttribute: "image",
};

const UNIFORMS = [
"u_sizeRatio",
"u_correctionRatio",
"u_cameraAngle",
"u_percentagePadding",
"u_matrix",
"u_colorizeImages",
"u_keepWithinCircle",
"u_atlas",
] as const;

/**
* To share the texture between the program instances of the graph and the
* hovered nodes (to prevent some flickering, mostly), this program must be
Expand Down Expand Up @@ -99,7 +88,7 @@ export default function getNodeImageProgram<
*/
const textureManager = new TextureManager(textureManagerOptions);

return class NodeImageProgram extends NodeProgram<(typeof UNIFORMS)[number], N, E, G> {
return class NodeImageProgram extends NodeProgram<string, N, E, G> {
static readonly ANGLE_1 = 0;
static readonly ANGLE_2 = (2 * Math.PI) / 3;
static readonly ANGLE_3 = (4 * Math.PI) / 3;
Expand All @@ -114,12 +103,23 @@ export default function getNodeImageProgram<
VERTEX_SHADER_SOURCE,
FRAGMENT_SHADER_SOURCE: getFragmentShader({ texturesCount: textureManager.getTextures().length }),
METHOD: WebGLRenderingContext.TRIANGLES,
UNIFORMS,
UNIFORMS: [
"u_sizeRatio",
"u_correctionRatio",
"u_cameraAngle",
"u_percentagePadding",
"u_matrix",
"u_colorizeImages",
"u_keepWithinCircle",
"u_atlas",
...(this.hasDepth ? ["u_maxZIndex"] : []),
],
ATTRIBUTES: [
{ name: "a_position", size: 2, type: FLOAT },
{ name: "a_size", size: 1, type: FLOAT },
{ name: "a_color", size: 4, type: UNSIGNED_BYTE, normalized: true },
{ name: "a_id", size: 4, type: UNSIGNED_BYTE, normalized: true },
...(this.hasDepth ? [{ name: "a_zIndex", size: 1, type: FLOAT }] : []),
{ name: "a_texture", size: 4, type: FLOAT },
{ name: "a_textureIndex", size: 1, type: FLOAT },
],
Expand All @@ -131,7 +131,6 @@ export default function getNodeImageProgram<
atlas: Atlas;
textures: WebGLTexture[];
textureImages: ImageData[];
latestRenderParams?: RenderParams;
textureManagerCallback: null | ((newAtlasData: { atlas: Atlas; textures: ImageData[] }) => void) = null;

constructor(gl: WebGLRenderingContext, pickingBuffer: WebGLFramebuffer | null, renderer: Sigma<N, E, G>) {
Expand All @@ -145,9 +144,10 @@ export default function getNodeImageProgram<
if (shouldUpgradeShaders) this.upgradeShaders();
this.bindTextures();

if (this.latestRenderParams) this.render(this.latestRenderParams);

if (this.renderer && this.renderer.refresh) this.renderer.refresh();
if (this.renderer?.refresh)
this.renderer.refresh({
schedule: true,
});
};
textureManager.on(TextureManager.NEW_TEXTURE_EVENT, this.textureManagerCallback);

Expand Down Expand Up @@ -233,6 +233,10 @@ export default function getNodeImageProgram<
array[startIndex++] = color;
array[startIndex++] = nodeIndex;

if (this.hasDepth) {
array[startIndex++] = data.depth;
}

// Reference texture:
if (imagePosition && typeof imagePosition.textureIndex === "number") {
const { width, height } = this.textureImages[imagePosition.textureIndex];
Expand Down Expand Up @@ -261,7 +265,6 @@ export default function getNodeImageProgram<
u_cameraAngle,
u_percentagePadding,
} = uniformLocations;
this.latestRenderParams = params;

gl.uniform1f(u_correctionRatio, params.correctionRatio);
gl.uniform1f(u_sizeRatio, keepWithinCircle ? params.sizeRatio : params.sizeRatio / Math.SQRT2);
Expand All @@ -274,6 +277,8 @@ export default function getNodeImageProgram<
);
gl.uniform1i(u_colorizeImages, drawingMode === "color" ? 1 : 0);
gl.uniform1i(u_keepWithinCircle, keepWithinCircle ? 1 : 0);

if (this.hasDepth) gl.uniform1f(uniformLocations.u_maxZIndex, params.maxNodesDepth);
}
};
}
8 changes: 8 additions & 0 deletions packages/node-image/src/shader-frag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,21 @@ void main(void) {
} else if (dist < v_radius) {
gl_FragColor = mix(transparent, color, (v_radius - dist) / border);
}
#ifdef HAS_DEPTH
if (dist >= v_radius) discard;
#endif
}
// Crop in a square else:
else {
float squareHalfSize = v_radius * ${Math.SQRT1_2 * Math.cos(Math.PI / 12)};
if (abs(diffVector.x) > squareHalfSize || abs(diffVector.y) > squareHalfSize) {
#ifdef HAS_DEPTH
discard;
#else
gl_FragColor = transparent;
#endif
} else {
gl_FragColor = color;
}
Expand Down
9 changes: 9 additions & 0 deletions packages/node-image/src/shader-vert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ varying float v_radius;
varying vec4 v_texture;
varying float v_textureIndex;
#ifdef HAS_DEPTH
attribute float a_zIndex;
uniform float u_maxZIndex;
#endif
const float bias = 255.0 / 254.0;
const float marginRatio = 1.05;
Expand All @@ -34,6 +39,10 @@ void main() {
v_diffVector = diffVector;
v_radius = size / 2.0 / marginRatio;
#ifdef HAS_DEPTH
gl_Position.z = a_zIndex / u_maxZIndex;
#endif
#ifdef PICKING_MODE
// For picking mode, we use the ID as the color:
v_color = a_id;
Expand Down
28 changes: 16 additions & 12 deletions packages/node-piechart/src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,11 @@ export default function getNodePiechartProgram<
};
const { slices, offset } = options;

const UNIFORMS = [
"u_sizeRatio",
"u_correctionRatio",
"u_cameraAngle",
"u_matrix",
"u_defaultColor",
...("value" in offset ? ["u_offset"] : []),
...slices.flatMap(({ color }, i) => ("value" in color ? [`u_sliceColor_${i + 1}`] : [])),
];

return class NodeBorderProgram<
N extends Attributes = Attributes,
E extends Attributes = Attributes,
G extends Attributes = Attributes,
> extends NodeProgram<(typeof UNIFORMS)[number], N, E, G> {
> extends NodeProgram<string, N, E, G> {
static readonly ANGLE_1 = 0;
static readonly ANGLE_2 = (2 * Math.PI) / 3;
static readonly ANGLE_3 = (4 * Math.PI) / 3;
Expand All @@ -45,10 +35,20 @@ export default function getNodePiechartProgram<
VERTEX_SHADER_SOURCE: getVertexShader(options),
FRAGMENT_SHADER_SOURCE: getFragmentShader(options),
METHOD: WebGLRenderingContext.TRIANGLES,
UNIFORMS,
UNIFORMS: [
"u_sizeRatio",
"u_correctionRatio",
"u_cameraAngle",
"u_matrix",
"u_defaultColor",
...(this.hasDepth ? ["u_maxZIndex"] : []),
...("value" in offset ? ["u_offset"] : []),
...slices.flatMap(({ color }, i) => ("value" in color ? [`u_sliceColor_${i + 1}`] : [])),
],
ATTRIBUTES: [
{ name: "a_position", size: 2, type: FLOAT },
{ name: "a_id", size: 4, type: UNSIGNED_BYTE, normalized: true },
...(this.hasDepth ? [{ name: "a_zIndex", size: 1, type: FLOAT }] : []),
{ name: "a_size", size: 1, type: FLOAT },
...("attribute" in offset ? [{ name: "a_offset", size: 1, type: FLOAT }] : []),
...slices.flatMap(({ color }, i) =>
Expand All @@ -71,6 +71,9 @@ export default function getNodePiechartProgram<
array[startIndex++] = data.x;
array[startIndex++] = data.y;
array[startIndex++] = nodeIndex;
if (this.hasDepth) {
array[startIndex++] = data.depth;
}
array[startIndex++] = data.size;
if ("attribute" in offset) {
array[startIndex++] = data[offset.attribute as "size"] || 0;
Expand All @@ -94,6 +97,7 @@ export default function getNodePiechartProgram<
gl.uniform1f(u_cameraAngle, params.cameraAngle);
gl.uniformMatrix3fv(u_matrix, false, params.matrix);

if (this.hasDepth) gl.uniform1f(uniformLocations.u_maxZIndex, params.maxNodesDepth);
if ("value" in offset) gl.uniform1f(uniformLocations.u_offset, offset.value);

const [r, g, b, a] = colorToArray(options.defaultColor || DEFAULT_COLOR);
Expand Down
4 changes: 4 additions & 0 deletions packages/node-piechart/src/shader-frag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ ${slices.map((_, i) => ` float angle_${i + 1} = angle_${i} + sliceValue_${i +
gl_FragColor = color;
} else if (dist < v_radius) {
gl_FragColor = mix(transparent, color, (v_radius - dist) / aaBorder);
} else {
#ifdef HAS_DEPTH
discard;
#endif
}
#endif
}
Expand Down
9 changes: 9 additions & 0 deletions packages/node-piechart/src/shader-vert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ ${slices
.join("\n")}
#endif
#ifdef HAS_DEPTH
attribute float a_zIndex;
uniform float u_maxZIndex;
#endif
const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0);
void main() {
Expand All @@ -49,6 +54,10 @@ void main() {
v_diffVector = diffVector;
${"attribute" in offset ? "v_offset = a_offset;\n" : ""}
#ifdef HAS_DEPTH
gl_Position.z = a_zIndex / u_maxZIndex;
#endif
#ifdef PICKING_MODE
v_color = a_id;
#else
Expand Down
7 changes: 5 additions & 2 deletions packages/sigma/src/rendering/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export abstract class NodeProgram<
return this.processVisibleItem(indexToColor(nodeIndex), i, data);
}

abstract processVisibleItem(nodeIndex: number, i: number, data: NodeDisplayData): void;
abstract processVisibleItem(nodeId: number, startIndex: number, data: NodeDisplayData): void;
}

class NodeProgramClass<
Expand Down Expand Up @@ -123,7 +123,10 @@ export function createNodeCompoundProgram<
}

process(nodeIndex: number, offset: number, data: NodeDisplayData): void {
this.programs.forEach((program) => program.process(nodeIndex, offset, data));
const l = this.programs.length;
this.programs.forEach((program, i) =>
program.process(nodeIndex, offset, { ...data, depth: data.depth + 1 - i / l }),
);
}

render(params: RenderParams): void {
Expand Down
Loading

0 comments on commit afb4de4

Please sign in to comment.