Project: hShadertoy GLSL to OpenCL Transpiler Target: GLSL ES 3.0 -> OpenCL C 1.2 Last Updated: 2025-11-20 Status: Production - Matrix Struct Refactor Complete + Full Struct Support
GLSL Source Code
|
v
[Parser] tree-sitter-glsl
|
v
GLSL AST (tree-sitter nodes)
|
v
[Analyzer] TypeChecker + SymbolTable
|
v
[Transformer] ASTTransformer (1300 lines)
|
v
Transformed AST (IR nodes)
|
v
[Code Generator] OpenCLEmitter (640 lines)
|
v
OpenCL C Code
Parser (src/glsl_to_opencl/parser/)
Analyzer (src/glsl_to_opencl/analyzer/)
TypeChecker: Type inference and validationSymbolTable: Variable and function trackingTransformer (src/glsl_to_opencl/transformer/)
ASTTransformer: Main transformation logic (single-pass visitor)transformed_ast.py: IR node definitions (immutable dataclasses)code_emitter.py: Legacy emitter (retained for compatibility)Code Generator (src/glsl_to_opencl/codegen/)
OpenCLEmitter: Production code generatorRuntime Library (houdini/ocl/include/)
glslHelpers.h: GLSL built-in functions (47 functions, overloadable)matrix_types.h: Struct-based matrix types (matrix2x2/3x3/4x4)matrix_ops.h: Matrix operations (mul, transpose, inverse, determinant)from src.glsl_to_opencl.parser import parse_glsl
ast = parse_glsl(glsl_source)
from src.glsl_to_opencl.analyzer import TypeChecker, create_builtin_symbol_table
symbol_table = create_builtin_symbol_table()
type_checker = TypeChecker(symbol_table)
from src.glsl_to_opencl.transformer import ASTTransformer
transformer = ASTTransformer(type_checker)
transformed_ast = transformer.transform(ast)
from src.glsl_to_opencl.codegen import OpenCLEmitter
emitter = OpenCLEmitter()
opencl_code = emitter.emit(transformed_ast)
| GLSL | OpenCL | Notes | |——|——–|——-| | float | float | Unchanged | | int | int | Unchanged | | uint | uint | Unchanged | | bool | bool | Unchanged (OpenCL: int internally) | | void | void | Unchanged |
| GLSL Type | OpenCL Type | Notes | |———–|————-|——-| | vec2/3/4 | float2/3/4 | Float vectors | | ivec2/3/4 | int2/3/4 | Integer vectors | | uvec2/3/4 | uint2/3/4 | Unsigned vectors | | bvec2/3/4 | int2/3/4 | Boolean vectors (as ints) |
Key Design Decision: All matrices use struct types that can be returned by value.
| GLSL Type | OpenCL Type | C Definition | Layout |
|---|---|---|---|
| mat2 | matrix2x2 | struct { float2 cols[2]; } |
Column-major, 2x2 |
| mat3 | matrix3x3 | struct { float3 cols[3]; } |
Column-major, 3x3 |
| mat4 | matrix4x4 | struct { float4 cols[4]; } |
Column-major, 4x4 |
Supported: Full GLSL struct support with OpenCL typedef struct transformation.
Struct Definition:
// GLSL
struct Geo {
vec3 pos;
vec3 scale;
vec3 rotation;
};
// OpenCL
typedef struct {
float3 pos;
float3 scale;
float3 rotation;
} Geo;
Features:
float t, d;)Limitation: Matrix types in struct fields are architecturally supported but not extensively tested (see Known Limitations).
Memory Layout (Column-Major):
// mat2 - 2 columns of float2
matrix2x2 M2;
M2.cols[0] = (float2)(m00, m10); // Column 0: [m00, m10]
M2.cols[1] = (float2)(m01, m11); // Column 1: [m01, m11]
// mat3 - 3 columns of float3
matrix3x3 M3;
M3.cols[0] = (float3)(m00, m10, m20);
M3.cols[1] = (float3)(m01, m11, m21);
M3.cols[2] = (float3)(m02, m12, m22);
// mat4 - 4 columns of float4
matrix4x4 M4;
M4.cols[0] = (float4)(m00, m10, m20, m30);
M4.cols[1] = (float4)(m01, m11, m21, m31);
M4.cols[2] = (float4)(m02, m12, m22, m32);
M4.cols[3] = (float4)(m03, m13, m23, m33);
Why Structs?
typedef fpreal3 mat3[3] required complex out-parameter transformationsmatrix3x3 result = GLSL_transpose_mat3(M);All precision qualifiers are removed during transformation:
highp, mediump, lowp -> (stripped)Float Literals - Add ‘f’ suffix
// GLSL
1.0, 0.5, .5, 3.14159
// OpenCL
1.0f, 0.5f, .5f, 3.14159f
Integer Literals - Unchanged
1, 42, 0xFF -> 1, 42, 0xFF
Boolean Literals - Unchanged
true, false -> true, false
Vector Constructors - Cast syntax
// GLSL
vec2(1.0, 2.0)
vec3(0.0)
vec4(v3, 1.0)
vec4(v2a, v2b)
// OpenCL
(float2)(1.0f, 2.0f)
(float3)(0.0f)
(float4)(v3, 1.0f)
(float4)(v2a, v2b)
Matrix Constructors - Diagonal (single scalar)
// GLSL
mat2(1.0)
mat3(1.0)
mat4(1.0)
// OpenCL
GLSL_matrix2x2_diagonal(1.0f)
GLSL_matrix3x3_diagonal(1.0f)
GLSL_matrix4x4_diagonal(1.0f)
Matrix Constructors - Full (all elements, column-major)
// GLSL
mat2(1, 2, 3, 4)
mat3(1,0,0, 0,1,0, 0,0,1)
mat4(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)
// OpenCL
GLSL_mat2(1.0f, 2.0f, 3.0f, 4.0f)
GLSL_mat3(1.0f,0.0f,0.0f, 0.0f,1.0f,0.0f, 0.0f,0.0f,1.0f)
GLSL_mat4(1.0f,0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f,0.0f, 0.0f,0.0f,1.0f,0.0f, 0.0f,0.0f,0.0f,1.0f)
Matrix Constructors - From columns
// GLSL
mat2(vec2(1,2), vec2(3,4))
mat3(vec3(1,0,0), vec3(0,1,0), vec3(0,0,1))
mat4(vec4(...), vec4(...), vec4(...), vec4(...))
// OpenCL
GLSL_mat2_cols((float2)(1.0f,2.0f), (float2)(3.0f,4.0f))
GLSL_mat3_cols((float3)(1.0f,0.0f,0.0f), (float3)(0.0f,1.0f,0.0f), (float3)(0.0f,0.0f,1.0f))
GLSL_mat4_cols(...)
Matrix Type Casting
// GLSL
mat4(mat3_var)
mat3(mat4_var)
// OpenCL
GLSL_mat4_from_mat3(mat3_var)
GLSL_mat3_from_mat4(mat4_var)
Struct Constructors - Compound literal syntax
// GLSL
struct Geo { vec3 pos; vec3 scale; vec3 rotation; };
Geo g = Geo(vec3(0), vec3(1), vec3(0));
struct Ray { vec3 o, d; };
Ray r = Ray(vec3(0,0,0), vec3(1,0,0));
// OpenCL
typedef struct { float3 pos; float3 scale; float3 rotation; } Geo;
Geo g = {(float3)(0), (float3)(1), (float3)(0)};
typedef struct { float3 o, d; } Ray;
Ray r = {(float3)(0.0f, 0.0f, 0.0f), (float3)(1.0f, 0.0f, 0.0f)};
Note: Struct constructors use C99 compound literal syntax { arg1, arg2, ... } instead of cast syntax.
Function Name Transformation - Add GLSL_ prefix
All 47 GLSL built-in functions map to GLSL_*() overloadable functions:
Trigonometric:
sin(x) -> GLSL_sin(x)
cos(x) -> GLSL_cos(x)
tan(x) -> GLSL_tan(x)
asin(x) -> GLSL_asin(x)
acos(x) -> GLSL_acos(x)
atan(x) -> GLSL_atan(x)
atan(y,x) -> GLSL_atan(y,x)
Hyperbolic:
sinh(x) -> GLSL_sinh(x)
cosh(x) -> GLSL_cosh(x)
tanh(x) -> GLSL_tanh(x)
asinh(x) -> GLSL_asinh(x)
acosh(x) -> GLSL_acosh(x)
atanh(x) -> GLSL_atanh(x)
Exponential/Power:
pow(x,y) -> GLSL_pow(x,y)
exp(x) -> GLSL_exp(x)
log(x) -> GLSL_log(x)
exp2(x) -> GLSL_exp2(x)
log2(x) -> GLSL_log2(x)
sqrt(x) -> GLSL_sqrt(x)
inversesqrt(x)-> GLSL_inversesqrt(x)
Common/Math:
abs(x) -> GLSL_abs(x)
sign(x) -> GLSL_sign(x)
floor(x) -> GLSL_floor(x)
ceil(x) -> GLSL_ceil(x)
trunc(x) -> GLSL_trunc(x)
fract(x) -> GLSL_fract(x) // x - floor(x)
mod(x,y) -> GLSL_mod(x,y) // x - y*floor(x/y), NOT remainder!
modf(x, out i) -> GLSL_modf(x, &i) // out parameter
min(x,y) -> GLSL_min(x,y)
max(x,y) -> GLSL_max(x,y)
clamp(x,a,b) -> GLSL_clamp(x,a,b)
mix(a,b,t) -> GLSL_mix(a,b,t)
step(edge,x) -> GLSL_step(edge,x)
smoothstep(a,b,x) -> GLSL_smoothstep(a,b,x)
Geometric:
length(v) -> GLSL_length(v)
distance(a,b) -> GLSL_distance(a,b)
dot(a,b) -> GLSL_dot(a,b)
cross(a,b) -> GLSL_cross(a,b)
normalize(v) -> GLSL_normalize(v)
faceforward(N,I,Nref)-> GLSL_faceforward(N,I,Nref)
reflect(I,N) -> GLSL_reflect(I,N)
refract(I,N,eta) -> GLSL_refract(I,N,eta)
Angle Conversion:
radians(deg) -> GLSL_radians(deg)
degrees(rad) -> GLSL_degrees(rad)
Derivatives (Dummy Placeholders):
dFdx(x) -> GLSL_dFdx(x) // Returns input unchanged
dFdy(x) -> GLSL_dFdy(x) // Returns input unchanged
fwidth(x) -> GLSL_fwidth(x) // Returns input unchanged
Note: OpenCL has no derivative hardware outside fragment shaders
Matrix Functions:
mat2 uses base function names, mat3/mat4 use suffixes:
// mat2
transpose(M2) -> GLSL_transpose(M2)
inverse(M2) -> GLSL_inverse(M2)
determinant(M2)->GLSL_determinant(M2)
// mat3
transpose(M3) -> GLSL_transpose_mat3(M3)
inverse(M3) -> GLSL_inverse_mat3(M3)
determinant(M3)->GLSL_determinant_mat3(M3)
// mat4
transpose(M4) -> GLSL_transpose_mat4(M4)
inverse(M4) -> GLSL_inverse_mat4(M4)
determinant(M4)->GLSL_determinant_mat4(M4)
All functions are overloadable - Support float, float2, float3, float4 variants automatically.
Critical: Matrix multiplication requires type-specific function names.
Matrix * Vector - Column vector
// GLSL
mat2 M2; vec2 v2;
vec2 result = M2 * v2;
mat3 M3; vec3 v3;
vec3 result = M3 * v3;
mat4 M4; vec4 v4;
vec4 result = M4 * v4;
// OpenCL
matrix2x2 M2; float2 v2;
float2 result = GLSL_mul_mat2_vec2(M2, v2);
matrix3x3 M3; float3 v3;
float3 result = GLSL_mul_mat3_vec3(M3, v3);
matrix4x4 M4; float4 v4;
float4 result = GLSL_mul_mat4_vec4(M4, v4);
Vector * Matrix - Row vector
// GLSL
vec2 v2; mat2 M2;
vec2 result = v2 * M2;
vec3 v3; mat3 M3;
vec3 result = v3 * M3;
vec4 v4; mat4 M4;
vec4 result = v4 * M4;
// OpenCL
float2 v2; matrix2x2 M2;
float2 result = GLSL_mul_vec2_mat2(v2, M2);
float3 v3; matrix3x3 M3;
float3 result = GLSL_mul_vec3_mat3(v3, M3);
float4 v4; matrix4x4 M4;
float4 result = GLSL_mul_vec4_mat4(v4, M4);
Matrix * Matrix
// GLSL
mat2 M1, M2;
mat2 result = M1 * M2;
mat3 M1, M2;
mat3 result = M1 * M2;
mat4 M1, M2;
mat4 result = M1 * M2;
// OpenCL
matrix2x2 M1, M2;
matrix2x2 result = GLSL_mul_mat2_mat2(M1, M2);
matrix3x3 M1, M2;
matrix3x3 result = GLSL_mul_mat3_mat3(M1, M2);
matrix4x4 M1, M2;
matrix4x4 result = GLSL_mul_mat4_mat4(M1, M2);
Compound Assignments
// GLSL
v2 *= M2;
v3 *= M3;
M3 *= M3;
// OpenCL
v2 = GLSL_mul_vec2_mat2(v2, M2);
v3 = GLSL_mul_vec3_mat3(v3, M3);
M3 = GLSL_mul_mat3_mat3(M3, M3);
Chained Operations
// GLSL
vec3 result = v * M1 * M2;
// OpenCL
float3 result = GLSL_mul_vec3_mat3(GLSL_mul_vec3_mat3(v, M1), M2);
Type Inference - Transformer tracks types through:
Standard Operators - Unchanged
Arithmetic: +, -, *, /, %
Comparison: <, >, <=, >=, ==, !=
Logical: &&, ||, !, ^^
Bitwise: &, |, ^, ~, <<, >>
Assignment: =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
Ternary: ? :
Exception: Matrix multiplication * transforms to GLSL_mul_* (see Section 4).
Unchanged - All control flow statements identical:
if (condition) { ... } else { ... }
for (init; condition; update) { ... }
while (condition) { ... }
do { ... } while (condition);
Undefined Variable Initialization (GLSL Semantics)
CRITICAL: GLSL implicitly zero-initializes undefined variables, while OpenCL leaves them undefined. The transpiler automatically adds zero initializers to match GLSL semantics.
// GLSL
float foo; // Implicitly initialized to 0.0
vec3 bar; // Implicitly initialized to vec3(0.0)
int x; // Implicitly initialized to 0
// OpenCL (transpiled)
float foo = 0.0f; // Explicit zero initialization
float3 bar = (float3)(0.0f); // Explicit zero initialization
int x = 0; // Explicit zero initialization
Single Declaration
// GLSL
float x = 1.0; // Explicit initializer (unchanged)
vec3 p; // No initializer (gets zero-init)
// OpenCL
float x = 1.0f; // Explicit initializer preserved
float3 p = (float3)(0.0f); // Zero initializer added
Comma-Separated Declarations
// GLSL
float x, y, z; // All undefined
int a = 10, b = 20; // All explicitly initialized
vec3 p, n, t; // All undefined
float a = 1.0, b, c = 3.0; // Mixed (b undefined)
// OpenCL
float x = 0.0f, y = 0.0f, z = 0.0f; // Zero-init added
int a = 10, b = 20; // Unchanged
float3 p = (float3)(0.0f), n = (float3)(0.0f), t = (float3)(0.0f); // Zero-init added
float a = 1.0f, b = 0.0f, c = 3.0f; // b gets zero-init
Matrix Types
// GLSL
mat2 M1;
mat3 M2, M3;
mat4 M4 = mat4(1.0);
// OpenCL
matrix2x2 M1 = GLSL_matrix2x2_diagonal(0.0f); // Zero matrix
matrix3x3 M2 = GLSL_matrix3x3_diagonal(0.0f), M3 = GLSL_matrix3x3_diagonal(0.0f);
matrix4x4 M4 = GLSL_matrix4x4_diagonal(1.0f); // Explicit initializer preserved
Supported Types for Auto-Initialization:
float, intvec2, vec3, vec4ivec2, ivec3, ivec4mat2, mat3, mat4Not Auto-Initialized:
bool, uint, uvec*, bvec* (less common, different semantics)Const Qualifier
// GLSL
const float PI = 3.14159;
const vec3 UP = vec3(0, 1, 0);
const float x = 1.0, y = 2.0;
// OpenCL
const float PI = 3.14159f;
const float3 UP = (float3)(0.0f, 1.0f, 0.0f);
const float x = 1.0f, y = 2.0f;
Struct Declarations
// GLSL - Global struct definition
struct Geo {
vec3 pos;
vec3 scale;
vec3 rotation;
};
struct Ray { vec3 o, d; }; // Comma-separated fields, one-line definition
Geo _geo = Geo(vec3(0), vec3(1), vec3(0));
Ray _ray;
// OpenCL
typedef struct {
float3 pos;
float3 scale;
float3 rotation;
} Geo;
typedef struct {
float3 o, d;
} Ray;
Geo _geo = {(float3)(0), (float3)(1), (float3)(0)}; // C99 compound literal
Ray _ray;
Local Struct Definitions (inside functions)
// GLSL
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
struct Foo { vec3 a; float b, c; };
Foo _bar = Foo(vec3(0), 1.0, 0.5);
}
// OpenCL
void mainImage(__private float4* fragColor, float2 fragCoord) {
typedef struct {
float3 a;
float b, c;
} Foo;
Foo _bar = {(float3)(0), 1.0f, 0.5f};
}
Struct Arrays
// GLSL
struct Point { float x, y, z; };
Point points[10];
// OpenCL
typedef struct {
float x, y, z;
} Point;
Point points[10];
Nested Structs
// GLSL
struct Point { float x, y, z; };
struct Line { Point start, end; };
Line l = Line(Point(0,0,0), Point(1,1,1));
// OpenCL
typedef struct {
float x, y, z;
} Point;
typedef struct {
Point start, end;
} Line;
Line l = { {0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f} };
GLSL Qualifiers:
in: Read-only (default, removed)out: Write-only output (becomes pointer)inout: Read-write (becomes pointer)const: Constant (unchanged)Transformation:
// GLSL
void foo(in float x, out vec2 result, inout vec3 data) {
result = vec2(x);
data *= 2.0;
}
// OpenCL
void foo(float x, __private float2* result, __private float3* data) {
*result = (float2)(x);
*data *= 2.0f;
}
// Call sites get address-of operator
// GLSL: foo(1.0, outVar, inoutVar);
// OpenCL: foo(1.0f, &outVar, &inoutVar);
All matrix types (mat2/3/4) use pointers for out/inout (struct behavior).
Unchanged - OpenCL supports identical swizzling:
v.xy, v.rgb, v.w -> v.xy, v.rgb, v.w
Macro Definitions - Transform bodies
// GLSL
#define PI 3.14159265
#define random(x) fract(sin(x))
// OpenCL
#define PI 3.14159265f
#define random(x) GLSL_fract(GLSL_sin(x))
Conditional Compilation - Pass through unchanged
#if, #ifdef, #ifndef, #else, #elif, #endif
Preserved - Explicit parentheses maintained for order of operations:
// GLSL
1.0 * (2.0 / iResolution.y) * (1.0 / fov)
// OpenCL
1.0f * (2.0f / iResolution.y) * (1.0f / fov)
47 GLSL built-in functions - All overloadable for float/float2/float3/float4
Implementation Strategy:
Key Semantic Differences:
GLSL_mod(x, y): Uses x - y * floor(x/y) (GLSL semantics) vs OpenCL remainderGLSL_fract(x): Uses x - floor(x) (GLSL semantics)GLSL_inversesqrt(x): Maps to OpenCL rsqrt(x) (reciprocal square root)Macros for Code Generation:
DEFINE_UNARY(NAME, BUILTIN): Generate 4 overloadsDEFINE_BINARY(NAME, BUILTIN): Generate 10 overloads (vec+scalar combinations)DEFINE_TERNARY(NAME, BUILTIN): Generate 10 overloadsExample:
DEFINE_UNARY(GLSL_sin, sin)
// Expands to:
// float GLSL_sin(float x){ return sin(x); }
// float2 GLSL_sin(float2 x){ return sin(x); }
// float3 GLSL_sin(float3 x){ return sin(x); }
// float4 GLSL_sin(float4 x){ return sin(x); }
Struct Definitions:
typedef struct {
float2 cols[2]; /* 2 columns of float2 */
} matrix2x2;
typedef struct {
float3 cols[3]; /* 3 columns of float3 */
} matrix3x3;
typedef struct {
float4 cols[4]; /* 4 columns of float4 */
} matrix4x4;
Column-major layout - M.cols[col][row] matches GLSL M[col][row]
450+ lines of matrix operations
Constructors:
GLSL_matrix2x2_diagonal(float s)GLSL_mat2/3/4(float m00, float m10, ...)GLSL_mat2/3/4_cols(vec col0, vec col1, ...)GLSL_mat3_from_mat4(matrix4x4), GLSL_mat4_from_mat3(matrix3x3)Operations:
GLSL_mul_mat2/3/4_vec2/3/4(M, v)GLSL_mul_vec2/3/4_mat2/3/4(v, M)GLSL_mul_mat2/3/4_mat2/3/4(M1, M2)GLSL_transpose(M2), GLSL_transpose_mat3/4(M3/4)GLSL_inverse(M2), GLSL_inverse_mat3/4(M3/4)GLSL_determinant(M2), GLSL_determinant_mat3/4(M3/4)GLSL_matrixCompMult(M2), GLSL_matrixCompMult_mat3/4(M3/4)All functions return by value - Enabled by struct-based types.
Issue: dFdx, dFdy, fwidth return input unchanged (no actual derivatives)
Reason: OpenCL has no derivative hardware outside fragment shaders
Impact: Shaders using derivatives for screen-space effects will not work correctly
Future: Potential Houdini COPs “Write Back Kernel” with convolution matrix
Issue: Matrix constructors are function calls, not compile-time constants Impact: Cannot use in switch cases or some global const contexts Workaround: Acceptable - OpenCL compilers optimize runtime initialization Example:
const matrix3x3 M = GLSL_mat3(...); // Runtime initialization (not compile-time)
Issue: Only simple identifiers supported Limitation: Cannot pass complex expressions as out parameters Example:
foo(x, arr[i]); // NOT SUPPORTED - arr[i] is not a simple identifier
// Workaround: Use temporary variable
vec2 temp = arr[i];
foo(x, temp);
arr[i] = temp;
Status: Architecturally supported but not extensively tested
Description: Struct fields can be matrix types (matrix2x2, matrix3x3, matrix4x4), but this combination has not been thoroughly tested in complex scenarios
Example:
// GLSL
struct Transform {
mat3 rotation;
vec3 translation;
};
// OpenCL (should work but not extensively tested)
typedef struct {
matrix3x3 rotation;
float3 translation;
} Transform;
Impact: Basic usage should work since matrix types are structs themselves, but edge cases may exist Workaround: Test carefully or avoid matrix fields in structs if encountering issues Future: Will be tested and documented as needed when encountered in real shaders
Total: 1514 tests passing, 6 skipped
Key Test Files:
test_ast_transformer_basic.py - Basic transformations (literals, types, operators)test_transformer_constructors.py - Vector/matrix constructorstest_ast_matrix_ops.py - Matrix multiplication detectiontest_transformer_matrix_functions.py - Matrix functions (transpose, inverse, determinant)test_transformer_qualifiers.py - Function parameter qualifiers (in/out/inout)test_transformer_const_qualifier.py - Const variable declarations (13 tests)test_transformer_structs.py - User-defined struct support (16 tests)Shaders that compile successfully:
tests/shaders/test/*.glsl - Feature tests (comma, macros, oporder, qualifiers, statement, structs)tests/shaders/simple/*.glsl - 9 Shadertoy shaders (vignette, gradient, hexagonal, ripples, silexars, sand, caustic, colorful, warping)tests/shaders/medium/spec.glsl - GLSL built-in function spectests/shaders/medium/ocean.glsl - Ocean waves (medium complexity)tests/shaders/medium/seascape.glsl - Seascape (complex)tests/shaders/medium/matrix.glsl - Matrix operations testBlockers:
tests/shaders/complex/adjugate.glsl - Requires preprocessor directive evaluation (#if AA>1)Pre-2025-11-15: Houdini array-based mat3 (fpreal3[3]) required 580+ lines of special-case code
Post-2025-11-16: Struct-based matrices (matrix2x2/3x3/4x4) - clean, simple, consistent
Code Deleted:
ast_transformer.pyopencl_emitter.pytransformed_ast.py (Mat3ResultReturn class)test_transformer_mat3_functions.pyBenefits:
// LITERALS
1.0 -> 1.0f
vec2(1, 2) -> (float2)(1.0f, 2.0f)
mat3(1.0) -> GLSL_matrix3x3_diagonal(1.0f)
// BUILT-INS
sin(x) -> GLSL_sin(x)
mod(x, y) -> GLSL_mod(x, y)
normalize(v) -> GLSL_normalize(v)
// MATRIX OPS
M3 * v3 -> GLSL_mul_mat3_vec3(M3, v3)
v3 * M3 -> GLSL_mul_vec3_mat3(v3, M3)
M3 * M3 -> GLSL_mul_mat3_mat3(M3, M3)
transpose(M3) -> GLSL_transpose_mat3(M3)
// PARAMETERS
out vec2 r -> __private float2* r
inout vec3 d -> __private float3* d
foo(x, outVar) -> foo(x, &outVar)
// DECLARATIONS
const float PI = 3.14; -> const float PI = 3.14f;
float x, y, z; -> float x, y, z;
// STRUCTS
struct Geo { vec3 pos; vec3 scale; }; -> typedef struct { float3 pos; float3 scale; } Geo;
Geo g = Geo(vec3(0), vec3(1)); -> Geo g = {(float3)(0), (float3)(1)};
g.pos -> g.pos
vec2 -> float2 mat2 -> matrix2x2
vec3 -> float3 mat3 -> matrix3x3
vec4 -> float4 mat4 -> matrix4x4
ivec2 -> int2
ivec3 -> int3
ivec4 -> int4
User-defined structs: Name -> Name (typedef struct)
End of Specification
For more details on specific features, see:
For development workflow and progress tracking:
docs/RULES.md - Development guidelines.agent/PROGRESS.md - Current status and next steps