Use the 3d camera¶
By default the viewer will set a uniform block with all the camera and projection matrices for you, so you can navigate the view in 3d if you want.
//the ViewBlock that is automatically filled by ipywebgl layout(std140) uniform ViewBlock { mat4 u_cameraMatrix; //the camera matrix in world space mat4 u_viewMatrix; //the inverse of the camera matrix mat4 u_projectionMatrix; //the projection matrix mat4 u_viewProjectionMatrix; //the projection * view matrix };
By default the matrix will be sent as row major to the shader, but if you prefer you can work in column major.
use : w = ipywebgl.GLViewer(shader_matrix_major=’column_major’) to be in column major.
all the examples will be ‘row_major’ in this case.
Import¶
[1]:
import ipywebgl
import numpy as np
Create viewer¶
And clear the color to make the background visible.
[2]:
w = ipywebgl.GLViewer()
w.clear_color(.8, .8, .8 ,1)
w.clear()
w.execute_commands(execute_once=True)
Program¶
Create a program that will display a grid on the ground. And use the Camera (ViewProjection) to rotate the view
[3]:
program = w.create_program_ext(
"""#version 300 es
//the ViewBlock that is automatically filled by ipywebgl
layout(std140) uniform ViewBlock
{
mat4 u_cameraMatrix; //the camera matrix in world space
mat4 u_viewMatrix; //the inverse of the camera matrix
mat4 u_projectionMatrix; //the projection matrix
mat4 u_viewProjectionMatrix; //the projection * view matrix
};
in vec3 in_vert;
void main() {
gl_Position = u_viewProjectionMatrix * vec4(in_vert, 1.0);
}
"""
,
"""#version 300 es
precision highp float;
out vec4 f_color;
void main() {
f_color = vec4(0.1, 0.1, 0.1, 1.0);
}
""")
Grid vertex buffer¶
Create a grid vertex array. By creating a set of lines in X and Z. (Y is up in our viewport)
[10]:
def grid(size, steps):
u = np.repeat(np.linspace(-size, size, steps), 2)
v = np.tile([-size, size], steps)
w = np.zeros(steps * 2)
return np.concatenate([np.dstack([u, w, v]), np.dstack([v, w, u])], dtype=np.float32)
points = grid(100,20)
vbo = w.create_buffer_ext(
src_data=points
)
vao = w.create_vertex_array_ext(
program,
[
(vbo, '3f32', 'in_vert'),
]
)
[5]:
#number of points in the buffer :
points.reshape([-1,3]).shape
[5]:
(80, 3)
Render¶
Render the view, you can now interact with the view with your mouse (left click and drag) to rotate and the ‘wasd’ keys to move
if you need to change the default keys:
you can do it at init time with : GLViewer(move_keys=’ijkl’)
or runtime with : w.move_keys = ‘ijkl’
Any letters can be used.
[15]:
w.clear()
w.use_program(program)
w.bind_vertex_array(vao)
w.draw_arrays('LINES', 0, points.reshape([-1,3]).shape[0])
w.execute_commands()
w
[15]:
Interact with the camera from python¶
Let’s set the camera values using the python code
We can build a simple rotating camera control with an interact slider
[7]:
w.camera_pos, w.camera_pitch, w.camera_yaw
[7]:
([0, 50, 200], 0.0, 0.0)
[14]:
from ipywidgets import widgets, interact
def set_camera(angle):
rad = angle/180.0*np.pi
w.camera_pos = [np.sin(rad)*200, 70, np.cos(rad)*200]
w.camera_yaw = angle
w.camera_pitch = -20
interact(
set_camera,
angle=widgets.IntSlider(min=0, max=360, step=1, value=0),
)
w
[14]:
[11]:
w.verbose = 0