forked from bartvdbraak/blender
Cycles: Ashikhmin-Shirley anisotropic BSDF
* Ashikhmin-Shirley anisotropic BSDF was added as closure * Anisotropic BSDF node now has two distributions Reviewers: brecht, dingto Differential Revision: https://developer.blender.org/D549
This commit is contained in:
parent
f5cb0cf1a5
commit
8ce1090d4e
@ -509,8 +509,10 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug
|
||||
else if(string_iequals(node.name(), "mapping")) {
|
||||
snode = new MappingNode();
|
||||
}
|
||||
else if(string_iequals(node.name(), "ward_bsdf")) {
|
||||
snode = new WardBsdfNode();
|
||||
else if(string_iequals(node.name(), "anisotropic_bsdf")) {
|
||||
AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode();
|
||||
xml_read_enum(&aniso->distribution, AnisotropicBsdfNode::distribution_enum, node, "distribution");
|
||||
snode = aniso;
|
||||
}
|
||||
else if(string_iequals(node.name(), "diffuse_bsdf")) {
|
||||
snode = new DiffuseBsdfNode();
|
||||
|
@ -318,7 +318,21 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
|
||||
node = new HoldoutNode();
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
|
||||
node = new WardBsdfNode();
|
||||
BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node);
|
||||
AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode();
|
||||
|
||||
switch (b_aniso_node.distribution())
|
||||
{
|
||||
case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
|
||||
aniso->distribution = ustring("Ashikhmin-Shirley");
|
||||
break;
|
||||
case BL::ShaderNodeBsdfAnisotropic::distribution_WARD:
|
||||
default:
|
||||
aniso->distribution = ustring("Ward");
|
||||
break;
|
||||
}
|
||||
|
||||
node = aniso;
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) {
|
||||
node = new DiffuseBsdfNode();
|
||||
|
@ -61,6 +61,7 @@ set(SRC_CLOSURE_HEADERS
|
||||
closure/bsdf_transparent.h
|
||||
closure/bsdf_util.h
|
||||
closure/bsdf_ward.h
|
||||
closure/bsdf_ashikhmin_shirley.h
|
||||
closure/bsdf_westin.h
|
||||
closure/bsdf_hair.h
|
||||
closure/bssrdf.h
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "../closure/bsdf_transparent.h"
|
||||
#ifdef __ANISOTROPIC__
|
||||
#include "../closure/bsdf_ward.h"
|
||||
#include "../closure/bsdf_ashikhmin_shirley.h"
|
||||
#endif
|
||||
#include "../closure/bsdf_westin.h"
|
||||
#include "../closure/bsdf_toon.h"
|
||||
@ -97,6 +98,10 @@ ccl_device int bsdf_sample(KernelGlobals *kg, const ShaderData *sd, const Shader
|
||||
label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
|
||||
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
label = bsdf_ashikhmin_shirley_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
|
||||
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
|
||||
break;
|
||||
#endif
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
|
||||
label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
|
||||
@ -189,6 +194,9 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const Shade
|
||||
case CLOSURE_BSDF_WARD_ID:
|
||||
eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
eval = bsdf_ashikhmin_shirley_eval_reflect(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
#endif
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
|
||||
eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
|
||||
@ -256,6 +264,9 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const Shade
|
||||
case CLOSURE_BSDF_WARD_ID:
|
||||
eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
eval = bsdf_ashikhmin_shirley_eval_transmit(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
#endif
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
|
||||
eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
|
||||
@ -341,6 +352,9 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
|
||||
case CLOSURE_BSDF_WARD_ID:
|
||||
bsdf_ward_blur(sc, roughness);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
bsdf_ashikhmin_shirley_blur(sc, roughness);
|
||||
break;
|
||||
#endif
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
|
||||
bsdf_ashikhmin_velvet_blur(sc, roughness);
|
||||
|
196
intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
Normal file
196
intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright 2011-2013 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
|
||||
*/
|
||||
|
||||
#ifndef __BSDF_ASHIKHMIN_SHIRLEY_H__
|
||||
#define __BSDF_ASHIKHMIN_SHIRLEY_H__
|
||||
|
||||
/*
|
||||
ASHIKHMIN SHIRLEY BSDF
|
||||
|
||||
Implementation of
|
||||
Michael Ashikhmin and Peter Shirley: "An Anisotropic Phong BRDF Model" (2000)
|
||||
|
||||
The Fresnel factor is missing to get a separable bsdf (intensity*color), as is
|
||||
the case with all other microfacet-based BSDF implementations in Cycles.
|
||||
|
||||
Other than that, the implementation directly follows the paper.
|
||||
*/
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
ccl_device int bsdf_ashikhmin_shirley_setup(ShaderClosure *sc)
|
||||
{
|
||||
sc->data0 = clamp(sc->data0, 1e-4f, 1.0f); /* store roughness. could already convert to exponent to save some cycles in eval, */
|
||||
sc->data1 = clamp(sc->data1, 1e-4f, 1.0f); /* but this is more consistent with other bsdfs and shader_blur. */
|
||||
|
||||
sc->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
|
||||
}
|
||||
|
||||
ccl_device void bsdf_ashikhmin_shirley_blur(ShaderClosure *sc, float roughness)
|
||||
{
|
||||
sc->data0 = fmaxf(roughness, sc->data0); /* clamp roughness */
|
||||
sc->data1 = fmaxf(roughness, sc->data1);
|
||||
}
|
||||
|
||||
ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float roughness)
|
||||
{
|
||||
return 2.0f / (roughness*roughness) - 2.0f;
|
||||
}
|
||||
|
||||
ccl_device float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
|
||||
{
|
||||
float3 N = sc->N;
|
||||
float3 T = sc->T;
|
||||
|
||||
float NdotI = dot(N, I); /* in Cycles/OSL convention I is omega_out */
|
||||
float NdotO = dot(N, omega_in); /* and consequently we use for O omaga_in ;) */
|
||||
|
||||
float out = 0.0f;
|
||||
|
||||
if (NdotI > 0.0f && NdotO > 0.0f) {
|
||||
NdotI = fmaxf(NdotI, 1e-6f);
|
||||
NdotO = fmaxf(NdotO, 1e-6f);
|
||||
float3 H = normalize(omega_in + I);
|
||||
float HdotI = fmaxf(dot(H, I), 1e-6f);
|
||||
float HdotN = fmaxf(dot(H, N), 1e-6f);
|
||||
|
||||
float pump = 1.0f / fmaxf(1e-6f, (HdotI*fmaxf(NdotO, NdotI))); /* pump from original paper (first derivative disc., but cancels the HdotI in the pdf nicely) */
|
||||
/*float pump = 1.0f / fmaxf(1e-4f, ((NdotO + NdotI) * (NdotO*NdotI))); */ /* pump from d-brdf paper */
|
||||
|
||||
float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data0);
|
||||
float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data1);
|
||||
|
||||
if (n_x == n_y) { /* => isotropic case */
|
||||
float e = n_x;
|
||||
float lobe = powf(HdotN, e);
|
||||
float norm = (n_x + 1.0f) / (8.0f * M_PI_F);
|
||||
|
||||
out = NdotO * norm * lobe * pump;
|
||||
*pdf = norm * lobe / HdotI; /* this is p_h / 4(H.I) (conversion from 'wh measure' to 'wi measure', eq. 8 in paper) */
|
||||
}
|
||||
else { /* => ANisotropic case */
|
||||
float3 X, Y;
|
||||
make_orthonormals_tangent(N, T, &X, &Y);
|
||||
|
||||
float HdotX = dot(H, X);
|
||||
float HdotY = dot(H, Y);
|
||||
float e = (n_x * HdotX*HdotX + n_y * HdotY*HdotY) / (1.0f - HdotN*HdotN);
|
||||
float lobe = powf(HdotN, e);
|
||||
float norm = sqrtf((n_x + 1.0f)*(n_y + 1.0f)) / (8.0f * M_PI_F);
|
||||
|
||||
out = NdotO * norm * lobe * pump;
|
||||
*pdf = norm * lobe / HdotI;
|
||||
}
|
||||
}
|
||||
|
||||
return make_float3(out, out, out);
|
||||
}
|
||||
|
||||
ccl_device float3 bsdf_ashikhmin_shirley_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
|
||||
{
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
ccl_device_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x, float n_y, float randu, float randv, float *phi, float *cos_theta)
|
||||
{
|
||||
*phi = atanf(sqrtf((n_x + 1.0f) / (n_y + 1.0f)) * tanf(M_PI_2_F * randu));
|
||||
float cos_phi = cosf(*phi);
|
||||
float sin_phi = sinf(*phi);
|
||||
*cos_theta = powf(randv, 1.0f / (n_x * cos_phi*cos_phi + n_y * sin_phi*sin_phi + 1.0f));
|
||||
}
|
||||
|
||||
ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
|
||||
{
|
||||
float3 N = sc->N;
|
||||
float3 T = sc->T;
|
||||
|
||||
float NdotI = dot(N, I);
|
||||
if (NdotI > 0.0f) {
|
||||
|
||||
float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data0);
|
||||
float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data1);
|
||||
|
||||
/* get x,y basis on the surface for anisotropy */
|
||||
float3 X, Y;
|
||||
make_orthonormals_tangent(N, T, &X, &Y);
|
||||
|
||||
/* sample spherical coords for h in tangent space */
|
||||
float phi;
|
||||
float cos_theta;
|
||||
if (n_x == n_y) { /* => simple isotropic sampling */
|
||||
phi = M_2PI_F * randu;
|
||||
cos_theta = powf(randv, 1.0f / (n_x + 1.0f));
|
||||
}
|
||||
else { /* => more complex anisotropic sampling */
|
||||
if (randu < 0.25f) { /* first quadrant */
|
||||
float remapped_randu = 4.0f * randu;
|
||||
bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
|
||||
}
|
||||
else if (randu < 0.5f) { /* second quadrant */
|
||||
float remapped_randu = 4.0f * (.5f - randu);
|
||||
bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
|
||||
phi = M_PI_F - phi;
|
||||
}
|
||||
else if (randu < 0.75f) { /* third quadrant */
|
||||
float remapped_randu = 4.0f * (randu - 0.5f);
|
||||
bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
|
||||
phi = M_PI_F + phi;
|
||||
}
|
||||
else { /* fourth quadrant */
|
||||
float remapped_randu = 4.0f * (1.0f - randu);
|
||||
bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
|
||||
phi = 2.0f * M_PI_F - phi;
|
||||
}
|
||||
}
|
||||
|
||||
/* get half vector in tangent space */
|
||||
float sin_theta = sqrtf(fmaxf(0.0f, 1.0f - cos_theta*cos_theta));
|
||||
float cos_phi = cosf(phi);
|
||||
float sin_phi = sinf(phi); /* no sqrt(1-cos^2) here b/c it causes artifacts */
|
||||
float3 h = make_float3(
|
||||
sin_theta * cos_phi,
|
||||
sin_theta * sin_phi,
|
||||
cos_theta
|
||||
);
|
||||
|
||||
/* half vector to world space */
|
||||
float3 H = h.x*X + h.y*Y + h.z*N;
|
||||
float HdotI = dot(H, I);
|
||||
if (HdotI < 0.0f) H = -H;
|
||||
|
||||
/* reflect I on H to get omega_in */
|
||||
*omega_in = -I + (2.0f * HdotI) * H;
|
||||
|
||||
/* leave the rest to eval_reflect */
|
||||
/* (could maybe optimize a few things by manual inlining, but I doubt it would make much difference) */
|
||||
*eval = bsdf_ashikhmin_shirley_eval_reflect(sc, I, *omega_in, pdf);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
/* just do the reflection thing for now */
|
||||
*domega_in_dx = (2.0f * dot(N, dIdx)) * N - dIdx;
|
||||
*domega_in_dy = (2.0f * dot(N, dIdy)) * N - dIdy;
|
||||
#endif
|
||||
}
|
||||
|
||||
return LABEL_REFLECT | LABEL_GLOSSY;
|
||||
}
|
||||
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __BSDF_ASHIKHMIN_SHIRLEY_H__ */
|
@ -52,6 +52,7 @@
|
||||
#include "closure/bsdf_refraction.h"
|
||||
#include "closure/bsdf_transparent.h"
|
||||
#include "closure/bsdf_ward.h"
|
||||
#include "closure/bsdf_ashikhmin_shirley.h"
|
||||
#include "closure/bsdf_westin.h"
|
||||
#include "closure/bsdf_toon.h"
|
||||
#include "closure/bsdf_hair.h"
|
||||
@ -110,6 +111,13 @@ BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY)
|
||||
CLOSURE_FLOAT_PARAM(WardClosure, sc.data1),
|
||||
BSDF_CLOSURE_CLASS_END(Ward, ward)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, ashikhmin_shirley, ashikhmin_shirley, LABEL_GLOSSY)
|
||||
CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, sc.N),
|
||||
CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, sc.T),
|
||||
CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, sc.data0),
|
||||
CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, sc.data1),
|
||||
BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(DiffuseToon, diffuse_toon, diffuse_toon, LABEL_DIFFUSE)
|
||||
CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(DiffuseToonClosure, sc.data0),
|
||||
@ -218,6 +226,8 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
|
||||
bsdf_microfacet_beckmann_refraction_params(), bsdf_microfacet_beckmann_refraction_prepare);
|
||||
register_closure(ss, "ward", id++,
|
||||
bsdf_ward_params(), bsdf_ward_prepare);
|
||||
register_closure(ss, "ashikhmin_shirley", id++,
|
||||
bsdf_ashikhmin_shirley_params(), bsdf_ashikhmin_shirley_prepare);
|
||||
register_closure(ss, "ashikhmin_velvet", id++,
|
||||
bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
|
||||
register_closure(ss, "diffuse_toon", id++,
|
||||
|
@ -4,6 +4,7 @@
|
||||
set(SRC_OSL
|
||||
node_add_closure.osl
|
||||
node_ambient_occlusion.osl
|
||||
node_anisotropic_bsdf.osl
|
||||
node_attribute.osl
|
||||
node_background.osl
|
||||
node_brick_texture.osl
|
||||
@ -73,7 +74,6 @@ set(SRC_OSL
|
||||
node_vector_transform.osl
|
||||
node_velvet_bsdf.osl
|
||||
node_voronoi_texture.osl
|
||||
node_ward_bsdf.osl
|
||||
node_wavelength.osl
|
||||
node_blackbody.osl
|
||||
node_wave_texture.osl
|
||||
|
@ -16,8 +16,9 @@
|
||||
|
||||
#include "stdosl.h"
|
||||
|
||||
shader node_ward_bsdf(
|
||||
shader node_anisotropic_bsdf(
|
||||
color Color = 0.0,
|
||||
string distribution = "Ward",
|
||||
float Roughness = 0.0,
|
||||
float Anisotropy = 0.0,
|
||||
float Rotation = 0.0,
|
||||
@ -44,6 +45,9 @@ shader node_ward_bsdf(
|
||||
RoughnessV = Roughness / (1.0 - aniso);
|
||||
}
|
||||
|
||||
BSDF = Color * ward(Normal, T, RoughnessU, RoughnessV);
|
||||
if (distribution == "Ashikhmin-Shirley")
|
||||
BSDF = Color * ashikhmin_shirley(Normal, T, RoughnessU, RoughnessV);
|
||||
else
|
||||
BSDF = Color * ward(Normal, T, RoughnessU, RoughnessV);
|
||||
}
|
||||
|
@ -486,6 +486,7 @@ closure color microfacet_ggx(normal N, float ag) BUILTIN;
|
||||
closure color microfacet_ggx_refraction(normal N, float ag, float eta) BUILTIN;
|
||||
closure color microfacet_beckmann(normal N, float ab) BUILTIN;
|
||||
closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN;
|
||||
closure color ashikhmin_shirley(normal N, vector T,float ax, float ay) BUILTIN;
|
||||
closure color ward(normal N, vector T,float ax, float ay) BUILTIN;
|
||||
closure color ashikhmin_velvet(normal N, float sigma) BUILTIN;
|
||||
closure color emission() BUILTIN;
|
||||
|
@ -269,7 +269,8 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
||||
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_WARD_ID: {
|
||||
case CLOSURE_BSDF_WARD_ID:
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: {
|
||||
#ifdef __CAUSTICS_TRICKS__
|
||||
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
|
||||
break;
|
||||
@ -301,7 +302,11 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
||||
sc->data1 = roughness/(1.0f - anisotropy);
|
||||
}
|
||||
|
||||
sd->flag |= bsdf_ward_setup(sc);
|
||||
if (type == CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID)
|
||||
sd->flag |= bsdf_ashikhmin_shirley_setup(sc);
|
||||
else
|
||||
sd->flag |= bsdf_ward_setup(sc);
|
||||
|
||||
#else
|
||||
sd->flag |= bsdf_diffuse_setup(sc);
|
||||
#endif
|
||||
|
@ -358,6 +358,7 @@ typedef enum ClosureType {
|
||||
CLOSURE_BSDF_MICROFACET_GGX_ID,
|
||||
CLOSURE_BSDF_MICROFACET_BECKMANN_ID,
|
||||
CLOSURE_BSDF_WARD_ID,
|
||||
CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID,
|
||||
CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
|
||||
CLOSURE_BSDF_WESTIN_BACKSCATTER_ID,
|
||||
CLOSURE_BSDF_PHONG_RAMP_ID,
|
||||
@ -403,7 +404,7 @@ typedef enum ClosureType {
|
||||
#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID)
|
||||
#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)
|
||||
#define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID)
|
||||
#define CLOSURE_IS_BSDF_ANISOTROPIC(type) (type == CLOSURE_BSDF_WARD_ID)
|
||||
#define CLOSURE_IS_BSDF_ANISOTROPIC(type) (type >= CLOSURE_BSDF_WARD_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID)
|
||||
#define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_GAUSSIAN_ID)
|
||||
#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_GAUSSIAN_ID)
|
||||
#define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
|
||||
|
@ -1583,11 +1583,23 @@ void BsdfNode::compile(OSLCompiler& compiler)
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* Ward BSDF Closure */
|
||||
/* Anisotropic BSDF Closure */
|
||||
|
||||
WardBsdfNode::WardBsdfNode()
|
||||
static ShaderEnum anisotropic_distribution_init()
|
||||
{
|
||||
closure = CLOSURE_BSDF_WARD_ID;
|
||||
ShaderEnum enm;
|
||||
|
||||
enm.insert("Ward", CLOSURE_BSDF_WARD_ID);
|
||||
enm.insert("Ashikhmin-Shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
|
||||
|
||||
return enm;
|
||||
}
|
||||
|
||||
ShaderEnum AnisotropicBsdfNode::distribution_enum = anisotropic_distribution_init();
|
||||
|
||||
AnisotropicBsdfNode::AnisotropicBsdfNode()
|
||||
{
|
||||
distribution = ustring("Ward");
|
||||
|
||||
add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT);
|
||||
|
||||
@ -1596,7 +1608,7 @@ WardBsdfNode::WardBsdfNode()
|
||||
add_input("Rotation", SHADER_SOCKET_FLOAT, 0.0f);
|
||||
}
|
||||
|
||||
void WardBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||
void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||
{
|
||||
if(shader->has_surface) {
|
||||
ShaderInput *tangent_in = input("Tangent");
|
||||
@ -1608,14 +1620,17 @@ void WardBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||
ShaderNode::attributes(shader, attributes);
|
||||
}
|
||||
|
||||
void WardBsdfNode::compile(SVMCompiler& compiler)
|
||||
void AnisotropicBsdfNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
closure = (ClosureType)distribution_enum[distribution];
|
||||
|
||||
BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation"));
|
||||
}
|
||||
|
||||
void WardBsdfNode::compile(OSLCompiler& compiler)
|
||||
void AnisotropicBsdfNode::compile(OSLCompiler& compiler)
|
||||
{
|
||||
compiler.add(this, "node_ward_bsdf");
|
||||
compiler.parameter("distribution", distribution);
|
||||
compiler.add(this, "node_anisotropic_bsdf");
|
||||
}
|
||||
|
||||
/* Glossy BSDF Closure */
|
||||
|
@ -218,9 +218,13 @@ public:
|
||||
bool scattering;
|
||||
};
|
||||
|
||||
class WardBsdfNode : public BsdfNode {
|
||||
class AnisotropicBsdfNode : public BsdfNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(WardBsdfNode)
|
||||
SHADER_NODE_CLASS(AnisotropicBsdfNode)
|
||||
|
||||
ustring distribution;
|
||||
static ShaderEnum distribution_enum;
|
||||
|
||||
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
||||
};
|
||||
|
||||
|
@ -930,6 +930,11 @@ static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), Point
|
||||
uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_shader_buts_anisotropic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_shader_buts_subsurface(uiLayout *layout, bContext *C, PointerRNA *ptr)
|
||||
{
|
||||
/* SSS does not work on GPU yet */
|
||||
@ -1096,6 +1101,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
|
||||
case SH_NODE_BSDF_REFRACTION:
|
||||
ntype->draw_buttons = node_shader_buts_glossy;
|
||||
break;
|
||||
case SH_NODE_BSDF_ANISOTROPIC:
|
||||
ntype->draw_buttons = node_shader_buts_anisotropic;
|
||||
break;
|
||||
case SH_NODE_SUBSURFACE_SCATTERING:
|
||||
ntype->draw_buttons = node_shader_buts_subsurface;
|
||||
break;
|
||||
|
@ -873,6 +873,10 @@ typedef struct NodeShaderUVMap {
|
||||
#define CMP_NODE_CHANNEL_MATTE_CS_YUV 3
|
||||
#define CMP_NODE_CHANNEL_MATTE_CS_YCC 4
|
||||
|
||||
/* anisotropic distributions */
|
||||
#define SHD_ANISOTROPIC_WARD 0
|
||||
#define SHD_ANISOTROPIC_ASHIKHMIN_SHIRLEY 1
|
||||
|
||||
/* glossy distributions */
|
||||
#define SHD_GLOSSY_BECKMANN 0
|
||||
#define SHD_GLOSSY_SHARP 1
|
||||
|
@ -2952,6 +2952,12 @@ static EnumPropertyItem node_glossy_items[] = {
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem node_anisotropic_items[] = {
|
||||
{SHD_ANISOTROPIC_WARD, "WARD", 0, "Ward", ""},
|
||||
{SHD_ANISOTROPIC_ASHIKHMIN_SHIRLEY, "ASHIKHMIN_SHIRLEY", 0, "Ashikhmin-Shirley", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem node_toon_items[] = {
|
||||
{SHD_TOON_DIFFUSE, "DIFFUSE", 0, "Diffuse", ""},
|
||||
{SHD_TOON_GLOSSY, "GLOSSY", 0, "Glossy", ""},
|
||||
@ -3699,6 +3705,17 @@ static void def_glossy(StructRNA *srna)
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
static void def_anisotropic(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "custom1");
|
||||
RNA_def_property_enum_items(prop, node_anisotropic_items);
|
||||
RNA_def_property_ui_text(prop, "Distribution", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
static void def_toon(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
@ -77,7 +77,7 @@ DefNode( ShaderNode, SH_NODE_ATTRIBUTE, def_sh_attribute, "AT
|
||||
DefNode( ShaderNode, SH_NODE_AMBIENT_OCCLUSION, 0, "AMBIENT_OCCLUSION", AmbientOcclusion, "Ambient Occlusion", "" )
|
||||
DefNode( ShaderNode, SH_NODE_BACKGROUND, 0, "BACKGROUND", Background, "Background", "" )
|
||||
DefNode( ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "" )
|
||||
DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, 0, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic BSDF", "" )
|
||||
DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, def_anisotropic, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic BSDF", "" )
|
||||
DefNode( ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse BSDF", "" )
|
||||
DefNode( ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfGlossy, "Glossy BSDF", "" )
|
||||
DefNode( ShaderNode, SH_NODE_BSDF_GLASS, def_glossy, "BSDF_GLASS", BsdfGlass, "Glass BSDF", "" )
|
||||
|
Loading…
Reference in New Issue
Block a user