Cycles and surface normals (normalmap shading)

Really nice, thank you so much!
Btw, is this working also in the bump node? Or is it only a NormalMap node fix?

wow, thanks for the support!

I definitely didn’t test with SSS, but I don’t see why it would work.
Indeed, this is just diffuse rays. not only diffuse textures, but any ray’s diffuse component should be affected…

…this includes bump maps, displacement maps used as bump, and normal maps, because I’m a bit of an madlad/idiot and my first PR is the BSDF in the cycles kernel to fix something that bugged me since 2019. So theoretically literally anything that uses tangent space bumps in a BSDF. The moon example is actually using a grayscale tiff file directly from NASA, and just sending the bump node results straight into a principled bsdf.

edit: and I’m still going to be working on glossy reflections. they are… a whole other beast.

firstly, I need to separate bump correction and intersecting bounce correction. These really should not have the same flag. they’re both related to bump, but have wildly different effects. one handles light at glancing angles, the other affects reflections, caustics, and so on.

most notably no one has found a reasonable way to handle backfacing normals in path tracing. like, ever. to add insult to injury, finding papers on it is hard, if there are more than a handful, even.
The current implementation simply flattens the rays till they’re parallel with the surface. The easiest way to do this is to curve the transition, so only the worst acting rays get flattened. basically the more it would intersect, the closer to flat it returns. Downside? it’s better than now, but basically forces a maximum steepness to glossy normal maps.

The implementation I would like, is a sort of self-reflection, or inherent multi-reflection. The idea is, in real life, if something was to come in at a very shallow bounce, and hit a rather smooth thing, it would act like a reflection, whether it hit once or twice. self-reflection would be nice, but at that point you’re 80% of the way to POM

8 Likes

This works with SSS, the limitation mentioned is not on your side.
In any case, the result is already very good.

ah! i thought you wanted to know if it affected subsurface scattering, I.E. the actual SSS “pretend you’re spreading through a solid and coming out different” stuff. if SSS has a diffuse component, it’ll work. it’s because the changes are in the bsdf.h file- so i guess it could affect anything that could draw from a normal map. i’ll admit, I’m feeling now that my test suite was shortsighted, just being a principled or diffuse sphere with some common bump and normal maps applied.

semi-bump, semi-PSA:
The normal map correction change has been merged!

Now- the work on this thread isn’t done yet; I joined it specifically to address the glossy normal correction issue, and then discovered that normal correction flag controls multiple functions that don’t actually relate to each other.

next on the docket is separating diffuse normal map correction and glossy normal map correction, which sound like they should be linked, but diffuse normal correction adds shading to terminators, while glossy normal correction affects the actual trajectory of rays and sampling.
It would be more apt to call a glossy normal correction option “bump reflection correction”, “negative reflection handling”, “sub-tangent reflections”, or simply “negative reflections”, which would let the option explain itself and delineate it from normal correction.

After a lot of thinking on the subject, I want there to be a drop-down for bump reflection handling. There are a number of algorithms, and depending on the software or look you prefer, they are all used interchangeably in production. The primary methods are:

  1. reduced normal height- by reducing how extreme normals can be, negative normals can’t occur below an arbitrary strength.
  2. clipped normal reflections- this is what blender uses. below a certain tangent, all reflections are set to an arbitrary angle (in blender’s case, parallel to tangent)
  3. smoothed clipped reflections- by clipping reflections earlier, you can “reserve some space” and make only the most negative reflections equal 0, with less extreme negative normals set above 0. This is incorrect, but makes a very coherent image.
  4. reflection- it is assumed any tangent below 0 will reflect in the opposite manner. for concave reflections this may produce artifacts, but overall it is a very performant, simple method, even compared to blender’s current clipping method
  5. implicit bounces- if a tangent is below zero, redo the calculation with the outgoing angle as the new incoming angle. Technically energy conserving, but does not apply light to a diffuse component, so inaccurate rougness, but very accurate light propagation
  6. true multi-bounce- same as implicit bounces, but energy conserving because it applies energy loss and lighting. requires more dedicated reworking of sampling, and can double the performance hit of bump maps. great for highly reflective scenes or concave reflective objects.
  7. internal multi-reflection- this is a compliment to self shading normals, and allows textures to effectively bounce light “inside” themselves using a displacement map, often stored in the alpha channel

I’m sure at least some of these can be implemented with minimal trouble- notably reduced normal strength, smoothed clipping, implicit bounces, and reflection(my current fascination) alongside the current clip method and “none”. 6 visually distinct varieties of bumpy reflection handling would definitely call for a dropdown. multi-bounce and internal reflections would interfere, so should be on the same drop-down, but require more changes to a wider breadth of blender to enable… and probably aren’t worth it for now.

18 Likes