Fix #109679: Normal map strength is applied incorrectly #109763
No reviewers
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Viewport & EEVEE
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Module
Viewport & EEVEE
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Severity
High
Severity
Low
Severity
Normal
Severity
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
8 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#109763
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "kaspian.jakobssongmail.com/blender:fix-normals"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Previously the normal strength calculations were linearly extrapolating
the supplied normal map respect to different scaling in the xy resp.
z-axis. This new method takes this into account and applies it in the
correct way.
The calculations are identical to the ones presented in #109679 but
translated into glsl.
Please see #109679 for more information and background.
Previously the error was presented in the following way:
(strength = 20 for clearer example)
Where the left side of the normal map is the node group and the right side is the normal map node
And now they are applied in the same way as the node-group suggested in #109679:
I've attached a test file with a packed normal map which can be used to reference previous version of blender and with this fix applied.
normal_map_test_3.3.blend
normal_map_test.blend
I believe this is the correct way of scaling normals based on the previous discussion but I'm open for suggestions.
Thanks for the PR! Are you able to attempt a fix for Cycles[1] and OSL[2] as well? The .glsl is only used for Eevee.
[1] https://projects.blender.org/blender/blender/src/branch/main/intern/cycles/kernel/svm/tex_coord.h#L266
[2] https://projects.blender.org/blender/blender/src/branch/main/intern/cycles/kernel/osl/shaders/node_normal_map.osl#L6
This looks good to me. Although I am not sure what we are our reference in this case. What standard are we trying to match?
I would also see that fixed for Cycles in the same PR to avoid introducing discrepancies between renderers.
@brecht maybe you have an opinion on this subject since it break compatibility of a core functionality.
Also note that formatting is incorrect. Please run
make format
in theblender-git
directory to fix this.Thank you for the comments and reviews.
I'll update the PR with Cycles and OSL support, and fix the formatting issues when I get home from work.
Also - I'll update this comment with a bit more background regarding the material I referenced, as to further make sure the change is actually sound :-)!
BR,
Kaspian
This seems to assume the normal being mixed is in tangent space, but I think it's in world space here? So it would work for a plane pointing along the Z axis, but not other shapes.
If the logic is deemed to be sound, then be sure to include some explanation comments in the code as well! ;)
I noticed the same thing. My original setup is in tangent space, this code will need to be too.
@brecht @Alex-R-Heskett you're both entirely right, it looked correct when doing it in world space as well but I think that was a happy coincidence rather than it being correct! :-)
My latest commit corrects this by simply scaling the x and y components before doing the transform from tangent-space to world-space. I've also added support for Cycles and OSL, formatted and added comments.
Here's a first preview comparing the Eevee edition, it's a bit hard to see on the scaled sphere but it works anyway.
Here's some links for reference:
https://computergraphics.stackexchange.com/questions/5411/correct-way-to-set-normal-strength
https://github.com/TwoTailsGames/Unity-Built-in-Shaders/blob/master/CGIncludes/UnityCG.cginc
With the relevant snippet here
I'll add some more comparisons with the Cycles/OSL support soon!
And here is the setup in cycles and OSL!
The previous linear extrapolating behaviour is also kept for object-, world, blender object-and blender world space, in order not to break compability and/or continue a discussion what the desired behavior should be. But I think that might be a discussion for another issue/PR :-)
This looks fine to me now.
It's breaking compatibility, but I think it's acceptable for 4.0, and adding an option or inserting nodes for the old behavior does not seem worth it.
@blender-bot build
The author name in the
git log
has some strange special character in it:When we squash commit this it won't be a problem, but just FYI, you might want to change the config for future commits.
Hmm, I think that tangent space is probably what most people are using in their files.
So unless there is a good reason not to, I would think just fixing all of them in one go would be the best as we are already going to break the mode most people are using.
But of course this is up to Clement and Brecht to decide.
One reason would be that it is expensive to go into tangent space just for that strength parameter. It is possible, but I don't know if it is worth it.
Misclick with the re-requested review @brecht, sorry!
Thank you for all the reviews and comments! I'll look more into whether a implementation that's only dependent on the last mix of normals can be done - as it should be to only scale the normals after the transformation from tangent-space to world-space is applied, right?
I'll submit another PR if that is the case, otherwise for this PR tangent space is probably the best way forward to correct it (for now).
BR,
Kaspian
This patch introduces quite some noise in the benchmark bmw27 scene, because that scene uses a texture with possible negative
color.z
, causing some normals to be pointing in the wrong hemisphere after this change. Not sure if we should check the sign, but still I would expect the normal to stay unchanged ifstrength == 0
.This expects the Blue channel of the normal map to be in the 0.5-1 range.
@kaspian.jakobssongmail.com are you looking into a solution for this? Or shall we solve it?
It wasn't immediately obvious to me how best to do it.
@brecht
I'll take a look at it and let you know if I can't fix it in the upcoming days
Hi!
Due to an oversight from my part the z-part wasn't actually scaled but that is now remedied following [1]. The noise introduced in the BMW scene was due to not actually scaling the z-normals whatsoever, but this is corrected with the latest commit.
[1] https://docs.unity3d.com/Packages/com.unity.shadergraph@7.1/manual/Normal-Strength-Node.html
OSL with the patch:
Blender 3.3:
Edit:
Doesn't seem as this PR is following my branch still, unsure how to push to this now since it's merged? Maybe start a new PR?
Here's the relevant commit anyway:
https://projects.blender.org/kaspian.jakobssongmail.com/blender/commit/15615bad476352f840a80a71d2825f0b7952907b
@kaspian.jakobssongmail.com you need to create a new PR.
This is because you can't really merge a pr multiple times, or at least you are not supposed to.
The noise in the BMW scene is due to the CarShellNew material using Noise Texture as a normal map which produces RGB values with range 0 to 1 which should be 0.5 to 1 for the blue channel.
If one will search "normal map online" or "generate normal map" the first URL is https://cpetry.github.io/NormalMap-Online/ which generates normal maps with the blue channel with range 0-1 by default.
Thanks, @kaspian.jakobssongmail.com, I pushed the fix to main. It seems to work well in my tests.
@unwave you can check tomorrow's daily builds to see if solved your examples. It's possible to create normal maps like that where the normals goes below the surface, I'm not sure we'll every be able to render those well but hopefully no worse than before now.