forked from StudioInfinity/dyna3
Sketch a point rendering pipeline
This commit is contained in:
parent
3590b1ad4e
commit
23f395331a
5 changed files with 116 additions and 37 deletions
|
@ -27,7 +27,7 @@ fn compile_shader(
|
||||||
shader
|
shader
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_program_with_shaders(
|
fn set_up_program(
|
||||||
context: &WebGl2RenderingContext,
|
context: &WebGl2RenderingContext,
|
||||||
vertex_shader_source: &str,
|
vertex_shader_source: &str,
|
||||||
fragment_shader_source: &str
|
fragment_shader_source: &str
|
||||||
|
@ -131,7 +131,8 @@ fn event_dir(event: &MouseEvent) -> Vector3<f64> {
|
||||||
let height = rect.height();
|
let height = rect.height();
|
||||||
let shortdim = width.min(height);
|
let shortdim = width.min(height);
|
||||||
|
|
||||||
// this constant should be kept synchronized with `inversive.frag`
|
// this constant should be kept synchronized with `spheres.frag` and
|
||||||
|
// `point.vert`
|
||||||
const FOCAL_SLOPE: f64 = 0.3;
|
const FOCAL_SLOPE: f64 = 0.3;
|
||||||
|
|
||||||
Vector3::new(
|
Vector3::new(
|
||||||
|
@ -225,13 +226,22 @@ pub fn Display() -> View {
|
||||||
.dyn_into::<WebGl2RenderingContext>()
|
.dyn_into::<WebGl2RenderingContext>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// create and use the rendering program
|
// disable depth testing
|
||||||
let program = create_program_with_shaders(
|
ctx.disable(WebGl2RenderingContext::DEPTH_TEST);
|
||||||
|
|
||||||
|
// set up the sphere rendering program
|
||||||
|
let sphere_program = set_up_program(
|
||||||
&ctx,
|
&ctx,
|
||||||
include_str!("identity.vert"),
|
include_str!("identity.vert"),
|
||||||
include_str!("inversive.frag")
|
include_str!("spheres.frag")
|
||||||
|
);
|
||||||
|
|
||||||
|
// set up the point rendering program
|
||||||
|
let point_program = set_up_program(
|
||||||
|
&ctx,
|
||||||
|
include_str!("point.vert"),
|
||||||
|
include_str!("point.frag")
|
||||||
);
|
);
|
||||||
ctx.use_program(Some(&program));
|
|
||||||
|
|
||||||
/* DEBUG */
|
/* DEBUG */
|
||||||
// print the maximum number of vectors that can be passed as
|
// print the maximum number of vectors that can be passed as
|
||||||
|
@ -250,31 +260,31 @@ pub fn Display() -> View {
|
||||||
&JsValue::from("uniform vectors available")
|
&JsValue::from("uniform vectors available")
|
||||||
);
|
);
|
||||||
|
|
||||||
// find indices of vertex attributes and uniforms
|
// find indices of sphere vertex attributes and uniforms
|
||||||
const SPHERE_MAX: usize = 200;
|
const SPHERE_MAX: usize = 200;
|
||||||
let position_index = ctx.get_attrib_location(&program, "position") as u32;
|
let viewport_position_index = ctx.get_attrib_location(&sphere_program, "position") as u32;
|
||||||
let sphere_cnt_loc = ctx.get_uniform_location(&program, "sphere_cnt");
|
let sphere_cnt_loc = ctx.get_uniform_location(&sphere_program, "sphere_cnt");
|
||||||
let sphere_sp_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
let sphere_sp_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
||||||
&ctx, &program, "sphere_list", Some("sp")
|
&ctx, &sphere_program, "sphere_list", Some("sp")
|
||||||
);
|
);
|
||||||
let sphere_lt_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
let sphere_lt_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
||||||
&ctx, &program, "sphere_list", Some("lt")
|
&ctx, &sphere_program, "sphere_list", Some("lt")
|
||||||
);
|
);
|
||||||
let color_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
let sphere_color_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
||||||
&ctx, &program, "color_list", None
|
&ctx, &sphere_program, "color_list", None
|
||||||
);
|
);
|
||||||
let highlight_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
let sphere_highlight_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
||||||
&ctx, &program, "highlight_list", None
|
&ctx, &sphere_program, "highlight_list", None
|
||||||
);
|
);
|
||||||
let resolution_loc = ctx.get_uniform_location(&program, "resolution");
|
let resolution_loc = ctx.get_uniform_location(&sphere_program, "resolution");
|
||||||
let shortdim_loc = ctx.get_uniform_location(&program, "shortdim");
|
let shortdim_loc = ctx.get_uniform_location(&sphere_program, "shortdim");
|
||||||
let opacity_loc = ctx.get_uniform_location(&program, "opacity");
|
let opacity_loc = ctx.get_uniform_location(&sphere_program, "opacity");
|
||||||
let layer_threshold_loc = ctx.get_uniform_location(&program, "layer_threshold");
|
let layer_threshold_loc = ctx.get_uniform_location(&sphere_program, "layer_threshold");
|
||||||
let debug_mode_loc = ctx.get_uniform_location(&program, "debug_mode");
|
let debug_mode_loc = ctx.get_uniform_location(&sphere_program, "debug_mode");
|
||||||
|
|
||||||
// set the vertex positions
|
// set the viewport vertex positions
|
||||||
const VERTEX_CNT: usize = 6;
|
const VERTEX_CNT: usize = 6;
|
||||||
let positions: [f32; 3*VERTEX_CNT] = [
|
let viewport_positions: [f32; 3*VERTEX_CNT] = [
|
||||||
// northwest triangle
|
// northwest triangle
|
||||||
-1.0, -1.0, 0.0,
|
-1.0, -1.0, 0.0,
|
||||||
-1.0, 1.0, 0.0,
|
-1.0, 1.0, 0.0,
|
||||||
|
@ -284,7 +294,9 @@ pub fn Display() -> View {
|
||||||
1.0, 1.0, 0.0,
|
1.0, 1.0, 0.0,
|
||||||
1.0, -1.0, 0.0
|
1.0, -1.0, 0.0
|
||||||
];
|
];
|
||||||
bind_vertex_attrib(&ctx, position_index, 3, &positions);
|
|
||||||
|
// find indices of point vertex attributes and uniforms
|
||||||
|
let point_position_index = ctx.get_attrib_location(&point_program, "position") as u32;
|
||||||
|
|
||||||
// set up a repainting routine
|
// set up a repainting routine
|
||||||
let (_, start_animation_loop, _) = create_raf(move || {
|
let (_, start_animation_loop, _) = create_raf(move || {
|
||||||
|
@ -387,6 +399,8 @@ pub fn Display() -> View {
|
||||||
frames_since_last_sample = 0;
|
frames_since_last_sample = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- get the assembly ---
|
||||||
|
|
||||||
// find the map from assembly space to world space
|
// find the map from assembly space to world space
|
||||||
let location = {
|
let location = {
|
||||||
let u = -location_z;
|
let u = -location_z;
|
||||||
|
@ -400,12 +414,12 @@ pub fn Display() -> View {
|
||||||
};
|
};
|
||||||
let asm_to_world = &location * &orientation;
|
let asm_to_world = &location * &orientation;
|
||||||
|
|
||||||
// get the assembly
|
// get the spheres
|
||||||
let (
|
let (
|
||||||
elt_cnt,
|
sphere_cnt,
|
||||||
reps_world,
|
sphere_reps_world,
|
||||||
colors,
|
sphere_colors,
|
||||||
highlights
|
sphere_highlights
|
||||||
) = state.assembly.elements.with(|elts| {
|
) = state.assembly.elements.with(|elts| {
|
||||||
(
|
(
|
||||||
// number of elements
|
// number of elements
|
||||||
|
@ -436,16 +450,45 @@ pub fn Display() -> View {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* SCAFFOLDING */
|
||||||
|
// get the points
|
||||||
|
let point_positions = {
|
||||||
|
use crate::engine::point;
|
||||||
|
|
||||||
|
/* DEBUG */
|
||||||
|
// hard-code the origin and the centers of the spheres in
|
||||||
|
// the general test assembly
|
||||||
|
let point_reps = [
|
||||||
|
point(0.0, 0.0, 0.0),
|
||||||
|
point(0.5, 0.5, 0.0),
|
||||||
|
point(-0.5, -0.5, 0.0),
|
||||||
|
point(-0.5, 0.5, 0.0),
|
||||||
|
point(0.5, -0.5, 0.0),
|
||||||
|
point(0.0, 0.15, 1.0),
|
||||||
|
point(0.0, -0.15, -1.0)
|
||||||
|
];
|
||||||
|
|
||||||
|
const SPACE_DIM: usize = 3;
|
||||||
|
let asm_to_world_sp = asm_to_world.rows(0, SPACE_DIM);
|
||||||
|
let point_reps_world_sp = point_reps.map(|rep| &asm_to_world_sp * rep);
|
||||||
|
DMatrix::from_columns(&point_reps_world_sp).cast::<f32>()
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- draw the spheres ---
|
||||||
|
|
||||||
|
// use the sphere rendering program
|
||||||
|
ctx.use_program(Some(&sphere_program));
|
||||||
|
|
||||||
// set the resolution
|
// set the resolution
|
||||||
let width = canvas.width() as f32;
|
let width = canvas.width() as f32;
|
||||||
let height = canvas.height() as f32;
|
let height = canvas.height() as f32;
|
||||||
ctx.uniform2f(resolution_loc.as_ref(), width, height);
|
ctx.uniform2f(resolution_loc.as_ref(), width, height);
|
||||||
ctx.uniform1f(shortdim_loc.as_ref(), width.min(height));
|
ctx.uniform1f(shortdim_loc.as_ref(), width.min(height));
|
||||||
|
|
||||||
// pass the assembly
|
// pass the assembly data
|
||||||
ctx.uniform1i(sphere_cnt_loc.as_ref(), elt_cnt);
|
ctx.uniform1i(sphere_cnt_loc.as_ref(), sphere_cnt);
|
||||||
for n in 0..reps_world.len() {
|
for n in 0..sphere_reps_world.len() {
|
||||||
let v = &reps_world[n];
|
let v = &sphere_reps_world[n];
|
||||||
ctx.uniform3f(
|
ctx.uniform3f(
|
||||||
sphere_sp_locs[n].as_ref(),
|
sphere_sp_locs[n].as_ref(),
|
||||||
v[0] as f32, v[1] as f32, v[2] as f32
|
v[0] as f32, v[1] as f32, v[2] as f32
|
||||||
|
@ -455,12 +498,12 @@ pub fn Display() -> View {
|
||||||
v[3] as f32, v[4] as f32
|
v[3] as f32, v[4] as f32
|
||||||
);
|
);
|
||||||
ctx.uniform3fv_with_f32_array(
|
ctx.uniform3fv_with_f32_array(
|
||||||
color_locs[n].as_ref(),
|
sphere_color_locs[n].as_ref(),
|
||||||
&colors[n]
|
&sphere_colors[n]
|
||||||
);
|
);
|
||||||
ctx.uniform1f(
|
ctx.uniform1f(
|
||||||
highlight_locs[n].as_ref(),
|
sphere_highlight_locs[n].as_ref(),
|
||||||
highlights[n]
|
sphere_highlights[n]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,9 +512,25 @@ pub fn Display() -> View {
|
||||||
ctx.uniform1i(layer_threshold_loc.as_ref(), LAYER_THRESHOLD);
|
ctx.uniform1i(layer_threshold_loc.as_ref(), LAYER_THRESHOLD);
|
||||||
ctx.uniform1i(debug_mode_loc.as_ref(), DEBUG_MODE);
|
ctx.uniform1i(debug_mode_loc.as_ref(), DEBUG_MODE);
|
||||||
|
|
||||||
|
// pass the viewport vertex positions
|
||||||
|
bind_vertex_attrib(&ctx, viewport_position_index, 3, &viewport_positions);
|
||||||
|
|
||||||
// draw the scene
|
// draw the scene
|
||||||
ctx.draw_arrays(WebGl2RenderingContext::TRIANGLES, 0, VERTEX_CNT as i32);
|
ctx.draw_arrays(WebGl2RenderingContext::TRIANGLES, 0, VERTEX_CNT as i32);
|
||||||
|
|
||||||
|
// --- draw the points ---
|
||||||
|
|
||||||
|
// use the point rendering program
|
||||||
|
ctx.use_program(Some(&point_program));
|
||||||
|
|
||||||
|
// pass the point vertex positions
|
||||||
|
bind_vertex_attrib(&ctx, point_position_index, 3, point_positions.as_slice());
|
||||||
|
|
||||||
|
// draw the scene
|
||||||
|
ctx.draw_arrays(WebGl2RenderingContext::POINTS, 0, point_positions.ncols() as i32);
|
||||||
|
|
||||||
|
// --- update the display state ---
|
||||||
|
|
||||||
// update the viewpoint
|
// update the viewpoint
|
||||||
assembly_to_world.set(asm_to_world);
|
assembly_to_world.set(asm_to_world);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ use web_sys::{console, wasm_bindgen::JsValue}; /* DEBUG */
|
||||||
|
|
||||||
// --- elements ---
|
// --- elements ---
|
||||||
|
|
||||||
#[cfg(feature = "dev")]
|
|
||||||
pub fn point(x: f64, y: f64, z: f64) -> DVector<f64> {
|
pub fn point(x: f64, y: f64, z: f64) -> DVector<f64> {
|
||||||
DVector::from_column_slice(&[x, y, z, 0.5, 0.5*(x*x + y*y + z*z)])
|
DVector::from_column_slice(&[x, y, z, 0.5, 0.5*(x*x + y*y + z*z)])
|
||||||
}
|
}
|
||||||
|
|
9
app-proto/src/point.frag
Normal file
9
app-proto/src/point.frag
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
out vec4 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
outColor = vec4(vec3(1.), 1.);
|
||||||
|
}
|
12
app-proto/src/point.vert
Normal file
12
app-proto/src/point.vert
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
in vec4 position;
|
||||||
|
|
||||||
|
// camera
|
||||||
|
const float focal_slope = 0.3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float depth = -focal_slope * position.z;
|
||||||
|
gl_Position = vec4(position.xy / depth, 0., 1.);
|
||||||
|
gl_PointSize = 5.;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue