Search Unity

Basic Shader using only one channel of a texture (texture splat)

Discussion in 'Shaders' started by melong, Sep 2, 2011.

  1. melong

    melong

    Joined:
    Sep 2, 2011
    Posts:
    22
    Hi everyone,

    I'm just beginning to learn how to write my own shaders, and here's what i came up with:

    Code (csharp):
    1. Shader "StrumpyShaders/Basic_AlphaMapSplatR - GLSL"
    2. {
    3. Properties
    4. {
    5. _Color("Color", Color) = (1,1,1)
    6. _AlphaMap("AlphaMap", 2D) = "black"
    7. }
    8.    
    9. SubShader
    10. {      
    11. Pass
    12. {
    13. Tags {"queue"="Transparent"}
    14. Blend SrcAlpha OneMinusSrcAlpha
    15. Zwrite Off
    16.            
    17. GLSLPROGRAM
    18.            
    19. varying mediump vec2 uv;
    20.                
    21. uniform lowp sampler2D _AlphaMap;
    22. uniform lowp vec3 _Color;
    23.    
    24. #ifdef VERTEX
    25. void main()
    26. {
    27. gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    28. uv = gl_MultiTexCoord0.xy;
    29. }
    30. #endif
    31.    
    32. #ifdef FRAGMENT
    33. void main()
    34. {
    35. vec4 AlphaMap = texture2D(_AlphaMap, uv);
    36. vec4 AlphaChannel = AlphaMap.r;
    37. gl_FragColor = vec4(_Color, AlphaChannel);
    38. }
    39. #endif  
    40. ENDGLSL
    41. }
    42. }
    43. }
    So this is a GLSL shader as you can see, and the idea is to use only one channel of an image (here it is the red channel) as alpha map so that i could store up to 4 greyscale alpha textures in only one image.
    It worked quite well back on the computer where i wrote this shader but when i came back home to use it on my own one, it doesn't work anymore and i get the following error :
    "No subshaders can run on this graphics card"
    and
    "GLSL Error in Fragment Shader: Fragment shader failed to compile with following errors: ERROR: 0:37: error(#160) Cannot convert from 'high float' to 'highp 4-component vector of float' ERROR: error(#273) 1 compilation errors. No code generated at line 0"

    Thank you for your help :)
     
  2. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Color properties are float4s (or vec4s in GL, I guess).

    Also, you're assigning your alpha channel to be a vec4 - it only needs to be one channel so you need it to be just a float. I think that's what your error's about.

    I'm not really up on GLSL, but this might work better (bold bits are bits I've changed);

    Code (csharp):
    1.  
    2. Shader "StrumpyShaders/Basic_AlphaMapSplatR - GLSL"
    3. {
    4.     Properties
    5.     {
    6.         [b]_Color("Color", Color) = (1,1,1,1)[/b]
    7.         _AlphaMap("AlphaMap", 2D) = "black"
    8.     }
    9.        
    10.     SubShader
    11.     {      
    12.         Pass
    13.         {
    14.             Tags {"queue"="Transparent"}
    15.             Blend SrcAlpha OneMinusSrcAlpha
    16.             Zwrite Off
    17.                        
    18.             GLSLPROGRAM
    19.                        
    20.                 varying mediump vec2 uv;
    21.                                
    22.                 uniform lowp sampler2D _AlphaMap;
    23.                 [b]uniform lowp vec4 _Color;[/b]
    24.                    
    25.                 #ifdef VERTEX
    26.                 void main()
    27.                 {
    28.                     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    29.                     uv = gl_MultiTexCoord0.xy;
    30.                 }
    31.                 #endif
    32.                    
    33.                 #ifdef FRAGMENT
    34.                 void main()
    35.                 {
    36.                     vec4 AlphaMap = texture2D(_AlphaMap, uv);
    37.                     [b]float AlphaChannel = AlphaMap.r;
    38.                     gl_FragColor = vec4(_Color.rgb, AlphaChannel);[/b]
    39.                 }
    40.                 #endif  
    41.             ENDGLSL
    42.         }
    43.     }
    44. }
    45.  
     
    Last edited: Sep 2, 2011
  3. melong

    melong

    Joined:
    Sep 2, 2011
    Posts:
    22
    Thank you very much farfarer for this quick reply.
    It's working now :)

    I didn't see this technique treated often so i'm wondering if it makes sense using it on mobile platforms such as iphone.
    Do you think it's worth doing such optimization ? Wouldn't there be some drawbacks ?
     
  4. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Really not sure. I'd add a selector for which channel to use, otherwise you'll only increase your draw-calls by needing one shader per channel used.

    But then I'm not sure whether adding in if statements would affect the performance of the shader much.
     
  5. melong

    melong

    Joined:
    Sep 2, 2011
    Posts:
    22
    I guess i should run some test to see how it affects performance. At least i hope it can saves on the texture size part.