raylib/ports/shaders
Licence This example has its own licence, rather than Odin's: raylib/ports/LICENSE
These are ported Raylib examples, and as such, they are subject to Raylib's license.
Copyright (c) 2013-2024 Ramon Santamaria (@raysan5)
The rest of the licence
This software is provided "as-is", without any express or implied warranty. In no event
will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you
wrote the original software. If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented
as being the original software.
3. This notice may not be removed or altered from any source distribution.
Code
shaders_mesh_instancing.odin ¶85 linesSource
1package main
2
3import "rlights"
4
5import rl "vendor:raylib"
6
7MAX_INSTANCES :: 10_000
8
9main :: proc() {
10 screenWidth :: 800
11 screenHeight :: 450
12
13 rl.InitWindow(screenWidth, screenHeight, "raylib [shaders] example - mesh instancing")
14 defer rl.CloseWindow()
15
16 camera := rl.Camera{
17 position = { -125, 125, -125 },
18 target = 0,
19 up = { 0, 1, 0 },
20 fovy = 45,
21 projection = .PERSPECTIVE,
22 }
23
24 cube := rl.GenMeshCube(1, 1, 1)
25
26 transforms := make([]rl.Matrix, MAX_INSTANCES)
27 defer delete(transforms)
28
29 for i in 0..<MAX_INSTANCES {
30 translation := rl.MatrixTranslate(f32(rl.GetRandomValue(-50, 50)), f32(rl.GetRandomValue(-50, 50)), f32(rl.GetRandomValue(-50, 50)))
31 axis := rl.Vector3Normalize({f32(rl.GetRandomValue(0, 360)), f32(rl.GetRandomValue(0, 360)), f32(rl.GetRandomValue(0, 360))})
32 angle := f32(rl.GetRandomValue(0, 10)) * f32(rl.DEG2RAD)
33 rotation := rl.MatrixRotate(axis, angle)
34
35 transforms[i] = rotation * translation
36 }
37
38 shader := rl.LoadShader("resources/shaders/lighting_instancing.vs", "resources/shaders/lighting.fs")
39 defer rl.UnloadShader(shader)
40
41 shader.locs[rl.ShaderLocationIndex.MATRIX_MVP] = i32(rl.GetShaderLocation(shader, "mvp"))
42 shader.locs[rl.ShaderLocationIndex.VECTOR_VIEW] = i32(rl.GetShaderLocation(shader, "viewPos"))
43 shader.locs[rl.ShaderLocationIndex.MATRIX_MODEL] = i32(rl.GetShaderLocationAttrib(shader, "instanceTransform"))
44
45 ambientLoc := rl.GetShaderLocation(shader, "ambient")
46 rl.SetShaderValue(shader, ambientLoc, &[4]f32{ 0.2, 0.2, 0.2, 1 }, .VEC4)
47
48 rlights.CreateLight(.Directional, { 50, 50, 0 }, 0, rl.WHITE, shader)
49
50 matInstances := rl.LoadMaterialDefault()
51 matInstances.shader = shader
52 matInstances.maps[rl.MaterialMapIndex.ALBEDO].color = rl.RED
53
54 matDefault := rl.LoadMaterialDefault()
55 matDefault.maps[rl.MaterialMapIndex.ALBEDO].color = rl.BLUE
56
57 rl.SetTargetFPS(60)
58
59 for !rl.WindowShouldClose() {
60 rl.UpdateCamera(&camera, .ORBITAL)
61
62 cameraPos := [3]f32{ camera.position.x, camera.position.y, camera.position.z }
63 rl.SetShaderValue(shader, rl.ShaderLocationIndex(shader.locs[rl.ShaderLocationIndex.VECTOR_VIEW]), &cameraPos, .VEC3)
64
65 {
66 rl.BeginDrawing()
67 defer rl.EndDrawing()
68
69 rl.ClearBackground(rl.RAYWHITE)
70
71 {
72 rl.BeginMode3D(camera)
73 defer rl.EndMode3D()
74
75 rl.DrawMesh(cube, matDefault, rl.MatrixTranslate(-10, 0, 0))
76
77 rl.DrawMeshInstanced(cube, matInstances, raw_data(transforms), MAX_INSTANCES)
78
79 rl.DrawMesh(cube, matDefault, rl.MatrixTranslate(10, 0, 0))
80 }
81
82 rl.DrawFPS(10, 10)
83 }
84 }
85}
Shaders
resources/shaders/lighting.fs ¶76 linesSource
#version 330
// Input vertex attributes (from vertex shader)
in vec3 fragPosition;
in vec2 fragTexCoord;
//in vec4 fragColor;
in vec3 fragNormal;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// NOTE: Add here your custom variables
#define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1
struct Light {
int enabled;
int type;
vec3 position;
vec3 target;
vec4 color;
};
// Input lighting values
uniform Light lights[MAX_LIGHTS];
uniform vec4 ambient;
uniform vec3 viewPos;
void main()
{
// Texel color fetching from texture sampler
vec4 texelColor = texture(texture0, fragTexCoord);
vec3 lightDot = vec3(0.0);
vec3 normal = normalize(fragNormal);
vec3 viewD = normalize(viewPos - fragPosition);
vec3 specular = vec3(0.0);
// NOTE: Implement here your fragment shader code
for (int i = 0; i < MAX_LIGHTS; i++)
{
if (lights[i].enabled == 1)
{
vec3 light = vec3(0.0);
if (lights[i].type == LIGHT_DIRECTIONAL)
{
light = -normalize(lights[i].target - lights[i].position);
}
if (lights[i].type == LIGHT_POINT)
{
light = normalize(lights[i].position - fragPosition);
}
float NdotL = max(dot(normal, light), 0.0);
lightDot += lights[i].color.rgb*NdotL;
float specCo = 0.0;
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(light), normal))), 16.0); // 16 refers to shine
specular += specCo;
}
}
finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
finalColor += texelColor*(ambient/10.0)*colDiffuse;
// Gamma correction
finalColor = pow(finalColor, vec4(1.0/2.2));
}
resources/shaders/lighting_instancing.vs ¶36 linesSource
#version 330
// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec3 vertexNormal;
//in vec4 vertexColor; // Not required
in mat4 instanceTransform;
// Input uniform values
uniform mat4 mvp;
uniform mat4 matNormal;
// Output vertex attributes (to fragment shader)
out vec3 fragPosition;
out vec2 fragTexCoord;
out vec4 fragColor;
out vec3 fragNormal;
// NOTE: Add here your custom variables
void main()
{
// Compute MVP for current instance
mat4 mvpi = mvp*instanceTransform;
// Send vertex attributes to fragment shader
fragPosition = vec3(mvpi*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
//fragColor = vertexColor;
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
// Calculate final vertex position
gl_Position = mvpi*vec4(vertexPosition, 1.0);
}
Declarations Used 33
- vendor:raylib BeginDrawing · BeginMode3D · BLUE · Camera · ClearBackground · CloseWindow · DEG2RAD · DrawFPS · DrawMesh · DrawMeshInstanced · EndDrawing · EndMode3D · GenMeshCube · GetRandomValue · GetShaderLocation · GetShaderLocationAttrib · InitWindow · LoadMaterialDefault · LoadShader · MaterialMapIndex · Matrix · MatrixRotate · MatrixTranslate · RAYWHITE · RED · SetShaderValue · SetTargetFPS · ShaderLocationIndex · UnloadShader · UpdateCamera · Vector3Normalize · WHITE · WindowShouldClose