JuliaGL / GLVisualize.jl

Visualization library written in Julia and OpenGL
Other
247 stars 34 forks source link

Rendering spheres with transparency #158

Open Cody-G opened 7 years ago

Cody-G commented 7 years ago

I've been rendering a rotating group of spheres with the perspective camera. I make the spheres somewhat transparent using the alpha value of the color that I assign, and I've noticed that the perspective and transparency combine in an unexpected way. I'm not sure this is a bug, but I'm not sure what I should do about it. You can see the issue by running the script below. Notice that the spheres that look smaller (so should be farther away) sometimes appear like they are in front of the larger, closer spheres. My best explanation is that the alpha value is applied as a surface density, so that distant spheres, which are smaller on-screen, have a higher alpha density on-screen so they are effectively less transparent. Does that make sense? Does anyone know how I could make this look more natural? I suppose I could set the alpha value dynamically based on distance from the camera, but I'm hoping there is an easier way.

using GLVisualize, GeometryTypes, Reactive, GLAbstraction, Colors
using Quaternions

ncolors = 5
cols = distinguishable_colors(ncolors)
eyepos = Vec3f0(300)
lookat = Vec3f0(0)
num_neurons = 100
col_idxs = zeros(Int,num_neurons)
nsamps = 200
space_sz = (221,241,139)
ctr = Vec3f0(space_sz)./2
cellradius = 10.0f0
angles = linspace(0.0f0, 2*pi, nsamps)
res = (800,600)
locs = []
spheres = []
window = glscreen(resolution=res, color=RGBA(0,0,0,0))
allcells = Array(GLAbstraction.Context{GLAbstraction.DeviceUnit},num_neurons)
cam = PerspectiveCamera(window.inputs, eyepos, lookat)
model = Signal(eye(Mat4f0))

#random locations, centered on origin, density changes continuously from corner-to-corner
for i = 1:num_neurons
    push!(locs, Vec3f0(map(x->(rand(1:sqrt(x)))^2, space_sz))-ctr)
end

for i = 1:num_neurons
    #assign location in space
    s = Sphere(Point(locs[i]), cellradius)
    push!(spheres, s)
    cell = GLNormalMesh(spheres[i], 24)
    #assign a random color
    col_idxs[i] = rand(1:ncolors)
    c = cols[col_idxs[i]]
    v = visualize(cell, color= RGBA{Float32}(red(c), green(c), blue(c), 0.5f0), model=model)
    allcells[i] = v
    _view(v, window, camera=cam)
end

@async renderloop(window)
t = 1
m =
while isopen(window)
    push!(model, rotationmatrix_z(angles[mod1(t, nsamps)]))
    yield()
    ModernGL.glFinish()
    sleep(0.1)
    t += 1
end
GLWindow.destroy!(window)
SimonDanisch commented 7 years ago

Sorry about that... I should have a section about this - transparency is currently not fully implement ( since it is surprisingly hard to get performance + good looks) I've implement a nice approximative approach on a branch, which i need to refactor!

On 23 Mar 2017 21:19, "Cody Greer" notifications@github.com wrote:

I've been rendering a rotating group of spheres with the perspective camera. I make the spheres somewhat transparent using the alpha value of the color that I assign, and I've noticed that the perspective and transparency combine in an unexpected way. I'm not sure this is a bug, but I'm not sure what I should do about it. You can see the issue by running the script below. Notice that the spheres that look smaller (so should be farther away) sometimes appear like they are in front of the larger, closer spheres. My best explanation is that the alpha value is applied as a surface density, so that distant spheres, which are smaller on-screen, have a higher alpha density on-screen so they are effectively less transparent. Does that make sense? Does anyone know how I could make this look more natural? I suppose I could set the alpha value dynamically based on distance from the camera, but I'm hoping there is an easier way.

using GLVisualize, GeometryTypes, Reactive, GLAbstraction, Colorsusing Quaternions

ncolors = 5 cols = distinguishable_colors(ncolors) eyepos = Vec3f0(300) lookat = Vec3f0(0) num_neurons = 100 col_idxs = zeros(Int,num_neurons) nsamps = 200 space_sz = (221,241,139) ctr = Vec3f0(space_sz)./2 cellradius = 10.0f0 angles = linspace(0.0f0, 2*pi, nsamps) res = (800,600) locs = [] spheres = [] window = glscreen(resolution=res, color=RGBA(0,0,0,0)) allcells = Array(GLAbstraction.Context{GLAbstraction.DeviceUnit},num_neurons) cam = PerspectiveCamera(window.inputs, eyepos, lookat) model = Signal(eye(Mat4f0))

random locations, centered on origin, density changes continuously

from corner-to-cornerfor i = 1:num_neurons push!(locs, Vec3f0(map(x->(rand(1:sqrt(x)))^2, space_sz))-ctr)end for i = 1:num_neurons

assign location in space

s = Sphere(Point(locs[i]), cellradius)
push!(spheres, s)
cell = GLNormalMesh(spheres[i], 24)
#assign a random color
col_idxs[i] = rand(1:ncolors)
c = cols[col_idxs[i]]
v = visualize(cell, color= RGBA{Float32}(red(c), green(c),

blue(c), 0.5f0), model=model) allcells[i] = v _view(v, window, camera=cam)end @async renderloop(window) t = 1 m =while isopen(window) push!(model, rotationmatrix_z(angles[mod1(t, nsamps)])) yield() ModernGL.glFinish() sleep(0.1) t += 1end GLWindow.destroy!(window)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/JuliaGL/GLVisualize.jl/issues/158, or mute the thread https://github.com/notifications/unsubscribe-auth/AA9rI4tFIj-9EUbU037TOF4Bnl7wJRK0ks5rotPhgaJpZM4MnTyr .

Cody-G commented 7 years ago

Cool no worries! Let me know if I can help test things out. I'll be using this package more often in the coming weeks.

Also an off-topic question: I'm going to explore controlling a GLVisualize window with widgets from GtkReactive. I don't have any specific questions because I haven't started yet, but do you envision any pitfalls with that? I do realize that you have some widgets already built into GLVisualize, but I like the generality of GTK. That said, if you envision problems with interface or performance I might adjust my strategy accordingly...