forked from bartvdbraak/blender
161 lines
6.5 KiB
Plaintext
161 lines
6.5 KiB
Plaintext
/*
|
|
* Copyright 2011-2017 Blender Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "node_fresnel.h"
|
|
#include "stdcycles.h"
|
|
|
|
shader node_principled_bsdf(string distribution = "Multiscatter GGX",
|
|
string subsurface_method = "burley",
|
|
color BaseColor = color(0.8, 0.8, 0.8),
|
|
float Subsurface = 0.0,
|
|
vector SubsurfaceRadius = vector(1.0, 1.0, 1.0),
|
|
color SubsurfaceColor = color(0.7, 0.1, 0.1),
|
|
float Metallic = 0.0,
|
|
float Specular = 0.5,
|
|
float SpecularTint = 0.0,
|
|
float Roughness = 0.5,
|
|
float Anisotropic = 0.0,
|
|
float AnisotropicRotation = 0.0,
|
|
float Sheen = 0.0,
|
|
float SheenTint = 0.5,
|
|
float Clearcoat = 0.0,
|
|
float ClearcoatRoughness = 0.03,
|
|
float IOR = 1.45,
|
|
float Transmission = 0.0,
|
|
float TransmissionRoughness = 0.0,
|
|
normal Normal = N,
|
|
normal ClearcoatNormal = N,
|
|
normal Tangent = normalize(dPdu),
|
|
output closure color BSDF = 0)
|
|
{
|
|
float f = max(IOR, 1e-5);
|
|
float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(Transmission, 0.0, 1.0));
|
|
float final_transmission = clamp(Transmission, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
|
|
float specular_weight = (1.0 - final_transmission);
|
|
|
|
vector T = Tangent;
|
|
|
|
float m_cdlum = luminance(BaseColor);
|
|
color m_ctint = m_cdlum > 0.0 ? BaseColor / m_cdlum :
|
|
color(0.0, 0.0, 0.0); // normalize lum. to isolate hue+sat
|
|
|
|
/* rotate tangent */
|
|
if (AnisotropicRotation != 0.0)
|
|
T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
|
|
|
|
if (diffuse_weight > 1e-5) {
|
|
if (Subsurface > 1e-5) {
|
|
color mixed_ss_base_color = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface);
|
|
if (subsurface_method == "burley") {
|
|
BSDF = mixed_ss_base_color * bssrdf("principled",
|
|
Normal,
|
|
Subsurface * SubsurfaceRadius,
|
|
SubsurfaceColor,
|
|
"roughness",
|
|
Roughness);
|
|
}
|
|
else {
|
|
BSDF = mixed_ss_base_color * bssrdf("principled_random_walk",
|
|
Normal,
|
|
Subsurface * SubsurfaceRadius,
|
|
mixed_ss_base_color,
|
|
"roughness",
|
|
Roughness);
|
|
}
|
|
}
|
|
else {
|
|
BSDF = BaseColor * principled_diffuse(Normal, Roughness);
|
|
}
|
|
|
|
if (Sheen > 1e-5) {
|
|
color sheen_color = color(1.0, 1.0, 1.0) * (1.0 - SheenTint) + m_ctint * SheenTint;
|
|
|
|
BSDF = BSDF + sheen_color * Sheen * principled_sheen(Normal);
|
|
}
|
|
|
|
BSDF = BSDF * diffuse_weight;
|
|
}
|
|
|
|
if (specular_weight > 1e-5) {
|
|
float aspect = sqrt(1.0 - Anisotropic * 0.9);
|
|
float r2 = Roughness * Roughness;
|
|
|
|
float alpha_x = r2 / aspect;
|
|
float alpha_y = r2 * aspect;
|
|
|
|
color tmp_col = color(1.0, 1.0, 1.0) * (1.0 - SpecularTint) + m_ctint * SpecularTint;
|
|
|
|
color Cspec0 = (Specular * 0.08 * tmp_col) * (1.0 - Metallic) + BaseColor * Metallic;
|
|
|
|
if (distribution == "GGX" || Roughness <= 0.075) {
|
|
BSDF = BSDF + specular_weight *
|
|
microfacet_ggx_aniso_fresnel(Normal,
|
|
T,
|
|
alpha_x,
|
|
alpha_y,
|
|
(2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0,
|
|
BaseColor,
|
|
Cspec0);
|
|
}
|
|
else {
|
|
BSDF = BSDF + specular_weight * microfacet_multi_ggx_aniso_fresnel(
|
|
Normal,
|
|
T,
|
|
alpha_x,
|
|
alpha_y,
|
|
(2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0,
|
|
BaseColor,
|
|
Cspec0);
|
|
}
|
|
}
|
|
|
|
if (final_transmission > 1e-5) {
|
|
color Cspec0 = BaseColor * SpecularTint + color(1.0, 1.0, 1.0) * (1.0 - SpecularTint);
|
|
float eta = backfacing() ? 1.0 / f : f;
|
|
|
|
if (distribution == "GGX" || Roughness <= 5e-2) {
|
|
float cosNO = dot(Normal, I);
|
|
float Fr = fresnel_dielectric_cos(cosNO, eta);
|
|
|
|
float refl_roughness = Roughness;
|
|
if (Roughness <= 1e-2)
|
|
refl_roughness = 0.0;
|
|
|
|
float transmission_roughness = refl_roughness;
|
|
if (distribution == "GGX")
|
|
transmission_roughness = 1.0 - (1.0 - refl_roughness) * (1.0 - TransmissionRoughness);
|
|
|
|
BSDF = BSDF +
|
|
final_transmission *
|
|
(Fr * microfacet_ggx_fresnel(
|
|
Normal, refl_roughness * refl_roughness, eta, BaseColor, Cspec0) +
|
|
(1.0 - Fr) * BaseColor *
|
|
microfacet_ggx_refraction(
|
|
Normal, transmission_roughness * transmission_roughness, eta));
|
|
}
|
|
else {
|
|
BSDF = BSDF +
|
|
final_transmission * microfacet_multi_ggx_glass_fresnel(
|
|
Normal, Roughness * Roughness, eta, BaseColor, Cspec0);
|
|
}
|
|
}
|
|
|
|
if (Clearcoat > 1e-5) {
|
|
BSDF = BSDF + principled_clearcoat(
|
|
ClearcoatNormal, Clearcoat, ClearcoatRoughness * ClearcoatRoughness);
|
|
}
|
|
}
|