Workarounds
While it’s not required to have the C# code without any syntax errors in order to edit it in Visual Studio, or convert it to valid GLSL code, it’s still very convenient to use code analysis where C# syntax errors could indicate possible GLSL errors as well.
To keep the errors list in Visual Studio clean, and still have the C# code convertible to a valid GLSL code, the following workarounds could be applied:
Floating Points
C# literals are of type double
by default (without an f
suffix), while GLSL literals are of type float
.
This is causing casting errors (CS0664) while writing a “GLSL like” code in C#, were double
literals are assigned to float
value types.
The Environment provides a Float
type, with _float
, and float_
aliases, that has an implicit casting between float
and double
, and can be used to eliminated these errors in most cases.
Note
When a casting error is encountered, replacing a float
type with a _float
or float_
, could eliminate it, in other cases an f
suffix could be added to the literal instead.
float x = 1.23;
// using a double literal
_float x = 1.23; // Float type alias
float_ x = 1.23; // Float type alias
// using a float literal (the suffix would be removed)
float x = 1.23f; // float primitive type
For methods declaration (input parameters, and return type), it’s recommended to always use the Float
type instead of the float
primitive, so that double
literals could be passed as parameters values, or returned without casting.
Example:
// use a "Float" type (float_), instead of a float primitive, for both // input parameter type, and return type. float_ sqrtSafe(float_ value) { if (value < 0.0) { // a double literal can be used as a return value (no need for // a suffix, "0.0f") return 0.0; } return sqrt(value); } ... // a double literal can be used as an input parameter value (no need for // a suffix, "2.0f") float result = sqrtSafe(2.0);
Casts
C# cast syntax is different from GLSL, for example a cast from float
to int
is (int)1.0
in C# and int(1.0)
in GLSL.
The _int()
or int_()
Environment methods could be used instead.
Similar methods are also defined for bool
, uint
, and float
.
int x = int(position.x);
int x = _int(position.x);
int x = int_(position.x);
Uniforms
To declare a uniform, a field could be used, with a uniform conversion rule, a const
or readonly
modifier could be added to reduce warnings, and would be removed by the rule.
The conversion rule can have additional line annotation properties that would be preserved, and parsed as part of the GLSL code.
//@uniform, min: 0.0, step: 0.1
uniform vec2 value = vec2(1.0, 2.0);
//@uniform, min: 0.0, step: 0.1
readonly vec2 value = vec2(1.0, 2.0);
Consts
Environment types such as vec2
, mat3
are not primitive types, and cannot be declared with the const
modifier, instead a readonly
modifier, or a const conversion rule (for local variables) could be used.
const vec2 value = vec2(1.0, 2.0);
class Image
{
readonly vec2 value = vec2(1.0, 2.0);
float getValue()
{
//@const
vec2 value = vec2(1.0, 2.0);
}
}
Defines
C# does not support define directives with a value, or macros, a define conversion rule could to be used instead.
#define PI 3.14159265
//@define
float PI = 3.14159265f;
#define sqr(x) ((x) * (x))
//@define
float sqr(float x) => ((x) * (x));
Overloads could be added with a remove-line conversion rule.
//@remove-line
vec2 sqr(vec2 x) => x * x;
//@remove-line
vec3 sqr(vec3 x) => x * x;
Automatic Conversion
- Arrays
C# array initialization uses curly brackets, while GLSL uses round ones.
Arrays can be automatically converted when a type is specified (usenew int[]
, and notnew[]
).new int[]{ 1, 2, 3 }
(C#) is converted toint[]( 1, 2, 3 )
(GLSL).
A multi-line array conversion is also supported.
- Preprocessor Directives
C# uses the
#if
directive for both conditions and symbols testing, while GLSL uses#if
for conditions, and#ifdef
/#ifndef
for symbols.Symbol testing directives are automatically converted.
#if A
(C#) is converted to#ifdef A
(GLSL)#if !A
(C#) is converted to#ifndef A
(GLSL)
More advanced directives could be converted with custom line rules.
- Modifiers
C# modifiers are automatically removed or replaced.
ref
andout
parameter modifiers are removed from functions calls, andref
is converted toinout
in functions declarations.Declaration conversion:
void modifyValue(ref int value) { ... }
(C#)
void modifyValue(inout int value) { ... }
(GLSL)
Call conversion:
modifyValue(ref value);
(C#)
modifyValue(value);
(GLSL)
getValue(out value);
(C#)
getValue(value);
(GLSL)
public
private
internal
protected
virtual
override
static
modifiers are removed.readonly
modifier is converted toconst
.
Other Workarounds
Other incompatibilities between C# and GLSL should be resolvable by using replace-line, or other custom conversion rules.