Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add depth to 3D contours and isosurfaces #1395

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions GLMakie/assets/shader/volume.frag
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ uniform int algorithm;
uniform float isovalue;
uniform float isorange;

uniform mat4 model, projectionview;

const float max_distance = 1.3;

const int num_samples = 200;
Expand Down Expand Up @@ -206,11 +208,17 @@ vec4 contours(vec3 front, vec3 dir)
vec3 Lo = vec3(0.0);
int i = 0;
vec3 camdir = normalize(-dir);
{{depth_init}}
// may write: float depth = 100000.0;
for (i; i < num_samples; ++i) {
float intensity = texture(volumedata, pos).x;
vec4 density = color_lookup(intensity, color_map, color_norm, color);
float opacity = density.a;
if(opacity > 0.0){
{{depth_main}}
// may write
// vec4 frag_coord = projectionview * model * vec4(pos, 1);
// depth = min(depth, frag_coord.z / frag_coord.w);
vec3 N = gennormal(pos, step_size);
vec3 L = normalize(o_light_dir - pos);
vec3 opaque = blinnphong(N, camdir, L, density.rgb);
Expand All @@ -221,6 +229,9 @@ vec4 contours(vec3 front, vec3 dir)
}
pos += dir;
}
{{depth_write}}
// may write:
// gl_FragDepth = depth == 100000.0 ? gl_FragDepth : 0.5 * depth + 0.5;
return vec4(Lo, 1-T);
}

Expand All @@ -231,9 +242,15 @@ vec4 isosurface(vec3 front, vec3 dir)
int i = 0;
vec4 diffuse_color = color_lookup(isovalue, color_map, color_norm, color);
vec3 camdir = normalize(-dir);
{{depth_init}}
// may write: float depth = 100000.0;
for (i; i < num_samples; ++i){
float density = texture(volumedata, pos).x;
if(abs(density - isovalue) < isorange){
{{depth_main}}
// may write:
// vec4 frag_coord = projectionview * model * vec4(pos, 1);
// depth = min(depth, frag_coord.z / frag_coord.w);
vec3 N = gennormal(pos, step_size);
vec3 L = normalize(o_light_dir - pos);
// back & frontface...
Expand All @@ -244,6 +261,9 @@ vec4 isosurface(vec3 front, vec3 dir)
}
pos += dir;
}
{{depth_write}}
// may write:
// gl_FragDepth = depth == 100000.0 ? gl_FragDepth : 0.5 * depth + 0.5;
return c;
}

Expand Down
25 changes: 24 additions & 1 deletion GLMakie/src/GLVisualize/visualize/image_like.jl
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,36 @@ function _default(main::VolumeTypes{T}, s::Style, data::Dict) where T <: VolumeE
absorption = 1f0
isovalue = 0.5f0
isorange = 0.01f0
shader = GLVisualizeShader("fragment_output.frag", "util.vert", "volume.vert", "volume.frag")
enable_depth = true
shader = GLVisualizeShader(
"fragment_output.frag", "util.vert", "volume.vert", "volume.frag",
view = Dict(
"depth_init" => vol_depth_init(to_value(enable_depth)),
"depth_main" => vol_depth_main(to_value(enable_depth)),
"depth_write" => vol_depth_write(to_value(enable_depth))
)
)
prerender = VolumePrerender(data[:transparency], data[:overdraw])
postrender = () -> glDisable(GL_CULL_FACE)
end
return data
end

vol_depth_init(enable) = enable ? "float depth = 100000.0;" : ""
function vol_depth_main(enable)
if enable
"""
vec4 frag_coord = projectionview * model * vec4(pos, 1);
depth = min(depth, frag_coord.z / frag_coord.w);
"""
else "" end
end
function vol_depth_write(enable)
if enable
"gl_FragDepth = depth == 100000.0 ? gl_FragDepth : 0.5 * depth + 0.5;"
else "" end
end

function _default(main::VolumeTypes{T}, s::Style, data::Dict) where T <: RGBA
@gen_defaults! data begin
volumedata = main => Texture
Expand Down
14 changes: 14 additions & 0 deletions GLMakie/test/glmakie_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,17 @@ end
set_window_config!(renderloop=GLMakie.renderloop)
fig
end

@cell "Contour and isosurface with correct depth" begin
# Make sure shaders can recompile
close(GLMakie.global_gl_screen())

fig = Figure()
left = LScene(fig[1, 1])
contour!(left, [sin(i+j) * sin(j+k) * sin(i+k) for i in 1:10, j in 1:10, k in 1:10], enable_depth = true)
mesh!(left, Sphere(Point3f(5), 6f0))
right = LScene(fig[1, 2])
volume!(right, [sin(2i) * sin(2j) * sin(2k) for i in 1:10, j in 1:10, k in 1:10], algorithm = :iso, enable_depth = true)
mesh!(right, Sphere(Point3f(5), 6f0))
fig
end
6 changes: 4 additions & 2 deletions src/basic_recipes/contours.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ $(ATTRIBUTES)
levels = 5,
linewidth = 1.0,
alpha = 1.0,
fillrange = false
fillrange = false,
enable_depth = true
)
end

Expand Down Expand Up @@ -114,7 +115,8 @@ function plot!(plot::Contour{<: Tuple{X, Y, Z, Vol}}) where {X, Y, Z, Vol}
plot, x, y, z, volume, colormap = cmap, colorrange = cliprange, algorithm = 7,
transparency = plot.transparency, overdraw = plot.overdraw,
ambient = plot.ambient, diffuse = plot.diffuse, lightposition = plot.lightposition,
shininess = plot.shininess, specular = plot.specular, inspectable = plot.inspectable
shininess = plot.shininess, specular = plot.specular, inspectable = plot.inspectable,
enable_depth = plot.enable_depth
)
end

Expand Down