The primary design goal of PolyCube is to be backwards compatible with EvalDraw and PolyDraw, popular fast prototyping environments. Usually, you can just copy and paste your existing EvalDraw/PolyDraw scripts and with no or minor changes they should compile and run the same way in PolyCube. (*)
* Check out the language specification below to find out the differences.
It is also similar in spirit to WebGLPlayground, however, in order to make WebGLPlayground scripts work in PolyCube, the @main section has to be ported from Javascript to RiceScript.
Additionally, PolyCube is introducing its own features and extensions, for example you can draw 2d graphics (using EvalDraw library) on top of full screen fragment shader. Another interesting (still in experimental stage) feature is #use macro - an extension to GLSL language that let's you use built-in constants/functions or maintain common code (with restrictions) between GLSL and RiceScript.
PolyCube/RiceScript is under continuous development and bug fixing, please check out release_notes.txt for updates.
If you want to quickly start with PolyCube, be sure to check out PolyCube Tutorial.
Reference Documentation
Below you can find full documentation of PolyCube framework, including script structure and standard library.
All function names in standard library are declared in both mixedCase and lowercase style (for PolyDraw/EvalDraw compatibility).
Script structure
Every script starts with RiceScript rendering logic followed by list of vertex and fragment shaders:
// RiceScript section always starts at the begining () { // RiceScript main function } // Custom function declaration
@v:firstShader // Vertex shader with optional name = "firstShader" // GLSL-code for vertex shader void main() { gl_Position = /* here calculate vertex position in clipping space */ ; } @f:firstShader // Fragment shader // GLSL-code for fragment shader void main() { gl_FragColor = /* here calculate fragment color */ ; } @v:secondShader // ... @f:secondShader // ... // More fragment and vertex shaders possible
Additionally, you can defined "common" sections that can be injected to both fragment and vertex shaders code using #use macro.
For example:
// RiceScript section () { // ... } @v:myCommonSection // GLSL-code for both vertex and fragment shader @v:myShader #use :myCommonSection // GLSL-code for vertex shader void main() { gl_Position = /* ... */; } @f:myShader #use :myCommonSection // GLSL-code for fragment shader void main() { gl_FragColor = /* ... */; } // ...
Macro reference
You can use following macros to set various environment options:
#option auto_clear 1 or 0
If set to 1, automatically clears 3d rendering canvas: depth, color and stencil; default value is 1;
#option opaque_canvas 1 or 0If set to 1, 3d rendering canvas alpha value is ignored; default value is 1
#option preserve_buffer 1 or 0This option is for optimization purposes only; by default it is set to 1 and equivalent to WebGL preserveDrawingBuffer:true; if set to 0, thumbnail feature doesn't work and buffer is automatically cleared (irrespective of auto_clear setting)
#option antialias 1 or 0Toggle full-screen antialiasing; default value is 1
Additionally, you can #use macro to integrate RiceScript and GLSL-code or to use common GLSL sections:
#use glsl_math
Declare in RiceScript section to enable GLSL-like math and structures (see library reference below)
#use noiseDeclare in fragment shader to enable built-in Perlin noise functions
#use myFunctionDeclare in fragment or vertex shader to translate myFunction from RiceScript to GLSL (experimental feature, see language specification for more details)
#use :myCommonSectionInject common GLSL code section into GLSL shader code
Template reference
Templates are pre-defined code libraries/frameworks that let's you create a simple program faster.
To use a template simply declare at the begining of your code:
#template templateName
Templates are written in RiceScript, therefore if you would like to extend functinality of your simple program, you can just copy, paste and modify template code instead of #template decleration.
Example templates: (warning: template source code does not compile on its own)
#template plot
#template volumetric_v1
EvalDraw-style plotting program that plots anonymous (x) function.
Template's source code and example.
#template shader_plot_v1Template's source code and example.
EvalDraw-style plotting program that plots 2d function implemented in GLSL. Special uniforms:
#template voxel
float template_time; // current shader time in seconds
vec2 template_cursor; // position of mouse cursor in plot coordinates
int template_bstatus; // mouse button state (1=LMB, 2=RMB, 4=MMB)
Template's
source code and example.vec2 template_cursor; // position of mouse cursor in plot coordinates
int template_bstatus; // mouse button state (1=LMB, 2=RMB, 4=MMB)
#template volumetric_v1
Evaluation and rendering of distance fields in GLSL with physically-based materials. Distance field is precalculated and stored in a texture. This template optionally uses WEBGL2 features (with backwards compatibility to WebGL 1.0). Special uniforms:
float template_time; // current shader time in seconds
Template's
source code and example.Standard library reference
Functions that takes vector/matrix (vec2, vec3, vec4, mat2, mat3, mat4) as an argument or return type can be only called if macro #use glsl_math is declared.
PolyCube maintains a static pool of 256 textures and 256 meshes; functions that deal with meshes/textures just take mesh/texture index as an argument, no dynamic allocation is necessary. Mesh pool is empty by default. Texture pool is initialized with two default 128x128 textures:
texture 0 = checker board,
texture 1 = polka-dot.
texture 1 = polka-dot.
By default, at the begining of every frame, first 4 textures from the pool are bound to first 4 texture units.
Following default uniforms are available in vertex or fragment shaders and shouldn't be explicitly declared:
uniform mat4 gl_ModelViewMatrix;
Model-view matrix; transformation from model to view space
uniform mat4 gl_ProjectionMatrix;Projection matrix; transformation from view to clipping space
uniform mat4 gl_ModelViewMatrixInverse;Inverse of model-view matrix
uniform mat3 gl_NormalMatrix;Transpose of the inverse of 3x3 part of model-view matrix
Additionally, a helper function ftransform() is predefined in vertex shaders:
vec4 ftransform() { return gl_ProjectionMatrix * ( gl_ModelViewMatrix * gl_Vertex ); }
void main()
{
gl_Position = ftransform();
}
WebGL 2.0 support
If WebGL 2.0 / GLSL ES 3.0 is available, macro WEBGL2 is predefined in GLSL shaders and WEBGL2 static variable in RiceScript section.
You can declare shader version explicity using #version macro:
#version 100 // or #version 300 es
If no version is declared and GLSL ES 3.0 is available:
#varying is predefined as out in vertex shaders and in in fragment shaders,
gl_FragColor is defined as default fragment shader output; otherwise, for GLSL 3.0 ES, shader output has to be declared using out keyword
both gl_FragDepthEXT and gl_FragDepth can be used interchangably
GL_EXT_frag_depth extension declaration is ignored; however, it can be still declared for GLSL 1.0 compatibility
Example of cross-compatible script:
() { if (WEBGL2) { // do something WebGL 2 specific, i.e. render to 3d texture } else { // WebGL 1 fallback, i.e. render to 2d texture emulating 3d texture } glColor(.4,.6,1,1); glQuad(1); } @v: // vertex shader start // no shader version declaration varying vec4 color; // in GLSL ES 3.0 will be automatically out void main() { color = gl_Color; gl_Position = ftransform(); } @f: // fragment shader start // no shader version declaration #extension GL_EXT_frag_depth : enable varying vec4 color; // in GLSL ES 3.0 will be automatically in void main() { #ifdef WEBGL2 // Put GLSL ES 3.0 compatible shader code here #else // GLSL 1.0 fallback #endif #ifdef GL_EXT_frag_depth gl_FragDepthEXT = .5; // in GLSL ES 3.0 will be replaced with gl_FragDepth #endif gl_FragColor = color; }
And the same example for GLSL 3.0 ES without backwards compatibility:
() { glColor(.4,.6,1,1); glQuad(1); } @v: // vertex shader start #version 300 es out vec4 color; void main() { color = gl_Color; gl_Position = ftransform(); } @f: // fragment shader start #version 300 es in vec4 color; out vec4 fragColor; void main() { gl_FragDepth = .5; fragColor = color; }
As mentioned, we can also omit version declaration, as GLSL 3.0 ES will be automatically used if available.
Therefore, the final code without backwards compatibility can be written shorty as follows:
() { glColor(.4,.6,1,1); glQuad(1); } @v: // vertex shader start out vec4 color; void main() { color = gl_Color; gl_Position = ftransform(); } @f: // fragment shader start in vec4 color; void main() { gl_FragDepth = .5; gl_FragColor = color; }
For more information about language syntax check out RiceScript specification. Go back to main page.