EEVEE-Next: Thickness ouput behavior #120384
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
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
EEVEE & Viewport
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
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
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
EEVEE & Viewport
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
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
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
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#120384
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
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?
The EEVEE rewrite introduced the
Thickness
material output.This parameter is used for approximating the inner geometry structure of the object without having to rely on raytracing for that. This is currently used for SSS, Translucent BSDF, Refraction BSDF and the nodes containing them.
It is used for computing the exit location and normal of transmission rays within an object.
In other render engine, this is computed either by:
We chose this last option for the following reasons:
Model Approximation
For all effects needing it, we consider the local geometry either as a sphere tangent to the shading point and of diameter
Thickness
, or as an semi-infinite slab of same thickness.Other Standards
Adobe Standard Material
The Adobe Standard Material has a reference to a similar parameter called
Volume Thickness
.The usage is different (as it is for volumetric approximation) and there is no mention about how the average is computed (uniform cone? cosine lobe?).
However, the parametrization is quite good (object local) as it can be baked into texture maps in LDR and reused across assets.
In addition, there is a
Volume Thickness Scale
parameter to scale theVolume Thickness
after baking.Output Node Socket Behavior
The output thickness value is treated as local space thickness. This mimics the displacement output and allow for a similar workflow (an intermediate node is used to scale back to world space if needed).
A value of 0 assumes the object is single sided and will only model one transmission event.
Unconnected Socket
An unconnected socket will infer the size of the whole object based solely on its bounding box largest axis length and assume uniform thickness. While this is a very crude approximation, this will match perfectly for sphere objects and give relatively good result for simple objects.
Note that considering the smallest axis might be better as it would allow for a single sided plane to have correct refraction.
This behavior is still opened to discussion. The other possibility is to assume 0 thickness and use one transmission event by default.
Versioning
Compatibility with older file should be as simple as adding a value node to the output and set it to the value that
Refraction Depth
.Input Data Baking
Generating good input data is not so trivial. We are reducing the model complexity quite drastically and there is many degrees of freedom and heuristics we can use. In any case, we need to shoot rays in a uniform hemisphere (or cosine, or cone) distribution inside the object.
The thickness can be computed as:
The distance can be:
These options can be implemented as part of an operator or geometry node group.
Thickness Scaling Node
To follow the displacement workflow, we will add a new node that will have
World Space
andObject Space
options, along with two input socketsThickness
andScaling
. It will output the thickness as aFloat
(as expected by the material output node).The
World Space
option will scale theThickness
input by the bounding box largest axis length so that it stays constant with object scaling. TheScaling
option will just scale the result of the space conversion.This allow full flexibility and clarity to amend the baked data and provide compatibility with the ASM standard.
Open Questions
Thickness from shadow
This was the default mode in legacy EEVEE. It was only used by BSSRDFs (subsurface scattering). Now that we support more transmission BSDFs, this interact with all of them. This create some funny looking refraction which are distorted by the shadows (which are not even aligned with the shading).
For now we take the min between the user thickness and the shadow one which creates some artifact because of shadow map aliasing. But if we have a cheap way to pre-compute something more correct than this, then it become rather pointless to have this option. Which would speed up rendering and simplify the usage.
Note that I think we can still release EEVEE-Next with only the default socket behavior and the world space output. The thickness scaling node can be added in 4.3 if that is too short to implement it. However, I'll provide a geometry node setup to output the thickness as an attribute.
After testing, the spherical object assumption doesn't work at all for planar surfaces. So we must have an option to select which mode to use.
Maybe the planar assumption might be made default for now (for compatibility with older file) and we'll decide if we have time to add the spherical one.
EDIT: it is not as simple. I committed the spherical one first. We will see how feedback goes.
Adding an option to have the planar assumption back is possible. If we go that way, I would also add a
Thin
mode so that the surface is considered having 0 thickness regardless of the material output. That would make foliage material easier to setup.Here is the comparison between the different BSDFs and the different engines.
Note that:
Thickness from shadow
issue discussed in the task.Blend file attached to this message.
Not bad !! But a lot of this still rest noisy in shadow and refracted elements :/
I feel like having specular response in the Refraction on EEVEE-Next is already a big improvement over legacy considering how many times glass materials would look wrong because of no specular highlights, the SSS seems to be good too all though i am curious if it exhibits the same Ambient occlusion issue when there is a non subsurface object near it leading to cyan SSS shifts.
Spoke with @SimonThommes about this.
Thickness from shadow map
we came to the conclusion that we do need to support both old behavior with thickness from shadow map, and new behavior with only the socket value.
Since we do not yet support for baking thickness automatically for transmission materials, this is the only way to fill the gap and not break older files. Also there might be valid workflow reasons to use the shadow map approximation (procedural geometry, weird geometry with poor parametrization, performance ...).
This will be presented as a checkbox in the material panel. We can afford to run this only on materials that needs it using a stencil buffer bit.
The issue would then be to decide on the way that the thickness from shadow map interacts with the thickness from the socket.
Currently we use the maximum of both since the automatic thickness is a quite good upper bound. But it is not always enough to avoid self shadow.
Additionally, the shadow map is quite imprecise and can lead to underestimation of the thickness leading to quite ugly fringes around the geometry. We can improve the sampling but there will always be failure case where the thickness from shadows will be zero.
So I propose to expose a parameter to scale the upper bound, and a parameter to set a lower bound as a fraction of the thickness socket. This way they would depends on object scale and almost never need adjustment. Good defaults should make these settings almost forgettable.
The setting cannot be per material nor per object for performance and architectural reasons, so it would be in the scene panel.
Thickness mode
For compatibility reasons (and mainly to support thin glass panels) we do need to support the slab approximation.
So this would be exposed per material using an enum:
It would also be convenient to have a setting to disable the thickness approximation all together. But adding an option for it makes the workflow different than displacement (where there is no disabled mode). Also, adding a
No thickness
mode would mean there would be case where the plugged values in the nodetree do nothing. So for now, the only way to remove the thickness approximation is to connect a value node to the thickness socket and set it to 0.