UI: Console Text Operations #108626

Manually merged
Campbell Barton merged 13 commits from Harley/blender:ConsoleSelect into main 2023-09-22 05:42:35 +02:00
865 changed files with 3802 additions and 2739 deletions
Showing only changes of commit d72767c626 - Show all commits

View File

@ -252,7 +252,9 @@ mark_as_advanced(BUILDINFO_OVERRIDE_TIME)
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16")
option(WITH_UNITY_BUILD "\
Enable unity build for modules that support it to improve compile times"
Enable unity build for modules that support it to improve compile times.\n\
WARNING: this option allows files to be built without all necessary headers!\n
This option should be disabled before manipulating or removing headers."
ON
)
mark_as_advanced(WITH_UNITY_BUILD)

View File

@ -79,7 +79,7 @@ SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
USE_ONLY_BUILTIN_RNA_TYPES = True
# Write a page for each static enum defined in:
# `source/blender/makesrna/RNA_enum_items.h` so the enums can be linked to instead of being expanded everywhere.
# `source/blender/makesrna/RNA_enum_items.hh` so the enums can be linked to instead of being expanded everywhere.
USE_SHARED_RNA_ENUM_ITEMS_STATIC = True
if USE_SHARED_RNA_ENUM_ITEMS_STATIC:

View File

@ -86,6 +86,58 @@ static float precompute_ggx_glass_E(float rough, float mu, float eta, float3 ran
return 0.0f;
}
static float precompute_ggx_gen_schlick_s(
float rough, float mu, float eta, float exponent, float3 rand)
{
MicrofacetBsdf bsdf;
bsdf.weight = one_float3();
bsdf.sample_weight = 1.0f;
bsdf.N = make_float3(0.0f, 0.0f, 1.0f);
bsdf.alpha_x = bsdf.alpha_y = sqr(rough);
bsdf.ior = eta;
bsdf.T = make_float3(1.0f, 0.0f, 0.0f);
bsdf_microfacet_ggx_setup(&bsdf);
FresnelGeneralizedSchlick fresnel;
fresnel.reflection_tint = one_float3();
fresnel.transmission_tint = one_float3();
fresnel.f0 = make_float3(0.0f, 1.0f, 0.0f);
fresnel.f90 = make_float3(1.0f, 1.0f, 0.0f);
fresnel.exponent = exponent;
bsdf.fresnel_type = MicrofacetFresnel::GENERALIZED_SCHLICK;
bsdf.fresnel = &fresnel;
float3 omega_in;
Spectrum eval;
float pdf = 0.0f, sampled_eta;
float2 sampled_roughness;
bsdf_microfacet_ggx_sample((ShaderClosure *)&bsdf,
0,
make_float3(0.0f, 0.0f, 1.0f),
make_float3(sqrtf(1.0f - sqr(mu)), 0.0f, mu),
rand,
&eval,
&omega_in,
&pdf,
&sampled_roughness,
&sampled_eta);
if (pdf != 0.0f) {
/* The idea here is that the resulting Fresnel factor is always bounded by
* F0..F90, so it's enough to precompute and store the interpolation factor. */
return saturatef(eval.x / eval.y);
}
return 0.0f;
}
inline float ior_parametrization(float z)
{
/* This parametrization ensures that the entire [1..inf] range of IORs is covered
* and that most precision is allocated to the common areas (1-2). */
return ior_from_F0(sqr(sqr(z)));
}
struct PrecomputeTerm {
int samples;
int nx, ny, nz;
@ -95,31 +147,61 @@ struct PrecomputeTerm {
static bool cycles_precompute(std::string name)
{
std::map<string, PrecomputeTerm> precompute_terms;
precompute_terms["ggx_E"] = {
1 << 23, 32, 32, 1, [](float rough, float mu, float ior, float3 rand) {
return precompute_ggx_E(rough, mu, rand);
}};
/* Overall albedo of the GGX microfacet BRDF, depending on cosI and roughness. */
precompute_terms["ggx_E"] = {1 << 23, 32, 32, 1, [](float rough, float mu, float, float3 rand) {
return precompute_ggx_E(rough, mu, rand);
}};
/* Overall albedo of the GGX microfacet BRDF, averaged over cosI */
precompute_terms["ggx_Eavg"] = {
1 << 26, 32, 1, 1, [](float rough, float mu, float ior, float3 rand) {
1 << 26, 32, 1, 1, [](float rough, float mu, float, float3 rand) {
return 2.0f * mu * precompute_ggx_E(rough, mu, rand);
}};
/* Overall albedo of the GGX microfacet BSDF with dielectric Fresnel,
* depending on cosI and roughness, for IOR>1. */
precompute_terms["ggx_glass_E"] = {
1 << 23, 16, 16, 16, [](float rough, float mu, float ior, float3 rand) {
1 << 23, 16, 16, 16, [](float rough, float mu, float z, float3 rand) {
float ior = ior_parametrization(z);
return precompute_ggx_glass_E(rough, mu, ior, rand);
}};
/* Overall albedo of the GGX microfacet BSDF with dielectric Fresnel,
* averaged over cosI, for IOR>1. */
precompute_terms["ggx_glass_Eavg"] = {
1 << 26, 16, 1, 16, [](float rough, float mu, float ior, float3 rand) {
1 << 26, 16, 1, 16, [](float rough, float mu, float z, float3 rand) {
float ior = ior_parametrization(z);
return 2.0f * mu * precompute_ggx_glass_E(rough, mu, ior, rand);
}};
/* Overall albedo of the GGX microfacet BSDF with dielectric Fresnel,
* depending on cosI and roughness, for IOR<1. */
precompute_terms["ggx_glass_inv_E"] = {
1 << 23, 16, 16, 16, [](float rough, float mu, float ior, float3 rand) {
1 << 23, 16, 16, 16, [](float rough, float mu, float z, float3 rand) {
float ior = ior_parametrization(z);
return precompute_ggx_glass_E(rough, mu, 1.0f / ior, rand);
}};
/* Overall albedo of the GGX microfacet BSDF with dielectric Fresnel,
* averaged over cosI, for IOR<1. */
precompute_terms["ggx_glass_inv_Eavg"] = {
1 << 26, 16, 1, 16, [](float rough, float mu, float ior, float3 rand) {
1 << 26, 16, 1, 16, [](float rough, float mu, float z, float3 rand) {
float ior = ior_parametrization(z);
return 2.0f * mu * precompute_ggx_glass_E(rough, mu, 1.0f / ior, rand);
}};
/* Interpolation factor between F0 and F90 for the generalized Schlick Fresnel,
* depending on cosI and roughness, for IOR>1, using dielectric Fresnel mode. */
precompute_terms["ggx_gen_schlick_ior_s"] = {
1 << 20, 16, 16, 16, [](float rough, float mu, float z, float3 rand) {
float ior = ior_parametrization(z);
return precompute_ggx_gen_schlick_s(rough, mu, ior, -1.0f, rand);
}};
/* Interpolation factor between F0 and F90 for the generalized Schlick Fresnel,
* depending on cosI and roughness, for IOR>1. */
precompute_terms["ggx_gen_schlick_s"] = {
1 << 20, 16, 16, 16, [](float rough, float mu, float z, float3 rand) {
/* Remap 0..1 to 0..inf, with 0.5 mapping to 5 (the default value). */
float exponent = 5.0f * ((1.0f - z) / z);
return precompute_ggx_gen_schlick_s(rough, mu, 1.0f, exponent, rand);
}};
if (precompute_terms.count(name) == 0) {
return false;
}
@ -142,9 +224,6 @@ static bool cycles_precompute(std::string name)
float rough = (nx == 1) ? 0.0f : clamp(float(x) / float(nx - 1), 1e-4f, 1.0f);
float mu = (ny == 1) ? rand.w : clamp(float(y) / float(ny - 1), 1e-4f, 1.0f);
float ior = (nz == 1) ? 0.0f : clamp(float(z) / float(nz - 1), 1e-4f, 0.99f);
/* This parametrization ensures that the entire [1..inf] range of IORs is covered
* and that most precision is allocated to the common areas (1-2). */
ior = ior_from_F0(sqr(sqr(ior)));
float value = term.evaluation(rough, mu, ior, float4_to_float3(rand));
if (isnan(value)) {

View File

@ -6,9 +6,9 @@
#define __BLENDER_DEVICE_H__
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "RNA_access.hh"
#include "RNA_blender_cpp.h"
#include "RNA_types.h"
#include "RNA_types.hh"
#include "device/device.h"

View File

@ -52,8 +52,6 @@ void BlenderSync::sync_light(BL::Object &b_parent,
case BL::Light::type_SPOT: {
BL::SpotLight b_spot_light(b_light);
light->set_size(b_spot_light.shadow_soft_size());
light->set_axisu(transform_get_column(&tfm, 0));
light->set_axisv(transform_get_column(&tfm, 1));
light->set_light_type(LIGHT_SPOT);
light->set_spot_angle(b_spot_light.spot_size());
light->set_spot_smooth(b_spot_light.spot_blend());
@ -74,8 +72,6 @@ void BlenderSync::sync_light(BL::Object &b_parent,
case BL::Light::type_AREA: {
BL::AreaLight b_area_light(b_light);
light->set_size(1.0f);
light->set_axisu(transform_get_column(&tfm, 0));
light->set_axisv(transform_get_column(&tfm, 1));
light->set_sizeu(b_area_light.size());
light->set_spread(b_area_light.spread());
switch (b_area_light.shape()) {
@ -106,8 +102,6 @@ void BlenderSync::sync_light(BL::Object &b_parent,
light->set_strength(strength);
/* location and (inverted!) direction */
light->set_co(transform_get_column(&tfm, 3));
light->set_dir(-transform_get_column(&tfm, 2));
light->set_tfm(tfm);
/* shader */

View File

@ -6,10 +6,10 @@
#define __BLENDER_SYNC_H__
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "RNA_access.hh"
#include "RNA_blender_cpp.h"
#include "RNA_path.h"
#include "RNA_types.h"
#include "RNA_path.hh"
#include "RNA_types.hh"
#include "blender/id_map.h"
#include "blender/util.h"

View File

@ -7,9 +7,9 @@
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "RNA_access.hh"
#include "RNA_blender_cpp.h"
#include "RNA_types.h"
#include "RNA_types.hh"
#include "scene/film.h"

View File

@ -65,14 +65,6 @@ void HdCyclesLight::Sync(HdSceneDelegate *sceneDelegate,
.Get<GfMatrix4d>());
#endif
_light->set_tfm(tfm);
_light->set_co(transform_get_column(&tfm, 3));
_light->set_dir(-transform_get_column(&tfm, 2));
if (_lightType == HdPrimTypeTokens->diskLight || _lightType == HdPrimTypeTokens->rectLight) {
_light->set_axisu(transform_get_column(&tfm, 0));
_light->set_axisv(transform_get_column(&tfm, 1));
}
}
if (*dirtyBits & DirtyBits::DirtyParams) {
@ -211,7 +203,23 @@ void HdCyclesLight::PopulateShaderGraph(HdSceneDelegate *sceneDelegate)
outputNode = bgNode;
}
else {
else if (sceneDelegate != nullptr) {
VtValue value;
const SdfPath &id = GetId();
value = sceneDelegate->GetLightParamValue(id, TfToken("falloff"));
if (!value.IsEmpty()) {
std::string strVal = value.Get<string>();
if (strVal == "Constant" || strVal == "Linear" || strVal == "Quadratic") {
LightFalloffNode *lfoNode = graph->create_node<LightFalloffNode>();
lfoNode->set_strength(1.f);
graph->add(lfoNode);
graph->connect(lfoNode->output(strVal.c_str()), graph->output()->input("Surface"));
outputNode = lfoNode;
}
}
}
if (outputNode == nullptr) {
EmissionNode *emissionNode = graph->create_node<EmissionNode>();
emissionNode->set_color(one_float3());
emissionNode->set_strength(1.0f);

View File

@ -139,7 +139,6 @@ set(SRC_KERNEL_CLOSURE_HEADERS
closure/bssrdf.h
closure/emissive.h
closure/volume.h
closure/bsdf_principled_diffuse.h
closure/bsdf_hair_principled.h
)

View File

@ -17,7 +17,6 @@
#include "kernel/closure/bsdf_toon.h"
#include "kernel/closure/bsdf_hair.h"
#include "kernel/closure/bsdf_hair_principled.h"
#include "kernel/closure/bsdf_principled_diffuse.h"
#include "kernel/closure/bssrdf.h"
#include "kernel/closure/volume.h"
// clang-format on
@ -50,11 +49,6 @@ ccl_device_inline float bsdf_get_roughness_squared(ccl_private const ShaderClosu
return sqr(sqr(bsdf->roughness));
}
if (sc->type == CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID) {
ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)sc;
return sqr(sqr(bsdf->roughness));
}
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
return 0.0f;
}
@ -204,11 +198,6 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
label = bsdf_principled_hair_sample(kg, sc, sd, rand, eval, wo, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
label = bsdf_principled_diffuse_sample(sc, Ng, sd->wi, rand_xy, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_SHEEN_ID:
label = bsdf_sheen_sample(sc, Ng, sd->wi, rand_xy, eval, wo, pdf);
*sampled_roughness = one_float2();
@ -341,10 +330,6 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
*roughness = make_float2(alpha, alpha);
*eta = ((ccl_private PrincipledHairBSDF *)sc)->eta;
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
*roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_SHEEN_ID:
alpha = ((ccl_private SheenBsdf *)sc)->roughness;
*roughness = make_float2(alpha, alpha);
@ -426,9 +411,6 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg,
else
label = LABEL_REFLECT | LABEL_GLOSSY;
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
label = LABEL_REFLECT | LABEL_DIFFUSE;
break;
case CLOSURE_BSDF_SHEEN_ID:
label = LABEL_REFLECT | LABEL_DIFFUSE;
break;
@ -520,9 +502,6 @@ ccl_device_inline
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
eval = bsdf_hair_transmission_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
eval = bsdf_principled_diffuse_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_SHEEN_ID:
eval = bsdf_sheen_eval(sc, sd->wi, wo, pdf);
break;
@ -581,7 +560,8 @@ ccl_device void bsdf_blur(KernelGlobals kg, ccl_private ShaderClosure *sc, float
#endif
}
ccl_device_inline Spectrum bsdf_albedo(ccl_private const ShaderData *sd,
ccl_device_inline Spectrum bsdf_albedo(KernelGlobals kg,
ccl_private const ShaderData *sd,
ccl_private const ShaderClosure *sc,
const bool reflection,
const bool transmission)
@ -598,8 +578,8 @@ ccl_device_inline Spectrum bsdf_albedo(ccl_private const ShaderData *sd,
* extra overhead though. */
#if defined(__SVM__) || defined(__OSL__)
if (CLOSURE_IS_BSDF_MICROFACET(sc->type)) {
albedo *= bsdf_microfacet_estimate_fresnel(
sd, (ccl_private const MicrofacetBsdf *)sc, reflection, transmission);
albedo *= bsdf_microfacet_estimate_albedo(
kg, sd, (ccl_private const MicrofacetBsdf *)sc, reflection, transmission);
}
else if (sc->type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID) {
/* TODO(lukas): Principled Hair could also be split into a glossy and a transmission component,

View File

@ -241,7 +241,7 @@ ccl_device_forceinline Spectrum microfacet_fresnel(ccl_private const MicrofacetB
* Used by Principled v1. */
const float F_real = fresnel_dielectric_cos(dot(wi, H), bsdf->ior);
const float F0_real = F0_from_ior(bsdf->ior);
s = inverse_lerp(F0_real, 1.0f, F_real);
s = saturatef(inverse_lerp(F0_real, 1.0f, F_real));
}
else {
/* Regular case: Generalized Schlick term. */
@ -329,16 +329,12 @@ ccl_device_inline void microfacet_ggx_preserve_energy(KernelGlobals kg,
* code for that), but e.g. a reflection-only closure with Fresnel applied can end up having
* a very low overall albedo.
* This is used to adjust the sample weight, as well as for the Diff/Gloss/Trans Color pass
* and the Denoising Albedo pass.
*
* NOTE: This code assumes the microfacet surface is fairly smooth. For very high roughness,
* the results are much more uniform across the surface.
* For better results, we'd be blending between this and Fss based on roughness, but that
* would involve storing or recomputing Fss, which is probably not worth it. */
ccl_device Spectrum bsdf_microfacet_estimate_fresnel(ccl_private const ShaderData *sd,
ccl_private const MicrofacetBsdf *bsdf,
const bool reflection,
const bool transmission)
* and the Denoising Albedo pass. */
ccl_device Spectrum bsdf_microfacet_estimate_albedo(KernelGlobals kg,
ccl_private const ShaderData *sd,
ccl_private const MicrofacetBsdf *bsdf,
const bool reflection,
const bool transmission)
{
const bool m_refraction = CLOSURE_IS_REFRACTION(bsdf->type);
const bool m_glass = CLOSURE_IS_GLASS(bsdf->type);
@ -347,7 +343,29 @@ ccl_device Spectrum bsdf_microfacet_estimate_fresnel(ccl_private const ShaderDat
Spectrum albedo = zero_spectrum();
if (reflection && (m_reflection || m_glass)) {
/* BSDF has a reflective lobe. */
albedo += microfacet_fresnel(bsdf, sd->wi, bsdf->N, false);
if (bsdf->fresnel_type == MicrofacetFresnel::GENERALIZED_SCHLICK) {
ccl_private FresnelGeneralizedSchlick *fresnel = (ccl_private FresnelGeneralizedSchlick *)
bsdf->fresnel;
float mu = dot(sd->wi, bsdf->N);
float rough = sqrtf(sqrtf(bsdf->alpha_x * bsdf->alpha_y));
float s;
if (fresnel->exponent < 0.0f) {
float z = sqrtf(fabsf((bsdf->ior - 1.0f) / (bsdf->ior + 1.0f)));
s = lookup_table_read_3D(
kg, rough, mu, z, kernel_data.tables.ggx_gen_schlick_ior_s, 16, 16, 16);
}
else {
float z = 1.0f / (0.2f * fresnel->exponent + 1.0f);
s = lookup_table_read_3D(
kg, rough, mu, z, kernel_data.tables.ggx_gen_schlick_s, 16, 16, 16);
}
albedo += mix(fresnel->f0, fresnel->f90, s) * fresnel->reflection_tint;
}
else {
/* If we don't (yet) have a way to estimate albedo in a way that accounts for roughness,
* fall back to assuming that the surface is smooth. */
albedo += microfacet_fresnel(bsdf, sd->wi, bsdf->N, false);
}
}
if (transmission && (m_refraction || m_glass)) {
/* BSDF has a refractive lobe (unless there's TIR). */
@ -733,7 +751,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_conductor(KernelGlobals kg,
{
bsdf->fresnel_type = MicrofacetFresnel::CONDUCTOR;
bsdf->fresnel = fresnel;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf, true, true));
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
if (preserve_energy) {
/* In order to estimate Fss of the conductor, we fit the F82-tint model to it based on the
@ -756,7 +774,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_dielectric_tint(
{
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC_TINT;
bsdf->fresnel = fresnel;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf, true, true));
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
if (preserve_energy) {
/* Assume that the transmissive tint makes up most of the overall color. */
@ -773,7 +791,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(
{
bsdf->fresnel_type = MicrofacetFresnel::GENERALIZED_SCHLICK;
bsdf->fresnel = fresnel;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf, true, true));
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
if (preserve_energy) {
Spectrum Fss = one_spectrum();
@ -851,7 +869,8 @@ ccl_device int bsdf_microfacet_ggx_setup(ccl_private MicrofacetBsdf *bsdf)
return SD_BSDF | bsdf_microfacet_eval_flag(bsdf);
}
ccl_device int bsdf_microfacet_ggx_clearcoat_setup(ccl_private MicrofacetBsdf *bsdf,
ccl_device int bsdf_microfacet_ggx_clearcoat_setup(KernelGlobals kg,
ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd)
{
bsdf->alpha_x = saturatef(bsdf->alpha_x);
@ -860,7 +879,7 @@ ccl_device int bsdf_microfacet_ggx_clearcoat_setup(ccl_private MicrofacetBsdf *b
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC;
bsdf->energy_scale = 1.0f;
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf, true, true));
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
return SD_BSDF | bsdf_microfacet_eval_flag(bsdf);
}

View File

@ -1,157 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#pragma once
/* DISNEY PRINCIPLED DIFFUSE BRDF
*
* Shading model by Brent Burley (Disney): "Physically Based Shading at Disney" (2012)
*
* "Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering" (2015)
* For the separation of retro-reflection, "2.3 Dielectric BRDF with integrated
* subsurface scattering"
*/
#include "kernel/closure/bsdf_util.h"
#include "kernel/sample/mapping.h"
CCL_NAMESPACE_BEGIN
enum PrincipledDiffuseBsdfComponents {
PRINCIPLED_DIFFUSE_FULL = 1,
PRINCIPLED_DIFFUSE_LAMBERT = 2,
PRINCIPLED_DIFFUSE_LAMBERT_EXIT = 4,
PRINCIPLED_DIFFUSE_RETRO_REFLECTION = 8,
};
typedef struct PrincipledDiffuseBsdf {
SHADER_CLOSURE_BASE;
float roughness;
int components;
} PrincipledDiffuseBsdf;
static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledDiffuseBsdf),
"PrincipledDiffuseBsdf is too large!");
ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf *bsdf)
{
bsdf->type = CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID;
bsdf->components = PRINCIPLED_DIFFUSE_FULL;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device Spectrum
bsdf_principled_diffuse_compute_brdf(ccl_private const PrincipledDiffuseBsdf *bsdf,
float3 N,
float3 V,
float3 L,
ccl_private float *pdf)
{
const float NdotL = dot(N, L);
if (NdotL <= 0) {
return zero_spectrum();
}
const float NdotV = dot(N, V);
const float FV = schlick_fresnel(NdotV);
const float FL = schlick_fresnel(NdotL);
float f = 0.0f;
/* Lambertian component. */
if (bsdf->components & (PRINCIPLED_DIFFUSE_FULL | PRINCIPLED_DIFFUSE_LAMBERT)) {
f += (1.0f - 0.5f * FV) * (1.0f - 0.5f * FL);
}
else if (bsdf->components & PRINCIPLED_DIFFUSE_LAMBERT_EXIT) {
f += (1.0f - 0.5f * FL);
}
/* Retro-reflection component. */
if (bsdf->components & (PRINCIPLED_DIFFUSE_FULL | PRINCIPLED_DIFFUSE_RETRO_REFLECTION)) {
/* H = normalize(L + V); // Bisector of an angle between L and V
* LH2 = 2 * dot(L, H)^2 = 2cos(x)^2 = cos(2x) + 1 = dot(L, V) + 1,
* half-angle x between L and V is at most 90 deg. */
const float LH2 = dot(L, V) + 1;
const float RR = bsdf->roughness * LH2;
f += RR * (FL + FV + FL * FV * (RR - 1.0f));
}
float value = M_1_PI_F * NdotL * f;
return make_spectrum(value);
}
/* Compute Fresnel at entry point, to be combined with #PRINCIPLED_DIFFUSE_LAMBERT_EXIT
* at the exit point to get the complete BSDF. */
ccl_device_inline float bsdf_principled_diffuse_compute_entry_fresnel(const float NdotV)
{
const float FV = schlick_fresnel(NdotV);
return (1.0f - 0.5f * FV);
}
/* Ad-hoc weight adjustment to avoid retro-reflection taking away half the
* samples from BSSRDF. */
ccl_device_inline float bsdf_principled_diffuse_retro_reflection_sample_weight(
ccl_private PrincipledDiffuseBsdf *bsdf, const float3 I)
{
return bsdf->roughness * schlick_fresnel(dot(bsdf->N, I));
}
ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf *bsdf,
int components)
{
bsdf->type = CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID;
bsdf->components = components;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device Spectrum bsdf_principled_diffuse_eval(ccl_private const ShaderClosure *sc,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc;
const float3 N = bsdf->N;
if (dot(N, wo) > 0.0f) {
const float3 V = wi;
const float3 L = wo;
*pdf = fmaxf(dot(N, wo), 0.0f) * M_1_PI_F;
return bsdf_principled_diffuse_compute_brdf(bsdf, N, V, L, pdf);
}
else {
*pdf = 0.0f;
return zero_spectrum();
}
}
ccl_device int bsdf_principled_diffuse_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 wi,
float2 rand,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf)
{
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc;
float3 N = bsdf->N;
sample_cos_hemisphere(N, rand, wo, pdf);
if (dot(Ng, *wo) > 0) {
*eval = bsdf_principled_diffuse_compute_brdf(bsdf, N, wi, *wo, pdf);
}
else {
*pdf = 0.0f;
*eval = zero_spectrum();
}
return LABEL_REFLECT | LABEL_DIFFUSE;
}
CCL_NAMESPACE_END

View File

@ -263,6 +263,11 @@ ccl_device_forceinline float bssrdf_pdf(const Spectrum radius, float r)
ccl_device_inline ccl_private Bssrdf *bssrdf_alloc(ccl_private ShaderData *sd, Spectrum weight)
{
float sample_weight = fabsf(average(weight));
if (sample_weight < CLOSURE_WEIGHT_CUTOFF) {
return NULL;
}
ccl_private Bssrdf *bssrdf = (ccl_private Bssrdf *)closure_alloc(
sd, sizeof(Bssrdf), CLOSURE_NONE_ID, weight);
@ -270,9 +275,8 @@ ccl_device_inline ccl_private Bssrdf *bssrdf_alloc(ccl_private ShaderData *sd, S
return NULL;
}
float sample_weight = fabsf(average(weight));
bssrdf->sample_weight = sample_weight;
return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? bssrdf : NULL;
return bssrdf;
}
ccl_device int bssrdf_setup(ccl_private ShaderData *sd,
@ -282,22 +286,6 @@ ccl_device int bssrdf_setup(ccl_private ShaderData *sd,
{
int flag = 0;
/* Add retro-reflection component as separate diffuse BSDF. */
if (bssrdf->roughness != FLT_MAX) {
ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc(
sd, sizeof(PrincipledDiffuseBsdf), bssrdf->weight);
if (bsdf) {
bsdf->N = bssrdf->N;
bsdf->roughness = bssrdf->roughness;
flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_RETRO_REFLECTION);
/* Ad-hoc weight adjustment to avoid retro-reflection taking away half the
* samples from BSSRDF. */
bsdf->sample_weight *= bsdf_principled_diffuse_retro_reflection_sample_weight(bsdf, sd->wi);
}
}
/* Verify if the radii are large enough to sample without precision issues. */
int bssrdf_channels = SPECTRUM_CHANNELS;
Spectrum diffuse_weight = zero_spectrum();
@ -313,24 +301,12 @@ ccl_device int bssrdf_setup(ccl_private ShaderData *sd,
if (bssrdf_channels < SPECTRUM_CHANNELS) {
/* Add diffuse BSDF if any radius too small. */
if (bssrdf->roughness != FLT_MAX) {
ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc(
sd, sizeof(PrincipledDiffuseBsdf), diffuse_weight);
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
sd, sizeof(DiffuseBsdf), diffuse_weight);
if (bsdf) {
bsdf->N = bssrdf->N;
bsdf->roughness = bssrdf->roughness;
flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_LAMBERT);
}
}
else {
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
sd, sizeof(DiffuseBsdf), diffuse_weight);
if (bsdf) {
bsdf->N = bssrdf->N;
flag |= bsdf_diffuse_setup(bsdf);
}
if (bsdf) {
bsdf->N = bssrdf->N;
flag |= bsdf_diffuse_setup(bsdf);
}
}

View File

@ -59,16 +59,7 @@ ccl_device_forceinline void film_write_denoising_features_surface(KernelGlobals
normal += sc->N * sc->sample_weight;
sum_weight += sc->sample_weight;
if (sc->type == CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID) {
/* BSSRDF already accounts for weight, retro-reflection would double up. */
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)
sc;
if (bsdf->components == PRINCIPLED_DIFFUSE_RETRO_REFLECTION) {
continue;
}
}
Spectrum closure_albedo = bsdf_albedo(sd, sc, true, true);
Spectrum closure_albedo = bsdf_albedo(kg, sd, sc, true, true);
if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
diffuse_albedo += closure_albedo;
sum_nonspecular_weight += sc->sample_weight;

View File

@ -10,7 +10,6 @@
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_diffuse.h"
#include "kernel/closure/bsdf_principled_diffuse.h"
#include "kernel/closure/bssrdf.h"
#include "kernel/closure/volume.h"
@ -53,9 +52,6 @@ ccl_device int subsurface_bounce(KernelGlobals kg,
/* Compute weight, optionally including Fresnel from entry point. */
Spectrum weight = surface_shader_bssrdf_sample_weight(sd, sc);
if (bssrdf->roughness != FLT_MAX) {
path_flag |= PATH_RAY_SUBSURFACE_USE_FRESNEL;
}
if (sd->flag & SD_BACKFACING) {
path_flag |= PATH_RAY_SUBSURFACE_BACKFACING;
@ -103,24 +99,12 @@ ccl_device void subsurface_shader_data_setup(KernelGlobals kg,
const Spectrum weight = one_spectrum();
if (path_flag & PATH_RAY_SUBSURFACE_USE_FRESNEL) {
ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc(
sd, sizeof(PrincipledDiffuseBsdf), weight);
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
sd, sizeof(DiffuseBsdf), weight);
if (bsdf) {
bsdf->N = N;
bsdf->roughness = FLT_MAX;
sd->flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_LAMBERT_EXIT);
}
}
else {
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
sd, sizeof(DiffuseBsdf), weight);
if (bsdf) {
bsdf->N = N;
sd->flag |= bsdf_diffuse_setup(bsdf);
}
if (bsdf) {
bsdf->N = N;
sd->flag |= bsdf_diffuse_setup(bsdf);
}
}

View File

@ -1011,7 +1011,7 @@ ccl_device Spectrum surface_shader_diffuse(KernelGlobals kg, ccl_private const S
ccl_private const ShaderClosure *sc = &sd->closure[i];
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type) || CLOSURE_IS_BSSRDF(sc->type))
eval += bsdf_albedo(sd, sc, true, true);
eval += bsdf_albedo(kg, sd, sc, true, true);
}
return eval;
@ -1025,7 +1025,7 @@ ccl_device Spectrum surface_shader_glossy(KernelGlobals kg, ccl_private const Sh
ccl_private const ShaderClosure *sc = &sd->closure[i];
if (CLOSURE_IS_BSDF_GLOSSY(sc->type) || CLOSURE_IS_GLASS(sc->type))
eval += bsdf_albedo(sd, sc, true, false);
eval += bsdf_albedo(kg, sd, sc, true, false);
}
return eval;
@ -1039,7 +1039,7 @@ ccl_device Spectrum surface_shader_transmission(KernelGlobals kg, ccl_private co
ccl_private const ShaderClosure *sc = &sd->closure[i];
if (CLOSURE_IS_BSDF_TRANSMISSION(sc->type) || CLOSURE_IS_GLASS(sc->type))
eval += bsdf_albedo(sd, sc, false, true);
eval += bsdf_albedo(kg, sd, sc, false, true);
}
return eval;

View File

@ -55,6 +55,14 @@ static_assert(sizeof(ShaderGlobals) == sizeof(OSL::ShaderGlobals) &&
#include "closures_template.h"
static OSL::ClosureParam *osl_closure_layer_params()
{
static OSL::ClosureParam params[] = {CLOSURE_CLOSURE_PARAM(LayerClosure, top),
CLOSURE_CLOSURE_PARAM(LayerClosure, base),
CLOSURE_FINISH_PARAM(LayerClosure)};
return params;
}
void OSLRenderServices::register_closures(OSL::ShadingSystem *ss)
{
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
@ -62,6 +70,8 @@ void OSLRenderServices::register_closures(OSL::ShadingSystem *ss)
#lower, OSL_CLOSURE_##Upper##_ID, osl_closure_##lower##_params(), nullptr, nullptr);
#include "closures_template.h"
ss->register_closure(
"layer", OSL_CLOSURE_LAYER_ID, osl_closure_layer_params(), nullptr, nullptr);
}
/* Surface & Background */

View File

@ -7,26 +7,9 @@
#pragma once
// clang-format off
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_util.h"
#include "kernel/closure/bsdf_ashikhmin_velvet.h"
#include "kernel/closure/bsdf_diffuse.h"
#include "kernel/closure/bsdf_microfacet.h"
#include "kernel/closure/bsdf_oren_nayar.h"
#include "kernel/closure/bsdf_sheen.h"
#include "kernel/closure/bsdf_transparent.h"
#include "kernel/closure/bsdf_ashikhmin_shirley.h"
#include "kernel/closure/bsdf_toon.h"
#include "kernel/closure/bsdf_hair.h"
#include "kernel/closure/bsdf_hair_principled.h"
#include "kernel/closure/bsdf_principled_diffuse.h"
#include "kernel/closure/volume.h"
#include "kernel/closure/bsdf_diffuse_ramp.h"
#include "kernel/closure/bsdf_phong_ramp.h"
#include "kernel/closure/bssrdf.h"
#include "kernel/closure/bsdf.h"
#include "kernel/closure/emissive.h"
// clang-format on
CCL_NAMESPACE_BEGIN
@ -42,6 +25,12 @@ CCL_NAMESPACE_BEGIN
#include "closures_template.h"
struct ccl_align(8) LayerClosure
{
ccl_private const OSLClosure *base;
ccl_private const OSLClosure *top;
};
ccl_device_forceinline bool osl_closure_skip(KernelGlobals kg,
ccl_private const ShaderData *sd,
uint32_t path_flag,
@ -65,7 +54,8 @@ ccl_device void osl_closure_diffuse_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const DiffuseClosure *closure)
ccl_private const DiffuseClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
return;
@ -86,7 +76,8 @@ ccl_device void osl_closure_oren_nayar_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const OrenNayarClosure *closure)
ccl_private const OrenNayarClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
return;
@ -108,7 +99,8 @@ ccl_device void osl_closure_translucent_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const TranslucentClosure *closure)
ccl_private const TranslucentClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
return;
@ -129,7 +121,8 @@ ccl_device void osl_closure_reflection_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const ReflectionClosure *closure)
ccl_private const ReflectionClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_SINGULAR)) {
return;
@ -151,7 +144,8 @@ ccl_device void osl_closure_refraction_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const RefractionClosure *closure)
ccl_private const RefractionClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_SINGULAR)) {
return;
@ -174,7 +168,8 @@ ccl_device void osl_closure_transparent_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const TransparentClosure *closure)
ccl_private const TransparentClosure *closure,
float3 *layer_albedo)
{
bsdf_transparent_setup(sd, rgb_to_spectrum(weight), path_flag);
}
@ -184,7 +179,8 @@ ccl_device void osl_closure_dielectric_bsdf_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const DielectricBSDFClosure *closure)
ccl_private const DielectricBSDFClosure *closure,
float3 *layer_albedo)
{
const bool has_reflection = !is_zero(closure->reflection_tint);
const bool has_transmission = !is_zero(closure->transmission_tint);
@ -243,13 +239,18 @@ ccl_device void osl_closure_dielectric_bsdf_setup(KernelGlobals kg,
fresnel->reflection_tint = rgb_to_spectrum(closure->reflection_tint);
fresnel->transmission_tint = rgb_to_spectrum(closure->transmission_tint);
bsdf_microfacet_setup_fresnel_dielectric_tint(kg, bsdf, sd, fresnel, preserve_energy);
if (layer_albedo != NULL && has_reflection && !has_transmission) {
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
}
}
ccl_device void osl_closure_conductor_bsdf_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const ConductorBSDFClosure *closure)
ccl_private const ConductorBSDFClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
@ -295,7 +296,8 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const GeneralizedSchlickBSDFClosure *closure)
ccl_private const GeneralizedSchlickBSDFClosure *closure,
float3 *layer_albedo)
{
const bool has_reflection = !is_zero(closure->reflection_tint);
const bool has_transmission = !is_zero(closure->transmission_tint);
@ -319,11 +321,21 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = ior_from_F0(average(closure->f0));
bsdf->T = closure->T;
if (closure->exponent < 0.0f) {
/* Trick for principled BSDF: Since we use the real Fresnel equation and remap
* to the F0...F90 range, this allows us to use the real IOR.
* Computing it back from F0 might give a different result in case of specular
* tinting. */
bsdf->ior = -closure->exponent;
}
else {
bsdf->ior = ior_from_F0(average(closure->f0));
}
if (sd->flag & SD_BACKFACING) {
bsdf->ior = 1.0f / bsdf->ior;
}
bsdf->T = closure->T;
bool preserve_energy = false;
@ -360,6 +372,10 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
fresnel->f90 = rgb_to_spectrum(closure->f90);
fresnel->exponent = closure->exponent;
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, preserve_energy);
if (layer_albedo != NULL && has_reflection && !has_transmission) {
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
}
}
/* Standard microfacet closures */
@ -368,7 +384,8 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetClosure *closure)
ccl_private const MicrofacetClosure *closure,
float3 *layer_albedo)
{
const int label = (closure->refract) ? LABEL_TRANSMIT : LABEL_REFLECT;
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | label)) {
@ -405,7 +422,7 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
}
/* Clearcoat */
else if (closure->distribution == make_string("clearcoat", 3490136178980547276ull)) {
sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(kg, bsdf, sd);
}
/* GGX (either single- or multi-scattering) */
else {
@ -424,6 +441,10 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, rgb_to_spectrum(weight));
}
}
if (layer_albedo != NULL && closure->refract == 0) {
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
}
}
/* Special-purpose Microfacet closures */
@ -433,7 +454,8 @@ ccl_device void osl_closure_microfacet_multi_ggx_glass_setup(
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetMultiGGXGlassClosure *closure)
ccl_private const MicrofacetMultiGGXGlassClosure *closure,
float3 *layer_albedo)
{
/* Technically, the MultiGGX closure may also transmit. However,
* since this is set statically and only used for caustic flags, this
@ -464,7 +486,8 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup(
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetMultiGGXClosure *closure)
ccl_private const MicrofacetMultiGGXClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
@ -485,49 +508,10 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup(
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, rgb_to_spectrum(closure->color));
}
ccl_device void osl_closure_microfacet_aniso_fresnel_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetAnisoFresnelClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
if (layer_albedo != NULL) {
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
ccl_private FresnelGeneralizedSchlick *fresnel = (ccl_private FresnelGeneralizedSchlick *)
closure_alloc_extra(sd, sizeof(FresnelGeneralizedSchlick));
if (!fresnel) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure