Posts
Search
Contact
Cookies
About
RSS

Lighting with raylib

Added 11 Jun 2019, 6:57 p.m. edited 18 Jun 2023, 7:20 p.m.

Initially I wasn't going to release this until I could find someone to go over the shader calculations, but while they are probably not "correct" it certainly works... so.... Lets look how we can implement some simple lighting using a shader.

https://www.youtube.com/watch?v=W_DdgtxhXHc

As well as code for the above example, I've also taken the time to code an example with the absolute minimum needed to show lighting with a shader, its this code that I'll describe here. Once you understand the basics of what is going on with the minimal example the main example will be simple to understand (honest its all actually straight forward) I'm assuming at least a basic understanding of raylib itself and I won't actually be detailing the shader code - but do feel free to fix it for me ;)

First of all we need to load our shader

Shader shader = LoadShader("data/simpleLight.vs", "data/simpleLight.fs");
shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
shader.locs[LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");

Shaders often have a number of common parameters, and indeed raylib helps us out by having a number of "standard" parameters, we're using just two here, the matrix that represents the orientation of the model and the position of the view (camera)

We also have a custom parameter that we're using, simply the level of ambient light, which we're just setting and leaving

int amb = GetShaderLocation(shader, "ambient");
SetShaderValue(shader, amb, (float[4]){0.2,0.2,0.2,1.0}, UNIFORM_VEC4);

The final set up step is to set the models shader to our shader and setup a light

model.materials[0].shader = shader;

Light light = CreateLight(LIGHT_POINT, (Vector3){ 2,2,0 }, Vector3Zero(), WHITE, shader);

You can have up to four lights (see the main example), when creating a light we specify the type, position, target, colour and the shader for the light. Note that for point light the target is irrelevant.

Each frame when doing our update, if we're not moving the lights about all we need update is the view position, you can either parcel the position into an array of 3 floats, or as the position structure is 3 floats you can just directly point to that.

SetShaderValue(shader, shader.locs[LOC_VECTOR_VIEW], &camera.position.x, UNIFORM_VEC3);

If you do change any of the light properties then you will need to update the light (here the lights are in an array of Lights)

UpdateLightValues(shader, lights[0]);

The model rendering is just as you would normally do it, nothing special needs to be done, everything is done in our setup and update, this means it is trivial just to get your model rendering normally without lighting and drop in the extra code to set up lighting and you're done!

You can get the source code here

Enjoy!