Skip to content

Commit

Permalink
[sigma] Fixes #1397
Browse files Browse the repository at this point in the history
The solution is to encode item IDs in only 3 channels (R, G and B), but
sending a full 4 channels color, but with a hard-coded alpha at 1.

It is non-optimal (we encode a 3 bytes data as a 4 bytes integer in the
ByteArray), but it solves the issue quite well.

Details:
- Updates indexToColor and colorToIndex to fit our solution
- Updates all vertex shaders so that the `v_color.a *= bias;` correction
  is also applied to the picking layer colors
- Updates program.ts to enable alpha blending for the picking layer
  • Loading branch information
jacomyal committed Dec 18, 2023
1 parent a58eccb commit e1a9c11
Show file tree
Hide file tree
Showing 12 changed files with 49 additions and 21 deletions.
3 changes: 2 additions & 1 deletion packages/examples/custom-rendering/node.border.vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void main() {
#else
// For normal mode, we use the color:
v_color = a_color;
v_color.a *= bias;
#endif

v_color.a *= bias;
}
11 changes: 8 additions & 3 deletions packages/sigma/src/rendering/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,10 +324,15 @@ export abstract class Program<Uniform extends string = string> implements Abstra
abstract setUniforms(params: RenderParams, programInfo: ProgramInfo): void;

protected renderProgram(params: RenderParams, programInfo: ProgramInfo): void {
const { gl, program, isPicking } = programInfo;
const { gl, program } = programInfo;

if (!isPicking) gl.enable(gl.BLEND);
else gl.disable(gl.BLEND);
// With the current fix for #1397, the alpha blending is enabled for the
// picking layer:
gl.enable(gl.BLEND);

// Original code:
// if (!isPicking) gl.enable(gl.BLEND);
// else gl.disable(gl.BLEND);

gl.useProgram(program);
this.setUniforms(params, programInfo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void main() {
#else
// For normal mode, we use the color:
v_color = a_color;
v_color.a *= bias;
#endif

v_color.a *= bias;
}
3 changes: 2 additions & 1 deletion packages/sigma/src/rendering/programs/edge-clamped/vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ void main() {
#else
// For normal mode, we use the color:
v_color = a_color;
v_color.a *= bias;
#endif

v_color.a *= bias;
}
3 changes: 2 additions & 1 deletion packages/sigma/src/rendering/programs/edge-line/vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ void main() {
#else
// For normal mode, we use the color:
v_color = a_color;
v_color.a *= bias;
#endif

v_color.a *= bias;
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ void main() {
#else
// For normal mode, we use the color:
v_color = a_color;
v_color.a *= bias;
#endif

v_color.a *= bias;
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void main() {
#else
// For normal mode, we use the color:
v_color = a_color;
v_color.a *= bias;
#endif

v_color.a *= bias;
}
3 changes: 2 additions & 1 deletion packages/sigma/src/rendering/programs/node-circle/vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void main() {
#else
// For normal mode, we use the color:
v_color = a_color;
v_color.a *= bias;
#endif

v_color.a *= bias;
}
3 changes: 2 additions & 1 deletion packages/sigma/src/rendering/programs/node-image/vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ void main() {
#else
// For normal mode, we use the color:
v_color = a_color;
v_color.a *= bias;

// Pass the texture coordinates:
v_texture = a_texture;
#endif

v_color.a *= bias;
}
3 changes: 2 additions & 1 deletion packages/sigma/src/rendering/programs/node-point/vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void main() {
#else
// For normal mode, we use the color:
v_color = a_color;
v_color.a *= bias;
#endif

v_color.a *= bias;
}
5 changes: 3 additions & 2 deletions packages/sigma/src/sigma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -799,8 +799,9 @@ export default class Sigma<GraphType extends Graph = Graph> extends TypedEventEm
// Add data to programs
for (let i = 0, l = nodes.length; i < l; i++) {
const node = nodes[i];
itemIDsIndex[incrID] = { type: "node", id: node };

nodeIndices[node] = incrID;
itemIDsIndex[nodeIndices[node]] = { type: "node", id: node };
incrID++;

const data = this.nodeDataCache[node];
Expand Down Expand Up @@ -842,8 +843,8 @@ export default class Sigma<GraphType extends Graph = Graph> extends TypedEventEm
for (let i = 0, l = edges.length; i < l; i++) {
const edge = edges[i];

itemIDsIndex[incrID] = { type: "edge", id: edge };
edgeIndices[edge] = incrID;
itemIDsIndex[edgeIndices[edge]] = { type: "edge", id: edge };
incrID++;

const data = this.edgeDataCache[edge];
Expand Down
27 changes: 20 additions & 7 deletions packages/sigma/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,18 +314,31 @@ export function indexToColor(index: number): number {
// If the index is already computed, we yield it
if (typeof FLOAT_INDEX_CACHE[index] !== "undefined") return FLOAT_INDEX_CACHE[index];

const r = (index & 0xff000000) >>> 24;
const g = (index & 0x00ff0000) >>> 16;
const b = (index & 0x0000ff00) >>> 8;
const a = index & 0x000000ff;
// To address issue #1397, one strategy is to keep encoding 4 bytes colors,
// but with alpha hard-set to 1.0 (or 255):
const r = (index & 0x00ff0000) >>> 16;
const g = (index & 0x0000ff00) >>> 8;
const b = index & 0x000000ff;
const a = 0x000000ff;

// The original 4 bytes color encoding was the following:
// const r = (index & 0xff000000) >>> 24;
// const g = (index & 0x00ff0000) >>> 16;
// const b = (index & 0x0000ff00) >>> 8;
// const a = index & 0x000000ff;

const color = rgbaToFloat(r, g, b, a);
const color = rgbaToFloat(r, g, b, a, true);
FLOAT_INDEX_CACHE[index] = color;

return color;
}
export function colorToIndex(r: number, g: number, b: number, a: number): number {
return a + (b << 8) + (g << 16) + (r << 24);
export function colorToIndex(r: number, g: number, b: number, _a: number): number {
// As for the function indexToColor, because of #1397 and the "alpha is always
// 1.0" strategy, we need to fix this function as well:
return b + (g << 8) + (r << 16);

// The original 4 bytes color decoding is the following:
// return a + (b << 8) + (g << 16) + (r << 24);
}

/**
Expand Down

0 comments on commit e1a9c11

Please sign in to comment.