I built my own Shader Language
Source: Dev.to
Coordinate Spaces
In standard GLSL, a vec4 is just a vec4. The compiler doesn’t know whether that vector represents a position in World Space, Model Space, or Clip Space. Accidentally multiplying a view‑space vector by a model matrix won’t produce a compile‑time error; instead you get a black screen or incorrect lighting and spend time debugging the mix‑up.
Main Idea
Cast introduces strong typing for coordinate spaces:
// Cast syntax
let modelPos : vec4 = ...;
let matrix : mat4 = ...;
// This works because the types match
let worldPos = matrix * modelPos;
// This would throw a compiler error
let wrong = projectionMatrix * modelPos;
By encoding the space in the type ( , , etc.), the compiler can verify that matrix‑vector multiplications are semantically correct.
Cleaning up the Syntax
Typical GLSL expression:
max(pow(dot(N, L), 32.0), 0.0)
Reading it from inside out can be cumbersome. Cast proposes a left‑to‑right, method‑chain style:
N.dot(L).pow(32.0).max(0.0)
Adding New Features
Receiver Types (inspired by Go)
Go example:
type SomeStruct struct {
width, height int
}
func (r *SomeStruct) SomeFunction() { ... }
Cast adopts a similar pattern:
struct SomeStruct { x: float, y: float }
fn (SomeStruct) SomeFunction() { ... }
Structured Uniform/IO Blocks
To keep shader files organized, Cast allows grouping of uniforms, inputs, and outputs:
uniform {
// uniform declarations
}
in {
// input declarations
}
out {
// output declarations
}
Current Status
Cast is currently a Proof of Concept. It is not production‑ready; many standard features are missing, and the compiler may crash under certain conditions.
Call for Feedback
The concepts—explicit coordinate spaces, method‑chain syntax, and receiver types—are open for discussion. Feedback on the syntax and architecture is welcome. Feel free to check out the source code, open an issue, or share thoughts on the matrix‑multiplication approach.