Home Technical Talk

Normal maps messed up in Cycles (but not in Eevee for some reason)

Buffinbag
polycounter lvl 3
Offline / Send Message
Buffinbag polycounter lvl 3
While experimenting with different ways to bake an AO map for fairly lowpoly objects with normal maps on them inside Blender I noticed that - for some reason - normal maps don't display correctly on edges and cylindrical shapes.
So, I made a simple test object and baked normals for it in Marmoset Toolbag:




Then I've set up a scene with just an HDRI map as a background, no lights, and disabled color management.
The object material is also as simple as it gets:



And here's how it looks in Cycles:



My first thought was to check if the normal map is in correct format - well, it is, flipping the green channel makes things even worse. The interesting part is, the exact same scene in Eevee looks completely fine, just as it should



Am I missing something important here? Can this be fixed or is it just the way Cycles does things? 

Edit: whoops, forgot to add the file (and texture)

Replies

  • Neox
    Offline / Send Message
    Neox godlike master sticky
    could it be, that cycles and blender viewport do not use the same tangentspace?
    would be odd, but to be fair 3dsmax for the longest time had a mismatch between its baker and its viewport...
  • gnoop
    Offline / Send Message
    gnoop sublime tool
    its same way in almost every ray tracer vs rasterizer.  Not sure why.   Same  in Octane  for  example
  • okidoki
    Online / Send Message
    okidoki greentooth
    In Blender for normal maps the color space should be non-color..  :wink:
  • pior
    Offline / Send Message
    pior grand marshal polycounter
    @Buffinbag
    "Am I missing something important here?"

    Yes - the upload of your file !
  • Buffinbag
    Offline / Send Message
    Buffinbag polycounter lvl 3
    pior said:
    @Buffinbag
    "Am I missing something important here?"

    Yes - the upload of your file !
    Sorry, added it to the post
  • Buffinbag
    Offline / Send Message
    Buffinbag polycounter lvl 3
    okidoki said:
    In Blender for normal maps the color space should be non-color..  :wink:
    As far as I know it both linear and non-color work for normals in Blender, in this case neither of them solve the problem
  • Buffinbag
    Offline / Send Message
    Buffinbag polycounter lvl 3
    gnoop said:
    its same way in almost every ray tracer vs rasterizer.  Not sure why.   Same  in Octane  for  example
    Yeah I'd expect to see some differences between how they handle normal maps, but here the normal map is just straight up broken in the raytracer
  • Buffinbag
    Offline / Send Message
    Buffinbag polycounter lvl 3
    Neox said:
    could it be, that cycles and blender viewport do not use the same tangentspace?
    would be odd, but to be fair 3dsmax for the longest time had a mismatch between its baker and its viewport...
    Seems possible, especially considering that there is a way to bring these same shading artifacts in Eevee - I did that just by plugging the normal map into an AO node and looking at the isolated diffuse color render pass





    I have a sneaking suspicion that the AO node may be utilizing Cycles for its raytracing (I doubt that the folks who worked on it would decide to create a whole new raytracer just for this node), and as a consequence be using the same shading information as Cycles. If that turns out to be the case It would explain a lot of things, but still I wonder if I'd be able to work around that
  • pior
    Offline / Send Message
    pior grand marshal polycounter
    Heya - the texture file isn't included/packed.
    As for the possible difference between both renderers : in the case of Blender they are definitely supposed to behave the same, as this has clearly been the goal ever since Eevee first came out. So at the very least this means that whatever issue you are running into should be of some interest to the devs.
  • Prime8
    Offline / Send Message
    Prime8 interpolator
    I had a quick look at the file.
    Couldn't test in detail without the textures, but found a few things which might cause Cycles to render not as expected.

    In Color Mangement set Display Device to srgb and don't use a fully white colour in the material.

  • Buffinbag
    Offline / Send Message
    Buffinbag polycounter lvl 3
    pior said:
    Heya - the texture file isn't included/packed.
    As for the possible difference between both renderers : in the case of Blender they are definitely supposed to behave the same, as this has clearly been the goal ever since Eevee first came out. So at the very least this means that whatever issue you are running into should be of some interest to the devs.
    Completely forgot that the texture isn't packed into the .blend file, added it to the archive
  • Buffinbag
    Offline / Send Message
    Buffinbag polycounter lvl 3
    Prime8 said:
    I had a quick look at the file.
    Couldn't test in detail without the textures, but found a few things which might cause Cycles to render not as expected.

    In Color Mangement set Display Device to srgb and don't use a fully white colour in the material.

    Added the texture to the archive
    As for color management - yeah I also tried that, the issue doesn't go away, just becomes less noticeable


  • Prime8
    Offline / Send Message
    Prime8 interpolator
    I'm not sure, I think it is a shadow termination issue in Cycles. If you use a direct light you can see it mainly shows up on the shadow side.
  • EarthQuake
    It looks like in the Eevee version there isn't a shadow casting light. But in Cycles there is, possibly a sky or env light that can only cast shadows with ray tracing. This could be the reason for the difference. Try with direct lights only and see if that is any better.

    You can expect differences from reflections and GI in Cycles too, but that shouldn't cause the faceting that we're seeing here.
  • Buffinbag
    Offline / Send Message
    Buffinbag polycounter lvl 3
    It looks like in the Eevee version there isn't a shadow casting light. But in Cycles there is, possibly a sky or env light that can only cast shadows with ray tracing. This could be the reason for the difference. Try with direct lights only and see if that is any better.

    You can expect differences from reflections and GI in Cycles too, but that shouldn't cause the faceting that we're seeing here.
    Tried doing that, no HDRI, pure black background, one point light. Here's the result in Eevee:



    And in Cycles:



    The normal map seems to be doing its job, but there's still faceting on top of it
  • EarthQuake
    I think this is generally expected. The problem is that there is a large bevel represented in the normal map but not the geometry. The shadows are based on the geometry, to solve this I think you'll need to bevel the low poly as well.

    I checked in Toolbag and I'm seeing a similar issue, in both the raster (Eevee-like) and ray-traced renderer (Cycles-like).

    In Toolbag this can be improved by adjusting the shadow offset. I think Blender has a similar setting but I forget what it's called.


  • Buffinbag
    Offline / Send Message
    Buffinbag polycounter lvl 3
    I think this is generally expected. The problem is that there is a large bevel represented in the normal map but not the geometry. The shadows are based on the geometry, to solve this I think you'll need to bevel the low poly as well.

    I checked in Toolbag and I'm seeing a similar issue, in both the raster (Eevee-like) and ray-traced renderer (Cycles-like).

    In Toolbag this can be improved by adjusting the shadow offset. I think Blender has a similar setting but I forget what it's called.
    Yeah, I can see similar stuff in Marmoset too, turning on raytracing really messes things up



    That would be really unfortunate if it turns out to be a given with all raytracers. I know that at least 3DS Max's Scanline renderer doesn't have such issues with normal maps, but I'm not sure if that piece of ancient technology has anything in common with modern ray-tracing engines.

    Modifying the geometry to support the normal map isn't really an option in my case, since I work with the kind of game assets where tris are limited and the normal map does the heavy lifting, so to speak, so guess I'll have to keep looking for ways to minimize these artifacts (or think about ditching raytracers from my workflow alltogether)
  • gnoop
    Offline / Send Message
    gnoop sublime tool
    From my experience  it's same in every  ray-tracer I tried.  And always been that way.     Mostly coming from  sky/environment light .    Guess it's why  they do small quads with displacement + actual bevels   instead of hard edges outside of gamedev.       Hard edges is a gamey thing.

    Actually I have seen a subtle  hard edge  reveling with  Unreal4  too  with  some older indirect illumination baking  technique .  A while ago.  It have never been 100% seamless  up close.  
    I also think the hard edges  are getting revealed  by Evee  too if you turn on "contact" shadows.  Same reason . They use a sort of ray tracing.
     
  • EarthQuake
    Yeah, the crux of the issue is that a normal map can fake shading, but it can't fake the actual geometry, which is used for shadowing.

    For best results, the normal map should be used to represent fine detail that doesn't affect the silhouette, while the primary forms should be represented in the low poly. Of course, you'll be triangle-limited depending on the project, target hardware, etc. But generally, if you can't afford to bevel a cube it's probably not a very important asset or something you would inspect up close. So I would think about presenting it more how you might view it in the game in these cases.

    It's also worth noting that the vertex cost for adding a hard edge is roughly the same as beveling the edge. There's a small cost for the additional triangles, but it's really the vertex count that tends to matter for performance. In many cases, you'll be draw call limited as well, and there may not be any difference between a 300 triangle or 3000 triangle mesh on modern hardware, drawing it as a unique object is the expensive part.
  • Buffinbag
    Offline / Send Message
    Buffinbag polycounter lvl 3
    Thanks for the replies, that really clears up a lot of weird stuff I encountered while working on game assets. That knowledge is definitely gonna come in handy, especially considering how common raytracing in games is becoming these days 
Sign In or Register to comment.