-
Notifications
You must be signed in to change notification settings - Fork 50
Notes
Shader files are written in OpenGL Shader Language (GLSL), version 1.10. The Book of Shaders is a good beginners guide to the shader language.
The map
function in the shader is executed once per voxel:
- It recieves the location of the voxel as its only argument
- Should return a float between
0
and255
representing the voxel color in the palette.
For example, the following shader will fill the entire volume with voxels colored from palette index 1
.
// xs_begin
// author : '@lachlanmcdonald'
// xs_end
float map(vec3 v) {
return 1.0;
}
- Shaders must contain the header (
xs_begin
andxs_end
), even if there are no arguments. -
author
is optional. Whilst there is no standard for it value, a URL or Twitter handle is implied. - As shaders return a
float
, the value is rounded. For instance,0.4999
will result in a voxel palette of1.0
. - Return values are clamped between
0.0
and255.0
, so it is safe to return a value of this range
Some hardware cannot cast betwen int
and float
without an explicit command, i.e.:
float a = 1.0;
int b = int(a * 2.0); // will work on all hardware
int b = a * 2.0; // will not work on all hardware
float c = 2 * 6; // will not work on all hardware
float c = float(2 * 6); // will work on all hardware
Similarly, a function must always return the expected return type (cannot be casted):
float a() {
return float(1); // will work
return 1; // will not work
}
The map
function is passed the center-point of the voxel. So, a voxel as position 0
, 0
, 0
will be passed to the map
function as vec3(0.5, 0.5, 0.5)
.
If this is undesirable, you can floor the entire vec3
in one operation:
v = floor(v);
Which is a more concise way to write:
v.x = floor(v.x);
v.y = floor(v.y);
v.z = floor(v.z);
voxel()
always refers to the original model. For example:
float map(vec3 v) {
if (all(equal(v, vec3(0.0, 0.0, 0.0)))) {
return 1.0;
} else {
return voxel(vec3(0.0, 0.0, 0.0));
}
}
Will not result in the entire model being replaced with index 0
. Instead, all voxels will be replaced with the original index at position 0,0,0
.
For example, b()
must be defined before a()
, or it will not be defined when a()
tries to call it.
float b() {
return 1.0;
}
float a() {
return b();
}
float map(vec3 v) {
return a();
}
voxel()
for retrieving a color index will return 0.0
when addressing beyond the volume size. Therefore, it is not necessary to check wether the x
, y
or z
co-ordinates will be out-of-bounds before calling voxel
.
For example:
voxel(500.0, 500.0, 500.0); // 0.0
voxel(-1.0, -1.0, -1.0); // 0.0
no_axis_mode
will be true
when no axis modes are set, false
otherwise.
bool no_axis_mode = all(equal(ivec3(i_axis), ivec3(0)));
bvec3 axis_mode = equal(ivec3(i_axis), ivec3(1));
axis_mode
is a bvec3
indicating which axis mode is set.
For example: axis_mode.x
will be true
if the X-axis mode is set.
In Visual Studio Code, GLSL shader syntax-highlighting can be enabled with the Shader languages support for VS Code extension.
.txt
files are not automatically detected as shaders. The following snippet can be added to the workspace settings to override the associations for .txt
files:
{
"files.associations": {
"**/shader/**/*.txt": "glsl"
}
}
All content in this wiki is licenced under the CC BY-NC-SA 4.0 license. Code snippets are dual-licenced under the MIT License.