I am looking at trying to get up to speed with shaders for OpenGL ES 2.0 (Programmable shaders) for the iPad 2. I’m having difficulty separating out what is Unity specific and what is a part of the OpenGL ES spec. I get the impression that Shaderlab wraps CG/HLSL. Is this the case?
Are there any good resources/tutorial/examples for understanding this? I have read wiki stuff (The iPhone examples are limited and the non-iPhone examples have a lot of graphic card specific complexity that I’m hoping to avoid having to sort out). I’ve looked at examples and I’ve read some of the forums but I’m still not getting it.
How useful is it for me to read about generic shader info? Can I play with Apple’s shader tools and it be applicable to writing shaders in shaderlab?
Is there a “Shaders for Dummies” that would be relevant? I’m reasonably well versed in C/C++ and I’ve got years of programming experience but this is first time I’m really looking at shaders themselves and I’m probably still somewhat weak on generic shader concepts.
The FAQ for this forum is somewhat sparse. I’m hoping people have a better understanding out. It seems clear that the iPad is very capable for someone who understands shaders. Any help would be great.
You can give my tutorial videos a look, but there’s a lot of fixed function information in there, which would only be useful on older iOS hardware. I learned a lot from, and based those videos around, the ShaderLab documentation. However, Unity’s GLSL documentation is nil, so if you come up with anything good, please show us, if you can.
Here’s a basic vertex lighting/Beäst-utilizing shader I wrote that’s aimed at performance, which may help. It also represents about the extent of what I know how to do, given the aforementioned lack of help.
There are two types of shaders that GLSL ES 2.0 supports : Vertex and Fragment. Other types ( e.g Geometry shaders ) are not supported.
The Vertex shader might get some input (more on that later) and should output at least gl_Position. A minimum Vertex shader is
void main()
{
// Each vertex position in screen ( window ) space ( = gl_Position ) is calculated
// by multiplying the vertex position in the World space ( = gl_Vertex ) ( It is either World or Object space, not sure )
// with the MVP matrix ( = gl_ModelViewProjectionMatrix ).
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
The Fragment shader might get some input and should output at least gl_FragColor. A minimum Fragment shader is
void main()
{
// For every pixel on the screen that belongs to this object
// paint the pixel red.
gl_FragColor = vec4 (1.0, 0.0, 0.0, 1.0);
}
To use the above shaders in a unity shader, the template is
Shader "Shader name"
{
Properties
{
//Fill any properties
}
SubShader
{
Tags { "Queue" = "Geometry" }
Pass
{
GLSLPROGRAM
#ifdef VERTEX
// Add Vertex shader code here
#endif
#ifdef FRAGMENT
// Add Fragment shader code here
#endif
ENDGLSL
}
}
}
So a simple shader that displays the object in red is
You can create and access shader’s properties ( ie color, texture, etc ) and access Unity’s built-in values from UnityCG.glslinc. I plan to create some posts in my blog regarding those aspects.
Also, keep an eye on any WebGl tutorial that contains Vertex or Fragment shader code, place them as shown above and the code should work.
Currently I have posted four GLSL tutorials. I prepare a tutorial series for Cg as well.
I will start publishing them in mid-September.
I have to admit that seeing nobody is interested for them until now has weakened my interest on publishing them.
Also, Unity appears to strongly discourage the use of GLSL.
I just spend some hours yesterday trying to get surface shaders to work with GLSL code (why doesn’t that work although you can use Cg code?) or to get the Unity 2.x shaders with GLSL to run (well, I guess it’s understandable that those shaders no longer work). However, both points would be nice to easily use shadows and cookies etc. with custom-maded GLSL shaders. Otherwise, it quickly gets very difficult to use even the basic features of Unity’s light sources.
Surface shaders are crossplatform as is cg (glsl isn’t, its mac - mobile only)
Surface shaders do a lot automatic which cuts the possibility to optimize it - thats something you don’t want to do for mobile or better if you want it you can just as well go with cg as there is no gain in glsl anymore due to how well the cg → glsl crosscompiler and optimizer works
And I fail to see the point on shadows cause shadows aren’t supported on mobile at all.
@dreamora: OK. I get your point. The thing is: I want to teach GLSL (on Windows and Mac). If Unity wouldn’t support GLSL, I wouldn’t use Unity for teaching GLSL. Makes sense, doesn’t it? That said, I’m just saying that it would be nice to use surface shaders with GLSL in order to make it easier to program GLSL shaders that use shadows.
You can’t use GLSL on windows without the -opengl enforce flag (is standalone and unity opengl force on windows does not feature the full set of capabilities, from what I recall deferred does not work and a few other things don’t work either. Its more a reminder of Unity 2 than a real thing, thats why there is no editor setting for it either), cause DirectX does not support GLSL and thats what is being used on windows. Also for windows shader programmers GLSL is really of no interest, as hard as it sounds. CG is much more important cause its very very close to HLSL which unlike GLSL is the major player (aside of cases where CG or FX / CGFX are used themself)
Ok I see what you are saying, but you should have qualified that you are talking about GLSL in Unity as otherwise your comments make no sense. Even then the stuff about window developers is way of the mark, of course they use glsl if using opengl and plenty of them do, otherwise nvidia and ATI/AMD would simply stop supporting it.
The differences between HLSL/CG and GLSL are extremely small and converting between them is, of course depending on the amount of code the shader has, a matter of a few minutes, or seconds when using one of those automatic converters around, because it is mostly just replacing some keywords.
Writing surface shaders in GLSL makes no sense, because surface shaders are only a small part of the final shader which unity will copy together for you. Okay, they could also support that process for GLSL, but the resulting shaders are very complex and anyway not suited for mobile devices, which is the online platform GLSL really makes sense for, as CG can be compiled just fine on mac, just not for OpenGL ES 2.0. I btw don´t like the concept of surface shaders, because they take a lot of control away from me.
I think you should all be avoiding GLSL for the following reasons:
unity themselves mention it on their blog and pdf, that GLSL isn’t any faster than HLSL in most cases, but HLSL will work on anything.
GLSL is poorly documented so your milage may vary.
It’s fine targetting GLSL if you never want to port to PC or any other platform, but this could potentially screw up webplayer as well for a lot of people. It’s pretty much only good for targetting mac or mobile.
Where HLSL is just as optimised but ported internally to the target platform. This is my understanding of it reading unity’s pdf.
That does not mean the GLSL shader will even run properly. I have several GLSL shaders which work fine on the mac but simply won’t ever work properly on the pc, even forcing unity into opengl doesn’t solve a damn thing. Yes the title bar of unity showed it was running under opengl.
So really, I can’t advocate GLSL as a platform for unity any longer going by what unity said.
But don’t forget to rename rows of matrices to columns and columns to rows.
Unity compiles Cg to OpenGL ES 2.0. The difference between the GLSL code produced by Unity for OpenGL and the GLSL code for OpenGL ES 2.0 is probably not a big deal.
Could you elaborate that? Can’t you just add Cg code for the functions that you want to customize?
I’m very interested in those examples. Can you make them accessible please? (I only know of the opposite case where a GLSL shader runs fine with Unity on Windows but not on Mac.)
Going by what Unity says, you are absolutely correct. However, you should realize that Unity has absolutely no interest in programmers writing portable code: the more programmers depend on Unity, the more revenue will Unity earn. (The same argument goes for Microsoft and HLSL, C#, J#, J++, etc.)