Skip to content
Jérôme Leclercq edited this page Aug 28, 2025 · 1 revision

NZSL Changelog

This changelog is dedicated to the shading language. For library & compiler, see releases.

NZSL 1.1

New features:

Untyped literals

Beginning with NZSL 1.1, integer and floating-point literals are no longer automatically typed as i32 and f32. They now are categorized into separate types (namely IntLiteral and FloatLiteral) that will be implicitly converted to the appropriate integer or floating-point type.

const VertexLocation: u32 = 0; //< this doesn't compile in NZSL 1.0 but compiles in NZSL 1.1
const VertexLocation: u32 = u32(0); //< this compile in NZSL 1.0 and NZSL 1.1
const VertexLocation: u32 = 0.0; //< this doesn't compile in both NZSL 1.0 and 1.1 (FloatLiteral cannot be cast to integer types)

Literals are resolved based on immediate context (const/variable declarations, function parameters, intrinsic constraints and for-range types). If no such context is available, they are resolved to f32 and i32 by default.

const Foo = 0; //< i32
const Bar: u32 = 1; //< u32
const Baz: u32 = -1; //< error: u32 cannot represent negative values

fn Qux()
{
    let x = min(1, u32(2)); //< 1 is resolved to u32 because "min" intrinsic requires that its parameters to be of the same type
    let lightCount: u32 = 4;
    for x in 0 -> lightCount //< NZSL 1.0 required an explicit cast from 0 to u32, NZSL 1.1 resolves 0 to u32 automatically
    {
    }
}

This change may break existing code, as attributes taking a u32 value (such as [set(x)], [binding(x)] and [location(x)]) no longer silently accept a i32 value.

option Loc: i32 = -1;

struct Foo
{
    [location(0)] //< valid in both NZSL 1.0 and NZSL 1.1
    x: i32,

    [location(Loc)] //< valid in NZSL 1.0 (if Loc is set to a positive value), forbidden in NZSL 1.1
    y: i32
}

Arrays, Matrix and Vector implicit type

It's now possible to declare a vector of any size without specifying its component type, following rules introduced with literal types.

let x = vec3(1.0, 2.0, 3.0); //< x is a vec3[f32]
let x = vec4(1, 2, u32(3), 4); //< x is a vec4[u32]
let x: vec2[f64] = vec2(1.0, 2.0); //< x is a vec2[f64]

This also works with arrays:

let x = 1.0;
let a = array(x, x, x); //< a is an array[f32, 3]

And you can of course combine those two:

const a = array(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 8, 9));

It works for matrices as well:

let x: f32 = 1.0;
let v = vec3[f64](-2.0, -1.0, 0.0);

let m1 = mat4(x); //< mat4[f32]
let m2 = mat3(m1); //< mat3[f32]
let m3 = mat2x3(x, x, x, x, x, x); //< mat2x3[f32]
let m4 = mat3(v, vec3(1.0, 2.0, 3.0), vec3(4.0, 5.0, 6.0)); //< mat3[f64]

Add type constants

Integer and floating-point primitive types support Max and Min constants, which are shortcut for their maximum and minimal representable value

Floating-point types additionally support Epsilon, Infinity, MinPositive and NaN constants.

fn main()
{
	let foo = f32.Epsilon;     // 1.192092896e-07
	let foo = f32.Max;         // 3.402823466e+38
	let foo = f32.Min;         // -3.402823466e+38
	let foo = f32.MinPositive; // 1.175494351e-38
	let foo = f32.Infinity;    // +inf
	let foo = f32.NaN;         // NaN
	
	let foo = f64.Epsilon;     // 2.2204460492503131e-016
	let foo = f64.Max;         // 1.7976931348623158e+308
	let foo = f64.Min;         // -1.7976931348623158e+308
	let foo = f64.MinPositive; // 2.2250738585072014e-308
	let foo = f64.Infinity;    // +inf
	let foo = f64.NaN;         // NaN

	let foo = i32.Max; // 2147483647
	let foo = i32.Min; // -2147483648

	let foo = u32.Max; // 4294967295
	let foo = u32.Min; // 0
}

Support for scalar layout

Implemented by @exdal

This layout aligns values only to the scalar components of the block and its composite members.

[layout(scalar)]
struct Foo
{
	v0: vec3[f32], //< offset 0
	v1: vec3[f32]  //< offset 12
}

Support for nested block comments

Lexing block comment (/* */) has been improved, as ending nested blocks will no longer affect the whole context.

/* We begin a block comment

  /* And another one

  */ //< end of block comment in NZSL 1.0

*/ //< end of block comment in NZSL 1.1

NZSL 1.0

Initial release.

Clone this wiki locally