Incorrect reflection baking at steep angles in cycles renderer #120729

Open
opened 2024-04-17 06:16:52 +02:00 by ma-ma · 4 comments

System Information
Operating system:windows
Graphics card:RTX4070

Blender Version
Broken: 4.1.1日期:2024-04-15 15:11哈希:e1743a0317bc分支: blender-v4.1-releaseDlondor

Worked: 4.1.1

Cycles to map the reflection will go wrong when the Angle is too large, such as the reflection of the sea level at the baking site, the reflection position will be incorrect and distorted

When you want to bake a reflection with a large Angle onto his tile.

**System Information** Operating system:windows Graphics card:RTX4070 **Blender Version** Broken: 4.1.1日期:2024-04-15 15:11哈希:e1743a0317bc分支: blender-v4.1-releaseDlondor Worked: 4.1.1 **Cycles to map the reflection will go wrong when the Angle is too large, such as the reflection of the sea level at the baking site, the reflection position will be incorrect and distorted** **When you want to bake a reflection with a large Angle onto his tile.**
ma-ma added the
Type
Report
Priority
Normal
Status
Needs Triage
labels 2024-04-17 06:16:53 +02:00
Member

I assume this is the issue you're referring too?

In which case, I can confirm the issue. This issue is caused by this piece of code in integrator_init_from_bake():

float3 D = camera_direction_from_point(kg, P);

const float DN = dot(D, N);

/* Nudge camera direction, so that the faces facing away from the camera still have
 * somewhat usable shading. (Otherwise, glossy faces would be simply black.)
 *
 * The surface normal offset affects smooth surfaces. Lower values will make
 * smooth surfaces more faceted, but higher values may show up from the camera
 * at grazing angles.
 *
 * This value can actually be pretty high before it's noticeably wrong. */
const float surface_normal_offset = 0.2f;

/* Keep the ray direction at least `surface_normal_offset` "above" the smooth normal. */
if (DN <= surface_normal_offset) {
  D -= N * (DN - surface_normal_offset);
  D = normalize(D);
}

Basically when the angle between the surface normal, and the vector pointing to the camera ray is greater than 78.4 degrees (if (DN <= surface_normal_offset)), then the baking view angle will be adjusted. So this is technically an expected result.

However it may be possible that the angle can be increased (done by decreasing surface_normal_offset) without introducing artifacts. Or the formula could be adjusted to provide a better result. So I will mark this as "Needs information from developer" just to get input on what to do here.

I assume this is the issue you're referring too? <video src="/attachments/2f342403-e02b-4d1b-8365-9fea936ca182" title="Reflection baking demonstration.mp4" controls></video> In which case, I can confirm the issue. This issue is caused by this piece of code in `integrator_init_from_bake()`: ``` float3 D = camera_direction_from_point(kg, P); const float DN = dot(D, N); /* Nudge camera direction, so that the faces facing away from the camera still have * somewhat usable shading. (Otherwise, glossy faces would be simply black.) * * The surface normal offset affects smooth surfaces. Lower values will make * smooth surfaces more faceted, but higher values may show up from the camera * at grazing angles. * * This value can actually be pretty high before it's noticeably wrong. */ const float surface_normal_offset = 0.2f; /* Keep the ray direction at least `surface_normal_offset` "above" the smooth normal. */ if (DN <= surface_normal_offset) { D -= N * (DN - surface_normal_offset); D = normalize(D); } ``` Basically when the angle between the surface normal, and the vector pointing to the camera ray is greater than 78.4 degrees (`if (DN <= surface_normal_offset)`), then the baking view angle will be adjusted. So this is technically an expected result. However it may be possible that the angle can be increased (done by decreasing `surface_normal_offset`) without introducing artifacts. Or the formula could be adjusted to provide a better result. So I will mark this as "Needs information from developer" just to get input on what to do here.
Alaska added
Status
Needs Info from Developers
Module
Render & Cycles
and removed
Status
Needs Triage
labels 2024-04-17 07:12:12 +02:00
Author

Thank you for your help, you have reproduced the problem perfectly, and the direction to the camera ray is greater than 78.4 degrees, I am making a mobile game with simple graphics, baking the mirror reflection effect, Can you add a button function to bake the right reflection effect?

Thank you for your help, you have reproduced the problem perfectly, and the direction to the camera ray is greater than 78.4 degrees, I am making a mobile game with simple graphics, baking the mirror reflection effect, Can you add a button function to bake the right reflection effect?
Alaska changed title from Incorrect baking reflection in cycles renderer to Incorrect reflection baking at steep angles in cycles renderer 2024-04-17 08:54:50 +02:00
Author

You’re correct. This code could indeed result in inaccurate rendering when dealing with reflections at large angles. This is because when the angle between the light ray and the surface is large, the ray might be forced to deviate from its original path, which could lead to rendering errors.

In such cases, one possible solution could be to dynamically adjust the value of surface_normal_offset so that it changes with the angle between the light ray and the surface normal. For instance, you could decrease the value of surface_normal_offset when the angle is large, and increase it when the angle is small. This could help maintain the quality of the rendering while preventing the light ray from “penetrating” the surface.

However, this is just one potential solution, and the actual implementation could vary depending on your specific needs and application scenario. I hope this suggestion is helpful to you!

You’re correct. This code could indeed result in inaccurate rendering when dealing with reflections at large angles. This is because when the angle between the light ray and the surface is large, the ray might be forced to deviate from its original path, which could lead to rendering errors. In such cases, one possible solution could be to dynamically adjust the value of surface_normal_offset so that it changes with the angle between the light ray and the surface normal. For instance, you could decrease the value of surface_normal_offset when the angle is large, and increase it when the angle is small. This could help maintain the quality of the rendering while preventing the light ray from “penetrating” the surface. However, this is just one potential solution, and the actual implementation could vary depending on your specific needs and application scenario. I hope this suggestion is helpful to you!
Member

One possible solution could be to dynamically adjust the value of surface_normal_offset so that it changes with the angle between the light ray and the surface normal. For instance, you could decrease the value of surface_normal_offset when the angle is large, and increase it when the angle is small.

This would give you the opposite effect from what you want. As you get closer to grazing angles (E.G. The scene you and I tested), the distortion caused by this code will become worse and worse.

If the opposite would happen (Swap the increasing and decreasing of surface_normal_offset), then assuming a linear relationship between the angle between normal and camera, and surface_normal_offset, this change wouldn't do much in most situations, and it may just be better to set surface_normal_offset to a fixed small value.

surface_normal_offset exists for a reason (it reduces/removes artifacts on some smooth shading curved objects). And values like 0.1 (84.3 degrees) are causing artifacts on some smooth objects in my testing.


Due to the surface_normal_offset design of reducing artifacts on objects with smooth shading, we can actually disable this feature for objects that make use of flat shading and artifacts shouldn't be visible. I've created a pull request for that here: !120773

However, work on adjusting the surface_normal_offset value or the formula might still be good for when users are using smooth shading.

> One possible solution could be to dynamically adjust the value of surface_normal_offset so that it changes with the angle between the light ray and the surface normal. For instance, you could decrease the value of surface_normal_offset when the angle is large, and increase it when the angle is small. This would give you the opposite effect from what you want. As you get closer to grazing angles (E.G. The scene you and I tested), the distortion caused by this code will become worse and worse. If the opposite would happen (Swap the increasing and decreasing of `surface_normal_offset`), then assuming a linear relationship between the angle between normal and camera, and `surface_normal_offset`, this change wouldn't do much in most situations, and it may just be better to set `surface_normal_offset` to a fixed small value. `surface_normal_offset` exists for a reason (it reduces/removes artifacts on some smooth shading curved objects). And values like 0.1 (84.3 degrees) are causing artifacts on some smooth objects in my testing. --- Due to the `surface_normal_offset` design of reducing artifacts on objects with smooth shading, we can actually disable this feature for objects that make use of flat shading and artifacts shouldn't be visible. I've created a pull request for that here: !120773 However, work on adjusting the `surface_normal_offset` value or the formula might still be good for when users are using smooth shading.
Sign in to join this conversation.
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
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#120729
No description provided.