Header menu logo Mibo.Raylib

Shaders

Shaders are GPU programs that transform vertices and determine pixel colors. They run on the graphics card in parallel, making them efficient for complex visual effects.

What They Are

Why Use Them

Use shaders when you need visual effects beyond what built-in rendering provides:

When to Write Them

You don't need custom shaders to start. Mibo.Raylib's built-in renderers work without them:

Write shaders when: - You have specific visual requirements - You need performance optimizations for your target hardware - You're building advanced rendering features

Loading Shaders

Shaders are GLSL strings loaded at runtime using Raylib.LoadShaderFromMemory or Raylib.LoadShader. There is no content pipeline — shaders are plain .fs/.vs files or embedded strings.

open Raylib_cs

// Load from file
let myShader = Raylib.LoadShader("shaders/vertex.vs", "shaders/fragment.fs")

// Or load from memory (GLSL strings)
let fragCode = """
#version 330
in vec2 fragTexCoord;
in vec4 fragColor;
out vec4 finalColor;

uniform vec4 tint;

void main() {
    vec4 texel = texture(texture0, fragTexCoord);
    finalColor = texel * tint;
}
"""

let myShader = Raylib.LoadShaderFromMemory(null, fragCode)

Setting Parameters

Set shader parameters using Raylib.SetShaderValue:

open System.Numerics
open System.Runtime.InteropServices
open Raylib_cs

// Set a float uniform
let loc = Raylib.GetShaderLocation(myShader, "tint")
let mutable value = 1.0f
use p = fixed &value
Raylib.SetShaderValue(myShader, loc, NativePtr.toVoidPtr p, ShaderUniformDataType.Float)

// Set a matrix uniform (no fixed needed)
let world = Matrix4x4.Identity
let matLoc = Raylib.GetShaderLocation(myShader, "world")
Raylib.SetShaderValueMatrix(myShader, matLoc, world)

Uniform Type

ShaderUniformDataType

float

ShaderUniformDataType.Float

Vector2

ShaderUniformDataType.Vec2

Vector3

ShaderUniformDataType.Vec3

Vector4

ShaderUniformDataType.Vec4

Matrix4x4

ShaderUniformDataType.Mat4

_IMPORTANT_: The project uses [<DisableRuntimeMarshalling>]. This affects how SetShaderValue works — see the critical warning below.

DisableRuntimeMarshalling and SetShaderValue

Because the project uses [<DisableRuntimeMarshalling>], you must use fixed + NativePtr.toVoidPtr when passing scalar, vector, or struct values to SetShaderValue. Passing raw values directly as void* arguments causes the runtime to treat the value itself as a memory address, leading to access violations.

DO NOT do this:

// WRONG — runtime treats the int value as a pointer address
Raylib.SetShaderValue(shader, loc, 1, ShaderUniformDataType.Int)

// WRONG — runtime treats the float value as a pointer address
Raylib.SetShaderValue(shader, loc, 0.5f, ShaderUniformDataType.Float)

// WRONG — runtime treats the Vector3 as a pointer address
Raylib.SetShaderValue(shader, loc, Vector3.One, ShaderUniformDataType.Vec3)

ALWAYS pin the value and pass a pointer:

open System.Runtime.InteropServices

let setShaderInt (shader: Shader) (loc: int) (value: int) =
    use p = fixed &value
    Raylib.SetShaderValue(shader, loc, NativePtr.toVoidPtr p, ShaderUniformDataType.Int)

let setShaderFloat (shader: Shader) (loc: int) (value: float32) =
    use p = fixed &value
    Raylib.SetShaderValue(shader, loc, NativePtr.toVoidPtr p, ShaderUniformDataType.Float)

let setShaderVec3 (shader: Shader) (loc: int) (value: Vector3) =
    use p = fixed &value
    Raylib.SetShaderValue(shader, loc, NativePtr.toVoidPtr p, ShaderUniformDataType.Vec3)

let setShaderVec4 (shader: Shader) (loc: int) (value: Vector4) =
    use p = fixed &value
    Raylib.SetShaderValue(shader, loc, NativePtr.toVoidPtr p, ShaderUniformDataType.Vec4)

Exceptions:

Where to Learn More

Shader binding contracts (what parameters each shader type expects) are documented in the rendering sections:

See also: raylib shaders documentation

val myShader: obj
val fragCode: string
namespace System
namespace System.Numerics
namespace System.Runtime
namespace System.Runtime.InteropServices
val loc: obj
val mutable value: float32
val p: nativeptr<float32>
val world: Matrix4x4
Multiple items
[<Struct>] type Matrix4x4 = new: value: Matrix3x2 -> unit + 1 overload member Equals: other: Matrix4x4 -> bool + 1 overload member GetDeterminant: unit -> float32 member GetElement: row: int * column: int -> float32 member GetHashCode: unit -> int member GetRow: index: int -> Vector4 member ToString: unit -> string member WithElement: row: int * column: int * value: float32 -> Matrix4x4 member WithRow: index: int * value: Vector4 -> Matrix4x4 static member ( * ) : value1: Matrix4x4 * value2: Matrix4x4 -> Matrix4x4 + 1 overload ...
<summary>Represents a 4x4 matrix.</summary>

--------------------
Matrix4x4 ()
Matrix4x4(value: Matrix3x2) : Matrix4x4
Matrix4x4(m11: float32, m12: float32, m13: float32, m14: float32, m21: float32, m22: float32, m23: float32, m24: float32, m31: float32, m32: float32, m33: float32, m34: float32, m41: float32, m42: float32, m43: float32, m44: float32) : Matrix4x4
property Matrix4x4.Identity: Matrix4x4 with get
<summary>Gets the multiplicative identity matrix.</summary>
<returns>Gets the multiplicative identity matrix.</returns>
val matLoc: obj
Multiple items
[<Struct>] type Vector3 = new: value: Vector2 * z: float32 -> unit + 3 overloads member CopyTo: array: float32 array -> unit + 2 overloads member Equals: other: Vector3 -> bool + 2 overloads member GetHashCode: unit -> int member Length: unit -> float32 member LengthSquared: unit -> float32 member ToString: unit -> string + 2 overloads member TryCopyTo: destination: Span<float32> -> bool static member (&&&) : left: Vector3 * right: Vector3 -> Vector3 static member ( * ) : left: Vector3 * right: Vector3 -> Vector3 + 2 overloads ...
<summary>Represents a vector with three single-precision floating-point values.</summary>

--------------------
Vector3 ()
Vector3(value: float32) : Vector3
Vector3(values: System.ReadOnlySpan<float32>) : Vector3
Vector3(value: Vector2, z: float32) : Vector3
Vector3(x: float32, y: float32, z: float32) : Vector3
property Vector3.One: Vector3 with get
<summary>Gets a vector whose 3 elements are equal to one.</summary>
<returns>A vector whose three elements are equal to one (that is, it returns the vector <code data-dev-comment-type="c">(1,1,1)</code>).</returns>
val setShaderInt: shader: 'a -> loc: int -> value: int -> 'b
val shader: 'a
val loc: int
Multiple items
val int: value: 'T -> int (requires member op_Explicit)

--------------------
type int = int32

--------------------
type int<'Measure> = int
val value: int
val p: nativeptr<int>
val setShaderFloat: shader: 'a -> loc: int -> value: float32 -> 'b
val value: float32
Multiple items
val float32: value: 'T -> float32 (requires member op_Explicit)

--------------------
type float32 = System.Single

--------------------
type float32<'Measure> = float32
val setShaderVec3: shader: 'a -> loc: int -> value: Vector3 -> 'b
val value: Vector3
val p: nativeptr<Vector3>
val setShaderVec4: shader: 'a -> loc: int -> value: Vector4 -> 'b
val value: Vector4
Multiple items
[<Struct>] type Vector4 = new: value: Vector2 * z: float32 * w: float32 -> unit + 4 overloads member CopyTo: array: float32 array -> unit + 2 overloads member Equals: other: Vector4 -> bool + 2 overloads member GetHashCode: unit -> int member Length: unit -> float32 member LengthSquared: unit -> float32 member ToString: unit -> string + 2 overloads member TryCopyTo: destination: Span<float32> -> bool static member (&&&) : left: Vector4 * right: Vector4 -> Vector4 static member ( * ) : left: Vector4 * right: Vector4 -> Vector4 + 2 overloads ...
<summary>Represents a vector with four single-precision floating-point values.</summary>

--------------------
Vector4 ()
Vector4(value: float32) : Vector4
Vector4(values: System.ReadOnlySpan<float32>) : Vector4
Vector4(value: Vector3, w: float32) : Vector4
Vector4(value: Vector2, z: float32, w: float32) : Vector4
Vector4(x: float32, y: float32, z: float32, w: float32) : Vector4
val p: nativeptr<Vector4>

Type something to start searching.