Skip to content

Commit

Permalink
implement clipping manually in WGLMakie
Browse files Browse the repository at this point in the history
  • Loading branch information
ffreyer committed Jun 13, 2024
1 parent 11f4da8 commit d777002
Show file tree
Hide file tree
Showing 17 changed files with 175 additions and 12 deletions.
8 changes: 7 additions & 1 deletion WGLMakie/assets/mesh.frag
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ flat in int sample_frag_color;

in vec3 o_normal;
in vec3 o_camdir;
in float o_clip_distance[8];

// Smoothes out edge around 0 light intensity, see GLMakie
float smooth_zero_max(float x) {
Expand Down Expand Up @@ -107,7 +108,12 @@ vec4 pack_int(uint id, uint index) {
return unpack;
}

void main() {
void main()
{
for (int i = 0; i < 8; i++)
if (o_clip_distance[i] < 0.0)
discard;

vec4 real_color = get_color(uniform_color, frag_uv, get_colorrange(), colormap);
vec3 shaded_color = real_color.rgb;

Expand Down
8 changes: 8 additions & 0 deletions WGLMakie/assets/mesh.vert
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ out vec3 o_normal;
out vec3 o_camdir;

out vec4 frag_color;
out float o_clip_distance[8];

uniform mat4 projection;
uniform mat4 view;
uniform vec3 eyeposition;
uniform vec4 clip_planes[8];

vec3 tovec3(vec2 v){return vec3(v, 0.0);}
vec3 tovec3(vec3 v){return v;}
Expand Down Expand Up @@ -61,11 +63,17 @@ vec4 vertex_color(float value, vec2 colorrange, sampler2D colormap){
}
}

void process_clip_planes(vec3 world_pos) {
for (int i = 0; i < 8; i++)
o_clip_distance[i] = dot(world_pos, clip_planes[i].xyz) - clip_planes[i].w;
}

void render(vec4 position_world, vec3 normal, mat4 view, mat4 projection)
{
// normal in world space
o_normal = get_normalmatrix() * normal;
// position in clip space (w/ depth)
process_clip_planes(position_world.xyz);
gl_Position = projection * view * position_world; // TODO consider using projectionview directly
gl_Position.z += gl_Position.w * get_depth_shift();
// direction to camera
Expand Down
5 changes: 5 additions & 0 deletions WGLMakie/assets/particles.frag
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ in vec4 frag_color;
in vec3 frag_normal;
in vec3 frag_position;
in vec3 o_camdir;
in float o_clip_distance[8];

// Smoothes out edge around 0 light intensity, see GLMakie
float smooth_zero_max(float x) {
Expand Down Expand Up @@ -43,6 +44,10 @@ vec4 pack_int(uint id, uint index) {
}

void main() {
for (int i = 0; i < 8; i++)
if (o_clip_distance[i] < 0.0)
discard;

vec3 L, N, light, color;
if (get_shading()) {
L = get_light_direction();
Expand Down
8 changes: 8 additions & 0 deletions WGLMakie/assets/particles.vert
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ precision mediump float;
uniform mat4 projection;
uniform mat4 view;
uniform vec3 eyeposition;
uniform vec4 clip_planes[8];

out vec3 frag_normal;
out vec3 frag_position;
out vec4 frag_color;
out vec3 o_camdir;
out float o_clip_distance[8];

vec3 qmul(vec4 q, vec3 v){
return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);
Expand All @@ -24,6 +26,11 @@ vec4 to_vec4(vec4 v4){return v4;}
vec3 to_vec3(vec2 v3){return vec3(v3, 0.0);}
vec3 to_vec3(vec3 v4){return v4;}

void process_clip_planes(vec3 world_pos) {
for (int i = 0; i < 8; i++)
o_clip_distance[i] = dot(world_pos, clip_planes[i].xyz) - clip_planes[i].w;
}

flat out uint frag_instance_id;

void main(){
Expand All @@ -34,6 +41,7 @@ void main(){
rotate(get_rotation(), vertex_position, N);
vertex_position = to_vec3(get_offset()) + vertex_position;
vec4 position_world = model * vec4(vertex_position, 1);
process_clip_planes(position_world.xyz);
frag_normal = N;
frag_color = to_vec4(get_color());
// direction to camera
Expand Down
5 changes: 5 additions & 0 deletions WGLMakie/assets/sprites.frag
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ in float frag_uvscale;
in float frag_distancefield_scale;
in vec4 frag_uv_offset_width;
flat in uint frag_instance_id;
in float o_clip_distance[8];

// These versions of aastep assume that `dist` is a signed distance function
// which has been scaled to be in units of pixels.
Expand Down Expand Up @@ -103,6 +104,10 @@ vec4 pack_int(uint id, uint index) {
}

void main() {
for (int i = 0; i < 8; i++)
if (o_clip_distance[i] < 0.0)
discard;

float signed_distance = 0.0;

vec4 uv_off = frag_uv_offset_width;
Expand Down
12 changes: 11 additions & 1 deletion WGLMakie/assets/sprites.vert
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
uniform mat4 projection;
uniform mat4 view;
uniform vec4 clip_planes[8];

uniform float atlas_tex_dim;

Expand All @@ -8,6 +9,7 @@ out vec2 frag_uv;
out float frag_uvscale;
out float frag_distancefield_scale;
out vec4 frag_uv_offset_width;
out float o_clip_distance[8];

flat out uint frag_instance_id;

Expand Down Expand Up @@ -58,6 +60,11 @@ float _determinant(mat2 m) {
return m[0][0] * m[1][1] - m[0][1] * m[1][0];
}

void process_clip_planes(vec3 world_pos) {
for (int i = 0; i < 8; i++)
o_clip_distance[i] = dot(world_pos, clip_planes[i].xyz) - clip_planes[i].w;
}

void main(){
// get_pos() returns the position of the scatter marker
// get_position() returns the (relative) position of the current quad vertex
Expand All @@ -68,9 +75,12 @@ void main(){
mat4 pview = projection * view;
mat4 trans = get_transform_marker() ? model : mat4(1.0);

vec4 position_world = model * vec4(tovec3(get_pos()), 1);
process_clip_planes(position_world.xyz);

// Compute centre of billboard in clipping coordinates
// Always transform text/scatter position argument
vec4 data_point = get_preprojection() * model * vec4(tovec3(get_pos()), 1);
vec4 data_point = get_preprojection() * position_world;
// maybe transform marker_offset + glyph offsets
data_point = vec4(data_point.xyz / data_point.w + mat3(trans) * tovec3(get_marker_offset()), 1);
data_point = pview * data_point;
Expand Down
5 changes: 5 additions & 0 deletions WGLMakie/assets/volume.frag
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ struct Nothing{ //Nothing type, to encode if some variable doesn't contain any d
bool _; //empty structs are not allowed
};
in vec3 frag_vert;
in float o_clip_distance[8];

const float max_distance = 1.3;

Expand Down Expand Up @@ -227,6 +228,10 @@ vec4 pack_int(uint id, uint index) {

void main()
{
for (int i = 0; i < 8; i++)
if (o_clip_distance[i] < 0.0)
discard;

vec4 color;
vec3 eye_unit = vec3(modelinv * vec4(eyeposition, 1));
vec3 back_position = frag_vert;
Expand Down
8 changes: 8 additions & 0 deletions WGLMakie/assets/volume.vert
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
out vec3 frag_vert;
out float o_clip_distance[8];

uniform mat4 projection, view;
uniform vec4 clip_planes[8];

void process_clip_planes(vec3 world_pos) {
for (int i = 0; i < 8; i++)
o_clip_distance[i] = dot(world_pos, clip_planes[i].xyz) - clip_planes[i].w;
}

void main()
{
frag_vert = position;
vec4 world_vert = model * vec4(position, 1);
process_clip_planes(world_vert.xyz);
gl_Position = projection * view * world_vert;
gl_Position.z += gl_Position.w * get_depth_shift();
}
5 changes: 5 additions & 0 deletions WGLMakie/assets/voxel.frag
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ flat in vec3 o_normal;
in vec3 o_uvw;
flat in int o_side;
in vec2 o_tex_uv;
in float o_clip_distance[8];

in vec3 o_camdir;

Expand Down Expand Up @@ -90,6 +91,10 @@ vec4 pack_int(uint id, uint index) {
}
void main()
{
for (int i = 0; i < 8; i++)
if (o_clip_distance[i] < 0.0)
discard;

vec2 voxel_uv = mod(o_tex_uv, 1.0);
if (voxel_uv.x < 0.5 * gap || voxel_uv.x > 1.0 - 0.5 * gap ||
voxel_uv.y < 0.5 * gap || voxel_uv.y > 1.0 - 0.5 * gap)
Expand Down
8 changes: 8 additions & 0 deletions WGLMakie/assets/voxel.vert
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ flat out vec3 o_normal;
out vec3 o_uvw;
flat out int o_side;
out vec2 o_tex_uv;
out float o_clip_distance[8];

#ifdef DEBUG_RENDER_ORDER
flat out float plane_render_idx;
Expand All @@ -15,6 +16,12 @@ flat out int plane_front;
out vec3 o_camdir;

uniform mat4 projection, view;
uniform vec4 clip_planes[8];

void process_clip_planes(vec3 world_pos) {
for (int i = 0; i < 8; i++)
o_clip_distance[i] = dot(world_pos, clip_planes[i].xyz) - clip_planes[i].w;
}

const vec3 unit_vecs[3] = vec3[]( vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1) );
const mat2x3 orientations[3] = mat2x3[](
Expand Down Expand Up @@ -136,6 +143,7 @@ void main() {
// place plane vertices
vec3 plane_vertex = vec3(size) * (orientations[dim] * get_position()) + displacement;
vec4 world_pos = get_model() * vec4(plane_vertex, 1.0f);
process_clip_planes(world_pos.xyz);
gl_Position = projection * view * world_pos;
gl_Position.z += gl_Position.w * get_depth_shift();

Expand Down
31 changes: 29 additions & 2 deletions WGLMakie/src/Lines.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ function lines_vertex_shader(uniforms, attributes, is_linesegments) {
${attribute_decl}
out vec3 f_quad_sdf;
out vec2 f_truncation; // invalid / not needed
out float f_linestart; // constant
out float f_linelength;
out float o_clip_distance[8];
flat out vec2 f_extrusion; // invalid / not needed
flat out float f_linewidth;
Expand All @@ -63,6 +63,7 @@ function lines_vertex_shader(uniforms, attributes, is_linesegments) {
flat out vec4 f_miter_vecs; // invalid / not needed
${uniform_decl}
uniform vec4 clip_planes[8];
// Constants
const float AA_RADIUS = 0.8;
Expand All @@ -73,6 +74,9 @@ function lines_vertex_shader(uniforms, attributes, is_linesegments) {
// Geometry/Position Utils
////////////////////////////////////////////////////////////////////////
vec4 world_space(vec3 point) { return model * vec4(point, 1); }
vec4 world_space(vec2 point) { return world_space(vec3(point, 0)); }
vec4 clip_space(vec3 point) {
return projectionview * model * vec4(point, 1);
}
Expand All @@ -93,6 +97,10 @@ function lines_vertex_shader(uniforms, attributes, is_linesegments) {
// Main
////////////////////////////////////////////////////////////////////////
void process_clip_planes(vec3 world_pos) {
for (int i = 0; i < 8; i++)
o_clip_distance[i] = dot(world_pos, clip_planes[i].xyz) - clip_planes[i].w;
}
void main() {
bool is_end = position.x == 1.0;
Expand Down Expand Up @@ -158,6 +166,8 @@ function lines_vertex_shader(uniforms, attributes, is_linesegments) {
// Varying vertex data
////////////////////////////////////////////////////////////////////
vec4 world_pos = world_space(is_end ? linepoint_end : linepoint_start);
process_clip_planes(world_pos.xyz);
// linecaps
f_capmode = ivec2(linecap);
Expand Down Expand Up @@ -207,6 +217,7 @@ function lines_vertex_shader(uniforms, attributes, is_linesegments) {
out vec2 f_truncation;
out float f_linestart;
out float f_linelength;
out float o_clip_distance[8];
flat out vec2 f_extrusion;
flat out float f_linewidth;
Expand All @@ -221,6 +232,7 @@ function lines_vertex_shader(uniforms, attributes, is_linesegments) {
flat out vec4 f_miter_vecs;
${uniform_decl}
uniform vec4 clip_planes[8];
// Constants
const float AA_RADIUS = 0.8;
Expand Down Expand Up @@ -319,6 +331,9 @@ function lines_vertex_shader(uniforms, attributes, is_linesegments) {
// Geometry/Position Utils
////////////////////////////////////////////////////////////////////////
vec4 world_space(vec3 point) { return model * vec4(point, 1); }
vec4 world_space(vec2 point) { return world_space(vec3(point, 0)); }
vec4 clip_space(vec3 point) {
return projectionview * model * vec4(point, 1);
}
Expand All @@ -340,6 +355,11 @@ function lines_vertex_shader(uniforms, attributes, is_linesegments) {
// Main
////////////////////////////////////////////////////////////////////////
void process_clip_planes(vec3 world_pos) {
for (int i = 0; i < 8; i++)
o_clip_distance[i] = dot(world_pos, clip_planes[i].xyz) - clip_planes[i].w;
}
void main() {
bool is_end = position.x == 1.0;
Expand Down Expand Up @@ -573,7 +593,9 @@ function lines_vertex_shader(uniforms, attributes, is_linesegments) {
////////////////////////////////////////////////////////////////////
// Varying vertex data
////////////////////////////////////////////////////////////////////
vec4 world_pos = world_space(is_end ? linepoint_end : linepoint_start);
process_clip_planes(world_pos.xyz);
vec3 offset;
int x = int(is_end);
Expand Down Expand Up @@ -664,6 +686,7 @@ function lines_fragment_shader(uniforms, attributes) {
in vec2 f_truncation;
in float f_linestart;
in float f_linelength;
in float o_clip_distance[8];
flat in float f_linewidth;
flat in vec4 f_pattern_overwrite;
Expand Down Expand Up @@ -787,6 +810,10 @@ function lines_fragment_shader(uniforms, attributes) {
void main(){
for (int i = 0; i < 8; i++)
if (o_clip_distance[i] < 0.0)
discard;
vec4 color;
// f_quad_sdf.x is the distance from p1, negative in v1 direction.
Expand Down
2 changes: 1 addition & 1 deletion WGLMakie/src/Serialization.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ function create_material(scene, program) {
transparent: true,
glslVersion: THREE.GLSL3,
depthTest: !program.overdraw.value,
depthWrite: !program.transparency.value,
depthWrite: !program.transparency.value
});
}

Expand Down
5 changes: 3 additions & 2 deletions WGLMakie/src/Shaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function uniform_type(obj) {
} else if (obj instanceof THREE.Texture) {
return "sampler2D";
} else {
return;
return "invalid";
}
}

Expand All @@ -51,7 +51,8 @@ export function uniforms_to_type_declaration(uniform_dict) {
for (const name in uniform_dict) {
const uniform = uniform_dict[name];
const type = uniform_type(uniform);
result += `uniform ${type} ${name};\n`;
if (type != "invalid")
result += `uniform ${type} ${name};\n`;
}
return result;
}
Expand Down
Loading

0 comments on commit d777002

Please sign in to comment.