Maya GLSL Shader Part 1
Back in 2015 I saw a making of trailer of Lightning Returns: Final Fantasy XIII where they showed the character Lightning inside Maya while lighting and material were changed in real-time.
At that time I thought it was really cool to preview in-game shaders inside Maya. The idea stuck with me and recently I've decided to try it out.
So here’s what I’ve found out about writing shaders inside of Maya.
GLSL shaders
I have decided to go with GLSL simply because I couldn't find much about using GLSL shaders in Maya while you can find more resources about using Cg and HLSL shaders.
Two ways to write shaders
I've found out there are two ways to write GLSL shaders in Maya:
The second method is a little bit more convoluted but by making good use of preprocessor directives, both vertex and fragment shader can then be used in external game engines without the need to rewrite them.
Enable GLSL shaders in Maya
First, you have to setup Maya to work with GLSL shaders.
Go to Windows -> Settings/Preferences -> Preferences -> Display -> Viewport 2.0 -> Render engine and set it to OpenGL - Core Profile (Compatibility).
This setting also works with CgFX shaders.
Now restart Maya.
Launch Maya again and go to Windows -> Settings/Preferences -> Plug-in Manager and enable glslShader.mll.
By doing this, you can select GLSL Shader when you create a new material.
The Scene
Add a sphere to the scene (or any primitive you like), right click and assign a new material.
Choose GLSL Shader as material type and give it a name.
Now open your text editor of choice, I use VSCode because it has syntax highlighting for multiple shading languages and also code completion.
Create a new file and save it as basic_single.ogsfx, then paste the following code:
At that time I thought it was really cool to preview in-game shaders inside Maya. The idea stuck with me and recently I've decided to try it out.
So here’s what I’ve found out about writing shaders inside of Maya.
GLSL shaders
I have decided to go with GLSL simply because I couldn't find much about using GLSL shaders in Maya while you can find more resources about using Cg and HLSL shaders.
Two ways to write shaders
I've found out there are two ways to write GLSL shaders in Maya:
- write everything (vertex and fragment shaders) inside a unique file with .ogsfx extension
- write vertex and fragment shaders into their respective files (.glslv and .glslf) and then include both inside a .ogsfx file
The second method is a little bit more convoluted but by making good use of preprocessor directives, both vertex and fragment shader can then be used in external game engines without the need to rewrite them.
Enable GLSL shaders in Maya
First, you have to setup Maya to work with GLSL shaders.
Go to Windows -> Settings/Preferences -> Preferences -> Display -> Viewport 2.0 -> Render engine and set it to OpenGL - Core Profile (Compatibility).
This setting also works with CgFX shaders.
Now restart Maya.
Launch Maya again and go to Windows -> Settings/Preferences -> Plug-in Manager and enable glslShader.mll.
By doing this, you can select GLSL Shader when you create a new material.
The Scene
Add a sphere to the scene (or any primitive you like), right click and assign a new material.
Choose GLSL Shader as material type and give it a name.
Now open your text editor of choice, I use VSCode because it has syntax highlighting for multiple shading languages and also code completion.
Create a new file and save it as basic_single.ogsfx, then paste the following code:
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 | 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; }; //Vertex shader GLSLShader VS { void main() { gl_Position = gMVP * vec4(inPosition, 1); } } //Fragment shader 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; } } |
The code is pretty self explanatory.
At line 1 we have Maya built-in uniform that stores the MVP matrix.
Then we have vs_input attribute that gets data from Maya and passes it to the vertex shader.
After that we have vs_to_ps attribute that is empty because we're not passing data from vertex to fragment shader.
Finally we have fs_out attribute that is the ouput of the fragment shader.
At line 22 I've defined the body of the vertex shader in which vertices are transformed to clip space.
At line 31 I've defined the body of the fragment shader that simply outputs a solid red color.
Now go into the Attribute Editor and select your GLSL material. You should see something like this:
At line 1 we have Maya built-in uniform that stores the MVP matrix.
Then we have vs_input attribute that gets data from Maya and passes it to the vertex shader.
After that we have vs_to_ps attribute that is empty because we're not passing data from vertex to fragment shader.
Finally we have fs_out attribute that is the ouput of the fragment shader.
At line 22 I've defined the body of the vertex shader in which vertices are transformed to clip space.
At line 31 I've defined the body of the fragment shader that simply outputs a solid red color.
Now go into the Attribute Editor and select your GLSL material. You should see something like this:
Next to Shader File there's a button, use it to load the basic_single.ogsfx file we have just written.
The sphere should turn red, if it doesn't, go to Shading and activate Hardware Texturing.
The three-files way
Open your text editor and create three files: basic.ogsfx, basic.glslv and basic.glslf.
The first file is the .ogsfx file we load into Maya and that includes the other two files that are the vertex and the fragment shader.
Paste the following code in the respective files:
basic.ogsfx
The sphere should turn red, if it doesn't, go to Shading and activate Hardware Texturing.
The three-files way
Open your text editor and create three files: basic.ogsfx, basic.glslv and basic.glslf.
The first file is the .ogsfx file we load into Maya and that includes the other two files that are the vertex and the fragment shader.
Paste the following code in the respective files:
basic.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 "basic.glslv" #include "basic.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 "basic.glslv" #include "basic.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 "basic.glslv" } // Fragment shader. GLSLShader FS { #include "basic.glslf" } // Techniques. technique Main { pass p0 { VertexShader (in vs_input, out vs_out) = VS; PixelShader (in fs_input, out fs_out) = FS; } } |
basic.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 |
basic.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 |
The code in the vertex and fragment shader is pretty much the same, the interesting part is in the .ogsfx file.
Basically it includes the .glslv and .glslf where uniforms and attributes should have been defined.
Also, it includes these two files where the body of the vertex and fragment shader should have been defined.
Now in the Attribute Editor load basic.ogsfx and the sphere should turn green this time.
The shader is super basic but I think it's perfect to keep the focus on the basic steps to setup Maya to work with GLSL shaders.
Basically it includes the .glslv and .glslf where uniforms and attributes should have been defined.
Also, it includes these two files where the body of the vertex and fragment shader should have been defined.
Now in the Attribute Editor load basic.ogsfx and the sphere should turn green this time.
The shader is super basic but I think it's perfect to keep the focus on the basic steps to setup Maya to work with GLSL shaders.