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
|
||||
}
|
||||
|
||||
fn create_program_with_shaders(
|
||||
fn set_up_program(
|
||||
context: &WebGl2RenderingContext,
|
||||
vertex_shader_source: &str,
|
||||
fragment_shader_source: &str
|
||||
|
@ -131,7 +131,8 @@ fn event_dir(event: &MouseEvent) -> Vector3<f64> {
|
|||
let height = rect.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;
|
||||
|
||||
Vector3::new(
|
||||
|
@ -225,13 +226,22 @@ pub fn Display() -> View {
|
|||
.dyn_into::<WebGl2RenderingContext>()
|
||||
.unwrap();
|
||||
|
||||
// create and use the rendering program
|
||||
let program = create_program_with_shaders(
|
||||
// disable depth testing
|
||||
ctx.disable(WebGl2RenderingContext::DEPTH_TEST);
|
||||
|
||||
// set up the sphere rendering program
|
||||
let sphere_program = set_up_program(
|
||||
&ctx,
|
||||
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 */
|
||||
// print the maximum number of vectors that can be passed as
|
||||
|
@ -250,31 +260,31 @@ pub fn Display() -> View {
|
|||
&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;
|
||||
let position_index = ctx.get_attrib_location(&program, "position") as u32;
|
||||
let sphere_cnt_loc = ctx.get_uniform_location(&program, "sphere_cnt");
|
||||
let viewport_position_index = ctx.get_attrib_location(&sphere_program, "position") as u32;
|
||||
let sphere_cnt_loc = ctx.get_uniform_location(&sphere_program, "sphere_cnt");
|
||||
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>(
|
||||
&ctx, &program, "sphere_list", Some("lt")
|
||||
&ctx, &sphere_program, "sphere_list", Some("lt")
|
||||
);
|
||||
let color_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
||||
&ctx, &program, "color_list", None
|
||||
let sphere_color_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
||||
&ctx, &sphere_program, "color_list", None
|
||||
);
|
||||
let highlight_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
||||
&ctx, &program, "highlight_list", None
|
||||
let sphere_highlight_locs = get_uniform_array_locations::<SPHERE_MAX>(
|
||||
&ctx, &sphere_program, "highlight_list", None
|
||||
);
|
||||
let resolution_loc = ctx.get_uniform_location(&program, "resolution");
|
||||
let shortdim_loc = ctx.get_uniform_location(&program, "shortdim");
|
||||
let opacity_loc = ctx.get_uniform_location(&program, "opacity");
|
||||
let layer_threshold_loc = ctx.get_uniform_location(&program, "layer_threshold");
|
||||
let debug_mode_loc = ctx.get_uniform_location(&program, "debug_mode");
|
||||
let resolution_loc = ctx.get_uniform_location(&sphere_program, "resolution");
|
||||
let shortdim_loc = ctx.get_uniform_location(&sphere_program, "shortdim");
|
||||
let opacity_loc = ctx.get_uniform_location(&sphere_program, "opacity");
|
||||
let layer_threshold_loc = ctx.get_uniform_location(&sphere_program, "layer_threshold");
|
||||
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;
|
||||
let positions: [f32; 3*VERTEX_CNT] = [
|
||||
let viewport_positions: [f32; 3*VERTEX_CNT] = [
|
||||
// northwest triangle
|
||||
-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
|
||||
];
|
||||
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
|
||||
let (_, start_animation_loop, _) = create_raf(move || {
|
||||
|
@ -387,6 +399,8 @@ pub fn Display() -> View {
|
|||
frames_since_last_sample = 0;
|
||||
}
|
||||
|
||||
// --- get the assembly ---
|
||||
|
||||
// find the map from assembly space to world space
|
||||
let location = {
|
||||
let u = -location_z;
|
||||
|
@ -400,12 +414,12 @@ pub fn Display() -> View {
|
|||
};
|
||||
let asm_to_world = &location * &orientation;
|
||||
|
||||
// get the assembly
|
||||
// get the spheres
|
||||
let (
|
||||
elt_cnt,
|
||||
reps_world,
|
||||
colors,
|
||||
highlights
|
||||
sphere_cnt,
|
||||
sphere_reps_world,
|
||||
sphere_colors,
|
||||
sphere_highlights
|
||||
) = state.assembly.elements.with(|elts| {
|
||||
(
|
||||
// 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
|
||||
let width = canvas.width() as f32;
|
||||
let height = canvas.height() as f32;
|
||||
ctx.uniform2f(resolution_loc.as_ref(), width, height);
|
||||
ctx.uniform1f(shortdim_loc.as_ref(), width.min(height));
|
||||
|
||||
// pass the assembly
|
||||
ctx.uniform1i(sphere_cnt_loc.as_ref(), elt_cnt);
|
||||
for n in 0..reps_world.len() {
|
||||
let v = &reps_world[n];
|
||||
// pass the assembly data
|
||||
ctx.uniform1i(sphere_cnt_loc.as_ref(), sphere_cnt);
|
||||
for n in 0..sphere_reps_world.len() {
|
||||
let v = &sphere_reps_world[n];
|
||||
ctx.uniform3f(
|
||||
sphere_sp_locs[n].as_ref(),
|
||||
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
|
||||
);
|
||||
ctx.uniform3fv_with_f32_array(
|
||||
color_locs[n].as_ref(),
|
||||
&colors[n]
|
||||
sphere_color_locs[n].as_ref(),
|
||||
&sphere_colors[n]
|
||||
);
|
||||
ctx.uniform1f(
|
||||
highlight_locs[n].as_ref(),
|
||||
highlights[n]
|
||||
sphere_highlight_locs[n].as_ref(),
|
||||
sphere_highlights[n]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -469,9 +512,25 @@ pub fn Display() -> View {
|
|||
ctx.uniform1i(layer_threshold_loc.as_ref(), LAYER_THRESHOLD);
|
||||
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
|
||||
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
|
||||
assembly_to_world.set(asm_to_world);
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ use web_sys::{console, wasm_bindgen::JsValue}; /* DEBUG */
|
|||
|
||||
// --- elements ---
|
||||
|
||||
#[cfg(feature = "dev")]
|
||||
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)])
|
||||
}
|
||||
|
|
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