Drawing meshes
Thus far we’ve only been drawing full-screen fragment shaders. This is great for post-processing effects or sdf art, but what if we want to draw a mesh?
Drawing a cube
You should see the sillouette of a cube on a gray background. Let’s break it down:
draw(Mesh, shader, shader)
is a function that takes a mesh, a vertex shader, and a fragment shader and draws it to the screen.- The first
shader { ... }
on line 8 is the vertex shader. It’s run once for each vertex in the mesh. It’s job is to transform the vertex’s position from model space to screen space. More on this later. - The second
shader { ... }
on line 14 is the fragment shader. You’ve seen this before, but in this case it’s run once for each pixel in the mesh. It’s job is to output a color for each pixel. - The
getCombinedMatrix
call will be explained below.
You can also move the camera around by click and dragging. The env.camera
is controlled like so:
- orbit mode (default):
Left click drag
: Rotate the camera around the originMiddle click drag
: Pan the cameraScroll
: Zoom in and out
- free mode (hold right click to unlock):
WASD
: Move the cameraRight click drag
: Rotate the cameraRight click hold + Scroll
: Incrase/decrease movement speedE/Q
: Move up/downC/Z
: Adjust fov
Vertex shaders and matrices
The vertex shader’s main job is to turn a vertex’s position from model space to clip space (a 2d screen coordinate). Typically this is done by multiplying the vertex’s position by a 4d matrix that contains teh necessary transformations. I won’t go into detail about how this works here but I’d suggest reading this article if you’re interested.
For now I’ll just outline some of the built-in shadeup helpers for this:
env.camera.getCombinedMatrix() -> float4x4
Returns a 4d matrix that transforms a vertex’s position from world space to clip space. This is the matrix that you’ll want to multiply your vertex’s position by in your vertex shader.
env.camera.getProjectionMatrix() -> float4x4
Returns a 4d matrix that transforms a vertex’s position from camera space to clip space. This is one part of the combined matrix.
env.camera.getViewMatrix() -> float4x4
Returns a 4d matrix that transforms a vertex’s position from world space to camera space. This is the other part of the combined matrix.
matrix::perspective(fov: float, aspect: float, near: float, far: float) -> float4x4
Returns a 4d matrix that transforms a vertex’s position from camera space to clip space. This is called internally by the camera.
env.camera.getOrthographicMatrix() -> float4x4
Returns a 4d matrix that transforms a vertex’s position from camera space to clip space. This is an alternate projection that doesn’t apply perspective.
Diffuse lighting
You should see a cube with a light source coming from the top right.
Diffuse lighting takes into account the angle between the surface normal and the light direction. The angle is calculated using the dot product. The dot product is a mathematical operation that returns a value between -1 and 1. If the two vectors are pointing in the same direction the dot product will be 1. If they’re pointing in opposite directions the dot product will be -1. If they’re perpendicular the dot product will be 0.
Other meshes
For more information on the built-in mesh helpers see the mesh module.