Skip to content

Commit

Permalink
Merge pull request #132 from nomic-ai/08-29-interpolate_between_old_f…
Browse files Browse the repository at this point in the history
…oreground_size_and_new_one

interpolate between old foreground size and new one
  • Loading branch information
bmschmidt authored Sep 3, 2024
2 parents 0e208bf + a6ba051 commit e02309d
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 36 deletions.
3 changes: 3 additions & 0 deletions dev/FourClasses.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ColorChange from './svelte/ColorChange.svelte';
import SizeSlider from './svelte/SizeSlider.svelte';
import PositionScales from './svelte/PositionScales.svelte';
import SelectPoints from './svelte/SelectPoints.svelte';
const startSize = 2;
const prefs = {
source_url: '/tiles',
Expand All @@ -13,6 +14,7 @@
zoom_balance: 0.22, // Rate at which points increase size. https://observablehq.com/@bmschmidt/zoom-strategies-for-huge-scatterplots-with-three-js
point_size: startSize, // Default point size before application of size scaling
background_color: '#EEEDDE',
duration: 100,
encoding: {
color: {
field: 'class',
Expand Down Expand Up @@ -42,6 +44,7 @@
<ColorChange {scatterplot}></ColorChange>
<SizeSlider size={startSize} {scatterplot}></SizeSlider>
<PositionScales {scatterplot} />
<SelectPoints {scatterplot}></SelectPoints>
</div>

<div id="deepscatter"></div>
Expand Down
48 changes: 48 additions & 0 deletions dev/svelte/SelectPoints.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script>
import { Bitmask, Scatterplot } from '../../src/deepscatter';
export let scatterplot;
let selectionNumber = 0;
async function makeSelection() {
const selection = await scatterplot.deeptable.select_data({
name: Math.random().toFixed(8),
tileFunction: async (tile) => {
const b = new Bitmask(tile.manifest.nPoints);
for (let i = 0; i < tile.manifest.nPoints; i++) {
if (Math.random() < 0.001) {
b.set(i);
}
}
return b.to_arrow();
},
});
await selection.ready;
await selection.applyToAllLoadedTiles();
console.log(selection);
console.log(selection.name);
scatterplot.plotAPI({
duration: 1000,
background_options: {
size: [0.5, 10],
opacity: [0.8, 3],
color: '#AAAAAA',
},
encoding: {
foreground: {
field: selection.name,
op: 'gt',
a: 0,
},
},
});
}
</script>

<div>
<button on:click={() => makeSelection()}>Select Points</button>
<button
on:click={() => scatterplot.plotAPI({ encoding: { foreground: null } })}
>Reset</button
>
</div>
87 changes: 61 additions & 26 deletions src/glsl/general.vert
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ uniform vec3 u_last_filter2_numeric; // An override for simple numeric operation

uniform vec3 u_foreground_numeric; // An override for simple numeric operations.
uniform vec3 u_last_foreground_numeric; // An override for simple numeric operations.

// If we need a background render on the previous position and the current position, respectively.
uniform vec2 u_background_draw_needed;

// Transform from data space to the open window.
uniform mat3 u_window_scale;
Expand Down Expand Up @@ -1241,22 +1242,28 @@ void main() {
a_last_filter2_is_constant
);

float foreground_status = choose_and_run_filter(
float current_foreground_status = choose_and_run_filter(
u_foreground_numeric,
a_foreground,
u_foreground_map_position,
a_foreground_is_constant
);


float last_foreground_status = choose_and_run_filter(
u_last_foreground_numeric,
a_last_foreground,
u_last_foreground_map_position,
a_last_foreground_is_constant
);
float fg_ease = mix(last_foreground_status, foreground_status, ease);

float fg_ease = mix(last_foreground_status, current_foreground_status, ease);

float foreground_status;
if (ease < ix_to_random(ix, 1.)) {
foreground_status = last_foreground_status;
} else {
foreground_status = current_foreground_status;
}

/*if (a_foreground_is_constant) {
Expand Down Expand Up @@ -1368,44 +1375,72 @@ void main() {
}

// Are we in a mode where we need to plot foreground and background?
if (u_foreground_number > -1.) {
if (u_background_draw_needed.x > 0. || u_background_draw_needed.y > 0.) {
// In that case, throw away points from the other half of the set.
// This status number will change in easing animation, causing points
// to snap from foreground to background as they move; no getting around that.
if (u_foreground_number != foreground_status) {
gl_Position = discard_me;
return;
}
if (u_foreground_number == 1.) {
gl_PointSize *= u_foreground_size;
fill = vec4(fill.rgb, min(1., fill.a * u_foreground_alpha));
}
// If we're in background mode, got to change the points a bit.
if (u_foreground_number == 0.) {
gl_PointSize *= u_background_size;
// Should the color piker run?
if (u_color_picker_mode >= 1.) {


// Color picking only rouns on background if background_mouseover is true.
if (u_color_picker_mode >= 1.) {
if (u_foreground_number == 0.) {
// Should the color picker run?
if (u_background_mouseover == 1.) {
// pass--keep the colors as are.
} else {
gl_Position = discard_me;
return;
}
}
}

float startSize = 1.0;
float endSize = 1.0;
vec4 startColor = fill;
vec4 endColor = fill;

if (u_background_draw_needed.x == 1.) {
if (last_foreground_status < 0.5) {
startSize = u_background_size;
startColor = u_background_rgba;
startColor.a *= fill.a;
} else {
float alpha = min(u_alpha * u_background_rgba.a, 1.);
if (alpha < 1./255.) {
// Very light alphas must be quantized. Only show an appropriate sample.
float seed = ix_to_random(ix, 38.6);
if (alpha * 255. < seed) {
gl_Position = discard_me;
return;
} else {
alpha = 1. / 255.;
}
}
fill = vec4(u_background_rgba.rgb, alpha);
startSize = u_foreground_size;
startColor = vec4(fill.rgb, min(1., fill.a * u_foreground_alpha));
}
}

if (u_background_draw_needed.y == 1.) {
if (current_foreground_status > 0.5) {
endSize = u_foreground_size;
endColor = vec4(fill.rgb, min(1., fill.a * u_foreground_alpha));
} else {
endSize = u_background_size;
endColor = u_background_rgba;
endColor.a *= fill.a;
// endColor.rgb = vec3(0., 0., 1.);
}
}

gl_PointSize *= mix(startSize, endSize, ease);
fill = mix(startColor, endColor, ease);

// Very light alphas must be quantized. Only show an appropriate sample.
if (fill.a < 1./255.) {
float seed = ix_to_random(ix, 38.6);
if (fill.a * 255. < seed) {
gl_Position = discard_me;
return;
} else {
fill.a = 1. / 255.;
}
}

}

point_size = gl_PointSize;
/* if (u_use_glyphset > 0. && point_size > 5.0) {
float random_letter = floor(64. * ix_to_random(ix, 1.3));
Expand Down
32 changes: 23 additions & 9 deletions src/regl_rendering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ export class ReglRenderer extends Renderer {
const transform: ZoomTransform = this.zoom
.transform as unknown as ZoomTransform;
const colorScales = this.aes.dim('color') as StatefulAesthetic<Color>;
const foreground = this.aes.dim(
'foreground',
) as StatefulAesthetic<Foreground>;
const [currentColor, lastColor] = [
colorScales.current,
colorScales.last,
Expand All @@ -173,6 +176,10 @@ export class ReglRenderer extends Renderer {
// string_index: 0,
prefs: JSON.parse(JSON.stringify(prefs)) as DS.APICall,
wrap_colors_after,
background_draw_needed: [
foreground.last.active,
foreground.current.active,
] as [boolean, boolean],
start_time: this.most_recent_restart,
webgl_scale: this._webgl_scale_history[0],
last_webgl_scale: this._webgl_scale_history[1],
Expand Down Expand Up @@ -216,11 +223,8 @@ export class ReglRenderer extends Renderer {
// Regl is faster if it can render a large number of draw calls together.
const prop_list: DS.TileDrawProps[] = [];
let call_no = 0;
const foreground = this.aes.dim(
'foreground',
) as StatefulAesthetic<Foreground>;
const needs_background_pass =
foreground.states[0].active || foreground.states[1].active;
props.background_draw_needed[0] || props.background_draw_needed[1];
for (const tile of this.visible_tiles()) {
// Do the binding operation; returns truthy if it's already done.
tile._buffer_manager =
Expand All @@ -234,21 +238,24 @@ export class ReglRenderer extends Renderer {
const this_props = {
manager: tile._buffer_manager,
number: call_no++,
foreground: needs_background_pass ? 1 : -1,
foreground_draw_number: needs_background_pass ? 1 : 1,
tile_id: tile.numeric_id,
...props,
} as DS.TileDrawProps;
prop_list.push(this_props);
if (needs_background_pass) {
const background_props = { ...this_props, foreground: 0 } as const;
const background_props = {
...this_props,
foreground_draw_number: 0,
} as const;
prop_list.push(background_props);
}
}
// Plot background first, and lower tiles before higher tiles.
prop_list.sort((a, b) => {
return (
(3 + a.foreground) * 1000 -
(3 + b.foreground) * 1000 +
(3 + a.foreground_draw_number) * 1000 -
(3 + b.foreground_draw_number) * 1000 +
b.number -
a.number
);
Expand Down Expand Up @@ -827,7 +834,14 @@ export class ReglRenderer extends Renderer {
u_alpha: (_: C, { alpha }: P) => {
return alpha;
},
u_foreground_number: (_: C, { foreground }: P) => foreground as number,
u_background_draw_needed: (_: C, { background_draw_needed }: P) => {
return [
background_draw_needed[0] ? 1 : 0,
background_draw_needed[1] ? 1 : 0,
];
},
u_foreground_number: (_: C, { foreground_draw_number }: P) =>
foreground_draw_number as number,
u_foreground_alpha: () => this.render_props.foreground_opacity,
u_background_rgba: () => {
const color = this.prefs.background_options.color;
Expand Down
3 changes: 2 additions & 1 deletion src/shared.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@ export type GlobalDrawProps = {
time: number;
update_time: number;
relative_time: number;
background_draw_needed: [boolean, boolean];
// string_index: number;
prefs: APICall;
wrap_colors_after: [number, number];
Expand Down Expand Up @@ -643,6 +644,6 @@ export type GlobalDrawProps = {
export type TileDrawProps = GlobalDrawProps & {
manager: TileBufferManager;
number: number;
foreground: 1 | 0 | -1;
foreground_draw_number: 1 | 0 | -1;
tile_id: number;
};

0 comments on commit e02309d

Please sign in to comment.