Search Unity

Can you use a specular map with a fixed pipeline?

Discussion in 'Shaders' started by Jessy, Oct 28, 2009.

  1. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    I don't know enough about Cg yet to be able to pick apart the specular shaders, so I don't know what the common way of handling a specular map is. My theory is that you'd just take the specular lighting calculation and use a "lightmap" on it. There aren't any examples of this technique that I can find, however.
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    specularity only exists with lights and real lights (pixel lights) don't exist in fixed function. fixed function interpolates basing on polygons which is commonly insufficient for any kind of real specularity.

    But you can naturally treat it as some kind of lightmap.
    That isn't really cheap but you can use the specularity map to brighten a lightmap through an additive pass.

    Question is how much you gain from that or if it even makes any difference because good lightmaps should already have these informations baked in by default.
     
  3. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    You can't bake in information that is variable in-game. I'm not talking about using a lightmap in the standard sense, where it just acts as another light. But it would work similarly (that is, it just darkens/colorizes what is already there) - if you only take the result of the specular calculation, and then multiply in some color, I would think you'd end up with something like this. Unless somebody tells me otherwise, I'm going to try making such a shader today.

    (And yes, I know it won't look like much of anything if I just have 4 vertices like in that example.)
     
  4. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    I guess I don't understand.

    Lightmaps are static, they can't be dynamic as they are used to lighten the otherwise massive costs of the lighting that ffp hardware just is not able to cope with.

    But perhaps you mean the variable on the specular end.
    Thats naturally possible if you alter it for some reason.

    Doing such a shader is definitely possible. There are different approaches to it from blending to overwriting data etc.
    I think you only need to build the passes in the correct order (lightmap + specular first then the lm-spec + diffuse) to have it working.

    used similar approaches back in DX7 for "texture lights" by switching textures on the higher textures stages in and out.
     
  5. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    You can certainly have a specular map in fixed function lighting. Just remember that it can only modulate the strength, not the exponent of the specular calculation. A shader that did this would need two passes because the lighting calculation needs to be split into ambient/diffuse, and then the specular. The passes can be done in any order, because they would be summed. The diffuse pass would be your regular diffuse pass, withou defining a specular colour. The specular pass would have a white specular colour, but not define anything else. The result of this lighting calculation would then be multiplied by the specular map (which could be any colour!) and the final result would be added to the destination. The specular pass should only require one texture operation.
     
  6. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Thanks, Daniel. That was the approach I took, so I'm glad to hear I was on the right track. As I mentioned in the grayscale bumpmap thread, my girlfriend is supposed to make a bump, specular, and self-illumination map this week. We'd never worked with either before yesterday (except normal maps, which aren't covered in the class yet :wink:), but I think I get the gist of things. However, as the name of the shader suggests, I think the "bump map" portion is kind of stupid.

    You think there is any way to combine these things with a 2-texture card?

    Code (csharp):
    1. Shader "Full-Color Glow  Specular + Lame 'Bumpmap'" {
    2.    
    3.  
    4. Properties
    5. {
    6.     _Shininess ("Shininess", Range (0,1) ) = .7
    7.     _Bumpiness ("Bumpiness", Range (0,1) ) = .3
    8.     _MainTex ("Texture (RGB)", 2D) = ""
    9.     _MaskedGlow ("Self Illumination with Mask", 2D) = ""
    10.     _SpecularBump ("Specular Map (RGB) + Bumpmap (A)", 2D) = ""
    11. }
    12.  
    13.  
    14. SubShader
    15. {
    16.     Lighting On
    17.     Blend AppSrcAdd AppDstAdd
    18.    
    19.     // Diffuse
    20.     Pass
    21.     {
    22.         Material
    23.         {
    24.             Diffuse (1,1,1)        
    25.         }
    26.        
    27.         // Subtract the inverted heightmap.
    28.         SetTexture [_SpecularBump]
    29.         {
    30.             combine primary - one - texture alpha
    31.         }
    32.        
    33.         // Add bumps.
    34.         SetTexture [_]
    35.         {
    36.             constantcolor (0,0,0, [_Bumpiness])
    37.             combine previous lerp (constant) primary
    38.         }
    39.        
    40.         // 'Light' the texture.
    41.         SetTexture [_MainTex]
    42.         {
    43.             combine texture * previous
    44.         }
    45.        
    46.         // Blend in self-illumination texture.
    47.         SetTexture [_MaskedGlow]
    48.         {
    49.             combine texture lerp (texture) previous
    50.         }
    51.     }
    52.    
    53.     // Specular
    54.     Pass
    55.     {
    56.         Material
    57.         {          
    58.             Specular (1,1,1)
    59.             Shininess [_Shininess]
    60.         }
    61.        
    62.         // subtract the inverted heightmap
    63.         SetTexture [_SpecularBump]
    64.         {
    65.             combine primary - one - texture alpha
    66.         }
    67.        
    68.         // Add bumps.
    69.         SetTexture [_]
    70.         {
    71.             constantcolor (0,0,0, [_Bumpiness])
    72.             combine previous lerp (constant) primary
    73.         }
    74.        
    75.         // Colorize the grey-white specular highlights.
    76.         SetTexture [_SpecularBump]
    77.         {
    78.             combine texture * previous
    79.         }
    80.     }
    81. }
    82.  
    83.  
    84. }
     
  7. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    I don't think you can get what you want from the iPhone. You'd have to do something like remove the Bumpiness property, and just bake that into your bump texture.
     
  8. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Unless I'm wrong (did only do small things yet with it), those shaders won't work anyway because your passes use more textures than you have per pass, at least if you intend to target pre 3GS hardware.
     
  9. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    What do you mean by "your passes use more textures than you have per pass"?
     
  10. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    The pre-3GS iphones only have a 2 texture unity graphic chip, which basically means that any texture after the second one in a pass is ignored. Above passes are 3 and 5 texture passes unless I missunderstood how combiners work, which means either invalid or 3GS only.
     
  11. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Ok, I thought you were talking about some other limitation. Jessy already asked whether the shader could be modified to work on a 2 texture card, which means the iPhone these days.

    Unfortunately, where Jessy's version uses 4, then 3 texture units, was only able to reduce it to 2, 1, 1, 3. The specular pass can't be made smaller due to the operations required for the bump map scaling. If the bumpiness property were baked into the texture, the shader could be done in passes with 2, 1, 2 operations.