GLSL Shader in Maya Part 1


Maya to act like an (expensive) shader editor

There aren't many shader editors out there, not as many as it used to be in the early 2000s when AMD had RenderMonkey and Nvidia had FX Composer.
They were pretty good softwares in my own humble opinion and it's a pity they have been discontinued.
These days we have Shadertoy but to be honest I prefer native applications, yes I'm old school!
I've always known that Maya supports HLSL and GLSL shaders in Viewport 2.0 so I've started to think that it would be really cool to use it like a shader editor.
But it's not as simple as I would have expected, the documentation around the net is pretty sparse so it's a matter of trials and errors.

Why GLSL and not HLSL?

I have nothing against HLSL, in fact I use it extensively in Unity (well to be precise I use Cg which is NVidia version of HLSL).
I've decided to go with GLSL simply because is more portable and I like to use Maya on Linux for my personal project.
Also GLSL can run on Android phones, yes it needs to be tweaked because OpenGL ES 2.0 uses a different version of GLSL but more or less the syntax is the same.

Two ways to write shaders

You can write GLSL shaders in Maya in two ways:
  1. Write everything (vertex and fragment shaders) inside a unique file with .ogsfx extension
  2. Write vertex and fragment shaders in different files (.glslv and .glslf) and then "include" them inside a third .ogsfx, just like you would do with headers files in C++.
I find the first method quicker but the .ogsfx files can only be read by Maya.
The second method is a little bit more intricate but the vertex and fragment shaders can be used in your own 3D engine without the need to rewrite them.

Using GLSL shaders in Maya

First of all make sure Maya is using OpenGL and not DirectX.
Go to Windows > Settings/Preferences > Preferences > Display > Viewport 2.0 > Rendering engine and choose OpenGL - Core Profile (strict)
Restart Maya and in a new scene add a simple sphere.
Right click on the sphere and click on Assign a new material, choose GLSL Shader and give it a name.
In the Attribute Editor, under the name of our GLSL shader, you'll find a button to load your .ogsfx source. 

A solid color example using a single .ogsfx file

Here's a basic solid color code example using just one unique .ogsfx file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
uniform mat4 gMVP : WorldViewProjection;

//Vertex shader input coming from the application
attribute vs_input
{
 vec3 inPosition : POSITION;
};

//Vertex shader output to fragment shader and also fragment shader input
attribute vs_to_ps
{

};

//Fragment shader output
attribute fs_out
{
 vec4 out_color : COLOR0;
};

GLSLShader VS
{
 void main()
 {
  gl_Position = gMVP * vec4(inPosition, 1);
 }
}

GLSLShader FS
{
 void main()
 {
  out_color = vec4(1, 0, 0, 1);
 }
}

technique Main
{
 pass p0
 {
  VertexShader (in vs_input, out vs_to_ps) = VS;
  PixelShader (in vs_to_ps, out fs_out) = FS;
 }
}

A solid color example using three files

solidcolor.ogsfx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Tell included shaders to use OGSFX semantics and streams:
#define OGSFX 1

//########################### UNIFORMS ###########################
// Uniform parameter handling
// Loads the uniforms from all shader stage files
#define HIDE_OGSFX_UNIFORMS 0
#define HIDE_OGSFX_STREAMS 1
#define HIDE_OGSFX_CODE 1

#include "solidcolor.glslv"
#include "solidcolor.glslf"
//########################### ATTRIBUTES ###########################
// Input stream handling:
// Loads the attribute streams from all shader stage files
#define HIDE_OGSFX_UNIFORMS 1
#define HIDE_OGSFX_STREAMS 0
#define HIDE_OGSFX_CODE 1

#include "solidcolor.glslv"#include "solidcolor.glslf"
//########################### FUNCTION ###########################
// Code handling:
// We need to load the vertex stage and fragment stage in two
// different GLSLShader blocks in order to specify them in the
// technique definition below:
#define HIDE_OGSFX_UNIFORMS 1
#define HIDE_OGSFX_STREAMS 1
#define HIDE_OGSFX_CODE 0

// Vertex shader.
GLSLShader VS
{
#include "solidcolor.glslv"}

// Fragment shader.
GLSLShader FS
{
#include "solidcolor.glslf"}

// Techniques.
technique Main
{
    pass p0
    {
        VertexShader (in vs_input, out vs_out) = VS;
        PixelShader (in fs_input, out fs_out) = FS;
    }
}

solidcolor.glslv
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//########################### GLSL VERSION ###########################
//If it's not a Maya OGSFX Shader set the GLSL version for common GLSL shaders
#if !OGSFX
#version 330
#endif

//########################### UNIFORMS ###########################
//Put here OGSFX uniform specific code
#if !HIDE_OGSFX_UNIFORMS
#if OGSFX

uniform mat4 MVP : WorldViewProjection;

#else

uniform mat4 MVP;

#endif //OGSFX
#endif // HIDE_OGSFX_UNIFORMS

//########################### ATTRIBUTES ###########################
//Put here OGSFX attribute specific code
#if !HIDE_OGSFX_STREAMS
#if OGSFX

attribute vs_input
{
    vec3 Position : POSITION;
};

// The vertex shader ouput and also the pixel shader input
attribute vs_out
{
    // None
};

#else

in vec3 Position;

#endif //OGSFX
#endif //HIDE_OGSFX_STREAMS

//########################### FUNCTION ###########################
//Put here main function
#if !HIDE_OGSFX_CODE

void main()
{
    gl_Position = MVP * vec4(Position, 1);
}

#endif //HIDE_OGSFX_STREAMS

soilidcolor.glslf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//########################### GLSL VERSION ###########################
//If it's not a Maya OGSFX Shader set the GLSL version for common GLSL shaders
#if !OGSFX
#version 330
#endif

//########################### UNIFORMS ###########################
//Put here OGSFX uniform specific code
#if !HIDE_OGSFX_UNIFORMS
#if OGSFX

#endif //OGFX
#endif //HIDE_OGSFX_UNIFORMS

//########################### ATTRIBUTES ###########################
//Put here OGSFX attribute specific code
#if !HIDE_OGSFX_STREAMS
#if OGSFX

attribute fs_input
{

};

attribute fs_out
{
    vec4 out_color : COLOR0;
};

#else 

out vec4 out_color;

#endif //OGSFX
#endif //HIDE_OGSFX_STREAMS

//########################### FUNCTION ###########################
//Put here main function
#if !HIDE_OGSFX_CODE

void main()
{
    out_color = vec4(0, 1, 0, 1);
}

#endif //HIDE_OGSFX_STREAMS

  

Comments

Popular posts from this blog

Unity Shader: Toon Water Shader

Unity Shader: Spherical Mask Dissolve