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

weird interplay between scale and lightposition #600

Closed
photor opened this issue May 12, 2020 · 8 comments
Closed

weird interplay between scale and lightposition #600

photor opened this issue May 12, 2020 · 8 comments
Labels
GLMakie This relates to GLMakie.jl, the OpenGL backend for Makie.

Comments

@photor
Copy link

photor commented May 12, 2020

I was drawing a surface plot of some configuration of a quantum system, using the following code:

using Makie
l = w = 30.0
p = m = 120
x=l*[(i-0.5)/p-0.5 for i = 1:p] #x ranges in (-15,15)
y=w*[(i-0.5)/m-0.5 for i = 1:m] #y ranges in (-15,15)
scene = Scene()
limits = FRect3D((-1.5, -1.5, 0), (3.0, 3.0, 2.5))
update_limits!(scene, limits)
z = ... #data of the configuration stored in a (120,120) array z, ranging in (0, 2.25)
surf = surface!(scene, x/10, y/10, z, colorrange=(-150,50))[end]
wf = wireframe!(scene, x/10, y/10, lift(x->x, surf[3]), transparency=true, color=(:black, 0.1))

Here I divided x and y by 10 because the ranges of x and y are much larger than z, and I didn't know how to use the scale! method at that time. Then the output was the following image, with a very nice shining effect:
shine
Later I knew the scale! method, so I revised the above code to the following one:

scene = Scene()
scale!(scene, (1,1,10))
limits = FRect3D((-15, -15, 0), (30, 30, 2.5))
update_limits!(scene, limits)
z = ... #data of the configuration stored in a (120,120) array z, ranging in (0, 2.25)
surf = surface!(scene, x, y, z, colorrange=(-150,50))[end]
wf = wireframe!(scene, x, y, lift(x->x, surf[3]), transparency=true, color=(:black, 0.1))

In this way, I can get the correct ticks on the x and y axes, but now the output becomes:
no_shine
The shining effect is gone. I realized that this result may be caused by an improper lightposition parameter, and I saw from somewhere that the default lightposition is Vec3f0(1,2,3), so maybe I should set a lightposition=Vec3f0(10,20,3) in the latter code? However, that proved to have no help (actually made the case even worse). I also tried various kinds of lightposition parameters, without any success. Any solutions suggested?

@SimonDanisch
Copy link
Member

Oh... that's likely because we don't scale the normals correctly...

@ffreyer
Copy link
Collaborator

ffreyer commented May 13, 2020

You could try generating and plotting a mesh instead of the surface plot

using GeometryBasics
vertices = Point3f0.(x, y, z)[:]
N, M = size(x)
lin = LinearIndices(x)
faces = [QuadFace(
    lin[i, j], lin[i+1, j], lin[i+1, j+1], lin[i, j+1]
) for i in 1:N-1 for j in 1:M-1]
m = normal_mesh(vertices, faces)
mesh!(scene, m, color=z)

If that fixes it then this is might also be a problem caused by using uv coordinates here.

@photor
Copy link
Author

photor commented May 13, 2020

You could try generating and plotting a mesh instead of the surface plot

using GeometryBasics
vertices = Point3f0.(x, y, z)[:]
N, M = size(x)
lin = LinearIndices(x)
faces = [QuadFace(
    lin[i, j], lin[i+1, j], lin[i+1, j+1], lin[i, j+1]
) for i in 1:N-1 for j in 1:M-1]
m = normal_mesh(vertices, faces)
mesh!(scene, m, color=z)

If that fixes it then this is might also be a problem caused by using uv coordinates here.

Thanks. Then I tried the follow code:

using Makie, GeometryBasics
function meshgrid(vx::AbstractVector{T}, vy::AbstractVector{T}) where {T}
vx'.+(a->0).(vy), (a->0).(vx').+vy
end
l = w = 30.0
p = m = 120
x=l*[(i-0.5)/p-0.5 for i = 1:p]
y=w*[(i-0.5)/m-0.5 for i = 1:m]
x,y=meshgrid(x,y)
z = ...
vertices = Point3f0.(x, y, z)[:]
N, M = size(z)
lin = LinearIndices(z)
faces = [QuadFace(
lin[i, j], lin[i+1, j], lin[i+1, j+1], lin[i, j+1]
) for i in 1:N-1 for j in 1:M-1]
scene=Scene()
scale!(scene, (1,1,10))
limits = FRect3D((-15, -15, 0), (30, 30, 2.5))
update_limits!(scene, limits)
surf = mesh!(scene, normal_mesh(vertices, faces), color = :orange)
wf = wireframe!(scene, x, y, z, transparency=true, color=(:black, 0.1))

and got the output:
mesh
which was not good. Even when I use the first method (dividing x and y by 10, without scale!) for mesh!, the case is no better:
mesh_by_10
Actually, when mesh! is used, it always seems that the light comes from below, and I can hardly change this situation by trying various kinds of lightposition parameters, weird. I also tried some simple functions, like cos(x^2+y^2), instead of my own data for mesh!, but the result is similar.

@photor
Copy link
Author

photor commented May 13, 2020

BTW, is there a simple way to get a single color plot using surface! ? The keyword argument like color=:orange used in mesh! doesn't work for surface!

@ffreyer
Copy link
Collaborator

ffreyer commented May 14, 2020

I think you can do colormap=(:green, :green).

The second mesh plot looks like the normals are inverted. If you do

faces = [QuadFace(
    lin[i, j], lin[i, j+1], lin[i+1, j+1], lin[i+1, j]
) for i in 1:N-1 for j in 1:M-1]

that should get fixed. But that doesn't solve your problem. I think Simon is right - there is something wrong with how GLMakie applies the scaling.

@ffreyer
Copy link
Collaborator

ffreyer commented May 14, 2020

I think this is already be fixed on the SSAO branches (regardless of whether you use SSAO). You could try with JuliaPlots/AbstractPlotting.jl#424 and JuliaPlots/GLMakie.jl#97.

@photor
Copy link
Author

photor commented May 14, 2020

I think you can do colormap=(:green, :green).

The second mesh plot looks like the normals are inverted. If you do

faces = [QuadFace(
    lin[i, j], lin[i, j+1], lin[i+1, j+1], lin[i+1, j]
) for i in 1:N-1 for j in 1:M-1]

that should get fixed. But that doesn't solve your problem. I think Simon is right - there is something wrong with how GLMakie applies the scaling.

Yes, you are right.

@asinghvi17 asinghvi17 added GLMakie This relates to GLMakie.jl, the OpenGL backend for Makie. lighting labels May 30, 2020
@ffreyer
Copy link
Collaborator

ffreyer commented May 31, 2021

Looks fine to me now, both with scaling the plot and scaling the scene.

@ffreyer ffreyer closed this as completed May 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GLMakie This relates to GLMakie.jl, the OpenGL backend for Makie.
Projects
None yet
Development

No branches or pull requests

4 participants