Home Technical Talk

Specular Maps obselete?

polycounter lvl 6
Offline / Send Message
dar0005 polycounter lvl 6
Hello , i have i question I've been wondering about for sometime. Are specular maps obsolete now and rendering have moved to reflective and gloss maps or does the texture type you use depended on the program?


  • Hito
    Offline / Send Message
    Hito interpolator
    I don't think it's obsolete... just a name change. still the same RGBA channels just driving different shader behaviour.
  • Joopson
    Offline / Send Message
    Joopson Polycount Sponsor
    There are two major workflows now, depending on the Engine and personal preference. Specular/Gloss, or Metalness/Roughness. Specular is still very much a useful map.
  • Panupat
    Offline / Send Message
    Panupat polycounter lvl 15
    For animation and feature film we still use the spec/gloss workflow most of the time. I personally find it easier to comprehend too when 1 = fully reflective and 0 = none.
  • dar0005
    Offline / Send Message
    dar0005 polycounter lvl 6
    How would one determine whether to use Specular/Gloss or Metalness/Roughness?
  • EarthQuake
    Typically, it will depend on what your engine uses. UE4 for instance, uses the metalness/roughness workflow.

    Recomended reading:


    The last one covers the differences between the two common workflows (and the difference between older gen workflows) in detail.
  • dar0005
    Offline / Send Message
    dar0005 polycounter lvl 6
    Thank you for the links i will read them to better understand this
  • echofourpapa
    Offline / Send Message
    echofourpapa polycounter lvl 4
    Unity gives you the option to use either spec/gloss or metal/rough(well, smooth anyway).  I remember at one point Aras at Unity posted on their forums that spec/gloss was more correct but metal/rough was faster.  I don't know how true that holds in all cases, but it's probably safe to assume it's true in Unity.
  • sprunghunt
    Offline / Send Message
    sprunghunt polycounter
    The metalness workflow can save texture memory as you can sometimes pack the two channels needed into a single texture. This leaves an extra channel free to hold other information like Ambient Occlusion data, height maps, or transparency. This assumes you have the kind of flexibility that allows you to change the shader to source data from various channels. 

    Personally the I find the metalness workflow in Unity 5.x is very inefficient for texture memory as it relies on packing the smoothness value into the alpha channel and wasting the Green and Blue channels. In the case of the Unity standard shader using a specular texture is probably the better choice.

    So these are the kinds of things you might want to take into consideration when thinking about metalness vs specular.
  • echofourpapa
    Offline / Send Message
    echofourpapa polycounter lvl 4
    The green channel isn't really "wasted" in Unity.  Both AO and Height read from the green channel, so you can pack (R)Metal (G) AO or Height and (A)Smoothness. It just shows up as a separate texture assignment.

    The blue channel is, in fact, wasted.  Makes no sense.

    If you are doing any iOS work, avoid any 4 channel Textures.  I've found out recently that PVR rgba compression KILLS quality, but PVR rgb does not.  If you are doing PBR on iOS I would recommend Metalness because you can pack most everything you need into three Textures of three channels, but with Specular you have to use four channels or four Textures.
  • EarthQuake
    Yeah Unity's texture packing method is really dumb. If you have a 32 bit image, you're using the same VMEM as 2 24 bit images (assuming you have compression enabled), which means you could use a full color specular map, and a RGB map packed with gloss, AO, and a 3rd map (height? alpha? emissive?) for the same cost.
  • JedTheKrampus
    Offline / Send Message
    JedTheKrampus polycounter lvl 8
    The reason why they do it that way is to avoid creating more DXT1 compression artifacts between the channels.
  • echofourpapa
    Offline / Send Message
    echofourpapa polycounter lvl 4

    Are you saying that this:
    Albedo RGB - color
    Spec RGB - color
    Mask RGB - Gloss, AO, Alpha
    Normal - RGB - normals

    Is less memory than this:
    Albedo RGBA - color & alpha
    Spec RGBA - color & gloss
    Normal RGBA - normal & height(or maybe AO)

    Metal/Rough is still less then because you could do:
    Albedo RGB -color
    Masks RGB -Metal, AO, Rough
    Normal RGB - normals(maybe even just XY normals in RG and height in B )
  • EarthQuake
    Echo: I'm not saying it has less, I'm saying it's the same, specifically with Unity 5. But specular maps are more flexible than metalness (if you want non 4% values for insulators in the metalness workflow you need to use yet another secondary specular map).

    Unity's workflow forces you to use a 32 bit image rather than a 24 bit image, with a wasted channel (8+8+8+8 = double the size of 8+8+8 with DXT). So you lose the primary advantage of the metalness workflow, memory savings, while being stuck with the restrictions of the metalness workflow, less flexibility and worse artifacts (nasty white edges near material transitions).

    You can pack metalness workflow content into less space, with engines like UE4 for instance, but not with Unity, as far as I am aware.
  • echofourpapa
    Offline / Send Message
    echofourpapa polycounter lvl 4
    Ah, I see.  I never though of that before.  Thank you .  :smiley:  

    You can fairly easily "write you own" shader in Unity, which is what I usually end up doing, to remove smoothness from the alpha of a metallic map.

     Create a new shader with by Assets -> Create-> Shader -> Standard Surface Shader and add in the two new textures and their output assignments.  

    You could use something Shader Forge or you can do it through code something like this:

    Shader "Custom/MetalPacked" {
    Properties {
    _Color ("Color", Color) = (1,1,1,1)
    _MainTex ("Albedo (RGB)", 2D) = "white" {}
    _MasksTex("Metal (R) AO (G) Smoothness (B)", 2D) = "white" {}
    _NormalTex("Normal (RGB)", 2D) = "white" {}
    SubShader {
    Tags { "RenderType"="Opaque" }
    LOD 200
    // Physically based Standard lighting model, and enable shadows on all light types
    #pragma surface surf Standard fullforwardshadows
    // Use shader model 3.0 target, to get nicer looking lighting
    #pragma target 3.0
    sampler2D _MainTex;
    sampler2D _MasksTex;
    sampler2D _NormalTex;
    struct Input {
    float2 uv_MainTex;
    fixed4 _Color;
    void surf (Input IN, inout SurfaceOutputStandard o) 
    // Albedo comes from a texture tinted by color
    fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    half3 normal = UnpackNormal(tex2D(_NormalTex, IN.uv_MainTex));
    half3 masks = tex2D(_MasksTex, IN.uv_MainTex).rgb;
    o.Albedo = c.rgb;
    o.Normal = normal;
    o.Occlusion = masks.g;
    o.Metallic = masks.r;
    o.Smoothness = masks.b;
    o.Alpha = c.a;

    FallBack "Standard"
  • echofourpapa
    Offline / Send Message
    echofourpapa polycounter lvl 4
    I seems the code tags in the new theme don't work?
  • dar0005
    Offline / Send Message
    dar0005 polycounter lvl 6
    I am a little lost about using different maps in different channels, could someone clear this up for me or post an example?
  • EarthQuake
    Echo, yeah, a custom shader is a good way to sort out the issue.

    Dar, its a very simple concept. For texture maps that only need grayscale inputs, you can pack multiple inputs into the red, green, blue (and alpha) channels of a single image. Think of each of those channels not as the colors they represent, but as individual grayscale channels.

    Does that clear it up?
  • dar0005
    Offline / Send Message
    dar0005 polycounter lvl 6
    yes it does , so basically use a gray scale map in each one of those channels if necessary or just one of them?
Sign In or Register to comment.