Search Unity

I Found a Problem With Metallic Rendering

Discussion in 'Shaders' started by King-Hayve, Feb 7, 2016.

  1. King-Hayve

    King-Hayve

    Joined:
    Aug 28, 2015
    Posts:
    7
    Hi, I believe I've stumbled upon a bug in the shaders while trying to keep my terrain from looking shiny. I'm going to try to explain this as best as possible since I do not know much about shaders.

    I was editing the terrain shader trying to see if I could make any small changes in the code to keep my terrain from looking shiny, and one of the changes I made was to take manual control of the metallic value like this:


    When experimenting with this value I found something that doesn't seem right about the way Unity renders the metallic value.

    I think the metallic effect is supposed to be comprised of 2 basic effects that I will call "Light effect" and "Dark effect" as seen in these pictures, the Dark effect seems to render correctly based on the value, but the Light effect seems to be reversed from what it is supposed to be.

    This is with o.Metallic set to 0.0, The light effect generally brightens the whole terrain in this picture but I highlighted the more prominent parts.:


    This is with o.Metallic set to 1.0:



    These next pictures I hope will explain the problem sufficiantly:





    It seems to me that inside the rendering code the value for "Light effect" needs to be multiplied by -1 to fix this problem, so that it is at full strength when o.Metallic = 1.0 and not when it is at 0.0

    Hopefully someone will understand this? If I am right I would very much like this bug to be fixed so that my terrain will not look shiny even when it's metallic value is 0.0

    Thank you for reading.
     
  2. Skolstvo

    Skolstvo

    Joined:
    Dec 21, 2015
    Posts:
    107
    That seems like the reflection is showing. What do you mean by dark and light effect?
     
  3. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    That's not wrong, I think you just misunderstand what PBR is and what's happening.

    At glancing angles, all surfaces will reflect a nearly all of the light that hits it. For dielectric surfaces (i.e. non-metals) the reflected light is the same colour as the incoming light. This means that at glancing angles, all things are "shiny".

    When you set something to metallic, the reflected light is coloured by the diffuse color of the surface (and the surface's diffuse colour is set to black). This is because metallic surfaces don't actually have a diffuse colour, their colour comes entirely from reflected light.

    So, in essence, by making your terrain completely metallic, what you're doing here is making your terrain reflect light in the same colour as the terrain.

    Which is why that colour changes, the areas you're saying are wrong when not metallic it might look right in this particular scene when you force them to be metallic, but it's not actually correct.
     
  4. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Even though in the physical world everything reflects a bit at grazing angles, I still don't agree that Unity forces this.

    It's fine by me that the standard shader follows this rule of always reflecting, but this rule is actually enforced one level deeper. Even if you write your own deferred shader that outputs pure black as reflection value to the g-buffer, Unity still adds reflection. That to me is not the correct way.

    Moreover since Unity is mainly used for games and these don't always need to represent the physical world.

    So again, I have no problem with the standard shader always outputting a reflection at grazing angles, being a PBR shader. But the engine adding reflections even if the reflection value is 0 in the g-buffer is one step to far in my opinion.

    Anyway, a work around is to decrease the smoothness/increase the roughness to reduce the visibility of the reflections.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    Don't use the standard shader, or use the standard specular shader which gives more control (though I don't know if you can use that with terrain). The standard shader is for physically based stuff and not intended for fully non realistic shading. The legacy shaders are a better fit for this.
     
  6. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    I use my own deferred shaders, but writing reflection color as 0, 0, 0 still shows reflections. That's my whole point. I don't mind the standard shader always writing a non-zero reflection color. But I do mind a zero reflection color still leading to reflections.
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    If you don't like the behavior you can override the deferred reflections shader. It is a little odd it still shows reflections with the all zeros, though not entirely surprising since there's often an epsilon someplace for this kind of shader code.
     
  8. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Thanks, I know. I haven't gotten around to that and it is frankly one step more than I was hoping would be needed.

    I don't think it's an epsilon. The effect is a bit too strong for that. It's just the everything reflects at grazing angles PBR rule that is implemented one layer lower than I hoped for.