Differences between CG Shaders and GLSL Shaders

Hi there,

Im trying to port a simple shader to GLSL, because the original CG Shader doesnt work on mobile.

Here is the original one: CG Shader - Pastebin.com
Here the ported GLSL (which doesnt work): Shader "Tileshader2" { Properties { _Color ("Main Color (A=Opacity)", - Pastebin.com

Since Unity (using 3.5.7) is always giving (at least for me) meaningless error description, I dont know whats going wrong.
If someone could take a look, that would be nice.

Thank you very much!
Alex

The error might be meaningless to you but it would be helpful for us.

Yes, you are right. Here the error:

GLSL Error in Fragment Shader: Error 0:38: Incompatible types initialization (and no available implicit conversion) ERROR: 0:39: use of undeclared identifier 'desat'

Here the compiled shader:

Shader "Tileshader2" {
 
	Properties {
	    _Color ("Main Color (A=Opacity)", Color) = (1,1,1,1)
	    _MainTex ("Base (A=Opacity)", 2D) = ""
	    _Saturation ("Saturation", Float) = 0.5
	}
	 
	Category {
	    Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
        LOD 200
 		ZWrite Off
	 
	    SubShader {
		    Pass {
		        // GLSL combinations: 1
Program "vp" {
SubProgram "opengl " {
Keywords { }
"!!GLSL

#define SHADER_API_OPENGL 1
#define tex2D texture2D
#define highp
#define mediump
#define lowp
#line 17

		        varying mediump vec2 uv;
		        
		        #ifdef VERTEX
		        uniform mediump vec4 _MainTex_ST;
		        void main() {
		            gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
		            uv = gl_MultiTexCoord0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
		        }
		        #endif
		        
		        #ifdef FRAGMENT
		        
		        uniform lowp vec4 _Color;
		        uniform lowp sampler2D _MainTex;
		        uniform lowp float _Saturation;
		        
		        void main() {
		        
		        	vec4 col 		= texture2D(_MainTex, uv) * _Color;
		        	vec4 desat 		= dot( col.rgb, vec3(0.3, 0.59, 0.11) );
		            gl_FragColor 	= mix( desat, col, _Saturation );
		            
		        }
		        #endif      
		        "
}
SubProgram "gles " {
Keywords { }
"!!GLES

#define SHADER_API_GLES 1
#define tex2D texture2D
#line 17

		        varying mediump vec2 uv;
		        
		        		        
		             
		        
#ifdef VERTEX
#define gl_ModelViewProjectionMatrix glstate_matrix_mvp
uniform mat4 glstate_matrix_mvp;
#define gl_Vertex _glesVertex
attribute vec4 _glesVertex;
#define gl_MultiTexCoord0 _glesMultiTexCoord0
attribute vec4 _glesMultiTexCoord0;

          uniform mediump vec4 _MainTex_ST;
          void main() {
              gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
              uv = gl_MultiTexCoord0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
          }
          
#endif
#ifdef FRAGMENT

          
          uniform lowp vec4 _Color;
          uniform lowp sampler2D _MainTex;
          uniform lowp float _Saturation;
          
          void main() {
          
           vec4 col   = texture2D(_MainTex, uv) * _Color;
           vec4 desat   = dot( col.rgb, vec3(0.3, 0.59, 0.11) );
              gl_FragColor  = mix( desat, col, _Saturation );
              
          }
          
#endif"
}
SubProgram "glesdesktop " {
Keywords { }
"!!GLES

#define SHADER_API_GLES 1
#define tex2D texture2D
#line 17

		        varying mediump vec2 uv;
		        
		        		        
		             
		        
#ifdef VERTEX
#define gl_ModelViewProjectionMatrix glstate_matrix_mvp
uniform mat4 glstate_matrix_mvp;
#define gl_Vertex _glesVertex
attribute vec4 _glesVertex;
#define gl_MultiTexCoord0 _glesMultiTexCoord0
attribute vec4 _glesMultiTexCoord0;

          uniform mediump vec4 _MainTex_ST;
          void main() {
              gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
              uv = gl_MultiTexCoord0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
          }
          
#endif
#ifdef FRAGMENT

          
          uniform lowp vec4 _Color;
          uniform lowp sampler2D _MainTex;
          uniform lowp float _Saturation;
          
          void main() {
          
           vec4 col   = texture2D(_MainTex, uv) * _Color;
           vec4 desat   = dot( col.rgb, vec3(0.3, 0.59, 0.11) );
              gl_FragColor  = mix( desat, col, _Saturation );
              
          }
          
#endif"
}
}

#LINE 41

		    }
	    }
	    
	    SubShader {
		    Pass {
		        SetTexture[_MainTex] {Combine texture * constant ConstantColor[_Color]}
		    }
	    }
    }
}

Hmm…

try changing
vec4 desat = dot( col.rgb, vec3(0.3, 0.59, 0.11) );

to
vec4 desat = vec4(dot( col.rgb, vec3(0.3, 0.59, 0.11) ));

Hi,
I do not have the possibility to check it now but I think
dot( col.rgb, vec3(0.3, 0.59, 0.11) ); is a vec3
and you need a vec4, so perhaps
vec4 desat = vec4( dot( col.rgb, vec3(0.3, 0.59, 0.11) ), 1.0 );
works

Thanks to the hint of Ippokratis I got the shader working.

It looks like this:

vec4 col 		= texture2D(_MainTex, uv) * _Color;
float d			= dot( col.rgb, vec3(0.3, 0.59, 0.11) );
vec4 desat 		= vec4( d, d, d, 1.0 );
gl_FragColor 	= mix( desat, col, _Saturation );

Now I have another problem, which might need a new new topic, I dont know, but I dont want to spam the forums.

When I try to set the properties of the shader from script, I get a null reference exception:

NullReferenceException
UnityEngine.Material.SetColor (System.String propertyName, Color color)
Tile.Update () (at Assets/Code/maps/UnitySlippyMap/Helpers/Tile.cs:56)

The line causing the exception:

// It doesnt work even if I set "Color" as property name parameter
material.SetColor( "_Color", TeasrUnity.Instance.mapTintColor );

The material is not null, I double checked that. Any ideas?

Hmm, apart from the error above, the GLSL Shader doesnt work on iOS. Any ideas why?

Which iOS device are you testing on? You can’t use GLES2.0 shaders (such as the one above) on devices before the iPhone 3GS - that’s the first one that supports 2.0. Before then you’re limited to fixed function shaders.

You can also use material.color = myColor which is a hard-coded version of setting the _Color value.

Might have better luck with that?

Also, I’m not sure, but material (lowercase) might be a reserved word like transform, gameObject, camera, etc are. Try changing it to myMaterial or mat or something like that?

Hi there,

I am testing on an iPad 1 and a Samsung Galaxy s2. I also tried the material.color shortcut before, which, by looking at the callstack, does the same thing as material.SetColor(x,y) and causes the same error above.

The “material” keyword is only a property of “Renderer”, so its not directly accessible in a MonoBehaviour. In my case its a cached variable of renderer.material, to avoid always calling the getter of property renderer.material.

Thank you for your feedback!

And TeasrUnity.Instance.mapTintColor isn’t null?

Can you do
material.SetColor( “_Color”, Color.red );
and have that work?

Hi there,

as of now, the shader is (and probably was) working on iPad and S2. Unity seems to become buggy at times, it didnt update the runtime project for xcode and the apk.

mapTintColor is a Color instance, thus a struct, which means its never null. So that cant be the error.

Thank you

Found the error, it was clearly my fault.

Thank you Farfarer and Ippokratis for your help, I appreciate very much!

what was the error!!.. please