mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Cycles: Improve smooth thin glass shadow
By allocating transparent BSDF for non-camera rays when roughness is sufficiently low Pull Request: https://projects.blender.org/blender/blender/pulls/159798
This commit is contained in:
parent
a2ed5854c0
commit
d4ee9b9e79
5 changed files with 45 additions and 10 deletions
|
|
@ -1268,8 +1268,20 @@ ccl_device_inline void bsdf_thin_glass_transmission_setup(KernelGlobals kg,
|
|||
const Spectrum weight,
|
||||
const float3 N,
|
||||
const float roughness,
|
||||
const float ior)
|
||||
const float ior,
|
||||
const PathRayVisibility ray_visibility,
|
||||
const uint32_t path_flag)
|
||||
{
|
||||
const float transmission_roughness = bsdf_thin_glass_transmission_roughness(roughness, ior);
|
||||
if (!(ray_visibility & PATH_RAY_VISIBILITY_CAMERA) &&
|
||||
roughness_is_almost_specular(transmission_roughness, transmission_roughness))
|
||||
{
|
||||
/* Smooth thin glass does not bend the ray and is effectively transparent, allocate transparent
|
||||
* closures for non-camera rays to improve sampling and keep render passes intact. */
|
||||
bsdf_transparent_setup(sd, weight, path_flag);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Model double refraction events as one reflection event with the incident ray mirrored along
|
||||
* the surface. */
|
||||
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
|
||||
|
|
@ -1277,7 +1289,7 @@ ccl_device_inline void bsdf_thin_glass_transmission_setup(KernelGlobals kg,
|
|||
if (bsdf) {
|
||||
bsdf->N = -N;
|
||||
bsdf->T = zero_float3();
|
||||
bsdf->alpha_x = bsdf->alpha_y = bsdf_thin_glass_transmission_roughness(roughness, ior);
|
||||
bsdf->alpha_x = bsdf->alpha_y = transmission_roughness;
|
||||
bsdf->ior = 1.0f;
|
||||
bsdf->fresnel_type = MicrofacetFresnel::NONE;
|
||||
bsdf->energy_scale = 1.0f;
|
||||
|
|
@ -1343,7 +1355,9 @@ ccl_device void bsdf_thin_glass_setup(KernelGlobals kg,
|
|||
const float ior,
|
||||
const FresnelThinFilm thinfilm,
|
||||
ccl_private Spectrum *r_reflectance,
|
||||
ccl_private Spectrum *r_transmittance)
|
||||
ccl_private Spectrum *r_transmittance,
|
||||
const PathRayVisibility ray_visibility,
|
||||
const uint32_t path_flag)
|
||||
{
|
||||
const float cos_theta_i = dot(N, sd->wi);
|
||||
bsdf_thin_glass_fresnel(kg,
|
||||
|
|
@ -1362,7 +1376,8 @@ ccl_device void bsdf_thin_glass_setup(KernelGlobals kg,
|
|||
kg, sd, reflection_tint, *r_reflectance * weight, N, roughness);
|
||||
}
|
||||
if (!is_zero(*r_transmittance)) {
|
||||
bsdf_thin_glass_transmission_setup(kg, sd, *r_transmittance * weight, N, roughness, ior);
|
||||
bsdf_thin_glass_transmission_setup(
|
||||
kg, sd, *r_transmittance * weight, N, roughness, ior, ray_visibility, path_flag);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
|
|||
ccl_device void osl_closure_thin_glass_setup(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
const PathRayVisibility path_visibility,
|
||||
const uint32_t /*path_flag*/,
|
||||
const uint32_t path_flag,
|
||||
const float3 weight,
|
||||
const ccl_private ThinGlassClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
|
|
@ -563,7 +563,9 @@ ccl_device void osl_closure_thin_glass_setup(KernelGlobals kg,
|
|||
closure->ior,
|
||||
thinfilm,
|
||||
&reflectance,
|
||||
&transmittance);
|
||||
&transmittance,
|
||||
path_visibility,
|
||||
path_flag);
|
||||
|
||||
if (layer_albedo != nullptr) {
|
||||
*layer_albedo = transmittance * !!has_transmission + reflectance * !!has_reflection;
|
||||
|
|
|
|||
|
|
@ -379,7 +379,9 @@ ccl_device
|
|||
ior,
|
||||
thinfilm,
|
||||
&reflectance,
|
||||
&transmittance);
|
||||
&transmittance,
|
||||
ray_visibility,
|
||||
path_flag);
|
||||
}
|
||||
else {
|
||||
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "util/string.h"
|
||||
#include "util/transform.h"
|
||||
|
||||
#include "kernel/closure/bsdf_microfacet.h"
|
||||
#include "kernel/svm/color_util.h"
|
||||
#include "kernel/svm/mapping_util.h"
|
||||
#include "kernel/svm/math_util.h"
|
||||
|
|
@ -2739,7 +2740,22 @@ void PrincipledBsdfNode::simplify_settings(Scene * /* scene */)
|
|||
|
||||
bool PrincipledBsdfNode::has_surface_transparent()
|
||||
{
|
||||
return (input("Alpha")->link != nullptr || alpha < (1.0f - CLOSURE_WEIGHT_CUTOFF));
|
||||
if (input("Alpha")->link != nullptr || alpha < (1.0f - CLOSURE_WEIGHT_CUTOFF)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Smooth thin glass are treated as transparent for non-camera rays. */
|
||||
if ((input("Thin Wall")->link || thin_wall) && has_nonzero_weight("Transmission Weight")) {
|
||||
if (input("Roughness")->link || input("IOR")->link) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const float transmission_roughness = bsdf_thin_glass_transmission_roughness(sqr(roughness),
|
||||
ior);
|
||||
return roughness_is_almost_specular(transmission_roughness, transmission_roughness);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PrincipledBsdfNode::is_thin_wall()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9122ea34bc214553dc600265dd629debfd93df684994ff136aff20be67242ac6
|
||||
size 33284
|
||||
oid sha256:59f3ab7dd107fb2d0a340e38e35e7e7a19df6c2cfd3103a15f3b90e14a9b5019
|
||||
size 33101
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue