143 lines
5.4 KiB
Plaintext
143 lines
5.4 KiB
Plaintext
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
|
|
|
#include "node_fresnel.h"
|
|
#include "stdcycles.h"
|
|
|
|
shader node_principled_bsdf(string distribution = "multi_ggx",
|
|
string subsurface_method = "random_walk",
|
|
color BaseColor = color(0.8, 0.8, 0.8),
|
|
float SubsurfaceWeight = 0.0,
|
|
float SubsurfaceScale = 0.1,
|
|
vector SubsurfaceRadius = vector(1.0, 1.0, 1.0),
|
|
float SubsurfaceIOR = 1.4,
|
|
float SubsurfaceAnisotropy = 0.0,
|
|
float Metallic = 0.0,
|
|
float SpecularIORLevel = 0.5,
|
|
color SpecularTint = color(1.0),
|
|
float Roughness = 0.5,
|
|
float Anisotropic = 0.0,
|
|
float AnisotropicRotation = 0.0,
|
|
float SheenWeight = 0.0,
|
|
float SheenRoughness = 0.5,
|
|
color SheenTint = 0.5,
|
|
float CoatWeight = 0.0,
|
|
float CoatRoughness = 0.03,
|
|
float CoatIOR = 1.5,
|
|
color CoatTint = color(1.0, 1.0, 1.0),
|
|
float IOR = 1.45,
|
|
float TransmissionWeight = 0.0,
|
|
color EmissionColor = 1.0,
|
|
float EmissionStrength = 0.0,
|
|
float Alpha = 1.0,
|
|
normal Normal = N,
|
|
normal CoatNormal = N,
|
|
normal Tangent = normalize(dPdu),
|
|
output closure color BSDF = 0)
|
|
{
|
|
color specular_tint = max(SpecularTint, color(0.0));
|
|
|
|
float r2 = clamp(Roughness, 0.0, 1.0);
|
|
r2 = r2 * r2;
|
|
|
|
float alpha_x = r2, alpha_y = r2;
|
|
|
|
/* Handle anisotropy. */
|
|
vector T = Tangent;
|
|
if (Anisotropic > 0.0) {
|
|
float aspect = sqrt(1.0 - clamp(Anisotropic, 0.0, 1.0) * 0.9);
|
|
alpha_x /= aspect;
|
|
alpha_y *= aspect;
|
|
if (AnisotropicRotation != 0.0)
|
|
T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
|
|
}
|
|
|
|
if (Metallic < 1.0 && TransmissionWeight < 1.0) {
|
|
float eta = IOR;
|
|
float f0 = F0_from_ior(eta);
|
|
if (SpecularIORLevel != 0.5) {
|
|
f0 *= 2.0 * max(SpecularIORLevel, 0.0);
|
|
eta = ior_from_F0(f0);
|
|
if (IOR < 1.0) {
|
|
eta = 1.0 / eta;
|
|
}
|
|
}
|
|
|
|
BSDF = BaseColor * diffuse(Normal);
|
|
if (SubsurfaceWeight > 1e-5) {
|
|
float subsurface_weight = min(SubsurfaceWeight, 1.0);
|
|
vector radius = SubsurfaceScale * SubsurfaceRadius;
|
|
float subsurface_ior = (subsurface_method == "random_walk_skin") ? SubsurfaceIOR : eta;
|
|
closure color SubsurfBSDF = bssrdf(subsurface_method,
|
|
Normal,
|
|
SubsurfaceScale * SubsurfaceRadius,
|
|
BaseColor,
|
|
"roughness",
|
|
Roughness,
|
|
"ior",
|
|
subsurface_ior,
|
|
"anisotropy",
|
|
SubsurfaceAnisotropy);
|
|
BSDF = mix(BSDF, BaseColor * SubsurfBSDF, subsurface_weight);
|
|
}
|
|
|
|
/* Apply specular tint */
|
|
color F0 = f0 * specular_tint;
|
|
color F90 = color(1.0);
|
|
|
|
BSDF = layer(
|
|
generalized_schlick_bsdf(
|
|
Normal, T, color(1.0), color(0.0), alpha_x, alpha_y, F0, F90, -eta, distribution),
|
|
BSDF);
|
|
}
|
|
|
|
closure color TransmissionBSDF = 0;
|
|
if (Metallic < 1.0 && TransmissionWeight > 0.0) {
|
|
float eta = max(IOR, 1e-5);
|
|
eta = backfacing() ? 1.0 / eta : eta;
|
|
|
|
color F0 = F0_from_ior(eta) * specular_tint;
|
|
color F90 = color(1.0);
|
|
|
|
TransmissionBSDF = generalized_schlick_bsdf(
|
|
Normal, vector(0.0), color(1.0), sqrt(BaseColor), r2, r2, F0, F90, -eta, distribution),
|
|
BSDF = mix(BSDF, TransmissionBSDF, clamp(TransmissionWeight, 0.0, 1.0));
|
|
}
|
|
|
|
closure color MetallicBSDF = 0;
|
|
if (Metallic > 0.0) {
|
|
color F0 = BaseColor;
|
|
color F82 = specular_tint;
|
|
MetallicBSDF = microfacet_f82_tint(distribution, Normal, T, alpha_x, alpha_y, F0, F82);
|
|
BSDF = mix(BSDF, MetallicBSDF, clamp(Metallic, 0.0, 1.0));
|
|
}
|
|
|
|
if (EmissionStrength > 0.0 && EmissionColor != color(0.0)) {
|
|
BSDF += EmissionStrength * EmissionColor * emission();
|
|
}
|
|
|
|
if (CoatWeight > 1e-5) {
|
|
float coat_ior = max(CoatIOR, 1.0);
|
|
if (CoatTint != color(1.0)) {
|
|
float coat_neta = 1.0 / coat_ior;
|
|
float cosNI = dot(I, CoatNormal);
|
|
float cosNT = sqrt(1.0 - coat_neta * coat_neta * (1 - cosNI * cosNI));
|
|
BSDF *= pow(CoatTint, CoatWeight / cosNT);
|
|
}
|
|
float coat_r2 = clamp(CoatRoughness, 0.0, 1.0);
|
|
coat_r2 = coat_r2 * coat_r2;
|
|
|
|
closure color CoatBSDF = dielectric_bsdf(
|
|
CoatNormal, vector(0.0), color(1.0), color(0.0), coat_r2, coat_r2, coat_ior, "ggx");
|
|
BSDF = layer(clamp(CoatWeight, 0.0, 1.0) * CoatBSDF, BSDF);
|
|
}
|
|
|
|
if (SheenWeight > 1e-5) {
|
|
closure color SheenBSDF = sheen(Normal, clamp(SheenRoughness, 0.0, 1.0));
|
|
BSDF = layer(clamp(SheenWeight, 0.0, 1.0) * SheenTint * SheenBSDF, BSDF);
|
|
}
|
|
|
|
BSDF = mix(transparent(), BSDF, clamp(Alpha, 0.0, 1.0));
|
|
}
|