WIP: Cycles: Implement BSDF layering #110444
|
@ -511,6 +511,9 @@ static ShaderNode *add_node(Scene *scene,
|
|||
else if (b_node.is_a(&RNA_ShaderNodeMixShader)) {
|
||||
node = graph->create_node<MixClosureNode>();
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeLayerShader)) {
|
||||
node = graph->create_node<LayerClosureNode>();
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeAttribute)) {
|
||||
BL::ShaderNodeAttribute b_attr_node(b_node);
|
||||
AttributeNode *attr = graph->create_node<AttributeNode>();
|
||||
|
|
|
@ -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 */
|
||||
|
@ -160,7 +170,8 @@ void osl_eval_nodes<SHADER_TYPE_SURFACE>(const KernelGlobalsCPU *kg,
|
|||
|
||||
/* flatten closure tree */
|
||||
if (globals->Ci) {
|
||||
flatten_closure_tree(kg, sd, path_flag, reinterpret_cast<OSLClosure *>(globals->Ci));
|
||||
flatten_closure_tree(
|
||||
kg, sd, path_flag, one_float3(), reinterpret_cast<OSLClosure *>(globals->Ci));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,7 +214,8 @@ void osl_eval_nodes<SHADER_TYPE_VOLUME>(const KernelGlobalsCPU *kg,
|
|||
|
||||
/* flatten closure tree */
|
||||
if (globals->Ci) {
|
||||
flatten_closure_tree(kg, sd, path_flag, reinterpret_cast<OSLClosure *>(globals->Ci));
|
||||
flatten_closure_tree(
|
||||
kg, sd, path_flag, one_float3(), reinterpret_cast<OSLClosure *>(globals->Ci));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,27 +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/bsdf_principled_sheen.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
|
||||
|
||||
|
@ -43,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,
|
||||
|
@ -66,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;
|
||||
|
@ -87,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;
|
||||
|
@ -109,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;
|
||||
|
@ -130,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;
|
||||
|
@ -152,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;
|
||||
|
@ -175,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);
|
||||
}
|
||||
|
@ -185,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);
|
||||
|
@ -244,13 +239,19 @@ 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->energy_scale *
|
||||
bsdf_albedo(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;
|
||||
|
@ -296,7 +297,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);
|
||||
|
@ -361,6 +363,11 @@ 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->energy_scale *
|
||||
bsdf_albedo(sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Standard microfacet closures */
|
||||
|
@ -369,7 +376,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)) {
|
||||
|
@ -425,6 +433,11 @@ 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->energy_scale *
|
||||
bsdf_albedo(sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Special-purpose Microfacet closures */
|
||||
|
@ -434,7 +447,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
|
||||
|
@ -465,7 +479,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;
|
||||
|
@ -486,6 +501,11 @@ 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));
|
||||
|
||||
if (layer_albedo != NULL) {
|
||||
*layer_albedo = bsdf->energy_scale *
|
||||
bsdf_albedo(sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device void osl_closure_microfacet_aniso_fresnel_setup(
|
||||
|
@ -493,7 +513,8 @@ ccl_device void osl_closure_microfacet_aniso_fresnel_setup(
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const MicrofacetAnisoFresnelClosure *closure)
|
||||
ccl_private const MicrofacetAnisoFresnelClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
|
||||
return;
|
||||
|
@ -529,6 +550,11 @@ ccl_device void osl_closure_microfacet_aniso_fresnel_setup(
|
|||
fresnel->f90 = rgb_to_spectrum(closure->f90);
|
||||
fresnel->exponent = -1.0f;
|
||||
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, preserve_energy);
|
||||
|
||||
if (layer_albedo != NULL) {
|
||||
*layer_albedo = bsdf->energy_scale *
|
||||
bsdf_albedo(sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ashikhmin Velvet */
|
||||
|
@ -538,7 +564,8 @@ ccl_device void osl_closure_ashikhmin_velvet_setup(
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const AshikhminVelvetClosure *closure)
|
||||
ccl_private const AshikhminVelvetClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
|
||||
return;
|
||||
|
@ -562,7 +589,8 @@ ccl_device void osl_closure_sheen_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const SheenClosure *closure)
|
||||
ccl_private const SheenClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
|
||||
return;
|
||||
|
@ -578,13 +606,18 @@ ccl_device void osl_closure_sheen_setup(KernelGlobals kg,
|
|||
bsdf->roughness = closure->roughness;
|
||||
|
||||
sd->flag |= bsdf_sheen_setup(kg, sd, bsdf);
|
||||
|
||||
if (layer_albedo != NULL) {
|
||||
*layer_albedo = bsdf->weight;
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device void osl_closure_diffuse_toon_setup(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const DiffuseToonClosure *closure)
|
||||
ccl_private const DiffuseToonClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
|
||||
return;
|
||||
|
@ -607,7 +640,8 @@ ccl_device void osl_closure_glossy_toon_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const GlossyToonClosure *closure)
|
||||
ccl_private const GlossyToonClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) {
|
||||
return;
|
||||
|
@ -633,7 +667,8 @@ ccl_device void osl_closure_principled_diffuse_setup(
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const PrincipledDiffuseClosure *closure)
|
||||
ccl_private const PrincipledDiffuseClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
|
||||
return;
|
||||
|
@ -656,7 +691,8 @@ ccl_device void osl_closure_principled_sheen_setup(
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const PrincipledSheenClosure *closure)
|
||||
ccl_private const PrincipledSheenClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
|
||||
return;
|
||||
|
@ -684,7 +720,8 @@ ccl_device void osl_closure_emission_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t /* path_flag */,
|
||||
float3 weight,
|
||||
ccl_private const GenericEmissiveClosure *closure)
|
||||
ccl_private const GenericEmissiveClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
emission_setup(sd, rgb_to_spectrum(weight));
|
||||
}
|
||||
|
@ -698,7 +735,8 @@ ccl_device void osl_closure_background_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t /* path_flag */,
|
||||
float3 weight,
|
||||
ccl_private const GenericBackgroundClosure *closure)
|
||||
ccl_private const GenericBackgroundClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
background_setup(sd, rgb_to_spectrum(weight));
|
||||
}
|
||||
|
@ -712,7 +750,8 @@ ccl_device void osl_closure_holdout_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t /* path_flag */,
|
||||
float3 weight,
|
||||
ccl_private const HoldoutClosure *closure)
|
||||
ccl_private const HoldoutClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, rgb_to_spectrum(weight));
|
||||
sd->flag |= SD_HOLDOUT;
|
||||
|
@ -722,7 +761,8 @@ ccl_device void osl_closure_diffuse_ramp_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t /* path_flag */,
|
||||
float3 weight,
|
||||
ccl_private const DiffuseRampClosure *closure)
|
||||
ccl_private const DiffuseRampClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
ccl_private DiffuseRampBsdf *bsdf = (ccl_private DiffuseRampBsdf *)bsdf_alloc(
|
||||
sd, sizeof(DiffuseRampBsdf), rgb_to_spectrum(weight));
|
||||
|
@ -748,7 +788,8 @@ ccl_device void osl_closure_phong_ramp_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t /* path_flag */,
|
||||
float3 weight,
|
||||
ccl_private const PhongRampClosure *closure)
|
||||
ccl_private const PhongRampClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
ccl_private PhongRampBsdf *bsdf = (ccl_private PhongRampBsdf *)bsdf_alloc(
|
||||
sd, sizeof(PhongRampBsdf), rgb_to_spectrum(weight));
|
||||
|
@ -774,7 +815,8 @@ ccl_device void osl_closure_bssrdf_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const BSSRDFClosure *closure)
|
||||
ccl_private const BSSRDFClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
ClosureType type;
|
||||
if (closure->method == make_string("burley", 186330084368958868ull)) {
|
||||
|
@ -820,7 +862,8 @@ ccl_device void osl_closure_hair_reflection_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const HairReflectionClosure *closure)
|
||||
ccl_private const HairReflectionClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) {
|
||||
return;
|
||||
|
@ -846,7 +889,8 @@ ccl_device void osl_closure_hair_transmission_setup(
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const HairTransmissionClosure *closure)
|
||||
ccl_private const HairTransmissionClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) {
|
||||
return;
|
||||
|
@ -871,7 +915,8 @@ ccl_device void osl_closure_principled_hair_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const PrincipledHairClosure *closure)
|
||||
ccl_private const PrincipledHairClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
#ifdef __HAIR__
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) {
|
||||
|
@ -910,7 +955,8 @@ ccl_device void osl_closure_absorption_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const VolumeAbsorptionClosure *closure)
|
||||
ccl_private const VolumeAbsorptionClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
volume_extinction_setup(sd, rgb_to_spectrum(weight));
|
||||
}
|
||||
|
@ -920,7 +966,8 @@ ccl_device void osl_closure_henyey_greenstein_setup(
|
|||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const VolumeHenyeyGreensteinClosure *closure)
|
||||
ccl_private const VolumeHenyeyGreensteinClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
volume_extinction_setup(sd, rgb_to_spectrum(weight));
|
||||
|
||||
|
|
|
@ -64,12 +64,14 @@ ccl_device_inline void shaderdata_to_shaderglobals(KernelGlobals kg,
|
|||
ccl_device void flatten_closure_tree(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
float3 weight,
|
||||
ccl_private const OSLClosure *closure)
|
||||
{
|
||||
int stack_size = 0;
|
||||
float3 weight = one_float3();
|
||||
float3 weight_stack[16];
|
||||
ccl_private const OSLClosure *closure_stack[16];
|
||||
int layer_stack_level = -1;
|
||||
float3 layer_albedo;
|
||||
|
||||
while (closure) {
|
||||
switch (closure->id) {
|
||||
|
@ -92,15 +94,39 @@ ccl_device void flatten_closure_tree(KernelGlobals kg,
|
|||
closure_stack[stack_size++] = add->closureB;
|
||||
continue;
|
||||
}
|
||||
case OSL_CLOSURE_LAYER_ID: {
|
||||
ccl_private const OSLClosureComponent *comp =
|
||||
static_cast<ccl_private const OSLClosureComponent *>(closure);
|
||||
ccl_private const LayerClosure *layer = reinterpret_cast<ccl_private const LayerClosure *>(
|
||||
comp + 1);
|
||||
|
||||
/* Layer closures may not appear in the top layer subtree of another layer closure. */
|
||||
kernel_assert(layer_stack_level == -1);
|
||||
|
||||
/* Push base layer onto the stack, will be handled after the top layers */
|
||||
weight_stack[stack_size] = weight;
|
||||
closure_stack[stack_size] = layer->base;
|
||||
/* Start accumulating albedo of the top layers */
|
||||
layer_stack_level = stack_size++;
|
||||
layer_albedo = zero_float3();
|
||||
/* Continue with the top layers */
|
||||
closure = layer->top;
|
||||
continue;
|
||||
}
|
||||
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
|
||||
case OSL_CLOSURE_##Upper##_ID: { \
|
||||
ccl_private const OSLClosureComponent *comp = \
|
||||
static_cast<ccl_private const OSLClosureComponent *>(closure); \
|
||||
float3 albedo = one_float3(); \
|
||||
osl_closure_##lower##_setup(kg, \
|
||||
sd, \
|
||||
path_flag, \
|
||||
weight * comp->weight, \
|
||||
reinterpret_cast<ccl_private const Upper##Closure *>(comp + 1)); \
|
||||
reinterpret_cast<ccl_private const Upper##Closure *>(comp + 1), \
|
||||
(layer_stack_level >= 0) ? &albedo : NULL); \
|
||||
if (layer_stack_level >= 0) { \
|
||||
layer_albedo += albedo; \
|
||||
} \
|
||||
break; \
|
||||
}
|
||||
#include "closures_template.h"
|
||||
|
@ -111,6 +137,13 @@ ccl_device void flatten_closure_tree(KernelGlobals kg,
|
|||
if (stack_size > 0) {
|
||||
weight = weight_stack[--stack_size];
|
||||
closure = closure_stack[stack_size];
|
||||
if (stack_size == layer_stack_level) {
|
||||
/* We just finished processing the top layers of a Layer closure, so adjust the weight to
|
||||
* account for the layering. */
|
||||
weight *= saturatef(1.0f - reduce_max(layer_albedo / weight));
|
||||
/* TODO: Skip if weight zero */
|
||||
layer_stack_level = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
closure = nullptr;
|
||||
|
@ -168,7 +201,7 @@ ccl_device_inline void osl_eval_nodes(KernelGlobals kg,
|
|||
sd->P = globals.P;
|
||||
}
|
||||
else if (globals.Ci) {
|
||||
flatten_closure_tree(kg, sd, path_flag, globals.Ci);
|
||||
flatten_closure_tree(kg, sd, path_flag, one_float3(), globals.Ci);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ set(SRC_OSL
|
|||
node_ies_light.osl
|
||||
node_image_texture.osl
|
||||
node_invert.osl
|
||||
node_layer_closure.osl
|
||||
node_layer_weight.osl
|
||||
node_light_falloff.osl
|
||||
node_light_path.osl
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
shader node_mix_closure(closure color Base = 0,
|
||||
closure color Top = 0,
|
||||
output closure color Closure = 0)
|
||||
{
|
||||
Closure = layer(Top, Base);
|
||||
}
|
|
@ -39,6 +39,7 @@ enum OSLClosureType {
|
|||
|
||||
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) OSL_CLOSURE_##Upper##_ID,
|
||||
#include "closures_template.h"
|
||||
OSL_CLOSURE_LAYER_ID,
|
||||
};
|
||||
|
||||
struct OSLClosure {
|
||||
|
|
|
@ -97,7 +97,7 @@ ccl_device_noinline
|
|||
svm_node_ao(KernelGlobals kg,
|
||||
ConstIntegratorGenericState state,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint flags, dist_offset, normal_offset, out_ao_offset;
|
||||
|
@ -110,8 +110,8 @@ ccl_device_noinline
|
|||
|
||||
IF_KERNEL_NODES_FEATURE(RAYTRACE)
|
||||
{
|
||||
float dist = stack_load_float_default(stack, dist_offset, node.w);
|
||||
float3 normal = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
|
||||
float dist = stack_load_float_default(svm, dist_offset, node.w);
|
||||
float3 normal = stack_valid(normal_offset) ? stack_load_float3(svm, normal_offset) : sd->N;
|
||||
|
||||
# ifdef __KERNEL_OPTIX__
|
||||
ao = optixDirectCall<float>(0, kg, state, sd, normal, dist, samples, flags);
|
||||
|
@ -121,12 +121,12 @@ ccl_device_noinline
|
|||
}
|
||||
|
||||
if (stack_valid(out_ao_offset)) {
|
||||
stack_store_float(stack, out_ao_offset, ao);
|
||||
stack_store_float(svm, out_ao_offset, ao);
|
||||
}
|
||||
|
||||
if (stack_valid(out_color_offset)) {
|
||||
float3 color = stack_load_float3(stack, color_offset);
|
||||
stack_store_float3(stack, out_color_offset, ao * color);
|
||||
float3 color = stack_load_float3(svm, color_offset);
|
||||
stack_store_float3(svm, out_color_offset, ao * color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,13 +21,13 @@ template<uint node_feature_mask, typename ConstIntegratorGenericState>
|
|||
ccl_device void svm_node_aov_color(KernelGlobals kg,
|
||||
ConstIntegratorGenericState state,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node,
|
||||
ccl_global float *render_buffer)
|
||||
{
|
||||
IF_KERNEL_NODES_FEATURE(AOV)
|
||||
{
|
||||
const float3 val = stack_load_float3(stack, node.y);
|
||||
const float3 val = stack_load_float3(svm, node.y);
|
||||
film_write_aov_pass_color(kg, state, render_buffer, node.z, val);
|
||||
}
|
||||
}
|
||||
|
@ -36,13 +36,13 @@ template<uint node_feature_mask, typename ConstIntegratorGenericState>
|
|||
ccl_device void svm_node_aov_value(KernelGlobals kg,
|
||||
ConstIntegratorGenericState state,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node,
|
||||
ccl_global float *render_buffer)
|
||||
{
|
||||
IF_KERNEL_NODES_FEATURE(AOV)
|
||||
{
|
||||
const float val = stack_load_float(stack, node.y);
|
||||
const float val = stack_load_float(svm, node.y);
|
||||
film_write_aov_pass_value(kg, state, render_buffer, node.z, val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ ccl_device AttributeDescriptor svm_node_attr_init(KernelGlobals kg,
|
|||
template<uint node_feature_mask>
|
||||
ccl_device_noinline void svm_node_attr(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT;
|
||||
|
@ -57,15 +57,15 @@ ccl_device_noinline void svm_node_attr(KernelGlobals kg,
|
|||
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
const float f = volume_attribute_value_to_float(value);
|
||||
stack_store_float(stack, out_offset, f);
|
||||
stack_store_float(svm, out_offset, f);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
const float3 f = volume_attribute_value_to_float3(value);
|
||||
stack_store_float3(stack, out_offset, f);
|
||||
stack_store_float3(svm, out_offset, f);
|
||||
}
|
||||
else {
|
||||
const float f = volume_attribute_value_to_alpha(value);
|
||||
stack_store_float(stack, out_offset, f);
|
||||
stack_store_float(svm, out_offset, f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ ccl_device_noinline void svm_node_attr(KernelGlobals kg,
|
|||
#endif
|
||||
|
||||
if (sd->type == PRIMITIVE_LAMP && node.y == ATTR_STD_UV) {
|
||||
stack_store_float3(stack, out_offset, make_float3(1.0f - sd->u - sd->v, sd->u, 0.0f));
|
||||
stack_store_float3(svm, out_offset, make_float3(1.0f - sd->u - sd->v, sd->u, 0.0f));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -84,13 +84,13 @@ ccl_device_noinline void svm_node_attr(KernelGlobals kg,
|
|||
object_inverse_position_transform(kg, sd, &f);
|
||||
}
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f));
|
||||
stack_store_float(svm, out_offset, average(f));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f);
|
||||
stack_store_float3(svm, out_offset, f);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -99,49 +99,49 @@ ccl_device_noinline void svm_node_attr(KernelGlobals kg,
|
|||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
float f = primitive_surface_attribute_float(kg, sd, desc, NULL, NULL);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f);
|
||||
stack_store_float(svm, out_offset, f);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f, f, f));
|
||||
stack_store_float3(svm, out_offset, make_float3(f, f, f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 f = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x);
|
||||
stack_store_float(svm, out_offset, f.x);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f));
|
||||
stack_store_float3(svm, out_offset, make_float3(f.x, f.y, 0.0f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
|
||||
float4 f = primitive_surface_attribute_float4(kg, sd, desc, NULL, NULL);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(float4_to_float3(f)));
|
||||
stack_store_float(svm, out_offset, average(float4_to_float3(f)));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, float4_to_float3(f));
|
||||
stack_store_float3(svm, out_offset, float4_to_float3(f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, f.w);
|
||||
stack_store_float(svm, out_offset, f.w);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f));
|
||||
stack_store_float(svm, out_offset, average(f));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f);
|
||||
stack_store_float3(svm, out_offset, f);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ ccl_device_forceinline float3 svm_node_bump_P_dy(const ccl_private ShaderData *s
|
|||
|
||||
ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT;
|
||||
|
@ -169,13 +169,13 @@ ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
|
|||
/* Volume */
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, 0.0f);
|
||||
stack_store_float(svm, out_offset, 0.0f);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
stack_store_float3(svm, out_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -188,13 +188,13 @@ ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
|
|||
object_inverse_position_transform(kg, sd, &f);
|
||||
}
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f));
|
||||
stack_store_float(svm, out_offset, average(f));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f);
|
||||
stack_store_float3(svm, out_offset, f);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -204,59 +204,59 @@ ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
|
|||
float dx;
|
||||
float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f + dx);
|
||||
stack_store_float(svm, out_offset, f + dx);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f + dx, f + dx, f + dx));
|
||||
stack_store_float3(svm, out_offset, make_float3(f + dx, f + dx, f + dx));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 dx;
|
||||
float2 f = primitive_surface_attribute_float2(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x + dx.x);
|
||||
stack_store_float(svm, out_offset, f.x + dx.x);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x + dx.x, f.y + dx.y, 0.0f));
|
||||
stack_store_float3(svm, out_offset, make_float3(f.x + dx.x, f.y + dx.y, 0.0f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
|
||||
float4 dx;
|
||||
float4 f = primitive_surface_attribute_float4(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(float4_to_float3(f + dx)));
|
||||
stack_store_float(svm, out_offset, average(float4_to_float3(f + dx)));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, float4_to_float3(f + dx));
|
||||
stack_store_float3(svm, out_offset, float4_to_float3(f + dx));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, f.w + dx.w);
|
||||
stack_store_float(svm, out_offset, f.w + dx.w);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 dx;
|
||||
float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f + dx));
|
||||
stack_store_float(svm, out_offset, average(f + dx));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f + dx);
|
||||
stack_store_float3(svm, out_offset, f + dx);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT;
|
||||
|
@ -267,13 +267,13 @@ ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg,
|
|||
/* Volume */
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, 0.0f);
|
||||
stack_store_float(svm, out_offset, 0.0f);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
stack_store_float3(svm, out_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -286,13 +286,13 @@ ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg,
|
|||
object_inverse_position_transform(kg, sd, &f);
|
||||
}
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f));
|
||||
stack_store_float(svm, out_offset, average(f));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f);
|
||||
stack_store_float3(svm, out_offset, f);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -302,52 +302,52 @@ ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg,
|
|||
float dy;
|
||||
float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f + dy);
|
||||
stack_store_float(svm, out_offset, f + dy);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f + dy, f + dy, f + dy));
|
||||
stack_store_float3(svm, out_offset, make_float3(f + dy, f + dy, f + dy));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 dy;
|
||||
float2 f = primitive_surface_attribute_float2(kg, sd, desc, NULL, &dy);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x + dy.x);
|
||||
stack_store_float(svm, out_offset, f.x + dy.x);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x + dy.x, f.y + dy.y, 0.0f));
|
||||
stack_store_float3(svm, out_offset, make_float3(f.x + dy.x, f.y + dy.y, 0.0f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
|
||||
float4 dy;
|
||||
float4 f = primitive_surface_attribute_float4(kg, sd, desc, NULL, &dy);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(float4_to_float3(f + dy)));
|
||||
stack_store_float(svm, out_offset, average(float4_to_float3(f + dy)));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, float4_to_float3(f + dy));
|
||||
stack_store_float3(svm, out_offset, float4_to_float3(f + dy));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, f.w + dy.w);
|
||||
stack_store_float(svm, out_offset, f.w + dy.w);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 dy;
|
||||
float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy);
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f + dy));
|
||||
stack_store_float(svm, out_offset, average(f + dy));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f + dy);
|
||||
stack_store_float3(svm, out_offset, f + dy);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
stack_store_float(svm, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -297,7 +297,7 @@ ccl_device_noinline
|
|||
svm_node_bevel(KernelGlobals kg,
|
||||
ConstIntegratorGenericState state,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint num_samples, radius_offset, normal_offset, out_offset;
|
||||
|
@ -307,7 +307,7 @@ ccl_device_noinline
|
|||
|
||||
IF_KERNEL_NODES_FEATURE(RAYTRACE)
|
||||
{
|
||||
float radius = stack_load_float(stack, radius_offset);
|
||||
float radius = stack_load_float(svm, radius_offset);
|
||||
|
||||
# ifdef __KERNEL_OPTIX__
|
||||
bevel_N = optixDirectCall<float3>(1, kg, state, sd, radius, num_samples);
|
||||
|
@ -317,12 +317,12 @@ ccl_device_noinline
|
|||
|
||||
if (stack_valid(normal_offset)) {
|
||||
/* Preserve input normal. */
|
||||
float3 ref_N = stack_load_float3(stack, normal_offset);
|
||||
float3 ref_N = stack_load_float3(svm, normal_offset);
|
||||
bevel_N = normalize(ref_N + (bevel_N - sd->N));
|
||||
}
|
||||
}
|
||||
|
||||
stack_store_float3(stack, out_offset, bevel_N);
|
||||
stack_store_float3(svm, out_offset, bevel_N);
|
||||
}
|
||||
|
||||
#endif /* __SHADER_RAYTRACE__ */
|
||||
|
|
|
@ -15,17 +15,17 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_blackbody(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint temperature_offset,
|
||||
uint col_offset)
|
||||
{
|
||||
/* Input */
|
||||
float temperature = stack_load_float(stack, temperature_offset);
|
||||
float temperature = stack_load_float(svm, temperature_offset);
|
||||
|
||||
float3 color_rgb = rec709_to_rgb(kg, svm_math_blackbody_color_rec709(temperature));
|
||||
color_rgb = max(color_rgb, zero_float3());
|
||||
|
||||
stack_store_float3(stack, col_offset, color_rgb);
|
||||
stack_store_float3(svm, col_offset, color_rgb);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -62,12 +62,14 @@ ccl_device_noinline_cpu float2 svm_brick(float3 p,
|
|||
return make_float2(tint, mortar);
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_tex_brick(
|
||||
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
||||
ccl_device_noinline void svm_node_tex_brick(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint4 node2 = read_node(kg, &offset);
|
||||
uint4 node3 = read_node(kg, &offset);
|
||||
uint4 node4 = read_node(kg, &offset);
|
||||
uint4 node2 = read_node(kg, svm);
|
||||
uint4 node3 = read_node(kg, svm);
|
||||
uint4 node4 = read_node(kg, svm);
|
||||
|
||||
/* Input and Output Sockets */
|
||||
uint co_offset, color1_offset, color2_offset, mortar_offset, scale_offset;
|
||||
|
@ -85,18 +87,18 @@ ccl_device_noinline int svm_node_tex_brick(
|
|||
|
||||
svm_unpack_node_uchar2(node2.x, &offset_frequency, &squash_frequency);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float3 co = stack_load_float3(svm, co_offset);
|
||||
|
||||
float3 color1 = stack_load_float3(stack, color1_offset);
|
||||
float3 color2 = stack_load_float3(stack, color2_offset);
|
||||
float3 mortar = stack_load_float3(stack, mortar_offset);
|
||||
float3 color1 = stack_load_float3(svm, color1_offset);
|
||||
float3 color2 = stack_load_float3(svm, color2_offset);
|
||||
float3 mortar = stack_load_float3(svm, mortar_offset);
|
||||
|
||||
float scale = stack_load_float_default(stack, scale_offset, node2.y);
|
||||
float mortar_size = stack_load_float_default(stack, mortar_size_offset, node2.z);
|
||||
float mortar_smooth = stack_load_float_default(stack, mortar_smooth_offset, node4.x);
|
||||
float bias = stack_load_float_default(stack, bias_offset, node2.w);
|
||||
float brick_width = stack_load_float_default(stack, brick_width_offset, node3.x);
|
||||
float row_height = stack_load_float_default(stack, row_height_offset, node3.y);
|
||||
float scale = stack_load_float_default(svm, scale_offset, node2.y);
|
||||
float mortar_size = stack_load_float_default(svm, mortar_size_offset, node2.z);
|
||||
float mortar_smooth = stack_load_float_default(svm, mortar_smooth_offset, node4.x);
|
||||
float bias = stack_load_float_default(svm, bias_offset, node2.w);
|
||||
float brick_width = stack_load_float_default(svm, brick_width_offset, node3.x);
|
||||
float row_height = stack_load_float_default(svm, row_height_offset, node3.y);
|
||||
float offset_amount = __int_as_float(node3.z);
|
||||
float squash_amount = __int_as_float(node3.w);
|
||||
|
||||
|
@ -120,10 +122,9 @@ ccl_device_noinline int svm_node_tex_brick(
|
|||
}
|
||||
|
||||
if (stack_valid(color_offset))
|
||||
stack_store_float3(stack, color_offset, color1 * (1.0f - f) + mortar * f);
|
||||
stack_store_float3(svm, color_offset, color1 * (1.0f - f) + mortar * f);
|
||||
if (stack_valid(fac_offset))
|
||||
stack_store_float(stack, fac_offset, f);
|
||||
return offset;
|
||||
stack_store_float(svm, fac_offset, f);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -8,20 +8,23 @@
|
|||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device_noinline void svm_node_brightness(
|
||||
ccl_private ShaderData *sd, ccl_private float *stack, uint in_color, uint out_color, uint node)
|
||||
ccl_device_noinline void svm_node_brightness(ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint in_color,
|
||||
uint out_color,
|
||||
uint node)
|
||||
{
|
||||
uint bright_offset, contrast_offset;
|
||||
float3 color = stack_load_float3(stack, in_color);
|
||||
float3 color = stack_load_float3(svm, in_color);
|
||||
|
||||
svm_unpack_node_uchar2(node, &bright_offset, &contrast_offset);
|
||||
float brightness = stack_load_float(stack, bright_offset);
|
||||
float contrast = stack_load_float(stack, contrast_offset);
|
||||
float brightness = stack_load_float(svm, bright_offset);
|
||||
float contrast = stack_load_float(svm, contrast_offset);
|
||||
|
||||
color = svm_brightness_contrast(color, brightness, contrast);
|
||||
|
||||
if (stack_valid(out_color))
|
||||
stack_store_float3(stack, out_color, color);
|
||||
stack_store_float3(svm, out_color, color);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -10,12 +10,12 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_enter_bump_eval(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint offset)
|
||||
{
|
||||
/* save state */
|
||||
stack_store_float3(stack, offset + 0, sd->P);
|
||||
stack_store_float(stack, offset + 3, sd->dP);
|
||||
stack_store_float3(svm, offset + 0, sd->P);
|
||||
stack_store_float(svm, offset + 3, sd->dP);
|
||||
|
||||
/* set state as if undisplaced */
|
||||
const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_POSITION_UNDISPLACED);
|
||||
|
@ -35,12 +35,12 @@ ccl_device_noinline void svm_node_enter_bump_eval(KernelGlobals kg,
|
|||
|
||||
ccl_device_noinline void svm_node_leave_bump_eval(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint offset)
|
||||
{
|
||||
/* restore state */
|
||||
sd->P = stack_load_float3(stack, offset + 0);
|
||||
sd->dP = stack_load_float(stack, offset + 3);
|
||||
sd->P = stack_load_float3(svm, offset + 0);
|
||||
sd->dP = stack_load_float(svm, offset + 3);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -8,7 +8,7 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_camera(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint out_vector,
|
||||
uint out_zdepth,
|
||||
uint out_distance)
|
||||
|
@ -23,13 +23,13 @@ ccl_device_noinline void svm_node_camera(KernelGlobals kg,
|
|||
distance = len(vector);
|
||||
|
||||
if (stack_valid(out_vector))
|
||||
stack_store_float3(stack, out_vector, normalize(vector));
|
||||
stack_store_float3(svm, out_vector, normalize(vector));
|
||||
|
||||
if (stack_valid(out_zdepth))
|
||||
stack_store_float(stack, out_zdepth, zdepth);
|
||||
stack_store_float(svm, out_zdepth, zdepth);
|
||||
|
||||
if (stack_valid(out_distance))
|
||||
stack_store_float(stack, out_distance, distance);
|
||||
stack_store_float(svm, out_distance, distance);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -24,7 +24,7 @@ ccl_device float svm_checker(float3 p)
|
|||
|
||||
ccl_device_noinline void svm_node_tex_checker(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint co_offset, color1_offset, color2_offset, scale_offset;
|
||||
|
@ -33,17 +33,17 @@ ccl_device_noinline void svm_node_tex_checker(KernelGlobals kg,
|
|||
svm_unpack_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &scale_offset);
|
||||
svm_unpack_node_uchar2(node.z, &color_offset, &fac_offset);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float3 color1 = stack_load_float3(stack, color1_offset);
|
||||
float3 color2 = stack_load_float3(stack, color2_offset);
|
||||
float scale = stack_load_float_default(stack, scale_offset, node.w);
|
||||
float3 co = stack_load_float3(svm, co_offset);
|
||||
float3 color1 = stack_load_float3(svm, color1_offset);
|
||||
float3 color2 = stack_load_float3(svm, color2_offset);
|
||||
float scale = stack_load_float_default(svm, scale_offset, node.w);
|
||||
|
||||
float f = svm_checker(co * scale);
|
||||
|
||||
if (stack_valid(color_offset))
|
||||
stack_store_float3(stack, color_offset, (f == 1.0f) ? color1 : color2);
|
||||
stack_store_float3(svm, color_offset, (f == 1.0f) ? color1 : color2);
|
||||
if (stack_valid(fac_offset))
|
||||
stack_store_float(stack, fac_offset, f);
|
||||
stack_store_float(svm, fac_offset, f);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -8,30 +8,28 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
/* Clamp Node */
|
||||
|
||||
ccl_device_noinline int svm_node_clamp(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint value_stack_offset,
|
||||
uint parameters_stack_offsets,
|
||||
uint result_stack_offset,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_clamp(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint value_stack_offset,
|
||||
uint parameters_stack_offsets,
|
||||
uint result_stack_offset)
|
||||
{
|
||||
uint min_stack_offset, max_stack_offset, type;
|
||||
svm_unpack_node_uchar3(parameters_stack_offsets, &min_stack_offset, &max_stack_offset, &type);
|
||||
|
||||
uint4 defaults = read_node(kg, &offset);
|
||||
uint4 defaults = read_node(kg, svm);
|
||||
|
||||
float value = stack_load_float(stack, value_stack_offset);
|
||||
float min = stack_load_float_default(stack, min_stack_offset, defaults.x);
|
||||
float max = stack_load_float_default(stack, max_stack_offset, defaults.y);
|
||||
float value = stack_load_float(svm, value_stack_offset);
|
||||
float min = stack_load_float_default(svm, min_stack_offset, defaults.x);
|
||||
float max = stack_load_float_default(svm, max_stack_offset, defaults.y);
|
||||
|
||||
if (type == NODE_CLAMP_RANGE && (min > max)) {
|
||||
stack_store_float(stack, result_stack_offset, clamp(value, max, min));
|
||||
stack_store_float(svm, result_stack_offset, clamp(value, max, min));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, result_stack_offset, clamp(value, min, max));
|
||||
stack_store_float(svm, result_stack_offset, clamp(value, min, max));
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -15,55 +15,59 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
/* Closure Nodes */
|
||||
|
||||
ccl_device_inline int svm_node_closure_bsdf_skip(KernelGlobals kg, int offset, uint type)
|
||||
ccl_device_inline void svm_node_closure_bsdf_skip(KernelGlobals kg,
|
||||
ccl_private SVMState *svm,
|
||||
uint type)
|
||||
{
|
||||
if (type == CLOSURE_BSDF_PRINCIPLED_ID) {
|
||||
/* Read all principled BSDF extra data to get the right offset. */
|
||||
read_node(kg, &offset);
|
||||
read_node(kg, &offset);
|
||||
read_node(kg, &offset);
|
||||
read_node(kg, &offset);
|
||||
read_node(kg, svm);
|
||||
read_node(kg, svm);
|
||||
read_node(kg, svm);
|
||||
read_node(kg, svm);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
template<uint node_feature_mask, ShaderType shader_type>
|
||||
ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
Spectrum closure_weight,
|
||||
uint4 node,
|
||||
uint32_t path_flag,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_closure_bsdf(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node,
|
||||
uint32_t path_flag)
|
||||
{
|
||||
uint type, param1_offset, param2_offset;
|
||||
|
||||
uint mix_weight_offset;
|
||||
svm_unpack_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset);
|
||||
float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
|
||||
float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(svm, mix_weight_offset) :
|
||||
1.0f);
|
||||
float3 closure_weight = svm->closure_weight * mix_weight;
|
||||
|
||||
/* note we read this extra node before weight check, so offset is added */
|
||||
uint4 data_node = read_node(kg, &offset);
|
||||
uint4 data_node = read_node(kg, svm);
|
||||
|
||||
/* Only compute BSDF for surfaces, transparent variable is shared with volume extinction. */
|
||||
IF_KERNEL_NODES_FEATURE(BSDF)
|
||||
{
|
||||
if ((shader_type != SHADER_TYPE_SURFACE) || mix_weight == 0.0f) {
|
||||
return svm_node_closure_bsdf_skip(kg, offset, type);
|
||||
svm_node_closure_bsdf_skip(kg, svm, type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return svm_node_closure_bsdf_skip(kg, offset, type);
|
||||
svm_node_closure_bsdf_skip(kg, svm, type);
|
||||
return;
|
||||
}
|
||||
|
||||
float3 N = stack_valid(data_node.x) ? safe_normalize(stack_load_float3(stack, data_node.x)) :
|
||||
const bool need_albedo = (svm->layer_albedo_offset != SVM_STACK_INVALID);
|
||||
float3 albedo = one_float3();
|
||||
|
||||
float3 N = stack_valid(data_node.x) ? safe_normalize(stack_load_float3(svm, data_node.x)) :
|
||||
sd->N;
|
||||
|
||||
float param1 = (stack_valid(param1_offset)) ? stack_load_float(stack, param1_offset) :
|
||||
float param1 = (stack_valid(param1_offset)) ? stack_load_float(svm, param1_offset) :
|
||||
__uint_as_float(node.z);
|
||||
float param2 = (stack_valid(param2_offset)) ? stack_load_float(stack, param2_offset) :
|
||||
float param2 = (stack_valid(param2_offset)) ? stack_load_float(svm, param2_offset) :
|
||||
__uint_as_float(node.w);
|
||||
|
||||
switch (type) {
|
||||
|
@ -71,9 +75,9 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset,
|
||||
sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset,
|
||||
eta_offset, transmission_offset, anisotropic_rotation_offset, pad1;
|
||||
uint4 data_node2 = read_node(kg, &offset);
|
||||
uint4 data_node2 = read_node(kg, svm);
|
||||
|
||||
float3 T = stack_load_float3(stack, data_node.y);
|
||||
float3 T = stack_load_float3(svm, data_node.y);
|
||||
svm_unpack_node_uchar4(data_node.z,
|
||||
&specular_offset,
|
||||
&roughness_offset,
|
||||
|
@ -90,17 +94,17 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
// get Disney principled parameters
|
||||
float metallic = param1;
|
||||
float subsurface = param2;
|
||||
float specular = stack_load_float(stack, specular_offset);
|
||||
float roughness = stack_load_float(stack, roughness_offset);
|
||||
float specular_tint = stack_load_float(stack, specular_tint_offset);
|
||||
float anisotropic = stack_load_float(stack, anisotropic_offset);
|
||||
float sheen = stack_load_float(stack, sheen_offset);
|
||||
float sheen_tint = stack_load_float(stack, sheen_tint_offset);
|
||||
float clearcoat = stack_load_float(stack, clearcoat_offset);
|
||||
float clearcoat_roughness = stack_load_float(stack, clearcoat_roughness_offset);
|
||||
float transmission = stack_load_float(stack, transmission_offset);
|
||||
float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
|
||||
float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
|
||||
float specular = stack_load_float(svm, specular_offset);
|
||||
float roughness = stack_load_float(svm, roughness_offset);
|
||||
float specular_tint = stack_load_float(svm, specular_tint_offset);
|
||||
float anisotropic = stack_load_float(svm, anisotropic_offset);
|
||||
float sheen = stack_load_float(svm, sheen_offset);
|
||||
float sheen_tint = stack_load_float(svm, sheen_tint_offset);
|
||||
float clearcoat = stack_load_float(svm, clearcoat_offset);
|
||||
float clearcoat_roughness = stack_load_float(svm, clearcoat_roughness_offset);
|
||||
float transmission = stack_load_float(svm, transmission_offset);
|
||||
float anisotropic_rotation = stack_load_float(svm, anisotropic_rotation_offset);
|
||||
float eta = fmaxf(stack_load_float(svm, eta_offset), 1e-5f);
|
||||
|
||||
ClosureType distribution = (ClosureType)data_node2.y;
|
||||
ClosureType subsurface_method = (ClosureType)data_node2.z;
|
||||
|
@ -118,37 +122,37 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
float specular_weight = (1.0f - final_transmission);
|
||||
|
||||
// get the base color
|
||||
uint4 data_base_color = read_node(kg, &offset);
|
||||
uint4 data_base_color = read_node(kg, svm);
|
||||
float3 base_color = stack_valid(data_base_color.x) ?
|
||||
stack_load_float3(stack, data_base_color.x) :
|
||||
stack_load_float3(svm, data_base_color.x) :
|
||||
make_float3(__uint_as_float(data_base_color.y),
|
||||
__uint_as_float(data_base_color.z),
|
||||
__uint_as_float(data_base_color.w));
|
||||
|
||||
// get the additional clearcoat normal and subsurface scattering radius
|
||||
uint4 data_cn_ssr = read_node(kg, &offset);
|
||||
uint4 data_cn_ssr = read_node(kg, svm);
|
||||
float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ?
|
||||
stack_load_float3(stack, data_cn_ssr.x) :
|
||||
stack_load_float3(svm, data_cn_ssr.x) :
|
||||
sd->N;
|
||||
clearcoat_normal = maybe_ensure_valid_specular_reflection(sd, clearcoat_normal);
|
||||
float3 subsurface_radius = stack_valid(data_cn_ssr.y) ?
|
||||
stack_load_float3(stack, data_cn_ssr.y) :
|
||||
stack_load_float3(svm, data_cn_ssr.y) :
|
||||
one_float3();
|
||||
float subsurface_ior = stack_valid(data_cn_ssr.z) ? stack_load_float(stack, data_cn_ssr.z) :
|
||||
float subsurface_ior = stack_valid(data_cn_ssr.z) ? stack_load_float(svm, data_cn_ssr.z) :
|
||||
1.4f;
|
||||
float subsurface_anisotropy = stack_valid(data_cn_ssr.w) ?
|
||||
stack_load_float(stack, data_cn_ssr.w) :
|
||||
stack_load_float(svm, data_cn_ssr.w) :
|
||||
0.0f;
|
||||
|
||||
// get the subsurface color
|
||||
uint4 data_subsurface_color = read_node(kg, &offset);
|
||||
uint4 data_subsurface_color = read_node(kg, svm);
|
||||
float3 subsurface_color = stack_valid(data_subsurface_color.x) ?
|
||||
stack_load_float3(stack, data_subsurface_color.x) :
|
||||
stack_load_float3(svm, data_subsurface_color.x) :
|
||||
make_float3(__uint_as_float(data_subsurface_color.y),
|
||||
__uint_as_float(data_subsurface_color.z),
|
||||
__uint_as_float(data_subsurface_color.w));
|
||||
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
|
||||
#ifdef __SUBSURFACE__
|
||||
float3 mixed_ss_base_color = subsurface_color * subsurface +
|
||||
|
@ -354,7 +358,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_DIFFUSE_ID: {
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
ccl_private OrenNayarBsdf *bsdf = (ccl_private OrenNayarBsdf *)bsdf_alloc(
|
||||
sd, sizeof(OrenNayarBsdf), weight);
|
||||
|
||||
|
@ -374,7 +378,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_TRANSLUCENT_ID: {
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
|
||||
sd, sizeof(DiffuseBsdf), weight);
|
||||
|
||||
|
@ -385,7 +389,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_TRANSPARENT_ID: {
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
bsdf_transparent_setup(sd, weight, path_flag);
|
||||
break;
|
||||
}
|
||||
|
@ -397,7 +401,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
|
||||
break;
|
||||
#endif
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
|
||||
sd, sizeof(MicrofacetBsdf), weight);
|
||||
|
||||
|
@ -419,10 +423,10 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
bsdf->alpha_y = roughness;
|
||||
}
|
||||
else {
|
||||
bsdf->T = stack_load_float3(stack, data_node.y);
|
||||
bsdf->T = stack_load_float3(svm, data_node.y);
|
||||
|
||||
/* rotate tangent */
|
||||
float rotation = stack_load_float(stack, data_node.z);
|
||||
float rotation = stack_load_float(svm, data_node.z);
|
||||
if (rotation != 0.0f)
|
||||
bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
|
||||
|
||||
|
@ -447,11 +451,16 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
|
||||
if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
|
||||
kernel_assert(stack_valid(data_node.w));
|
||||
const Spectrum color = rgb_to_spectrum(stack_load_float3(stack, data_node.w));
|
||||
const Spectrum color = rgb_to_spectrum(stack_load_float3(svm, data_node.w));
|
||||
bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, color);
|
||||
}
|
||||
}
|
||||
|
||||
if (need_albedo) {
|
||||
albedo = bsdf->energy_scale *
|
||||
bsdf_albedo(sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
|
@ -460,7 +469,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
if (!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
|
||||
break;
|
||||
#endif
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
|
||||
sd, sizeof(MicrofacetBsdf), weight);
|
||||
|
||||
|
@ -495,7 +504,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
|
||||
break;
|
||||
#endif
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
|
||||
sd, sizeof(MicrofacetBsdf), weight);
|
||||
|
||||
|
@ -520,7 +529,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
|
||||
if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) {
|
||||
kernel_assert(stack_valid(data_node.z));
|
||||
const Spectrum color = rgb_to_spectrum(stack_load_float3(stack, data_node.z));
|
||||
const Spectrum color = rgb_to_spectrum(stack_load_float3(svm, data_node.z));
|
||||
bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, color);
|
||||
}
|
||||
}
|
||||
|
@ -529,7 +538,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
ccl_private VelvetBsdf *bsdf = (ccl_private VelvetBsdf *)bsdf_alloc(
|
||||
sd, sizeof(VelvetBsdf), weight);
|
||||
|
||||
|
@ -542,7 +551,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_SHEEN_ID: {
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
ccl_private SheenBsdf *bsdf = (ccl_private SheenBsdf *)bsdf_alloc(
|
||||
sd, sizeof(SheenBsdf), weight);
|
||||
|
||||
|
@ -551,6 +560,10 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
bsdf->roughness = param1;
|
||||
|
||||
sd->flag |= bsdf_sheen_setup(kg, sd, bsdf);
|
||||
|
||||
if (need_albedo) {
|
||||
albedo = bsdf->weight;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -561,7 +574,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
ATTR_FALLTHROUGH;
|
||||
#endif
|
||||
case CLOSURE_BSDF_DIFFUSE_TOON_ID: {
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
ccl_private ToonBsdf *bsdf = (ccl_private ToonBsdf *)bsdf_alloc(
|
||||
sd, sizeof(ToonBsdf), weight);
|
||||
|
||||
|
@ -579,16 +592,16 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
}
|
||||
#ifdef __HAIR__
|
||||
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: {
|
||||
uint4 data_node2 = read_node(kg, &offset);
|
||||
uint4 data_node3 = read_node(kg, &offset);
|
||||
uint4 data_node4 = read_node(kg, &offset);
|
||||
uint4 data_node2 = read_node(kg, svm);
|
||||
uint4 data_node3 = read_node(kg, svm);
|
||||
uint4 data_node4 = read_node(kg, svm);
|
||||
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
|
||||
uint offset_ofs, ior_ofs, color_ofs, parametrization;
|
||||
svm_unpack_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, ¶metrization);
|
||||
float alpha = stack_load_float_default(stack, offset_ofs, data_node.z);
|
||||
float ior = stack_load_float_default(stack, ior_ofs, data_node.w);
|
||||
float alpha = stack_load_float_default(svm, offset_ofs, data_node.z);
|
||||
float ior = stack_load_float_default(svm, ior_ofs, data_node.w);
|
||||
|
||||
uint coat_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs;
|
||||
svm_unpack_node_uchar4(data_node2.x,
|
||||
|
@ -607,7 +620,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
random = primitive_surface_attribute_float(kg, sd, attr_descr_random, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
random = stack_load_float_default(stack, random_ofs, data_node3.y);
|
||||
random = stack_load_float_default(svm, random_ofs, data_node3.y);
|
||||
}
|
||||
|
||||
ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)bsdf_alloc(
|
||||
|
@ -620,14 +633,13 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
break;
|
||||
|
||||
/* Random factors range: [-randomization/2, +randomization/2]. */
|
||||
float random_roughness = stack_load_float_default(
|
||||
stack, random_roughness_ofs, data_node3.w);
|
||||
float random_roughness = stack_load_float_default(svm, random_roughness_ofs, data_node3.w);
|
||||
float factor_random_roughness = 1.0f + 2.0f * (random - 0.5f) * random_roughness;
|
||||
float roughness = param1 * factor_random_roughness;
|
||||
float radial_roughness = param2 * factor_random_roughness;
|
||||
|
||||
/* Remap Coat value to [0, 100]% of Roughness. */
|
||||
float coat = stack_load_float_default(stack, coat_ofs, data_node2.y);
|
||||
float coat = stack_load_float_default(svm, coat_ofs, data_node2.y);
|
||||
float m0_roughness = 1.0f - clamp(coat, 0.0f, 1.0f);
|
||||
|
||||
bsdf->N = maybe_ensure_valid_specular_reflection(sd, N);
|
||||
|
@ -640,17 +652,17 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
|
||||
switch (parametrization) {
|
||||
case NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION: {
|
||||
float3 absorption_coefficient = stack_load_float3(stack, absorption_coefficient_ofs);
|
||||
float3 absorption_coefficient = stack_load_float3(svm, absorption_coefficient_ofs);
|
||||
bsdf->sigma = rgb_to_spectrum(absorption_coefficient);
|
||||
break;
|
||||
}
|
||||
case NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION: {
|
||||
float melanin = stack_load_float_default(stack, melanin_ofs, data_node2.z);
|
||||
float melanin = stack_load_float_default(svm, melanin_ofs, data_node2.z);
|
||||
float melanin_redness = stack_load_float_default(
|
||||
stack, melanin_redness_ofs, data_node2.w);
|
||||
svm, melanin_redness_ofs, data_node2.w);
|
||||
|
||||
/* Randomize melanin. */
|
||||
float random_color = stack_load_float_default(stack, random_color_ofs, data_node3.z);
|
||||
float random_color = stack_load_float_default(svm, random_color_ofs, data_node3.z);
|
||||
random_color = clamp(random_color, 0.0f, 1.0f);
|
||||
float factor_random_color = 1.0f + 2.0f * (random - 0.5f) * random_color;
|
||||
melanin *= factor_random_color;
|
||||
|
@ -665,7 +677,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
pheomelanin);
|
||||
|
||||
/* Optional tint. */
|
||||
float3 tint = stack_load_float3(stack, tint_ofs);
|
||||
float3 tint = stack_load_float3(svm, tint_ofs);
|
||||
Spectrum tint_sigma = bsdf_principled_hair_sigma_from_reflectance(
|
||||
rgb_to_spectrum(tint), radial_roughness);
|
||||
|
||||
|
@ -673,7 +685,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
case NODE_PRINCIPLED_HAIR_REFLECTANCE: {
|
||||
float3 color = stack_load_float3(stack, color_ofs);
|
||||
float3 color = stack_load_float3(svm, color_ofs);
|
||||
bsdf->sigma = bsdf_principled_hair_sigma_from_reflectance(rgb_to_spectrum(color),
|
||||
radial_roughness);
|
||||
break;
|
||||
|
@ -692,7 +704,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
}
|
||||
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
|
||||
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: {
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
|
||||
ccl_private HairBsdf *bsdf = (ccl_private HairBsdf *)bsdf_alloc(
|
||||
sd, sizeof(HairBsdf), weight);
|
||||
|
@ -701,10 +713,10 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
bsdf->N = maybe_ensure_valid_specular_reflection(sd, N);
|
||||
bsdf->roughness1 = param1;
|
||||
bsdf->roughness2 = param2;
|
||||
bsdf->offset = -stack_load_float(stack, data_node.z);
|
||||
bsdf->offset = -stack_load_float(svm, data_node.z);
|
||||
|
||||
if (stack_valid(data_node.y)) {
|
||||
bsdf->T = normalize(stack_load_float3(stack, data_node.y));
|
||||
bsdf->T = normalize(stack_load_float3(svm, data_node.y));
|
||||
}
|
||||
else if (!(sd->type & PRIMITIVE_CURVE)) {
|
||||
bsdf->T = normalize(sd->dPdv);
|
||||
|
@ -729,7 +741,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
case CLOSURE_BSSRDF_BURLEY_ID:
|
||||
case CLOSURE_BSSRDF_RANDOM_WALK_ID:
|
||||
case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID: {
|
||||
Spectrum weight = closure_weight * mix_weight;
|
||||
Spectrum weight = closure_weight;
|
||||
ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
|
||||
|
||||
if (bssrdf) {
|
||||
|
@ -739,13 +751,13 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
|
||||
param1 = 0.0f;
|
||||
|
||||
bssrdf->radius = rgb_to_spectrum(stack_load_float3(stack, data_node.z) * param1);
|
||||
bssrdf->albedo = closure_weight;
|
||||
bssrdf->radius = rgb_to_spectrum(stack_load_float3(svm, data_node.z) * param1);
|
||||
bssrdf->albedo = svm->closure_weight;
|
||||
bssrdf->N = N;
|
||||
bssrdf->roughness = FLT_MAX;
|
||||
|
||||
const float subsurface_ior = clamp(param2, 1.01f, 3.8f);
|
||||
const float subsurface_anisotropy = stack_load_float(stack, data_node.w);
|
||||
const float subsurface_anisotropy = stack_load_float(svm, data_node.w);
|
||||
bssrdf->anisotropy = clamp(subsurface_anisotropy, 0.0f, 0.9f);
|
||||
|
||||
sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type, subsurface_ior);
|
||||
|
@ -758,14 +770,17 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
|
||||
return offset;
|
||||
/* Accumulate albedo for layering. */
|
||||
if (need_albedo) {
|
||||
albedo += stack_load_float3(svm, svm->layer_albedo_offset);
|
||||
stack_store_float3(svm, svm->layer_albedo_offset, albedo);
|
||||
}
|
||||
}
|
||||
|
||||
template<ShaderType shader_type>
|
||||
ccl_device_noinline void svm_node_closure_volume(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
Spectrum closure_weight,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
#ifdef __VOLUME__
|
||||
|
@ -778,19 +793,19 @@ ccl_device_noinline void svm_node_closure_volume(KernelGlobals kg,
|
|||
|
||||
uint mix_weight_offset;
|
||||
svm_unpack_node_uchar4(node.y, &type, &density_offset, &anisotropy_offset, &mix_weight_offset);
|
||||
float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
|
||||
float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(svm, mix_weight_offset) :
|
||||
1.0f);
|
||||
|
||||
if (mix_weight == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
|
||||
float density = (stack_valid(density_offset)) ? stack_load_float(svm, density_offset) :
|
||||
__uint_as_float(node.z);
|
||||
density = mix_weight * fmaxf(density, 0.0f);
|
||||
|
||||
/* Compute scattering coefficient. */
|
||||
Spectrum weight = closure_weight;
|
||||
Spectrum weight = svm->closure_weight;
|
||||
|
||||
if (type == CLOSURE_VOLUME_ABSORPTION_ID) {
|
||||
weight = one_spectrum() - weight;
|
||||
|
@ -805,7 +820,7 @@ ccl_device_noinline void svm_node_closure_volume(KernelGlobals kg,
|
|||
|
||||
if (volume) {
|
||||
float anisotropy = (stack_valid(anisotropy_offset)) ?
|
||||
stack_load_float(stack, anisotropy_offset) :
|
||||
stack_load_float(svm, anisotropy_offset) :
|
||||
__uint_as_float(node.w);
|
||||
volume->g = anisotropy; /* g */
|
||||
sd->flag |= volume_henyey_greenstein_setup(volume);
|
||||
|
@ -818,36 +833,34 @@ ccl_device_noinline void svm_node_closure_volume(KernelGlobals kg,
|
|||
}
|
||||
|
||||
template<ShaderType shader_type>
|
||||
ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
Spectrum closure_weight,
|
||||
uint4 node,
|
||||
uint32_t path_flag,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_principled_volume(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node,
|
||||
uint32_t path_flag)
|
||||
{
|
||||
#ifdef __VOLUME__
|
||||
uint4 value_node = read_node(kg, &offset);
|
||||
uint4 attr_node = read_node(kg, &offset);
|
||||
uint4 value_node = read_node(kg, svm);
|
||||
uint4 attr_node = read_node(kg, svm);
|
||||
|
||||
/* Only sum extinction for volumes, variable is shared with surface transparency. */
|
||||
if (shader_type != SHADER_TYPE_VOLUME) {
|
||||
return offset;
|
||||
return;
|
||||
}
|
||||
|
||||
uint density_offset, anisotropy_offset, absorption_color_offset, mix_weight_offset;
|
||||
svm_unpack_node_uchar4(
|
||||
node.y, &density_offset, &anisotropy_offset, &absorption_color_offset, &mix_weight_offset);
|
||||
float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
|
||||
float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(svm, mix_weight_offset) :
|
||||
1.0f);
|
||||
|
||||
if (mix_weight == 0.0f) {
|
||||
return offset;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Compute density. */
|
||||
float primitive_density = 1.0f;
|
||||
float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
|
||||
float density = (stack_valid(density_offset)) ? stack_load_float(svm, density_offset) :
|
||||
__uint_as_float(value_node.x);
|
||||
density = mix_weight * fmaxf(density, 0.0f);
|
||||
|
||||
|
@ -862,7 +875,7 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
|
|||
|
||||
if (density > CLOSURE_WEIGHT_CUTOFF) {
|
||||
/* Compute scattering color. */
|
||||
Spectrum color = closure_weight;
|
||||
Spectrum color = svm->closure_weight;
|
||||
|
||||
const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y);
|
||||
if (attr_color.offset != ATTR_STD_NOT_FOUND) {
|
||||
|
@ -874,14 +887,14 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
|
|||
sd, sizeof(HenyeyGreensteinVolume), color * density);
|
||||
if (volume) {
|
||||
float anisotropy = (stack_valid(anisotropy_offset)) ?
|
||||
stack_load_float(stack, anisotropy_offset) :
|
||||
stack_load_float(svm, anisotropy_offset) :
|
||||
__uint_as_float(value_node.y);
|
||||
volume->g = anisotropy;
|
||||
sd->flag |= volume_henyey_greenstein_setup(volume);
|
||||
}
|
||||
|
||||
/* Add extinction weight. */
|
||||
float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)),
|
||||
float3 absorption_color = max(sqrt(stack_load_float3(svm, absorption_color_offset)),
|
||||
zero_float3());
|
||||
|
||||
Spectrum zero = zero_spectrum();
|
||||
|
@ -894,24 +907,24 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
|
|||
/* Compute emission. */
|
||||
if (path_flag & PATH_RAY_SHADOW) {
|
||||
/* Don't need emission for shadows. */
|
||||
return offset;
|
||||
return;
|
||||
}
|
||||
|
||||
uint emission_offset, emission_color_offset, blackbody_offset, temperature_offset;
|
||||
svm_unpack_node_uchar4(
|
||||
node.z, &emission_offset, &emission_color_offset, &blackbody_offset, &temperature_offset);
|
||||
float emission = (stack_valid(emission_offset)) ? stack_load_float(stack, emission_offset) :
|
||||
float emission = (stack_valid(emission_offset)) ? stack_load_float(svm, emission_offset) :
|
||||
__uint_as_float(value_node.z);
|
||||
float blackbody = (stack_valid(blackbody_offset)) ? stack_load_float(stack, blackbody_offset) :
|
||||
float blackbody = (stack_valid(blackbody_offset)) ? stack_load_float(svm, blackbody_offset) :
|
||||
__uint_as_float(value_node.w);
|
||||
|
||||
if (emission > CLOSURE_WEIGHT_CUTOFF) {
|
||||
float3 emission_color = stack_load_float3(stack, emission_color_offset);
|
||||
float3 emission_color = stack_load_float3(svm, emission_color_offset);
|
||||
emission_setup(sd, rgb_to_spectrum(emission * emission_color));
|
||||
}
|
||||
|
||||
if (blackbody > CLOSURE_WEIGHT_CUTOFF) {
|
||||
float T = stack_load_float(stack, temperature_offset);
|
||||
float T = stack_load_float(svm, temperature_offset);
|
||||
|
||||
/* Add flame temperature from attribute if available. */
|
||||
const AttributeDescriptor attr_temperature = find_attribute(kg, sd, attr_node.z);
|
||||
|
@ -928,26 +941,24 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
|
|||
float intensity = sigma * mix(1.0f, T4, blackbody);
|
||||
|
||||
if (intensity > CLOSURE_WEIGHT_CUTOFF) {
|
||||
float3 blackbody_tint = stack_load_float3(stack, node.w);
|
||||
float3 blackbody_tint = stack_load_float3(svm, node.w);
|
||||
float3 bb = blackbody_tint * intensity *
|
||||
rec709_to_rgb(kg, svm_math_blackbody_color_rec709(T));
|
||||
emission_setup(sd, rgb_to_spectrum(bb));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return offset;
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_closure_emission(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
Spectrum closure_weight,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint mix_weight_offset = node.y;
|
||||
Spectrum weight = closure_weight;
|
||||
Spectrum weight = svm->closure_weight;
|
||||
|
||||
if (stack_valid(mix_weight_offset)) {
|
||||
float mix_weight = stack_load_float(stack, mix_weight_offset);
|
||||
float mix_weight = stack_load_float(svm, mix_weight_offset);
|
||||
|
||||
if (mix_weight == 0.0f)
|
||||
return;
|
||||
|
@ -959,15 +970,14 @@ ccl_device_noinline void svm_node_closure_emission(ccl_private ShaderData *sd,
|
|||
}
|
||||
|
||||
ccl_device_noinline void svm_node_closure_background(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
Spectrum closure_weight,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint mix_weight_offset = node.y;
|
||||
Spectrum weight = closure_weight;
|
||||
Spectrum weight = svm->closure_weight;
|
||||
|
||||
if (stack_valid(mix_weight_offset)) {
|
||||
float mix_weight = stack_load_float(stack, mix_weight_offset);
|
||||
float mix_weight = stack_load_float(svm, mix_weight_offset);
|
||||
|
||||
if (mix_weight == 0.0f)
|
||||
return;
|
||||
|
@ -979,22 +989,21 @@ ccl_device_noinline void svm_node_closure_background(ccl_private ShaderData *sd,
|
|||
}
|
||||
|
||||
ccl_device_noinline void svm_node_closure_holdout(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
Spectrum closure_weight,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint mix_weight_offset = node.y;
|
||||
|
||||
if (stack_valid(mix_weight_offset)) {
|
||||
float mix_weight = stack_load_float(stack, mix_weight_offset);
|
||||
float mix_weight = stack_load_float(svm, mix_weight_offset);
|
||||
|
||||
if (mix_weight == 0.0f)
|
||||
return;
|
||||
|
||||
closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, closure_weight * mix_weight);
|
||||
closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, svm->closure_weight * mix_weight);
|
||||
}
|
||||
else
|
||||
closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, closure_weight);
|
||||
closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, svm->closure_weight);
|
||||
|
||||
sd->flag |= SD_HOLDOUT;
|
||||
}
|
||||
|
@ -1002,35 +1011,33 @@ ccl_device_noinline void svm_node_closure_holdout(ccl_private ShaderData *sd,
|
|||
/* Closure Nodes */
|
||||
|
||||
ccl_device void svm_node_closure_set_weight(
|
||||
ccl_private ShaderData *sd, ccl_private Spectrum *closure_weight, uint r, uint g, uint b)
|
||||
ccl_private ShaderData *sd, ccl_private SVMState *svm, uint r, uint g, uint b)
|
||||
{
|
||||
*closure_weight = rgb_to_spectrum(
|
||||
svm->closure_weight = rgb_to_spectrum(
|
||||
make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b)));
|
||||
}
|
||||
|
||||
ccl_device void svm_node_closure_weight(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private Spectrum *closure_weight,
|
||||
ccl_private SVMState *svm,
|
||||
uint weight_offset)
|
||||
{
|
||||
*closure_weight = rgb_to_spectrum(stack_load_float3(stack, weight_offset));
|
||||
svm->closure_weight = rgb_to_spectrum(stack_load_float3(svm, weight_offset));
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_emission_weight(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private Spectrum *closure_weight,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint color_offset = node.y;
|
||||
uint strength_offset = node.z;
|
||||
|
||||
float strength = stack_load_float(stack, strength_offset);
|
||||
*closure_weight = rgb_to_spectrum(stack_load_float3(stack, color_offset)) * strength;
|
||||
float strength = stack_load_float(svm, strength_offset);
|
||||
svm->closure_weight = rgb_to_spectrum(stack_load_float3(svm, color_offset)) * strength;
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_mix_closure(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
/* fetch weight from blend input, previous mix closures,
|
||||
|
@ -1039,29 +1046,56 @@ ccl_device_noinline void svm_node_mix_closure(ccl_private ShaderData *sd,
|
|||
svm_unpack_node_uchar4(
|
||||
node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset);
|
||||
|
||||
float weight = stack_load_float(stack, weight_offset);
|
||||
float weight = stack_load_float(svm, weight_offset);
|
||||
weight = saturatef(weight);
|
||||
|
||||
float in_weight = (stack_valid(in_weight_offset)) ? stack_load_float(stack, in_weight_offset) :
|
||||
float in_weight = (stack_valid(in_weight_offset)) ? stack_load_float(svm, in_weight_offset) :
|
||||
1.0f;
|
||||
|
||||
if (stack_valid(weight1_offset))
|
||||
stack_store_float(stack, weight1_offset, in_weight * (1.0f - weight));
|
||||
stack_store_float(svm, weight1_offset, in_weight * (1.0f - weight));
|
||||
if (stack_valid(weight2_offset))
|
||||
stack_store_float(stack, weight2_offset, in_weight * weight);
|
||||
stack_store_float(svm, weight2_offset, in_weight * weight);
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_layer_closure_accumulate(ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint weight_in_offset = node.y, albedo_out_offset = node.z, weight_out_offset = node.w;
|
||||
float weight = stack_load_float(svm, weight_in_offset);
|
||||
stack_store_float(svm, weight_out_offset, weight);
|
||||
stack_store_float3(svm, albedo_out_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
kernel_assert(svm->layer_albedo_offset == SVM_STACK_INVALID);
|
||||
svm->layer_albedo_offset = albedo_out_offset;
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_layer_closure(ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint weight_in_offset = node.y, albedo_in_offset = node.z, weight_out_offset = node.w;
|
||||
float weight = stack_load_float(svm, weight_in_offset);
|
||||
float3 albedo = stack_load_float3(svm, albedo_in_offset);
|
||||
weight *= saturatef(1.0f - reduce_max(albedo / weight));
|
||||
stack_store_float(svm, weight_out_offset, weight);
|
||||
|
||||
kernel_assert(svm->layer_albedo_offset == albedo_in_offset);
|
||||
svm->layer_albedo_offset = SVM_STACK_INVALID;
|
||||
}
|
||||
|
||||
/* (Bump) normal */
|
||||
|
||||
ccl_device void svm_node_set_normal(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint in_direction,
|
||||
uint out_normal)
|
||||
{
|
||||
float3 normal = stack_load_float3(stack, in_direction);
|
||||
float3 normal = stack_load_float3(svm, in_direction);
|
||||
sd->N = normal;
|
||||
stack_store_float3(stack, out_normal, normal);
|
||||
stack_store_float3(svm, out_normal, normal);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -10,54 +10,54 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_convert(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint from,
|
||||
uint to)
|
||||
{
|
||||
switch (type) {
|
||||
case NODE_CONVERT_FI: {
|
||||
float f = stack_load_float(stack, from);
|
||||
stack_store_int(stack, to, float_to_int(f));
|
||||
float f = stack_load_float(svm, from);
|
||||
stack_store_int(svm, to, float_to_int(f));
|
||||
break;
|
||||
}
|
||||
case NODE_CONVERT_FV: {
|
||||
float f = stack_load_float(stack, from);
|
||||
stack_store_float3(stack, to, make_float3(f, f, f));
|
||||
float f = stack_load_float(svm, from);
|
||||
stack_store_float3(svm, to, make_float3(f, f, f));
|
||||
break;
|
||||
}
|
||||
case NODE_CONVERT_CF: {
|
||||
float3 f = stack_load_float3(stack, from);
|
||||
float3 f = stack_load_float3(svm, from);
|
||||
float g = linear_rgb_to_gray(kg, f);
|
||||
stack_store_float(stack, to, g);
|
||||
stack_store_float(svm, to, g);
|
||||
break;
|
||||
}
|
||||
case NODE_CONVERT_CI: {
|
||||
float3 f = stack_load_float3(stack, from);
|
||||
float3 f = stack_load_float3(svm, from);
|
||||
int i = (int)linear_rgb_to_gray(kg, f);
|
||||
stack_store_int(stack, to, i);
|
||||
stack_store_int(svm, to, i);
|
||||
break;
|
||||
}
|
||||
case NODE_CONVERT_VF: {
|
||||
float3 f = stack_load_float3(stack, from);
|
||||
float3 f = stack_load_float3(svm, from);
|
||||
float g = average(f);
|
||||
stack_store_float(stack, to, g);
|
||||
stack_store_float(svm, to, g);
|
||||
break;
|
||||
}
|
||||
case NODE_CONVERT_VI: {
|
||||
float3 f = stack_load_float3(stack, from);
|
||||
float3 f = stack_load_float3(svm, from);
|
||||
int i = (int)average(f);
|
||||
stack_store_int(stack, to, i);
|
||||
stack_store_int(svm, to, i);
|
||||
break;
|
||||
}
|
||||
case NODE_CONVERT_IF: {
|
||||
float f = (float)stack_load_int(stack, from);
|
||||
stack_store_float(stack, to, f);
|
||||
float f = (float)stack_load_int(svm, from);
|
||||
stack_store_float(svm, to, f);
|
||||
break;
|
||||
}
|
||||
case NODE_CONVERT_IV: {
|
||||
float f = (float)stack_load_int(stack, from);
|
||||
stack_store_float3(stack, to, make_float3(f, f, f));
|
||||
float f = (float)stack_load_int(svm, from);
|
||||
stack_store_float3(svm, to, make_float3(f, f, f));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ CCL_NAMESPACE_BEGIN
|
|||
template<uint node_feature_mask>
|
||||
ccl_device_noinline void svm_node_set_bump(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
|
@ -22,8 +22,7 @@ ccl_device_noinline void svm_node_set_bump(KernelGlobals kg,
|
|||
uint normal_offset, scale_offset, invert, use_object_space;
|
||||
svm_unpack_node_uchar4(node.y, &normal_offset, &scale_offset, &invert, &use_object_space);
|
||||
|
||||
float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) :
|
||||
sd->N;
|
||||
float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(svm, normal_offset) : sd->N;
|
||||
|
||||
differential3 dP = differential_from_compact(sd->Ng, sd->dP);
|
||||
|
||||
|
@ -41,9 +40,9 @@ ccl_device_noinline void svm_node_set_bump(KernelGlobals kg,
|
|||
uint c_offset, x_offset, y_offset, strength_offset;
|
||||
svm_unpack_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &strength_offset);
|
||||
|
||||
float h_c = stack_load_float(stack, c_offset);
|
||||
float h_x = stack_load_float(stack, x_offset);
|
||||
float h_y = stack_load_float(stack, y_offset);
|
||||
float h_c = stack_load_float(svm, c_offset);
|
||||
float h_x = stack_load_float(svm, x_offset);
|
||||
float h_y = stack_load_float(svm, y_offset);
|
||||
|
||||
/* compute surface gradient and determinant */
|
||||
float det = dot(dP.dx, Rx);
|
||||
|
@ -51,8 +50,8 @@ ccl_device_noinline void svm_node_set_bump(KernelGlobals kg,
|
|||
|
||||
float absdet = fabsf(det);
|
||||
|
||||
float strength = stack_load_float(stack, strength_offset);
|
||||
float scale = stack_load_float(stack, scale_offset);
|
||||
float strength = stack_load_float(svm, strength_offset);
|
||||
float scale = stack_load_float(svm, scale_offset);
|
||||
|
||||
if (invert)
|
||||
scale *= -1.0f;
|
||||
|
@ -72,10 +71,10 @@ ccl_device_noinline void svm_node_set_bump(KernelGlobals kg,
|
|||
object_normal_transform(kg, sd, &normal_out);
|
||||
}
|
||||
|
||||
stack_store_float3(stack, node.w, normal_out);
|
||||
stack_store_float3(svm, node.w, normal_out);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, node.w, zero_float3());
|
||||
stack_store_float3(svm, node.w, zero_float3());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -85,12 +84,12 @@ ccl_device_noinline void svm_node_set_bump(KernelGlobals kg,
|
|||
template<uint node_feature_mask>
|
||||
ccl_device void svm_node_set_displacement(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint fac_offset)
|
||||
{
|
||||
IF_KERNEL_NODES_FEATURE(BUMP)
|
||||
{
|
||||
float3 dP = stack_load_float3(stack, fac_offset);
|
||||
float3 dP = stack_load_float3(svm, fac_offset);
|
||||
sd->P += dP;
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +97,7 @@ ccl_device void svm_node_set_displacement(KernelGlobals kg,
|
|||
template<uint node_feature_mask>
|
||||
ccl_device_noinline void svm_node_displacement(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
IF_KERNEL_NODES_FEATURE(BUMP)
|
||||
|
@ -107,10 +106,10 @@ ccl_device_noinline void svm_node_displacement(KernelGlobals kg,
|
|||
svm_unpack_node_uchar4(
|
||||
node.y, &height_offset, &midlevel_offset, &scale_offset, &normal_offset);
|
||||
|
||||
float height = stack_load_float(stack, height_offset);
|
||||
float midlevel = stack_load_float(stack, midlevel_offset);
|
||||
float scale = stack_load_float(stack, scale_offset);
|
||||
float3 normal = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
|
||||
float height = stack_load_float(svm, height_offset);
|
||||
float midlevel = stack_load_float(svm, midlevel_offset);
|
||||
float scale = stack_load_float(svm, scale_offset);
|
||||
float3 normal = stack_valid(normal_offset) ? stack_load_float3(svm, normal_offset) : sd->N;
|
||||
uint space = node.w;
|
||||
|
||||
float3 dP = normal;
|
||||
|
@ -126,18 +125,20 @@ ccl_device_noinline void svm_node_displacement(KernelGlobals kg,
|
|||
dP *= (height - midlevel) * scale;
|
||||
}
|
||||
|
||||
stack_store_float3(stack, node.z, dP);
|
||||
stack_store_float3(svm, node.z, dP);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, node.z, zero_float3());
|
||||
stack_store_float3(svm, node.z, zero_float3());
|
||||
}
|
||||
}
|
||||
|
||||
template<uint node_feature_mask>
|
||||
ccl_device_noinline int svm_node_vector_displacement(
|
||||
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
||||
ccl_device_noinline void svm_node_vector_displacement(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint4 data_node = read_node(kg, &offset);
|
||||
uint4 data_node = read_node(kg, svm);
|
||||
uint vector_offset, midlevel_offset, scale_offset, displacement_offset;
|
||||
svm_unpack_node_uchar4(
|
||||
node.y, &vector_offset, &midlevel_offset, &scale_offset, &displacement_offset);
|
||||
|
@ -146,9 +147,9 @@ ccl_device_noinline int svm_node_vector_displacement(
|
|||
{
|
||||
uint space = data_node.x;
|
||||
|
||||
float3 vector = stack_load_float3(stack, vector_offset);
|
||||
float midlevel = stack_load_float(stack, midlevel_offset);
|
||||
float scale = stack_load_float(stack, scale_offset);
|
||||
float3 vector = stack_load_float3(svm, vector_offset);
|
||||
float midlevel = stack_load_float(svm, midlevel_offset);
|
||||
float scale = stack_load_float(svm, scale_offset);
|
||||
float3 dP = (vector - make_float3(midlevel, midlevel, midlevel)) * scale;
|
||||
|
||||
if (space == NODE_NORMAL_MAP_TANGENT) {
|
||||
|
@ -180,14 +181,12 @@ ccl_device_noinline int svm_node_vector_displacement(
|
|||
object_dir_transform(kg, sd, &dP);
|
||||
}
|
||||
|
||||
stack_store_float3(stack, displacement_offset, dP);
|
||||
stack_store_float3(svm, displacement_offset, dP);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, displacement_offset, zero_float3());
|
||||
stack_store_float3(svm, displacement_offset, zero_float3());
|
||||
(void)data_node;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -9,29 +9,29 @@ CCL_NAMESPACE_BEGIN
|
|||
/* Fresnel Node */
|
||||
|
||||
ccl_device_noinline void svm_node_fresnel(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint ior_offset,
|
||||
uint ior_value,
|
||||
uint node)
|
||||
{
|
||||
uint normal_offset, out_offset;
|
||||
svm_unpack_node_uchar2(node, &normal_offset, &out_offset);
|
||||
float eta = (stack_valid(ior_offset)) ? stack_load_float(stack, ior_offset) :
|
||||
float eta = (stack_valid(ior_offset)) ? stack_load_float(svm, ior_offset) :
|
||||
__uint_as_float(ior_value);
|
||||
float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
|
||||
float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(svm, normal_offset) : sd->N;
|
||||
|
||||
eta = fmaxf(eta, 1e-5f);
|
||||
eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
|
||||
|
||||
float f = fresnel_dielectric_cos(dot(sd->wi, normal_in), eta);
|
||||
|
||||
stack_store_float(stack, out_offset, f);
|
||||
stack_store_float(svm, out_offset, f);
|
||||
}
|
||||
|
||||
/* Layer Weight Node */
|
||||
|
||||
ccl_device_noinline void svm_node_layer_weight(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint blend_offset = node.y;
|
||||
|
@ -40,10 +40,9 @@ ccl_device_noinline void svm_node_layer_weight(ccl_private ShaderData *sd,
|
|||
uint type, normal_offset, out_offset;
|
||||
svm_unpack_node_uchar3(node.w, &type, &normal_offset, &out_offset);
|
||||
|
||||
float blend = (stack_valid(blend_offset)) ? stack_load_float(stack, blend_offset) :
|
||||
float blend = (stack_valid(blend_offset)) ? stack_load_float(svm, blend_offset) :
|
||||
__uint_as_float(blend_value);
|
||||
float3 normal_in = (stack_valid(normal_offset)) ? stack_load_float3(stack, normal_offset) :
|
||||
sd->N;
|
||||
float3 normal_in = (stack_valid(normal_offset)) ? stack_load_float3(svm, normal_offset) : sd->N;
|
||||
|
||||
float f;
|
||||
|
||||
|
@ -66,7 +65,7 @@ ccl_device_noinline void svm_node_layer_weight(ccl_private ShaderData *sd,
|
|||
f = 1.0f - f;
|
||||
}
|
||||
|
||||
stack_store_float(stack, out_offset, f);
|
||||
stack_store_float(svm, out_offset, f);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -7,18 +7,18 @@
|
|||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device_noinline void svm_node_gamma(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint in_gamma,
|
||||
uint in_color,
|
||||
uint out_color)
|
||||
{
|
||||
float3 color = stack_load_float3(stack, in_color);
|
||||
float gamma = stack_load_float(stack, in_gamma);
|
||||
float3 color = stack_load_float3(svm, in_color);
|
||||
float gamma = stack_load_float(svm, in_gamma);
|
||||
|
||||
color = svm_math_gamma_color(color, gamma);
|
||||
|
||||
if (stack_valid(out_color))
|
||||
stack_store_float3(stack, out_color, color);
|
||||
stack_store_float3(svm, out_color, color);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -10,7 +10,7 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_geometry(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint out_offset)
|
||||
{
|
||||
|
@ -41,12 +41,12 @@ ccl_device_noinline void svm_node_geometry(KernelGlobals kg,
|
|||
data = make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
stack_store_float3(stack, out_offset, data);
|
||||
stack_store_float3(svm, out_offset, data);
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_geometry_bump_dx(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint out_offset)
|
||||
{
|
||||
|
@ -61,19 +61,19 @@ ccl_device_noinline void svm_node_geometry_bump_dx(KernelGlobals kg,
|
|||
data = make_float3(1.0f - sd->u - sd->du.dx - sd->v - sd->dv.dx, sd->u + sd->du.dx, 0.0f);
|
||||
break;
|
||||
default:
|
||||
svm_node_geometry(kg, sd, stack, type, out_offset);
|
||||
svm_node_geometry(kg, sd, svm, type, out_offset);
|
||||
return;
|
||||
}
|
||||
|
||||
stack_store_float3(stack, out_offset, data);
|
||||
stack_store_float3(svm, out_offset, data);
|
||||
#else
|
||||
svm_node_geometry(kg, sd, stack, type, out_offset);
|
||||
svm_node_geometry(kg, sd, svm, type, out_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_geometry_bump_dy(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint out_offset)
|
||||
{
|
||||
|
@ -88,13 +88,13 @@ ccl_device_noinline void svm_node_geometry_bump_dy(KernelGlobals kg,
|
|||
data = make_float3(1.0f - sd->u - sd->du.dy - sd->v - sd->dv.dy, sd->u + sd->du.dy, 0.0f);
|
||||
break;
|
||||
default:
|
||||
svm_node_geometry(kg, sd, stack, type, out_offset);
|
||||
svm_node_geometry(kg, sd, svm, type, out_offset);
|
||||
return;
|
||||
}
|
||||
|
||||
stack_store_float3(stack, out_offset, data);
|
||||
stack_store_float3(svm, out_offset, data);
|
||||
#else
|
||||
svm_node_geometry(kg, sd, stack, type, out_offset);
|
||||
svm_node_geometry(kg, sd, svm, type, out_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ ccl_device_noinline void svm_node_geometry_bump_dy(KernelGlobals kg,
|
|||
|
||||
ccl_device_noinline void svm_node_object_info(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint out_offset)
|
||||
{
|
||||
|
@ -110,11 +110,11 @@ ccl_device_noinline void svm_node_object_info(KernelGlobals kg,
|
|||
|
||||
switch (type) {
|
||||
case NODE_INFO_OB_LOCATION: {
|
||||
stack_store_float3(stack, out_offset, object_location(kg, sd));
|
||||
stack_store_float3(svm, out_offset, object_location(kg, sd));
|
||||
return;
|
||||
}
|
||||
case NODE_INFO_OB_COLOR: {
|
||||
stack_store_float3(stack, out_offset, object_color(kg, sd->object));
|
||||
stack_store_float3(svm, out_offset, object_color(kg, sd->object));
|
||||
return;
|
||||
}
|
||||
case NODE_INFO_OB_ALPHA:
|
||||
|
@ -140,64 +140,64 @@ ccl_device_noinline void svm_node_object_info(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
|
||||
stack_store_float(stack, out_offset, data);
|
||||
stack_store_float(svm, out_offset, data);
|
||||
}
|
||||
|
||||
/* Particle Info */
|
||||
|
||||
ccl_device_noinline void svm_node_particle_info(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint out_offset)
|
||||
{
|
||||
switch (type) {
|
||||
case NODE_INFO_PAR_INDEX: {
|
||||
int particle_id = object_particle_id(kg, sd->object);
|
||||
stack_store_float(stack, out_offset, particle_index(kg, particle_id));
|
||||
stack_store_float(svm, out_offset, particle_index(kg, particle_id));
|
||||
break;
|
||||
}
|
||||
case NODE_INFO_PAR_RANDOM: {
|
||||
int particle_id = object_particle_id(kg, sd->object);
|
||||
float random = hash_uint2_to_float(particle_index(kg, particle_id), 0);
|
||||
stack_store_float(stack, out_offset, random);
|
||||
stack_store_float(svm, out_offset, random);
|
||||
break;
|
||||
}
|
||||
case NODE_INFO_PAR_AGE: {
|
||||
int particle_id = object_particle_id(kg, sd->object);
|
||||
stack_store_float(stack, out_offset, particle_age(kg, particle_id));
|
||||
stack_store_float(svm, out_offset, particle_age(kg, particle_id));
|
||||
break;
|
||||
}
|
||||
case NODE_INFO_PAR_LIFETIME: {
|
||||
int particle_id = object_particle_id(kg, sd->object);
|
||||
stack_store_float(stack, out_offset, particle_lifetime(kg, particle_id));
|
||||
stack_store_float(svm, out_offset, particle_lifetime(kg, particle_id));
|
||||
break;
|
||||
}
|
||||
case NODE_INFO_PAR_LOCATION: {
|
||||
int particle_id = object_particle_id(kg, sd->object);
|
||||
stack_store_float3(stack, out_offset, particle_location(kg, particle_id));
|
||||
stack_store_float3(svm, out_offset, particle_location(kg, particle_id));
|
||||
break;
|
||||
}
|
||||
#if 0 /* XXX float4 currently not supported in SVM stack */
|
||||
case NODE_INFO_PAR_ROTATION: {
|
||||
int particle_id = object_particle_id(kg, sd->object);
|
||||
stack_store_float4(stack, out_offset, particle_rotation(kg, particle_id));
|
||||
stack_store_float4(svm, out_offset, particle_rotation(kg, particle_id));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case NODE_INFO_PAR_SIZE: {
|
||||
int particle_id = object_particle_id(kg, sd->object);
|
||||
stack_store_float(stack, out_offset, particle_size(kg, particle_id));
|
||||
stack_store_float(svm, out_offset, particle_size(kg, particle_id));
|
||||
break;
|
||||
}
|
||||
case NODE_INFO_PAR_VELOCITY: {
|
||||
int particle_id = object_particle_id(kg, sd->object);
|
||||
stack_store_float3(stack, out_offset, particle_velocity(kg, particle_id));
|
||||
stack_store_float3(svm, out_offset, particle_velocity(kg, particle_id));
|
||||
break;
|
||||
}
|
||||
case NODE_INFO_PAR_ANGULAR_VELOCITY: {
|
||||
int particle_id = object_particle_id(kg, sd->object);
|
||||
stack_store_float3(stack, out_offset, particle_angular_velocity(kg, particle_id));
|
||||
stack_store_float3(svm, out_offset, particle_angular_velocity(kg, particle_id));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ ccl_device_noinline void svm_node_particle_info(KernelGlobals kg,
|
|||
|
||||
ccl_device_noinline void svm_node_hair_info(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint out_offset)
|
||||
{
|
||||
|
@ -219,7 +219,7 @@ ccl_device_noinline void svm_node_hair_info(KernelGlobals kg,
|
|||
switch (type) {
|
||||
case NODE_INFO_CURVE_IS_STRAND: {
|
||||
data = (sd->type & PRIMITIVE_CURVE) != 0;
|
||||
stack_store_float(stack, out_offset, data);
|
||||
stack_store_float(svm, out_offset, data);
|
||||
break;
|
||||
}
|
||||
case NODE_INFO_CURVE_INTERCEPT:
|
||||
|
@ -230,12 +230,12 @@ ccl_device_noinline void svm_node_hair_info(KernelGlobals kg,
|
|||
break; /* handled as attribute */
|
||||
case NODE_INFO_CURVE_THICKNESS: {
|
||||
data = curve_thickness(kg, sd);
|
||||
stack_store_float(stack, out_offset, data);
|
||||
stack_store_float(svm, out_offset, data);
|
||||
break;
|
||||
}
|
||||
case NODE_INFO_CURVE_TANGENT_NORMAL: {
|
||||
data3 = curve_tangent_normal(kg, sd);
|
||||
stack_store_float3(stack, out_offset, data3);
|
||||
stack_store_float3(svm, out_offset, data3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -248,16 +248,16 @@ ccl_device_noinline void svm_node_hair_info(KernelGlobals kg,
|
|||
|
||||
ccl_device_noinline void svm_node_point_info(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint out_offset)
|
||||
{
|
||||
switch (type) {
|
||||
case NODE_INFO_POINT_POSITION:
|
||||
stack_store_float3(stack, out_offset, point_position(kg, sd));
|
||||
stack_store_float3(svm, out_offset, point_position(kg, sd));
|
||||
break;
|
||||
case NODE_INFO_POINT_RADIUS:
|
||||
stack_store_float(stack, out_offset, point_radius(kg, sd));
|
||||
stack_store_float(svm, out_offset, point_radius(kg, sd));
|
||||
break;
|
||||
case NODE_INFO_POINT_RANDOM:
|
||||
break; /* handled as attribute */
|
||||
|
|
|
@ -51,22 +51,22 @@ ccl_device float svm_gradient(float3 p, NodeGradientType type)
|
|||
}
|
||||
|
||||
ccl_device_noinline void svm_node_tex_gradient(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint type, co_offset, color_offset, fac_offset;
|
||||
|
||||
svm_unpack_node_uchar4(node.y, &type, &co_offset, &fac_offset, &color_offset);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float3 co = stack_load_float3(svm, co_offset);
|
||||
|
||||
float f = svm_gradient(co, (NodeGradientType)type);
|
||||
f = saturatef(f);
|
||||
|
||||
if (stack_valid(fac_offset))
|
||||
stack_store_float(stack, fac_offset, f);
|
||||
stack_store_float(svm, fac_offset, f);
|
||||
if (stack_valid(color_offset))
|
||||
stack_store_float3(stack, color_offset, make_float3(f, f, f));
|
||||
stack_store_float3(svm, color_offset, make_float3(f, f, f));
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -8,7 +8,7 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_hsv(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint in_color_offset, fac_offset, out_color_offset;
|
||||
|
@ -16,13 +16,13 @@ ccl_device_noinline void svm_node_hsv(KernelGlobals kg,
|
|||
svm_unpack_node_uchar3(node.y, &in_color_offset, &fac_offset, &out_color_offset);
|
||||
svm_unpack_node_uchar3(node.z, &hue_offset, &sat_offset, &val_offset);
|
||||
|
||||
float fac = stack_load_float(stack, fac_offset);
|
||||
float3 in_color = stack_load_float3(stack, in_color_offset);
|
||||
float fac = stack_load_float(svm, fac_offset);
|
||||
float3 in_color = stack_load_float3(svm, in_color_offset);
|
||||
float3 color = in_color;
|
||||
|
||||
float hue = stack_load_float(stack, hue_offset);
|
||||
float sat = stack_load_float(stack, sat_offset);
|
||||
float val = stack_load_float(stack, val_offset);
|
||||
float hue = stack_load_float(svm, hue_offset);
|
||||
float sat = stack_load_float(svm, sat_offset);
|
||||
float val = stack_load_float(svm, val_offset);
|
||||
|
||||
color = rgb_to_hsv(color);
|
||||
|
||||
|
@ -43,7 +43,7 @@ ccl_device_noinline void svm_node_hsv(KernelGlobals kg,
|
|||
color.z = max(color.z, 0.0f);
|
||||
|
||||
if (stack_valid(out_color_offset))
|
||||
stack_store_float3(stack, out_color_offset, color);
|
||||
stack_store_float3(svm, out_color_offset, color);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -88,14 +88,14 @@ ccl_device_inline float kernel_ies_interp(KernelGlobals kg, int slot, float h_an
|
|||
#ifdef __SVM__
|
||||
ccl_device_noinline void svm_node_ies(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint vector_offset, strength_offset, fac_offset, slot = node.z;
|
||||
svm_unpack_node_uchar3(node.y, &strength_offset, &vector_offset, &fac_offset);
|
||||
|
||||
float3 vector = stack_load_float3(stack, vector_offset);
|
||||
float strength = stack_load_float_default(stack, strength_offset, node.w);
|
||||
float3 vector = stack_load_float3(svm, vector_offset);
|
||||
float strength = stack_load_float_default(svm, strength_offset, node.w);
|
||||
|
||||
vector = normalize(vector);
|
||||
float v_angle = safe_acosf(-vector.z);
|
||||
|
@ -104,7 +104,7 @@ ccl_device_noinline void svm_node_ies(KernelGlobals kg,
|
|||
float fac = strength * kernel_ies_interp(kg, slot, h_angle, v_angle);
|
||||
|
||||
if (stack_valid(fac_offset)) {
|
||||
stack_store_float(stack, fac_offset, fac);
|
||||
stack_store_float(svm, fac_offset, fac);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,14 +34,16 @@ ccl_device_inline float3 texco_remap_square(float3 co)
|
|||
return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f;
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_tex_image(
|
||||
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
||||
ccl_device_noinline void svm_node_tex_image(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint co_offset, out_offset, alpha_offset, flags;
|
||||
|
||||
svm_unpack_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &flags);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float3 co = stack_load_float3(svm, co_offset);
|
||||
float2 tex_co;
|
||||
if (node.w == NODE_IMAGE_PROJ_SPHERE) {
|
||||
co = texco_remap_square(co);
|
||||
|
@ -61,7 +63,7 @@ ccl_device_noinline int svm_node_tex_image(
|
|||
int num_nodes = (int)node.y;
|
||||
if (num_nodes > 0) {
|
||||
/* Remember the offset of the node following the tile nodes. */
|
||||
int next_offset = offset + num_nodes;
|
||||
int next_offset = svm->offset + num_nodes;
|
||||
|
||||
/* Find the tile that the UV lies in. */
|
||||
int tx = (int)tex_co.x;
|
||||
|
@ -73,7 +75,7 @@ ccl_device_noinline int svm_node_tex_image(
|
|||
|
||||
/* Find the index of the tile. */
|
||||
for (int i = 0; i < num_nodes; i++) {
|
||||
uint4 tile_node = read_node(kg, &offset);
|
||||
uint4 tile_node = read_node(kg, svm);
|
||||
if (tile_node.x == tile) {
|
||||
id = tile_node.y;
|
||||
break;
|
||||
|
@ -92,7 +94,7 @@ ccl_device_noinline int svm_node_tex_image(
|
|||
}
|
||||
|
||||
/* Skip over the remaining nodes. */
|
||||
offset = next_offset;
|
||||
svm->offset = next_offset;
|
||||
}
|
||||
else {
|
||||
id = -num_nodes;
|
||||
|
@ -101,15 +103,14 @@ ccl_device_noinline int svm_node_tex_image(
|
|||
float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, flags);
|
||||
|
||||
if (stack_valid(out_offset))
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
|
||||
stack_store_float3(svm, out_offset, make_float3(f.x, f.y, f.z));
|
||||
if (stack_valid(alpha_offset))
|
||||
stack_store_float(stack, alpha_offset, f.w);
|
||||
return offset;
|
||||
stack_store_float(svm, alpha_offset, f.w);
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_tex_image_box(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
/* get object space normal */
|
||||
|
@ -184,7 +185,7 @@ ccl_device_noinline void svm_node_tex_image_box(KernelGlobals kg,
|
|||
uint co_offset, out_offset, alpha_offset, flags;
|
||||
svm_unpack_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &flags);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float3 co = stack_load_float3(svm, co_offset);
|
||||
uint id = node.y;
|
||||
|
||||
float4 f = zero_float4();
|
||||
|
@ -204,14 +205,14 @@ ccl_device_noinline void svm_node_tex_image_box(KernelGlobals kg,
|
|||
}
|
||||
|
||||
if (stack_valid(out_offset))
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
|
||||
stack_store_float3(svm, out_offset, make_float3(f.x, f.y, f.z));
|
||||
if (stack_valid(alpha_offset))
|
||||
stack_store_float(stack, alpha_offset, f.w);
|
||||
stack_store_float(svm, alpha_offset, f.w);
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_tex_environment(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint id = node.y;
|
||||
|
@ -220,7 +221,7 @@ ccl_device_noinline void svm_node_tex_environment(KernelGlobals kg,
|
|||
|
||||
svm_unpack_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &flags);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float3 co = stack_load_float3(svm, co_offset);
|
||||
float2 uv;
|
||||
|
||||
co = safe_normalize(co);
|
||||
|
@ -233,9 +234,9 @@ ccl_device_noinline void svm_node_tex_environment(KernelGlobals kg,
|
|||
float4 f = svm_image_texture(kg, id, uv.x, uv.y, flags);
|
||||
|
||||
if (stack_valid(out_offset))
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
|
||||
stack_store_float3(svm, out_offset, make_float3(f.x, f.y, f.z));
|
||||
if (stack_valid(alpha_offset))
|
||||
stack_store_float(stack, alpha_offset, f.w);
|
||||
stack_store_float(svm, alpha_offset, f.w);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -12,20 +12,20 @@ ccl_device float invert(float color, float factor)
|
|||
}
|
||||
|
||||
ccl_device_noinline void svm_node_invert(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint in_fac,
|
||||
uint in_color,
|
||||
uint out_color)
|
||||
{
|
||||
float factor = stack_load_float(stack, in_fac);
|
||||
float3 color = stack_load_float3(stack, in_color);
|
||||
float factor = stack_load_float(svm, in_fac);
|
||||
float3 color = stack_load_float3(svm, in_color);
|
||||
|
||||
color.x = invert(color.x, factor);
|
||||
color.y = invert(color.y, factor);
|
||||
color.z = invert(color.z, factor);
|
||||
|
||||
if (stack_valid(out_color))
|
||||
stack_store_float3(stack, out_color, color);
|
||||
stack_store_float3(svm, out_color, color);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -12,7 +12,7 @@ template<uint node_feature_mask, typename ConstIntegratorGenericState>
|
|||
ccl_device_noinline void svm_node_light_path(KernelGlobals kg,
|
||||
ConstIntegratorGenericState state,
|
||||
ccl_private const ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint out_offset,
|
||||
uint32_t path_flag)
|
||||
|
@ -93,20 +93,20 @@ ccl_device_noinline void svm_node_light_path(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
|
||||
stack_store_float(stack, out_offset, info);
|
||||
stack_store_float(svm, out_offset, info);
|
||||
}
|
||||
|
||||
/* Light Falloff Node */
|
||||
|
||||
ccl_device_noinline void svm_node_light_falloff(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint strength_offset, out_offset, smooth_offset;
|
||||
|
||||
svm_unpack_node_uchar3(node.z, &strength_offset, &smooth_offset, &out_offset);
|
||||
|
||||
float strength = stack_load_float(stack, strength_offset);
|
||||
float strength = stack_load_float(svm, strength_offset);
|
||||
uint type = node.y;
|
||||
|
||||
switch (type) {
|
||||
|
@ -120,7 +120,7 @@ ccl_device_noinline void svm_node_light_falloff(ccl_private ShaderData *sd,
|
|||
break;
|
||||
}
|
||||
|
||||
float smooth = stack_load_float(stack, smooth_offset);
|
||||
float smooth = stack_load_float(svm, smooth_offset);
|
||||
|
||||
if (smooth > 0.0f) {
|
||||
float squared = sd->ray_length * sd->ray_length;
|
||||
|
@ -130,7 +130,7 @@ ccl_device_noinline void svm_node_light_falloff(ccl_private ShaderData *sd,
|
|||
}
|
||||
}
|
||||
|
||||
stack_store_float(stack, out_offset, strength);
|
||||
stack_store_float(svm, out_offset, strength);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -93,8 +93,10 @@ ccl_device_noinline_cpu float3 svm_magic(float3 p, float scale, int n, float dis
|
|||
return make_float3(0.5f - x, 0.5f - y, 0.5f - z);
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_tex_magic(
|
||||
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
||||
ccl_device_noinline void svm_node_tex_magic(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint depth;
|
||||
uint scale_offset, distortion_offset, co_offset, fac_offset, color_offset;
|
||||
|
@ -102,18 +104,17 @@ ccl_device_noinline int svm_node_tex_magic(
|
|||
svm_unpack_node_uchar3(node.y, &depth, &color_offset, &fac_offset);
|
||||
svm_unpack_node_uchar3(node.z, &co_offset, &scale_offset, &distortion_offset);
|
||||
|
||||
uint4 node2 = read_node(kg, &offset);
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float scale = stack_load_float_default(stack, scale_offset, node2.x);
|
||||
float distortion = stack_load_float_default(stack, distortion_offset, node2.y);
|
||||
uint4 node2 = read_node(kg, svm);
|
||||
float3 co = stack_load_float3(svm, co_offset);
|
||||
float scale = stack_load_float_default(svm, scale_offset, node2.x);
|
||||
float distortion = stack_load_float_default(svm, distortion_offset, node2.y);
|
||||
|
||||
float3 color = svm_magic(co, scale, depth, distortion);
|
||||
|
||||
if (stack_valid(fac_offset))
|
||||
stack_store_float(stack, fac_offset, average(color));
|
||||
stack_store_float(svm, fac_offset, average(color));
|
||||
if (stack_valid(color_offset))
|
||||
stack_store_float3(stack, color_offset, color);
|
||||
return offset;
|
||||
stack_store_float3(svm, color_offset, color);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -14,13 +14,12 @@ ccl_device_inline float smootherstep(float edge0, float edge1, float x)
|
|||
return x * x * x * (x * (x * 6.0f - 15.0f) + 10.0f);
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_map_range(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint value_stack_offset,
|
||||
uint parameters_stack_offsets,
|
||||
uint results_stack_offsets,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_map_range(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint value_stack_offset,
|
||||
uint parameters_stack_offsets,
|
||||
uint results_stack_offsets)
|
||||
{
|
||||
uint from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset;
|
||||
uint type_stack_offset, steps_stack_offset, result_stack_offset;
|
||||
|
@ -32,15 +31,15 @@ ccl_device_noinline int svm_node_map_range(KernelGlobals kg,
|
|||
svm_unpack_node_uchar3(
|
||||
results_stack_offsets, &type_stack_offset, &steps_stack_offset, &result_stack_offset);
|
||||
|
||||
uint4 defaults = read_node(kg, &offset);
|
||||
uint4 defaults2 = read_node(kg, &offset);
|
||||
uint4 defaults = read_node(kg, svm);
|
||||
uint4 defaults2 = read_node(kg, svm);
|
||||
|
||||
float value = stack_load_float(stack, value_stack_offset);
|
||||
float from_min = stack_load_float_default(stack, from_min_stack_offset, defaults.x);
|
||||
float from_max = stack_load_float_default(stack, from_max_stack_offset, defaults.y);
|
||||
float to_min = stack_load_float_default(stack, to_min_stack_offset, defaults.z);
|
||||
float to_max = stack_load_float_default(stack, to_max_stack_offset, defaults.w);
|
||||
float steps = stack_load_float_default(stack, steps_stack_offset, defaults2.x);
|
||||
float value = stack_load_float(svm, value_stack_offset);
|
||||
float from_min = stack_load_float_default(svm, from_min_stack_offset, defaults.x);
|
||||
float from_max = stack_load_float_default(svm, from_max_stack_offset, defaults.y);
|
||||
float to_min = stack_load_float_default(svm, to_min_stack_offset, defaults.z);
|
||||
float to_max = stack_load_float_default(svm, to_max_stack_offset, defaults.w);
|
||||
float steps = stack_load_float_default(svm, steps_stack_offset, defaults2.x);
|
||||
|
||||
float result;
|
||||
|
||||
|
@ -72,17 +71,15 @@ ccl_device_noinline int svm_node_map_range(KernelGlobals kg,
|
|||
else {
|
||||
result = 0.0f;
|
||||
}
|
||||
stack_store_float(stack, result_stack_offset, result);
|
||||
return offset;
|
||||
stack_store_float(svm, result_stack_offset, result);
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_vector_map_range(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint value_stack_offset,
|
||||
uint parameters_stack_offsets,
|
||||
uint results_stack_offsets,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_vector_map_range(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint value_stack_offset,
|
||||
uint parameters_stack_offsets,
|
||||
uint results_stack_offsets)
|
||||
{
|
||||
uint from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset;
|
||||
uint steps_stack_offset, clamp_stack_offset, range_type_stack_offset, result_stack_offset;
|
||||
|
@ -97,12 +94,12 @@ ccl_device_noinline int svm_node_vector_map_range(KernelGlobals kg,
|
|||
&range_type_stack_offset,
|
||||
&result_stack_offset);
|
||||
|
||||
float3 value = stack_load_float3(stack, value_stack_offset);
|
||||
float3 from_min = stack_load_float3(stack, from_min_stack_offset);
|
||||
float3 from_max = stack_load_float3(stack, from_max_stack_offset);
|
||||
float3 to_min = stack_load_float3(stack, to_min_stack_offset);
|
||||
float3 to_max = stack_load_float3(stack, to_max_stack_offset);
|
||||
float3 steps = stack_load_float3(stack, steps_stack_offset);
|
||||
float3 value = stack_load_float3(svm, value_stack_offset);
|
||||
float3 from_min = stack_load_float3(svm, from_min_stack_offset);
|
||||
float3 from_max = stack_load_float3(svm, from_max_stack_offset);
|
||||
float3 to_min = stack_load_float3(svm, to_min_stack_offset);
|
||||
float3 to_max = stack_load_float3(svm, to_max_stack_offset);
|
||||
float3 steps = stack_load_float3(svm, steps_stack_offset);
|
||||
|
||||
int type = range_type_stack_offset;
|
||||
int use_clamp = (type == NODE_MAP_RANGE_SMOOTHSTEP || type == NODE_MAP_RANGE_SMOOTHERSTEP) ?
|
||||
|
@ -146,8 +143,7 @@ ccl_device_noinline int svm_node_vector_map_range(KernelGlobals kg,
|
|||
clamp(result.z, to_min.z, to_max.z);
|
||||
}
|
||||
|
||||
stack_store_float3(stack, result_stack_offset, result);
|
||||
return offset;
|
||||
stack_store_float3(svm, result_stack_offset, result);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -12,7 +12,7 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_mapping(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint inputs_stack_offsets,
|
||||
uint result_stack_offset)
|
||||
|
@ -24,51 +24,47 @@ ccl_device_noinline void svm_node_mapping(KernelGlobals kg,
|
|||
&rotation_stack_offset,
|
||||
&scale_stack_offset);
|
||||
|
||||
float3 vector = stack_load_float3(stack, vector_stack_offset);
|
||||
float3 location = stack_load_float3(stack, location_stack_offset);
|
||||
float3 rotation = stack_load_float3(stack, rotation_stack_offset);
|
||||
float3 scale = stack_load_float3(stack, scale_stack_offset);
|
||||
float3 vector = stack_load_float3(svm, vector_stack_offset);
|
||||
float3 location = stack_load_float3(svm, location_stack_offset);
|
||||
float3 rotation = stack_load_float3(svm, rotation_stack_offset);
|
||||
float3 scale = stack_load_float3(svm, scale_stack_offset);
|
||||
|
||||
float3 result = svm_mapping((NodeMappingType)type, vector, location, rotation, scale);
|
||||
stack_store_float3(stack, result_stack_offset, result);
|
||||
stack_store_float3(svm, result_stack_offset, result);
|
||||
}
|
||||
|
||||
/* Texture Mapping */
|
||||
|
||||
ccl_device_noinline int svm_node_texture_mapping(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint vec_offset,
|
||||
uint out_offset,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_texture_mapping(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint vec_offset,
|
||||
uint out_offset)
|
||||
{
|
||||
float3 v = stack_load_float3(stack, vec_offset);
|
||||
float3 v = stack_load_float3(svm, vec_offset);
|
||||
|
||||
Transform tfm;
|
||||
tfm.x = read_node_float(kg, &offset);
|
||||
tfm.y = read_node_float(kg, &offset);
|
||||
tfm.z = read_node_float(kg, &offset);
|
||||
tfm.x = read_node_float(kg, svm);
|
||||
tfm.y = read_node_float(kg, svm);
|
||||
tfm.z = read_node_float(kg, svm);
|
||||
|
||||
float3 r = transform_point(&tfm, v);
|
||||
stack_store_float3(stack, out_offset, r);
|
||||
return offset;
|
||||
stack_store_float3(svm, out_offset, r);
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_min_max(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint vec_offset,
|
||||
uint out_offset,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_min_max(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint vec_offset,
|
||||
uint out_offset)
|
||||
{
|
||||
float3 v = stack_load_float3(stack, vec_offset);
|
||||
float3 v = stack_load_float3(svm, vec_offset);
|
||||
|
||||
float3 mn = float4_to_float3(read_node_float(kg, &offset));
|
||||
float3 mx = float4_to_float3(read_node_float(kg, &offset));
|
||||
float3 mn = float4_to_float3(read_node_float(kg, svm));
|
||||
float3 mx = float4_to_float3(read_node_float(kg, svm));
|
||||
|
||||
float3 r = min(max(mn, v), mx);
|
||||
stack_store_float3(stack, out_offset, r);
|
||||
return offset;
|
||||
stack_store_float3(svm, out_offset, r);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -8,7 +8,7 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_math(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint inputs_stack_offsets,
|
||||
uint result_stack_offset)
|
||||
|
@ -16,21 +16,20 @@ ccl_device_noinline void svm_node_math(KernelGlobals kg,
|
|||
uint a_stack_offset, b_stack_offset, c_stack_offset;
|
||||
svm_unpack_node_uchar3(inputs_stack_offsets, &a_stack_offset, &b_stack_offset, &c_stack_offset);
|
||||
|
||||
float a = stack_load_float(stack, a_stack_offset);
|
||||
float b = stack_load_float(stack, b_stack_offset);
|
||||
float c = stack_load_float(stack, c_stack_offset);
|
||||
float a = stack_load_float(svm, a_stack_offset);
|
||||
float b = stack_load_float(svm, b_stack_offset);
|
||||
float c = stack_load_float(svm, c_stack_offset);
|
||||
float result = svm_math((NodeMathType)type, a, b, c);
|
||||
|
||||
stack_store_float(stack, result_stack_offset, result);
|
||||
stack_store_float(svm, result_stack_offset, result);
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_vector_math(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint type,
|
||||
uint inputs_stack_offsets,
|
||||
uint outputs_stack_offsets,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_vector_math(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint type,
|
||||
uint inputs_stack_offsets,
|
||||
uint outputs_stack_offsets)
|
||||
{
|
||||
uint value_stack_offset, vector_stack_offset;
|
||||
uint a_stack_offset, b_stack_offset, param1_stack_offset;
|
||||
|
@ -38,10 +37,10 @@ ccl_device_noinline int svm_node_vector_math(KernelGlobals kg,
|
|||
inputs_stack_offsets, &a_stack_offset, &b_stack_offset, ¶m1_stack_offset);
|
||||
svm_unpack_node_uchar2(outputs_stack_offsets, &value_stack_offset, &vector_stack_offset);
|
||||
|
||||
float3 a = stack_load_float3(stack, a_stack_offset);
|
||||
float3 b = stack_load_float3(stack, b_stack_offset);
|
||||
float3 a = stack_load_float3(svm, a_stack_offset);
|
||||
float3 b = stack_load_float3(svm, b_stack_offset);
|
||||
float3 c = make_float3(0.0f, 0.0f, 0.0f);
|
||||
float param1 = stack_load_float(stack, param1_stack_offset);
|
||||
float param1 = stack_load_float(svm, param1_stack_offset);
|
||||
|
||||
float value;
|
||||
float3 vector;
|
||||
|
@ -50,17 +49,16 @@ ccl_device_noinline int svm_node_vector_math(KernelGlobals kg,
|
|||
if (type == NODE_VECTOR_MATH_WRAP || type == NODE_VECTOR_MATH_FACEFORWARD ||
|
||||
type == NODE_VECTOR_MATH_MULTIPLY_ADD)
|
||||
{
|
||||
uint4 extra_node = read_node(kg, &offset);
|
||||
c = stack_load_float3(stack, extra_node.x);
|
||||
uint4 extra_node = read_node(kg, svm);
|
||||
c = stack_load_float3(svm, extra_node.x);
|
||||
}
|
||||
|
||||
svm_vector_math(&value, &vector, (NodeVectorMathType)type, a, b, c, param1);
|
||||
|
||||
if (stack_valid(value_stack_offset))
|
||||
stack_store_float(stack, value_stack_offset, value);
|
||||
stack_store_float(svm, value_stack_offset, value);
|
||||
if (stack_valid(vector_stack_offset))
|
||||
stack_store_float3(stack, vector_stack_offset, vector);
|
||||
return offset;
|
||||
stack_store_float3(svm, vector_stack_offset, vector);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -8,28 +8,26 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
/* Node */
|
||||
|
||||
ccl_device_noinline int svm_node_mix(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint fac_offset,
|
||||
uint c1_offset,
|
||||
uint c2_offset,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_mix(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint fac_offset,
|
||||
uint c1_offset,
|
||||
uint c2_offset)
|
||||
{
|
||||
/* read extra data */
|
||||
uint4 node1 = read_node(kg, &offset);
|
||||
uint4 node1 = read_node(kg, svm);
|
||||
|
||||
float fac = stack_load_float(stack, fac_offset);
|
||||
float3 c1 = stack_load_float3(stack, c1_offset);
|
||||
float3 c2 = stack_load_float3(stack, c2_offset);
|
||||
float fac = stack_load_float(svm, fac_offset);
|
||||
float3 c1 = stack_load_float3(svm, c1_offset);
|
||||
float3 c2 = stack_load_float3(svm, c2_offset);
|
||||
float3 result = svm_mix_clamped_factor((NodeMix)node1.y, fac, c1, c2);
|
||||
|
||||
stack_store_float3(stack, node1.z, result);
|
||||
return offset;
|
||||
stack_store_float3(svm, node1.z, result);
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_mix_color(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint options,
|
||||
uint input_offset,
|
||||
uint result_offset)
|
||||
|
@ -40,21 +38,21 @@ ccl_device_noinline void svm_node_mix_color(ccl_private ShaderData *sd,
|
|||
svm_unpack_node_uchar3(
|
||||
input_offset, &fac_in_stack_offset, &a_in_stack_offset, &b_in_stack_offset);
|
||||
|
||||
float t = stack_load_float(stack, fac_in_stack_offset);
|
||||
float t = stack_load_float(svm, fac_in_stack_offset);
|
||||
if (use_clamp > 0) {
|
||||
t = saturatef(t);
|
||||
}
|
||||
float3 a = stack_load_float3(stack, a_in_stack_offset);
|
||||
float3 b = stack_load_float3(stack, b_in_stack_offset);
|
||||
float3 a = stack_load_float3(svm, a_in_stack_offset);
|
||||
float3 b = stack_load_float3(svm, b_in_stack_offset);
|
||||
float3 result = svm_mix((NodeMix)blend_type, t, a, b);
|
||||
if (use_clamp_result) {
|
||||
result = saturate(result);
|
||||
}
|
||||
stack_store_float3(stack, result_offset, result);
|
||||
stack_store_float3(svm, result_offset, result);
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_mix_float(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint use_clamp,
|
||||
uint input_offset,
|
||||
uint result_offset)
|
||||
|
@ -63,19 +61,19 @@ ccl_device_noinline void svm_node_mix_float(ccl_private ShaderData *sd,
|
|||
svm_unpack_node_uchar3(
|
||||
input_offset, &fac_in_stack_offset, &a_in_stack_offset, &b_in_stack_offset);
|
||||
|
||||
float t = stack_load_float(stack, fac_in_stack_offset);
|
||||
float t = stack_load_float(svm, fac_in_stack_offset);
|
||||
if (use_clamp > 0) {
|
||||
t = saturatef(t);
|
||||
}
|
||||
float a = stack_load_float(stack, a_in_stack_offset);
|
||||
float b = stack_load_float(stack, b_in_stack_offset);
|
||||
float a = stack_load_float(svm, a_in_stack_offset);
|
||||
float b = stack_load_float(svm, b_in_stack_offset);
|
||||
float result = a * (1 - t) + b * t;
|
||||
|
||||
stack_store_float(stack, result_offset, result);
|
||||
stack_store_float(svm, result_offset, result);
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_mix_vector(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint input_offset,
|
||||
uint result_offset)
|
||||
{
|
||||
|
@ -83,18 +81,18 @@ ccl_device_noinline void svm_node_mix_vector(ccl_private ShaderData *sd,
|
|||
svm_unpack_node_uchar4(
|
||||
input_offset, &use_clamp, &fac_in_stack_offset, &a_in_stack_offset, &b_in_stack_offset);
|
||||
|
||||
float t = stack_load_float(stack, fac_in_stack_offset);
|
||||
float t = stack_load_float(svm, fac_in_stack_offset);
|
||||
if (use_clamp > 0) {
|
||||
t = saturatef(t);
|
||||
}
|
||||
float3 a = stack_load_float3(stack, a_in_stack_offset);
|
||||
float3 b = stack_load_float3(stack, b_in_stack_offset);
|
||||
float3 a = stack_load_float3(svm, a_in_stack_offset);
|
||||
float3 b = stack_load_float3(svm, b_in_stack_offset);
|
||||
float3 result = a * (one_float3() - t) + b * t;
|
||||
stack_store_float3(stack, result_offset, result);
|
||||
stack_store_float3(svm, result_offset, result);
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_mix_vector_non_uniform(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint input_offset,
|
||||
uint result_offset)
|
||||
{
|
||||
|
@ -102,14 +100,14 @@ ccl_device_noinline void svm_node_mix_vector_non_uniform(ccl_private ShaderData
|
|||
svm_unpack_node_uchar4(
|
||||
input_offset, &use_clamp, &fac_in_stack_offset, &a_in_stack_offset, &b_in_stack_offset);
|
||||
|
||||
float3 t = stack_load_float3(stack, fac_in_stack_offset);
|
||||
float3 t = stack_load_float3(svm, fac_in_stack_offset);
|
||||
if (use_clamp > 0) {
|
||||
t = saturate(t);
|
||||
}
|
||||
float3 a = stack_load_float3(stack, a_in_stack_offset);
|
||||
float3 b = stack_load_float3(stack, b_in_stack_offset);
|
||||
float3 a = stack_load_float3(svm, a_in_stack_offset);
|
||||
float3 b = stack_load_float3(svm, b_in_stack_offset);
|
||||
float3 result = a * (one_float3() - t) + b * t;
|
||||
stack_store_float3(stack, result_offset, result);
|
||||
stack_store_float3(svm, result_offset, result);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -704,13 +704,12 @@ ccl_device_noinline_cpu float noise_musgrave_ridged_multi_fractal_4d(
|
|||
return value;
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_tex_musgrave(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint offsets1,
|
||||
uint offsets2,
|
||||
uint offsets3,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_tex_musgrave(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint offsets1,
|
||||
uint offsets2,
|
||||
uint offsets3)
|
||||
{
|
||||
uint type, dimensions, co_stack_offset, w_stack_offset;
|
||||
uint scale_stack_offset, detail_stack_offset, dimension_stack_offset, lacunarity_stack_offset;
|
||||
|
@ -724,17 +723,17 @@ ccl_device_noinline int svm_node_tex_musgrave(KernelGlobals kg,
|
|||
&lacunarity_stack_offset);
|
||||
svm_unpack_node_uchar3(offsets3, &offset_stack_offset, &gain_stack_offset, &fac_stack_offset);
|
||||
|
||||
uint4 defaults1 = read_node(kg, &offset);
|
||||
uint4 defaults2 = read_node(kg, &offset);
|
||||
uint4 defaults1 = read_node(kg, svm);
|
||||
uint4 defaults2 = read_node(kg, svm);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_stack_offset);
|
||||
float w = stack_load_float_default(stack, w_stack_offset, defaults1.x);
|
||||
float scale = stack_load_float_default(stack, scale_stack_offset, defaults1.y);
|
||||
float detail = stack_load_float_default(stack, detail_stack_offset, defaults1.z);
|
||||
float dimension = stack_load_float_default(stack, dimension_stack_offset, defaults1.w);
|
||||
float lacunarity = stack_load_float_default(stack, lacunarity_stack_offset, defaults2.x);
|
||||
float foffset = stack_load_float_default(stack, offset_stack_offset, defaults2.y);
|
||||
float gain = stack_load_float_default(stack, gain_stack_offset, defaults2.z);
|
||||
float3 co = stack_load_float3(svm, co_stack_offset);
|
||||
float w = stack_load_float_default(svm, w_stack_offset, defaults1.x);
|
||||
float scale = stack_load_float_default(svm, scale_stack_offset, defaults1.y);
|
||||
float detail = stack_load_float_default(svm, detail_stack_offset, defaults1.z);
|
||||
float dimension = stack_load_float_default(svm, dimension_stack_offset, defaults1.w);
|
||||
float lacunarity = stack_load_float_default(svm, lacunarity_stack_offset, defaults2.x);
|
||||
float foffset = stack_load_float_default(svm, offset_stack_offset, defaults2.y);
|
||||
float gain = stack_load_float_default(svm, gain_stack_offset, defaults2.z);
|
||||
|
||||
dimension = fmaxf(dimension, 1e-5f);
|
||||
detail = clamp(detail, 0.0f, 15.0f);
|
||||
|
@ -847,8 +846,7 @@ ccl_device_noinline int svm_node_tex_musgrave(KernelGlobals kg,
|
|||
fac = 0.0f;
|
||||
}
|
||||
|
||||
stack_store_float(stack, fac_stack_offset, fac);
|
||||
return offset;
|
||||
stack_store_float(svm, fac_stack_offset, fac);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -18,6 +18,8 @@ SHADER_NODE_TYPE(NODE_CLOSURE_SET_WEIGHT)
|
|||
SHADER_NODE_TYPE(NODE_CLOSURE_WEIGHT)
|
||||
SHADER_NODE_TYPE(NODE_EMISSION_WEIGHT)
|
||||
SHADER_NODE_TYPE(NODE_MIX_CLOSURE)
|
||||
SHADER_NODE_TYPE(NODE_LAYER_CLOSURE_ACCUMULATE)
|
||||
SHADER_NODE_TYPE(NODE_LAYER_CLOSURE)
|
||||
SHADER_NODE_TYPE(NODE_JUMP_IF_ZERO)
|
||||
SHADER_NODE_TYPE(NODE_JUMP_IF_ONE)
|
||||
SHADER_NODE_TYPE(NODE_GEOMETRY)
|
||||
|
@ -111,5 +113,7 @@ SHADER_NODE_TYPE(NODE_MIX_VECTOR_NON_UNIFORM)
|
|||
|
||||
/* Padding for struct alignment. */
|
||||
SHADER_NODE_TYPE(NODE_PAD1)
|
||||
SHADER_NODE_TYPE(NODE_PAD2)
|
||||
SHADER_NODE_TYPE(NODE_PAD3)
|
||||
|
||||
#undef SHADER_NODE_TYPE
|
||||
|
|
|
@ -132,13 +132,12 @@ ccl_device void noise_texture_4d(float4 co,
|
|||
}
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_tex_noise(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint dimensions,
|
||||
uint offsets1,
|
||||
uint offsets2,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_tex_noise(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint dimensions,
|
||||
uint offsets1,
|
||||
uint offsets2)
|
||||
{
|
||||
uint vector_stack_offset, w_stack_offset, scale_stack_offset;
|
||||
uint detail_stack_offset, roughness_stack_offset, distortion_stack_offset;
|
||||
|
@ -152,15 +151,15 @@ ccl_device_noinline int svm_node_tex_noise(KernelGlobals kg,
|
|||
&value_stack_offset,
|
||||
&color_stack_offset);
|
||||
|
||||
uint4 defaults1 = read_node(kg, &offset);
|
||||
uint4 defaults2 = read_node(kg, &offset);
|
||||
uint4 defaults1 = read_node(kg, svm);
|
||||
uint4 defaults2 = read_node(kg, svm);
|
||||
|
||||
float3 vector = stack_load_float3(stack, vector_stack_offset);
|
||||
float w = stack_load_float_default(stack, w_stack_offset, defaults1.x);
|
||||
float scale = stack_load_float_default(stack, scale_stack_offset, defaults1.y);
|
||||
float detail = stack_load_float_default(stack, detail_stack_offset, defaults1.z);
|
||||
float roughness = stack_load_float_default(stack, roughness_stack_offset, defaults1.w);
|
||||
float distortion = stack_load_float_default(stack, distortion_stack_offset, defaults2.x);
|
||||
float3 vector = stack_load_float3(svm, vector_stack_offset);
|
||||
float w = stack_load_float_default(svm, w_stack_offset, defaults1.x);
|
||||
float scale = stack_load_float_default(svm, scale_stack_offset, defaults1.y);
|
||||
float detail = stack_load_float_default(svm, detail_stack_offset, defaults1.z);
|
||||
float roughness = stack_load_float_default(svm, roughness_stack_offset, defaults1.w);
|
||||
float distortion = stack_load_float_default(svm, distortion_stack_offset, defaults2.x);
|
||||
|
||||
vector *= scale;
|
||||
w *= scale;
|
||||
|
@ -199,12 +198,11 @@ ccl_device_noinline int svm_node_tex_noise(KernelGlobals kg,
|
|||
}
|
||||
|
||||
if (stack_valid(value_stack_offset)) {
|
||||
stack_store_float(stack, value_stack_offset, value);
|
||||
stack_store_float(svm, value_stack_offset, value);
|
||||
}
|
||||
if (stack_valid(color_stack_offset)) {
|
||||
stack_store_float3(stack, color_stack_offset, color);
|
||||
stack_store_float3(svm, color_stack_offset, color);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -6,17 +6,16 @@
|
|||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device_noinline int svm_node_normal(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint in_normal_offset,
|
||||
uint out_normal_offset,
|
||||
uint out_dot_offset,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_normal(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint in_normal_offset,
|
||||
uint out_normal_offset,
|
||||
uint out_dot_offset)
|
||||
{
|
||||
/* read extra data */
|
||||
uint4 node1 = read_node(kg, &offset);
|
||||
float3 normal = stack_load_float3(stack, in_normal_offset);
|
||||
uint4 node1 = read_node(kg, svm);
|
||||
float3 normal = stack_load_float3(svm, in_normal_offset);
|
||||
|
||||
float3 direction;
|
||||
direction.x = __int_as_float(node1.x);
|
||||
|
@ -25,11 +24,10 @@ ccl_device_noinline int svm_node_normal(KernelGlobals kg,
|
|||
direction = normalize(direction);
|
||||
|
||||
if (stack_valid(out_normal_offset))
|
||||
stack_store_float3(stack, out_normal_offset, direction);
|
||||
stack_store_float3(svm, out_normal_offset, direction);
|
||||
|
||||
if (stack_valid(out_dot_offset))
|
||||
stack_store_float(stack, out_dot_offset, dot(direction, normalize(normal)));
|
||||
return offset;
|
||||
stack_store_float(svm, out_dot_offset, dot(direction, normalize(normal)));
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -78,76 +78,79 @@ ccl_device_inline float4 rgb_ramp_lookup(
|
|||
return a;
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_rgb_ramp(
|
||||
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
||||
ccl_device_noinline void svm_node_rgb_ramp(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint fac_offset, color_offset, alpha_offset;
|
||||
uint interpolate = node.z;
|
||||
|
||||
svm_unpack_node_uchar3(node.y, &fac_offset, &color_offset, &alpha_offset);
|
||||
|
||||
uint table_size = read_node(kg, &offset).x;
|
||||
uint table_size = read_node(kg, svm).x;
|
||||
|
||||
float fac = stack_load_float(stack, fac_offset);
|
||||
float4 color = rgb_ramp_lookup(kg, offset, fac, interpolate, false, table_size);
|
||||
float fac = stack_load_float(svm, fac_offset);
|
||||
float4 color = rgb_ramp_lookup(kg, svm->offset, fac, interpolate, false, table_size);
|
||||
|
||||
if (stack_valid(color_offset))
|
||||
stack_store_float3(stack, color_offset, float4_to_float3(color));
|
||||
stack_store_float3(svm, color_offset, float4_to_float3(color));
|
||||
if (stack_valid(alpha_offset))
|
||||
stack_store_float(stack, alpha_offset, color.w);
|
||||
stack_store_float(svm, alpha_offset, color.w);
|
||||
|
||||
offset += table_size;
|
||||
return offset;
|
||||
svm->offset += table_size;
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_curves(
|
||||
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
||||
ccl_device_noinline void svm_node_curves(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint fac_offset, color_offset, out_offset, extrapolate;
|
||||
svm_unpack_node_uchar4(node.y, &fac_offset, &color_offset, &out_offset, &extrapolate);
|
||||
|
||||
uint table_size = read_node(kg, &offset).x;
|
||||
uint table_size = read_node(kg, svm).x;
|
||||
|
||||
float fac = stack_load_float(stack, fac_offset);
|
||||
float3 color = stack_load_float3(stack, color_offset);
|
||||
float fac = stack_load_float(svm, fac_offset);
|
||||
float3 color = stack_load_float3(svm, color_offset);
|
||||
|
||||
const float min_x = __int_as_float(node.z), max_x = __int_as_float(node.w);
|
||||
const float range_x = max_x - min_x;
|
||||
const float3 relpos = (color - make_float3(min_x, min_x, min_x)) / range_x;
|
||||
|
||||
float r = rgb_ramp_lookup(kg, offset, relpos.x, true, extrapolate, table_size).x;
|
||||
float g = rgb_ramp_lookup(kg, offset, relpos.y, true, extrapolate, table_size).y;
|
||||
float b = rgb_ramp_lookup(kg, offset, relpos.z, true, extrapolate, table_size).z;
|
||||
float r = rgb_ramp_lookup(kg, svm->offset, relpos.x, true, extrapolate, table_size).x;
|
||||
float g = rgb_ramp_lookup(kg, svm->offset, relpos.y, true, extrapolate, table_size).y;
|
||||
float b = rgb_ramp_lookup(kg, svm->offset, relpos.z, true, extrapolate, table_size).z;
|
||||
|
||||
color = (1.0f - fac) * color + fac * make_float3(r, g, b);
|
||||
stack_store_float3(stack, out_offset, color);
|
||||
stack_store_float3(svm, out_offset, color);
|
||||
|
||||
offset += table_size;
|
||||
return offset;
|
||||
svm->offset += table_size;
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_curve(
|
||||
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
||||
ccl_device_noinline void svm_node_curve(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint fac_offset, value_in_offset, out_offset, extrapolate;
|
||||
svm_unpack_node_uchar4(node.y, &fac_offset, &value_in_offset, &out_offset, &extrapolate);
|
||||
|
||||
uint table_size = read_node(kg, &offset).x;
|
||||
uint table_size = read_node(kg, svm).x;
|
||||
|
||||
float fac = stack_load_float(stack, fac_offset);
|
||||
float in = stack_load_float(stack, value_in_offset);
|
||||
float fac = stack_load_float(svm, fac_offset);
|
||||
float in = stack_load_float(svm, value_in_offset);
|
||||
|
||||
const float min = __int_as_float(node.z), max = __int_as_float(node.w);
|
||||
const float range = max - min;
|
||||
const float relpos = (in - min) / range;
|
||||
|
||||
float v = float_ramp_lookup(kg, offset, relpos, true, extrapolate, table_size);
|
||||
float v = float_ramp_lookup(kg, svm->offset, relpos, true, extrapolate, table_size);
|
||||
|
||||
in = (1.0f - fac) * in + fac * v;
|
||||
stack_store_float(stack, out_offset, in);
|
||||
stack_store_float(svm, out_offset, in);
|
||||
|
||||
offset += table_size;
|
||||
return offset;
|
||||
svm->offset += table_size;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -8,7 +8,7 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_combine_color(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint color_type,
|
||||
uint inputs_stack_offsets,
|
||||
uint result_stack_offset)
|
||||
|
@ -17,25 +17,25 @@ ccl_device_noinline void svm_node_combine_color(KernelGlobals kg,
|
|||
svm_unpack_node_uchar3(
|
||||
inputs_stack_offsets, &red_stack_offset, &green_stack_offset, &blue_stack_offset);
|
||||
|
||||
float r = stack_load_float(stack, red_stack_offset);
|
||||
float g = stack_load_float(stack, green_stack_offset);
|
||||
float b = stack_load_float(stack, blue_stack_offset);
|
||||
float r = stack_load_float(svm, red_stack_offset);
|
||||
float g = stack_load_float(svm, green_stack_offset);
|
||||
float b = stack_load_float(svm, blue_stack_offset);
|
||||
|
||||
/* Combine, and convert back to RGB */
|
||||
float3 color = svm_combine_color((NodeCombSepColorType)color_type, make_float3(r, g, b));
|
||||
|
||||
if (stack_valid(result_stack_offset))
|
||||
stack_store_float3(stack, result_stack_offset, color);
|
||||
stack_store_float3(svm, result_stack_offset, color);
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_separate_color(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint color_type,
|
||||
uint input_stack_offset,
|
||||
uint results_stack_offsets)
|
||||
{
|
||||
float3 color = stack_load_float3(stack, input_stack_offset);
|
||||
float3 color = stack_load_float3(svm, input_stack_offset);
|
||||
|
||||
/* Convert color space */
|
||||
color = svm_separate_color((NodeCombSepColorType)color_type, color);
|
||||
|
@ -45,11 +45,11 @@ ccl_device_noinline void svm_node_separate_color(KernelGlobals kg,
|
|||
results_stack_offsets, &red_stack_offset, &green_stack_offset, &blue_stack_offset);
|
||||
|
||||
if (stack_valid(red_stack_offset))
|
||||
stack_store_float(stack, red_stack_offset, color.x);
|
||||
stack_store_float(svm, red_stack_offset, color.x);
|
||||
if (stack_valid(green_stack_offset))
|
||||
stack_store_float(stack, green_stack_offset, color.y);
|
||||
stack_store_float(svm, green_stack_offset, color.y);
|
||||
if (stack_valid(blue_stack_offset))
|
||||
stack_store_float(stack, blue_stack_offset, color.z);
|
||||
stack_store_float(svm, blue_stack_offset, color.z);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -6,52 +6,48 @@
|
|||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device_noinline int svm_node_combine_hsv(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint hue_in,
|
||||
uint saturation_in,
|
||||
uint value_in,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_combine_hsv(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint hue_in,
|
||||
uint saturation_in,
|
||||
uint value_in)
|
||||
{
|
||||
uint4 node1 = read_node(kg, &offset);
|
||||
uint4 node1 = read_node(kg, svm);
|
||||
uint color_out = node1.y;
|
||||
|
||||
float hue = stack_load_float(stack, hue_in);
|
||||
float saturation = stack_load_float(stack, saturation_in);
|
||||
float value = stack_load_float(stack, value_in);
|
||||
float hue = stack_load_float(svm, hue_in);
|
||||
float saturation = stack_load_float(svm, saturation_in);
|
||||
float value = stack_load_float(svm, value_in);
|
||||
|
||||
/* Combine, and convert back to RGB */
|
||||
float3 color = hsv_to_rgb(make_float3(hue, saturation, value));
|
||||
|
||||
if (stack_valid(color_out))
|
||||
stack_store_float3(stack, color_out, color);
|
||||
return offset;
|
||||
stack_store_float3(svm, color_out, color);
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_separate_hsv(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint color_in,
|
||||
uint hue_out,
|
||||
uint saturation_out,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_separate_hsv(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint color_in,
|
||||
uint hue_out,
|
||||
uint saturation_out)
|
||||
{
|
||||
uint4 node1 = read_node(kg, &offset);
|
||||
uint4 node1 = read_node(kg, svm);
|
||||
uint value_out = node1.y;
|
||||
|
||||
float3 color = stack_load_float3(stack, color_in);
|
||||
float3 color = stack_load_float3(svm, color_in);
|
||||
|
||||
/* Convert to HSV */
|
||||
color = rgb_to_hsv(color);
|
||||
|
||||
if (stack_valid(hue_out))
|
||||
stack_store_float(stack, hue_out, color.x);
|
||||
stack_store_float(svm, hue_out, color.x);
|
||||
if (stack_valid(saturation_out))
|
||||
stack_store_float(stack, saturation_out, color.y);
|
||||
stack_store_float(svm, saturation_out, color.y);
|
||||
if (stack_valid(value_out))
|
||||
stack_store_float(stack, value_out, color.z);
|
||||
return offset;
|
||||
stack_store_float(svm, value_out, color.z);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -9,32 +9,32 @@ CCL_NAMESPACE_BEGIN
|
|||
/* Vector combine / separate, used for the RGB and XYZ nodes */
|
||||
|
||||
ccl_device void svm_node_combine_vector(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint in_offset,
|
||||
uint vector_index,
|
||||
uint out_offset)
|
||||
{
|
||||
float vector = stack_load_float(stack, in_offset);
|
||||
float vector = stack_load_float(svm, in_offset);
|
||||
|
||||
if (stack_valid(out_offset))
|
||||
stack_store_float(stack, out_offset + vector_index, vector);
|
||||
stack_store_float(svm, out_offset + vector_index, vector);
|
||||
}
|
||||
|
||||
ccl_device void svm_node_separate_vector(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint ivector_offset,
|
||||
uint vector_index,
|
||||
uint out_offset)
|
||||
{
|
||||
float3 vector = stack_load_float3(stack, ivector_offset);
|
||||
float3 vector = stack_load_float3(svm, ivector_offset);
|
||||
|
||||
if (stack_valid(out_offset)) {
|
||||
if (vector_index == 0)
|
||||
stack_store_float(stack, out_offset, vector.x);
|
||||
stack_store_float(svm, out_offset, vector.x);
|
||||
else if (vector_index == 1)
|
||||
stack_store_float(stack, out_offset, vector.y);
|
||||
stack_store_float(svm, out_offset, vector.y);
|
||||
else
|
||||
stack_store_float(stack, out_offset, vector.z);
|
||||
stack_store_float(svm, out_offset, vector.z);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -202,19 +202,18 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals kg,
|
|||
return xyz_to_rgb_clamped(kg, xyz);
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_tex_sky(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
ccl_private float *stack,
|
||||
uint4 node,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_tex_sky(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
/* Load data */
|
||||
uint dir_offset = node.y;
|
||||
uint out_offset = node.z;
|
||||
int sky_model = node.w;
|
||||
|
||||
float3 dir = stack_load_float3(stack, dir_offset);
|
||||
float3 dir = stack_load_float3(svm, dir_offset);
|
||||
float3 f;
|
||||
|
||||
/* Preetham and Hosek share the same data */
|
||||
|
@ -223,49 +222,49 @@ ccl_device_noinline int svm_node_tex_sky(KernelGlobals kg,
|
|||
float sunphi, suntheta, radiance_x, radiance_y, radiance_z;
|
||||
float config_x[9], config_y[9], config_z[9];
|
||||
|
||||
float4 data = read_node_float(kg, &offset);
|
||||
float4 data = read_node_float(kg, svm);
|
||||
sunphi = data.x;
|
||||
suntheta = data.y;
|
||||
radiance_x = data.z;
|
||||
radiance_y = data.w;
|
||||
|
||||
data = read_node_float(kg, &offset);
|
||||
data = read_node_float(kg, svm);
|
||||
radiance_z = data.x;
|
||||
config_x[0] = data.y;
|
||||
config_x[1] = data.z;
|
||||
config_x[2] = data.w;
|
||||
|
||||
data = read_node_float(kg, &offset);
|
||||
data = read_node_float(kg, svm);
|
||||
config_x[3] = data.x;
|
||||
config_x[4] = data.y;
|
||||
config_x[5] = data.z;
|
||||
config_x[6] = data.w;
|
||||
|
||||
data = read_node_float(kg, &offset);
|
||||
data = read_node_float(kg, svm);
|
||||
config_x[7] = data.x;
|
||||
config_x[8] = data.y;
|
||||
config_y[0] = data.z;
|
||||
config_y[1] = data.w;
|
||||
|
||||
data = read_node_float(kg, &offset);
|
||||
data = read_node_float(kg, svm);
|
||||
config_y[2] = data.x;
|
||||
config_y[3] = data.y;
|
||||
config_y[4] = data.z;
|
||||
config_y[5] = data.w;
|
||||
|
||||
data = read_node_float(kg, &offset);
|
||||
data = read_node_float(kg, svm);
|
||||
config_y[6] = data.x;
|
||||
config_y[7] = data.y;
|
||||
config_y[8] = data.z;
|
||||
config_z[0] = data.w;
|
||||
|
||||
data = read_node_float(kg, &offset);
|
||||
data = read_node_float(kg, svm);
|
||||
config_z[1] = data.x;
|
||||
config_z[2] = data.y;
|
||||
config_z[3] = data.z;
|
||||
config_z[4] = data.w;
|
||||
|
||||
data = read_node_float(kg, &offset);
|
||||
data = read_node_float(kg, svm);
|
||||
config_z[5] = data.x;
|
||||
config_z[6] = data.y;
|
||||
config_z[7] = data.z;
|
||||
|
@ -302,18 +301,18 @@ ccl_device_noinline int svm_node_tex_sky(KernelGlobals kg,
|
|||
/* Define variables */
|
||||
float nishita_data[4];
|
||||
|
||||
float4 data = read_node_float(kg, &offset);
|
||||
float4 data = read_node_float(kg, svm);
|
||||
float3 pixel_bottom = make_float3(data.x, data.y, data.z);
|
||||
float3 pixel_top;
|
||||
pixel_top.x = data.w;
|
||||
|
||||
data = read_node_float(kg, &offset);
|
||||
data = read_node_float(kg, svm);
|
||||
pixel_top.y = data.x;
|
||||
pixel_top.z = data.y;
|
||||
nishita_data[0] = data.z;
|
||||
nishita_data[1] = data.w;
|
||||
|
||||
data = read_node_float(kg, &offset);
|
||||
data = read_node_float(kg, svm);
|
||||
nishita_data[2] = data.x;
|
||||
nishita_data[3] = data.y;
|
||||
uint texture_id = __float_as_uint(data.z);
|
||||
|
@ -323,8 +322,7 @@ ccl_device_noinline int svm_node_tex_sky(KernelGlobals kg,
|
|||
kg, dir, path_flag, pixel_bottom, pixel_top, nishita_data, texture_id);
|
||||
}
|
||||
|
||||
stack_store_float3(stack, out_offset, f);
|
||||
return offset;
|
||||
stack_store_float3(svm, out_offset, f);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -29,62 +29,69 @@
|
|||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
typedef struct SVMState {
|
||||
float stack[SVM_STACK_SIZE];
|
||||
int offset;
|
||||
float3 closure_weight;
|
||||
int layer_albedo_offset;
|
||||
} SVMState;
|
||||
|
||||
/* Stack */
|
||||
|
||||
ccl_device_inline float3 stack_load_float3(ccl_private float *stack, uint a)
|
||||
ccl_device_inline float3 stack_load_float3(ccl_private SVMState *svm, uint a)
|
||||
{
|
||||
kernel_assert(a + 2 < SVM_STACK_SIZE);
|
||||
|
||||
ccl_private float *stack_a = stack + a;
|
||||
ccl_private float *stack_a = svm->stack + a;
|
||||
return make_float3(stack_a[0], stack_a[1], stack_a[2]);
|
||||
}
|
||||
|
||||
ccl_device_inline void stack_store_float3(ccl_private float *stack, uint a, float3 f)
|
||||
ccl_device_inline void stack_store_float3(ccl_private SVMState *svm, uint a, float3 f)
|
||||
{
|
||||
kernel_assert(a + 2 < SVM_STACK_SIZE);
|
||||
|
||||
ccl_private float *stack_a = stack + a;
|
||||
ccl_private float *stack_a = svm->stack + a;
|
||||
stack_a[0] = f.x;
|
||||
stack_a[1] = f.y;
|
||||
stack_a[2] = f.z;
|
||||
}
|
||||
|
||||
ccl_device_inline float stack_load_float(ccl_private float *stack, uint a)
|
||||
ccl_device_inline float stack_load_float(ccl_private SVMState *svm, uint a)
|
||||
{
|
||||
kernel_assert(a < SVM_STACK_SIZE);
|
||||
|
||||
return stack[a];
|
||||
return svm->stack[a];
|
||||
}
|
||||
|
||||
ccl_device_inline float stack_load_float_default(ccl_private float *stack, uint a, uint value)
|
||||
ccl_device_inline float stack_load_float_default(ccl_private SVMState *svm, uint a, uint value)
|
||||
{
|
||||
return (a == (uint)SVM_STACK_INVALID) ? __uint_as_float(value) : stack_load_float(stack, a);
|
||||
return (a == (uint)SVM_STACK_INVALID) ? __uint_as_float(value) : stack_load_float(svm, a);
|
||||
}
|
||||
|
||||
ccl_device_inline void stack_store_float(ccl_private float *stack, uint a, float f)
|
||||
ccl_device_inline void stack_store_float(ccl_private SVMState *svm, uint a, float f)
|
||||
{
|
||||
kernel_assert(a < SVM_STACK_SIZE);
|
||||
|
||||
stack[a] = f;
|
||||
svm->stack[a] = f;
|
||||
}
|
||||
|
||||
ccl_device_inline int stack_load_int(ccl_private float *stack, uint a)
|
||||
ccl_device_inline int stack_load_int(ccl_private SVMState *svm, uint a)
|
||||
{
|
||||
kernel_assert(a < SVM_STACK_SIZE);
|
||||
|
||||
return __float_as_int(stack[a]);
|
||||
return __float_as_int(svm->stack[a]);
|
||||
}
|
||||
|
||||
ccl_device_inline int stack_load_int_default(ccl_private float *stack, uint a, uint value)
|
||||
ccl_device_inline int stack_load_int_default(ccl_private SVMState *svm, uint a, uint value)
|
||||
{
|
||||
return (a == (uint)SVM_STACK_INVALID) ? (int)value : stack_load_int(stack, a);
|
||||
return (a == (uint)SVM_STACK_INVALID) ? (int)value : stack_load_int(svm, a);
|
||||
}
|
||||
|
||||
ccl_device_inline void stack_store_int(ccl_private float *stack, uint a, int i)
|
||||
ccl_device_inline void stack_store_int(ccl_private SVMState *svm, uint a, int i)
|
||||
{
|
||||
kernel_assert(a < SVM_STACK_SIZE);
|
||||
|
||||
stack[a] = __int_as_float(i);
|
||||
svm->stack[a] = __int_as_float(i);
|
||||
}
|
||||
|
||||
ccl_device_inline bool stack_valid(uint a)
|
||||
|
@ -94,21 +101,21 @@ ccl_device_inline bool stack_valid(uint a)
|
|||
|
||||
/* Reading Nodes */
|
||||
|
||||
ccl_device_inline uint4 read_node(KernelGlobals kg, ccl_private int *offset)
|
||||
ccl_device_inline uint4 read_node(KernelGlobals kg, ccl_private SVMState *svm)
|
||||
{
|
||||
uint4 node = kernel_data_fetch(svm_nodes, *offset);
|
||||
(*offset)++;
|
||||
uint4 node = kernel_data_fetch(svm_nodes, svm->offset);
|
||||
svm->offset++;
|
||||
return node;
|
||||
}
|
||||
|
||||
ccl_device_inline float4 read_node_float(KernelGlobals kg, ccl_private int *offset)
|
||||
ccl_device_inline float4 read_node_float(KernelGlobals kg, ccl_private SVMState *svm)
|
||||
{
|
||||
uint4 node = kernel_data_fetch(svm_nodes, *offset);
|
||||
uint4 node = kernel_data_fetch(svm_nodes, svm->offset);
|
||||
float4 f = make_float4(__uint_as_float(node.x),
|
||||
__uint_as_float(node.y),
|
||||
__uint_as_float(node.z),
|
||||
__uint_as_float(node.w));
|
||||
(*offset)++;
|
||||
svm->offset++;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
@ -222,12 +229,12 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
|
|||
ccl_global float *render_buffer,
|
||||
uint32_t path_flag)
|
||||
{
|
||||
float stack[SVM_STACK_SIZE];
|
||||
Spectrum closure_weight;
|
||||
int offset = sd->shader & SHADER_MASK;
|
||||
SVMState svm;
|
||||
svm.offset = sd->shader & SHADER_MASK;
|
||||
svm.layer_albedo_offset = SVM_STACK_INVALID;
|
||||
|
||||
while (1) {
|
||||
uint4 node = read_node(kg, &offset);
|
||||
uint4 node = read_node(kg, &svm);
|
||||
|
||||
switch (node.x) {
|
||||
SVM_CASE(NODE_END)
|
||||
|
@ -235,344 +242,347 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
|
|||
SVM_CASE(NODE_SHADER_JUMP)
|
||||
{
|
||||
if (type == SHADER_TYPE_SURFACE)
|
||||
offset = node.y;
|
||||
svm.offset = node.y;
|
||||
else if (type == SHADER_TYPE_VOLUME)
|
||||
offset = node.z;
|
||||
svm.offset = node.z;
|
||||
else if (type == SHADER_TYPE_DISPLACEMENT)
|
||||
offset = node.w;
|
||||
svm.offset = node.w;
|
||||
else
|
||||
return;
|
||||
break;
|
||||
}
|
||||
SVM_CASE(NODE_CLOSURE_BSDF)
|
||||
offset = svm_node_closure_bsdf<node_feature_mask, type>(
|
||||
kg, sd, stack, closure_weight, node, path_flag, offset);
|
||||
svm_node_closure_bsdf<node_feature_mask, type>(kg, sd, &svm, node, path_flag);
|
||||
break;
|
||||
SVM_CASE(NODE_CLOSURE_EMISSION)
|
||||
IF_KERNEL_NODES_FEATURE(EMISSION)
|
||||
{
|
||||
svm_node_closure_emission(sd, stack, closure_weight, node);
|
||||
svm_node_closure_emission(sd, &svm, node);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_CLOSURE_BACKGROUND)
|
||||
IF_KERNEL_NODES_FEATURE(EMISSION)
|
||||
{
|
||||
svm_node_closure_background(sd, stack, closure_weight, node);
|
||||
svm_node_closure_background(sd, &svm, node);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_CLOSURE_SET_WEIGHT)
|
||||
svm_node_closure_set_weight(sd, &closure_weight, node.y, node.z, node.w);
|
||||
svm_node_closure_set_weight(sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_CLOSURE_WEIGHT)
|
||||
svm_node_closure_weight(sd, stack, &closure_weight, node.y);
|
||||
svm_node_closure_weight(sd, &svm, node.y);
|
||||
break;
|
||||
SVM_CASE(NODE_EMISSION_WEIGHT)
|
||||
IF_KERNEL_NODES_FEATURE(EMISSION)
|
||||
{
|
||||
svm_node_emission_weight(kg, sd, stack, &closure_weight, node);
|
||||
svm_node_emission_weight(kg, sd, &svm, node);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_MIX_CLOSURE)
|
||||
svm_node_mix_closure(sd, stack, node);
|
||||
svm_node_mix_closure(sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_LAYER_CLOSURE_ACCUMULATE)
|
||||
svm_node_layer_closure_accumulate(sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_LAYER_CLOSURE)
|
||||
svm_node_layer_closure(sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_JUMP_IF_ZERO)
|
||||
if (stack_load_float(stack, node.z) <= 0.0f)
|
||||
offset += node.y;
|
||||
if (stack_load_float(&svm, node.z) <= 0.0f)
|
||||
svm.offset += node.y;
|
||||
break;
|
||||
SVM_CASE(NODE_JUMP_IF_ONE)
|
||||
if (stack_load_float(stack, node.z) >= 1.0f)
|
||||
offset += node.y;
|
||||
if (stack_load_float(&svm, node.z) >= 1.0f)
|
||||
svm.offset += node.y;
|
||||
break;
|
||||
SVM_CASE(NODE_GEOMETRY)
|
||||
svm_node_geometry(kg, sd, stack, node.y, node.z);
|
||||
svm_node_geometry(kg, sd, &svm, node.y, node.z);
|
||||
break;
|
||||
SVM_CASE(NODE_CONVERT)
|
||||
svm_node_convert(kg, sd, stack, node.y, node.z, node.w);
|
||||
svm_node_convert(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_COORD)
|
||||
offset = svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
|
||||
svm_node_tex_coord(kg, sd, path_flag, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_VALUE_F)
|
||||
svm_node_value_f(kg, sd, stack, node.y, node.z);
|
||||
svm_node_value_f(kg, sd, &svm, node.y, node.z);
|
||||
break;
|
||||
SVM_CASE(NODE_VALUE_V)
|
||||
offset = svm_node_value_v(kg, sd, stack, node.y, offset);
|
||||
svm_node_value_v(kg, sd, &svm, node.y);
|
||||
break;
|
||||
SVM_CASE(NODE_ATTR)
|
||||
svm_node_attr<node_feature_mask>(kg, sd, stack, node);
|
||||
svm_node_attr<node_feature_mask>(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_VERTEX_COLOR)
|
||||
svm_node_vertex_color(kg, sd, stack, node.y, node.z, node.w);
|
||||
svm_node_vertex_color(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_GEOMETRY_BUMP_DX)
|
||||
IF_KERNEL_NODES_FEATURE(BUMP)
|
||||
{
|
||||
svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z);
|
||||
svm_node_geometry_bump_dx(kg, sd, &svm, node.y, node.z);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_GEOMETRY_BUMP_DY)
|
||||
IF_KERNEL_NODES_FEATURE(BUMP)
|
||||
{
|
||||
svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z);
|
||||
svm_node_geometry_bump_dy(kg, sd, &svm, node.y, node.z);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_SET_DISPLACEMENT)
|
||||
svm_node_set_displacement<node_feature_mask>(kg, sd, stack, node.y);
|
||||
svm_node_set_displacement<node_feature_mask>(kg, sd, &svm, node.y);
|
||||
break;
|
||||
SVM_CASE(NODE_DISPLACEMENT)
|
||||
svm_node_displacement<node_feature_mask>(kg, sd, stack, node);
|
||||
svm_node_displacement<node_feature_mask>(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_VECTOR_DISPLACEMENT)
|
||||
offset = svm_node_vector_displacement<node_feature_mask>(kg, sd, stack, node, offset);
|
||||
svm_node_vector_displacement<node_feature_mask>(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_IMAGE)
|
||||
offset = svm_node_tex_image(kg, sd, stack, node, offset);
|
||||
svm_node_tex_image(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_IMAGE_BOX)
|
||||
svm_node_tex_image_box(kg, sd, stack, node);
|
||||
svm_node_tex_image_box(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_NOISE)
|
||||
offset = svm_node_tex_noise(kg, sd, stack, node.y, node.z, node.w, offset);
|
||||
svm_node_tex_noise(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_SET_BUMP)
|
||||
svm_node_set_bump<node_feature_mask>(kg, sd, stack, node);
|
||||
svm_node_set_bump<node_feature_mask>(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_ATTR_BUMP_DX)
|
||||
IF_KERNEL_NODES_FEATURE(BUMP)
|
||||
{
|
||||
svm_node_attr_bump_dx(kg, sd, stack, node);
|
||||
svm_node_attr_bump_dx(kg, sd, &svm, node);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_ATTR_BUMP_DY)
|
||||
IF_KERNEL_NODES_FEATURE(BUMP)
|
||||
{
|
||||
svm_node_attr_bump_dy(kg, sd, stack, node);
|
||||
svm_node_attr_bump_dy(kg, sd, &svm, node);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_VERTEX_COLOR_BUMP_DX)
|
||||
IF_KERNEL_NODES_FEATURE(BUMP)
|
||||
{
|
||||
svm_node_vertex_color_bump_dx(kg, sd, stack, node.y, node.z, node.w);
|
||||
svm_node_vertex_color_bump_dx(kg, sd, &svm, node.y, node.z, node.w);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_VERTEX_COLOR_BUMP_DY)
|
||||
IF_KERNEL_NODES_FEATURE(BUMP)
|
||||
{
|
||||
svm_node_vertex_color_bump_dy(kg, sd, stack, node.y, node.z, node.w);
|
||||
svm_node_vertex_color_bump_dy(kg, sd, &svm, node.y, node.z, node.w);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_COORD_BUMP_DX)
|
||||
IF_KERNEL_NODES_FEATURE(BUMP)
|
||||
{
|
||||
offset = svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node, offset);
|
||||
svm_node_tex_coord_bump_dx(kg, sd, path_flag, &svm, node);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_COORD_BUMP_DY)
|
||||
IF_KERNEL_NODES_FEATURE(BUMP)
|
||||
{
|
||||
offset = svm_node_tex_coord_bump_dy(kg, sd, path_flag, stack, node, offset);
|
||||
svm_node_tex_coord_bump_dy(kg, sd, path_flag, &svm, node);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_CLOSURE_SET_NORMAL)
|
||||
IF_KERNEL_NODES_FEATURE(BUMP)
|
||||
{
|
||||
svm_node_set_normal(kg, sd, stack, node.y, node.z);
|
||||
svm_node_set_normal(kg, sd, &svm, node.y, node.z);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_ENTER_BUMP_EVAL)
|
||||
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
|
||||
{
|
||||
svm_node_enter_bump_eval(kg, sd, stack, node.y);
|
||||
svm_node_enter_bump_eval(kg, sd, &svm, node.y);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_LEAVE_BUMP_EVAL)
|
||||
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
|
||||
{
|
||||
svm_node_leave_bump_eval(kg, sd, stack, node.y);
|
||||
svm_node_leave_bump_eval(kg, sd, &svm, node.y);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_HSV)
|
||||
svm_node_hsv(kg, sd, stack, node);
|
||||
svm_node_hsv(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_CLOSURE_HOLDOUT)
|
||||
svm_node_closure_holdout(sd, stack, closure_weight, node);
|
||||
svm_node_closure_holdout(sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_FRESNEL)
|
||||
svm_node_fresnel(sd, stack, node.y, node.z, node.w);
|
||||
svm_node_fresnel(sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_LAYER_WEIGHT)
|
||||
svm_node_layer_weight(sd, stack, node);
|
||||
svm_node_layer_weight(sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_CLOSURE_VOLUME)
|
||||
IF_KERNEL_NODES_FEATURE(VOLUME)
|
||||
{
|
||||
svm_node_closure_volume<type>(kg, sd, stack, closure_weight, node);
|
||||
svm_node_closure_volume<type>(kg, sd, &svm, node);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_PRINCIPLED_VOLUME)
|
||||
IF_KERNEL_NODES_FEATURE(VOLUME)
|
||||
{
|
||||
offset = svm_node_principled_volume<type>(
|
||||
kg, sd, stack, closure_weight, node, path_flag, offset);
|
||||
svm_node_principled_volume<type>(kg, sd, &svm, node, path_flag);
|
||||
}
|
||||
break;
|
||||
SVM_CASE(NODE_MATH)
|
||||
svm_node_math(kg, sd, stack, node.y, node.z, node.w);
|
||||
svm_node_math(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_VECTOR_MATH)
|
||||
offset = svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, offset);
|
||||
svm_node_vector_math(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_RGB_RAMP)
|
||||
offset = svm_node_rgb_ramp(kg, sd, stack, node, offset);
|
||||
svm_node_rgb_ramp(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_GAMMA)
|
||||
svm_node_gamma(sd, stack, node.y, node.z, node.w);
|
||||
svm_node_gamma(sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_BRIGHTCONTRAST)
|
||||
svm_node_brightness(sd, stack, node.y, node.z, node.w);
|
||||
svm_node_brightness(sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_LIGHT_PATH)
|
||||
svm_node_light_path<node_feature_mask>(kg, state, sd, stack, node.y, node.z, path_flag);
|
||||
svm_node_light_path<node_feature_mask>(kg, state, sd, &svm, node.y, node.z, path_flag);
|
||||
break;
|
||||
SVM_CASE(NODE_OBJECT_INFO)
|
||||
svm_node_object_info(kg, sd, stack, node.y, node.z);
|
||||
svm_node_object_info(kg, sd, &svm, node.y, node.z);
|
||||
break;
|
||||
SVM_CASE(NODE_PARTICLE_INFO)
|
||||
svm_node_particle_info(kg, sd, stack, node.y, node.z);
|
||||
svm_node_particle_info(kg, sd, &svm, node.y, node.z);
|
||||
break;
|
||||
#if defined(__HAIR__)
|
||||
SVM_CASE(NODE_HAIR_INFO)
|
||||
svm_node_hair_info(kg, sd, stack, node.y, node.z);
|
||||
svm_node_hair_info(kg, sd, &svm, node.y, node.z);
|
||||
break;
|
||||
#endif
|
||||
#if defined(__POINTCLOUD__)
|
||||
SVM_CASE(NODE_POINT_INFO)
|
||||
svm_node_point_info(kg, sd, stack, node.y, node.z);
|
||||
svm_node_point_info(kg, sd, &svm, node.y, node.z);
|
||||
break;
|
||||
#endif
|
||||
SVM_CASE(NODE_TEXTURE_MAPPING)
|
||||
offset = svm_node_texture_mapping(kg, sd, stack, node.y, node.z, offset);
|
||||
svm_node_texture_mapping(kg, sd, &svm, node.y, node.z);
|
||||
break;
|
||||
SVM_CASE(NODE_MAPPING)
|
||||
svm_node_mapping(kg, sd, stack, node.y, node.z, node.w);
|
||||
svm_node_mapping(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_MIN_MAX)
|
||||
offset = svm_node_min_max(kg, sd, stack, node.y, node.z, offset);
|
||||
svm_node_min_max(kg, sd, &svm, node.y, node.z);
|
||||
break;
|
||||
SVM_CASE(NODE_CAMERA)
|
||||
svm_node_camera(kg, sd, stack, node.y, node.z, node.w);
|
||||
svm_node_camera(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_ENVIRONMENT)
|
||||
svm_node_tex_environment(kg, sd, stack, node);
|
||||
svm_node_tex_environment(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_SKY)
|
||||
offset = svm_node_tex_sky(kg, sd, path_flag, stack, node, offset);
|
||||
svm_node_tex_sky(kg, sd, path_flag, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_GRADIENT)
|
||||
svm_node_tex_gradient(sd, stack, node);
|
||||
svm_node_tex_gradient(sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_VORONOI)
|
||||
offset = svm_node_tex_voronoi<node_feature_mask>(
|
||||
kg, sd, stack, node.y, node.z, node.w, offset);
|
||||
svm_node_tex_voronoi<node_feature_mask>(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_MUSGRAVE)
|
||||
offset = svm_node_tex_musgrave(kg, sd, stack, node.y, node.z, node.w, offset);
|
||||
svm_node_tex_musgrave(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_WAVE)
|
||||
offset = svm_node_tex_wave(kg, sd, stack, node, offset);
|
||||
svm_node_tex_wave(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_MAGIC)
|
||||
offset = svm_node_tex_magic(kg, sd, stack, node, offset);
|
||||
svm_node_tex_magic(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_CHECKER)
|
||||
svm_node_tex_checker(kg, sd, stack, node);
|
||||
svm_node_tex_checker(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_BRICK)
|
||||
offset = svm_node_tex_brick(kg, sd, stack, node, offset);
|
||||
svm_node_tex_brick(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_TEX_WHITE_NOISE)
|
||||
svm_node_tex_white_noise(kg, sd, stack, node.y, node.z, node.w);
|
||||
svm_node_tex_white_noise(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_NORMAL)
|
||||
offset = svm_node_normal(kg, sd, stack, node.y, node.z, node.w, offset);
|
||||
svm_node_normal(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_LIGHT_FALLOFF)
|
||||
svm_node_light_falloff(sd, stack, node);
|
||||
svm_node_light_falloff(sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_IES)
|
||||
svm_node_ies(kg, sd, stack, node);
|
||||
svm_node_ies(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_CURVES)
|
||||
offset = svm_node_curves(kg, sd, stack, node, offset);
|
||||
svm_node_curves(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_FLOAT_CURVE)
|
||||
offset = svm_node_curve(kg, sd, stack, node, offset);
|
||||
svm_node_curve(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_TANGENT)
|
||||
svm_node_tangent(kg, sd, stack, node);
|
||||
svm_node_tangent(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_NORMAL_MAP)
|
||||
svm_node_normal_map(kg, sd, stack, node);
|
||||
svm_node_normal_map(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_INVERT)
|
||||
svm_node_invert(sd, stack, node.y, node.z, node.w);
|
||||
svm_node_invert(sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_MIX)
|
||||
offset = svm_node_mix(kg, sd, stack, node.y, node.z, node.w, offset);
|
||||
svm_node_mix(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_SEPARATE_COLOR)
|
||||
svm_node_separate_color(kg, sd, stack, node.y, node.z, node.w);
|
||||
svm_node_separate_color(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_COMBINE_COLOR)
|
||||
svm_node_combine_color(kg, sd, stack, node.y, node.z, node.w);
|
||||
svm_node_combine_color(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_SEPARATE_VECTOR)
|
||||
svm_node_separate_vector(sd, stack, node.y, node.z, node.w);
|
||||
svm_node_separate_vector(sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_COMBINE_VECTOR)
|
||||
svm_node_combine_vector(sd, stack, node.y, node.z, node.w);
|
||||
svm_node_combine_vector(sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_SEPARATE_HSV)
|
||||
offset = svm_node_separate_hsv(kg, sd, stack, node.y, node.z, node.w, offset);
|
||||
svm_node_separate_hsv(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_COMBINE_HSV)
|
||||
offset = svm_node_combine_hsv(kg, sd, stack, node.y, node.z, node.w, offset);
|
||||
svm_node_combine_hsv(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_VECTOR_ROTATE)
|
||||
svm_node_vector_rotate(sd, stack, node.y, node.z, node.w);
|
||||
svm_node_vector_rotate(sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_VECTOR_TRANSFORM)
|
||||
svm_node_vector_transform(kg, sd, stack, node);
|
||||
svm_node_vector_transform(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_WIREFRAME)
|
||||
svm_node_wireframe(kg, sd, stack, node);
|
||||
svm_node_wireframe(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_WAVELENGTH)
|
||||
svm_node_wavelength(kg, sd, stack, node.y, node.z);
|
||||
svm_node_wavelength(kg, sd, &svm, node.y, node.z);
|
||||
break;
|
||||
SVM_CASE(NODE_BLACKBODY)
|
||||
svm_node_blackbody(kg, sd, stack, node.y, node.z);
|
||||
svm_node_blackbody(kg, sd, &svm, node.y, node.z);
|
||||
break;
|
||||
SVM_CASE(NODE_MAP_RANGE)
|
||||
offset = svm_node_map_range(kg, sd, stack, node.y, node.z, node.w, offset);
|
||||
svm_node_map_range(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_VECTOR_MAP_RANGE)
|
||||
offset = svm_node_vector_map_range(kg, sd, stack, node.y, node.z, node.w, offset);
|
||||
svm_node_vector_map_range(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_CLAMP)
|
||||
offset = svm_node_clamp(kg, sd, stack, node.y, node.z, node.w, offset);
|
||||
svm_node_clamp(kg, sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
#ifdef __SHADER_RAYTRACE__
|
||||
SVM_CASE(NODE_BEVEL)
|
||||
svm_node_bevel<node_feature_mask>(kg, state, sd, stack, node);
|
||||
svm_node_bevel<node_feature_mask>(kg, state, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_AMBIENT_OCCLUSION)
|
||||
svm_node_ao<node_feature_mask>(kg, state, sd, stack, node);
|
||||
svm_node_ao<node_feature_mask>(kg, state, sd, &svm, node);
|
||||
break;
|
||||
#endif
|
||||
|
||||
SVM_CASE(NODE_TEX_VOXEL)
|
||||
offset = svm_node_tex_voxel<node_feature_mask>(kg, sd, stack, node, offset);
|
||||
svm_node_tex_voxel<node_feature_mask>(kg, sd, &svm, node);
|
||||
break;
|
||||
SVM_CASE(NODE_AOV_START)
|
||||
if (!svm_node_aov_check(path_flag, render_buffer)) {
|
||||
|
@ -580,22 +590,22 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
|
|||
}
|
||||
break;
|
||||
SVM_CASE(NODE_AOV_COLOR)
|
||||
svm_node_aov_color<node_feature_mask>(kg, state, sd, stack, node, render_buffer);
|
||||
svm_node_aov_color<node_feature_mask>(kg, state, sd, &svm, node, render_buffer);
|
||||
break;
|
||||
SVM_CASE(NODE_AOV_VALUE)
|
||||
svm_node_aov_value<node_feature_mask>(kg, state, sd, stack, node, render_buffer);
|
||||
svm_node_aov_value<node_feature_mask>(kg, state, sd, &svm, node, render_buffer);
|
||||
break;
|
||||
SVM_CASE(NODE_MIX_COLOR)
|
||||
svm_node_mix_color(sd, stack, node.y, node.z, node.w);
|
||||
svm_node_mix_color(sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_MIX_FLOAT)
|
||||
svm_node_mix_float(sd, stack, node.y, node.z, node.w);
|
||||
svm_node_mix_float(sd, &svm, node.y, node.z, node.w);
|
||||
break;
|
||||
SVM_CASE(NODE_MIX_VECTOR)
|
||||
svm_node_mix_vector(sd, stack, node.y, node.z);
|
||||
svm_node_mix_vector(sd, &svm, node.y, node.z);
|
||||
break;
|
||||
SVM_CASE(NODE_MIX_VECTOR_NON_UNIFORM)
|
||||
svm_node_mix_vector_non_uniform(sd, stack, node.y, node.z);
|
||||
svm_node_mix_vector_non_uniform(sd, &svm, node.y, node.z);
|
||||
break;
|
||||
default:
|
||||
kernel_assert(!"Unknown node type was passed to the SVM machine");
|
||||
|
|
|
@ -12,12 +12,11 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
/* Texture Coordinate Node */
|
||||
|
||||
ccl_device_noinline int svm_node_tex_coord(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
ccl_private float *stack,
|
||||
uint4 node,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_tex_coord(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
float3 data = zero_float3();
|
||||
uint type = node.y;
|
||||
|
@ -33,9 +32,9 @@ ccl_device_noinline int svm_node_tex_coord(KernelGlobals kg,
|
|||
}
|
||||
else {
|
||||
Transform tfm;
|
||||
tfm.x = read_node_float(kg, &offset);
|
||||
tfm.y = read_node_float(kg, &offset);
|
||||
tfm.z = read_node_float(kg, &offset);
|
||||
tfm.x = read_node_float(kg, svm);
|
||||
tfm.y = read_node_float(kg, svm);
|
||||
tfm.z = read_node_float(kg, svm);
|
||||
data = transform_point(&tfm, data);
|
||||
}
|
||||
break;
|
||||
|
@ -89,16 +88,14 @@ ccl_device_noinline int svm_node_tex_coord(KernelGlobals kg,
|
|||
}
|
||||
}
|
||||
|
||||
stack_store_float3(stack, out_offset, data);
|
||||
return offset;
|
||||
stack_store_float3(svm, out_offset, data);
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
ccl_private float *stack,
|
||||
uint4 node,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_tex_coord_bump_dx(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
float3 data = zero_float3();
|
||||
|
@ -115,9 +112,9 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg,
|
|||
}
|
||||
else {
|
||||
Transform tfm;
|
||||
tfm.x = read_node_float(kg, &offset);
|
||||
tfm.y = read_node_float(kg, &offset);
|
||||
tfm.z = read_node_float(kg, &offset);
|
||||
tfm.x = read_node_float(kg, svm);
|
||||
tfm.y = read_node_float(kg, svm);
|
||||
tfm.z = read_node_float(kg, svm);
|
||||
data = transform_point(&tfm, data);
|
||||
}
|
||||
break;
|
||||
|
@ -171,19 +168,17 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg,
|
|||
}
|
||||
}
|
||||
|
||||
stack_store_float3(stack, out_offset, data);
|
||||
return offset;
|
||||
stack_store_float3(svm, out_offset, data);
|
||||
#else
|
||||
return svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
|
||||
svm_node_tex_coord(kg, sd, path_flag, stack, node);
|
||||
#endif
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
ccl_private float *stack,
|
||||
uint4 node,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_tex_coord_bump_dy(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
float3 data = zero_float3();
|
||||
|
@ -200,9 +195,9 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg,
|
|||
}
|
||||
else {
|
||||
Transform tfm;
|
||||
tfm.x = read_node_float(kg, &offset);
|
||||
tfm.y = read_node_float(kg, &offset);
|
||||
tfm.z = read_node_float(kg, &offset);
|
||||
tfm.x = read_node_float(kg, svm);
|
||||
tfm.y = read_node_float(kg, svm);
|
||||
tfm.z = read_node_float(kg, svm);
|
||||
data = transform_point(&tfm, data);
|
||||
}
|
||||
break;
|
||||
|
@ -256,32 +251,31 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg,
|
|||
}
|
||||
}
|
||||
|
||||
stack_store_float3(stack, out_offset, data);
|
||||
return offset;
|
||||
stack_store_float3(svm, out_offset, data);
|
||||
#else
|
||||
return svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
|
||||
svm_node_tex_coord(kg, sd, path_flag, stack, node);
|
||||
#endif
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_normal_map(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint color_offset, strength_offset, normal_offset, space;
|
||||
svm_unpack_node_uchar4(node.y, &color_offset, &strength_offset, &normal_offset, &space);
|
||||
|
||||
float3 color = stack_load_float3(stack, color_offset);
|
||||
float3 color = stack_load_float3(svm, color_offset);
|
||||
color = 2.0f * make_float3(color.x - 0.5f, color.y - 0.5f, color.z - 0.5f);
|
||||
|
||||
bool is_backfacing = (sd->flag & SD_BACKFACING) != 0;
|
||||
float3 N;
|
||||
float strength = stack_load_float(stack, strength_offset);
|
||||
float strength = stack_load_float(svm, strength_offset);
|
||||
if (space == NODE_NORMAL_MAP_TANGENT) {
|
||||
/* tangent space */
|
||||
if (sd->object == OBJECT_NONE || (sd->type & PRIMITIVE_TRIANGLE) == 0) {
|
||||
/* Fallback to unperturbed normal. */
|
||||
stack_store_float3(stack, normal_offset, sd->N);
|
||||
stack_store_float3(svm, normal_offset, sd->N);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -291,7 +285,7 @@ ccl_device_noinline void svm_node_normal_map(KernelGlobals kg,
|
|||
|
||||
if (attr.offset == ATTR_STD_NOT_FOUND || attr_sign.offset == ATTR_STD_NOT_FOUND) {
|
||||
/* Fallback to unperturbed normal. */
|
||||
stack_store_float3(stack, normal_offset, sd->N);
|
||||
stack_store_float3(svm, normal_offset, sd->N);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -354,12 +348,12 @@ ccl_device_noinline void svm_node_normal_map(KernelGlobals kg,
|
|||
N = sd->N;
|
||||
}
|
||||
|
||||
stack_store_float3(stack, normal_offset, N);
|
||||
stack_store_float3(svm, normal_offset, N);
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_tangent(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint tangent_offset, direction_type, axis;
|
||||
|
@ -383,7 +377,7 @@ ccl_device_noinline void svm_node_tangent(KernelGlobals kg,
|
|||
if (direction_type == NODE_TANGENT_UVMAP) {
|
||||
/* UV map */
|
||||
if (desc.offset == ATTR_STD_NOT_FOUND) {
|
||||
stack_store_float3(stack, tangent_offset, zero_float3());
|
||||
stack_store_float3(svm, tangent_offset, zero_float3());
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
@ -409,7 +403,7 @@ ccl_device_noinline void svm_node_tangent(KernelGlobals kg,
|
|||
|
||||
object_normal_transform(kg, sd, &tangent);
|
||||
tangent = cross(sd->N, normalize(cross(tangent, sd->N)));
|
||||
stack_store_float3(stack, tangent_offset, tangent);
|
||||
stack_store_float3(svm, tangent_offset, tangent);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -10,26 +10,24 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device void svm_node_value_f(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint ivalue,
|
||||
uint out_offset)
|
||||
{
|
||||
stack_store_float(stack, out_offset, __uint_as_float(ivalue));
|
||||
stack_store_float(svm, out_offset, __uint_as_float(ivalue));
|
||||
}
|
||||
|
||||
ccl_device int svm_node_value_v(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint out_offset,
|
||||
int offset)
|
||||
ccl_device void svm_node_value_v(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint out_offset)
|
||||
{
|
||||
/* read extra data */
|
||||
uint4 node1 = read_node(kg, &offset);
|
||||
uint4 node1 = read_node(kg, svm);
|
||||
float3 p = make_float3(
|
||||
__uint_as_float(node1.y), __uint_as_float(node1.z), __uint_as_float(node1.w));
|
||||
|
||||
stack_store_float3(stack, out_offset, p);
|
||||
return offset;
|
||||
stack_store_float3(svm, out_offset, p);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -9,7 +9,7 @@ CCL_NAMESPACE_BEGIN
|
|||
/* Vector Rotate */
|
||||
|
||||
ccl_device_noinline void svm_node_vector_rotate(ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint input_stack_offsets,
|
||||
uint axis_stack_offsets,
|
||||
uint result_stack_offset)
|
||||
|
@ -24,12 +24,12 @@ ccl_device_noinline void svm_node_vector_rotate(ccl_private ShaderData *sd,
|
|||
|
||||
if (stack_valid(result_stack_offset)) {
|
||||
|
||||
float3 vector = stack_load_float3(stack, vector_stack_offset);
|
||||
float3 center = stack_load_float3(stack, center_stack_offset);
|
||||
float3 vector = stack_load_float3(svm, vector_stack_offset);
|
||||
float3 center = stack_load_float3(svm, center_stack_offset);
|
||||
float3 result = make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
if (type == NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) {
|
||||
float3 rotation = stack_load_float3(stack, rotation_stack_offset); // Default XYZ.
|
||||
float3 rotation = stack_load_float3(svm, rotation_stack_offset); // Default XYZ.
|
||||
Transform rotationTransform = euler_to_transform(rotation);
|
||||
if (invert) {
|
||||
result = transform_direction_transposed(&rotationTransform, vector - center) + center;
|
||||
|
@ -55,18 +55,18 @@ ccl_device_noinline void svm_node_vector_rotate(ccl_private ShaderData *sd,
|
|||
axis_length = 1.0f;
|
||||
break;
|
||||
default:
|
||||
axis = stack_load_float3(stack, axis_stack_offset);
|
||||
axis = stack_load_float3(svm, axis_stack_offset);
|
||||
axis_length = len(axis);
|
||||
break;
|
||||
}
|
||||
float angle = stack_load_float(stack, angle_stack_offset);
|
||||
float angle = stack_load_float(svm, angle_stack_offset);
|
||||
angle = invert ? -angle : angle;
|
||||
result = (axis_length != 0.0f) ?
|
||||
rotate_around_axis(vector - center, axis / axis_length, angle) + center :
|
||||
vector;
|
||||
}
|
||||
|
||||
stack_store_float3(stack, result_stack_offset, result);
|
||||
stack_store_float3(svm, result_stack_offset, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_vector_transform(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint itype, ifrom, ito;
|
||||
|
@ -19,7 +19,7 @@ ccl_device_noinline void svm_node_vector_transform(KernelGlobals kg,
|
|||
svm_unpack_node_uchar3(node.y, &itype, &ifrom, &ito);
|
||||
svm_unpack_node_uchar2(node.z, &vector_in, &vector_out);
|
||||
|
||||
float3 in = stack_load_float3(stack, vector_in);
|
||||
float3 in = stack_load_float3(svm, vector_in);
|
||||
|
||||
NodeVectorTransformType type = (NodeVectorTransformType)itype;
|
||||
NodeVectorTransformConvertSpace from = (NodeVectorTransformConvertSpace)ifrom;
|
||||
|
@ -117,7 +117,7 @@ ccl_device_noinline void svm_node_vector_transform(KernelGlobals kg,
|
|||
|
||||
/* Output */
|
||||
if (stack_valid(vector_out)) {
|
||||
stack_store_float3(stack, vector_out, in);
|
||||
stack_store_float3(svm, vector_out, in);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_vertex_color(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint layer_id,
|
||||
uint color_offset,
|
||||
uint alpha_offset)
|
||||
|
@ -17,24 +17,24 @@ ccl_device_noinline void svm_node_vertex_color(KernelGlobals kg,
|
|||
if (descriptor.offset != ATTR_STD_NOT_FOUND) {
|
||||
if (descriptor.type == NODE_ATTR_FLOAT4 || descriptor.type == NODE_ATTR_RGBA) {
|
||||
float4 vertex_color = primitive_surface_attribute_float4(kg, sd, descriptor, NULL, NULL);
|
||||
stack_store_float3(stack, color_offset, float4_to_float3(vertex_color));
|
||||
stack_store_float(stack, alpha_offset, vertex_color.w);
|
||||
stack_store_float3(svm, color_offset, float4_to_float3(vertex_color));
|
||||
stack_store_float(svm, alpha_offset, vertex_color.w);
|
||||
}
|
||||
else {
|
||||
float3 vertex_color = primitive_surface_attribute_float3(kg, sd, descriptor, NULL, NULL);
|
||||
stack_store_float3(stack, color_offset, vertex_color);
|
||||
stack_store_float(stack, alpha_offset, 1.0f);
|
||||
stack_store_float3(svm, color_offset, vertex_color);
|
||||
stack_store_float(svm, alpha_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, color_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
stack_store_float(stack, alpha_offset, 0.0f);
|
||||
stack_store_float3(svm, color_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
stack_store_float(svm, alpha_offset, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_vertex_color_bump_dx(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint layer_id,
|
||||
uint color_offset,
|
||||
uint alpha_offset)
|
||||
|
@ -45,26 +45,26 @@ ccl_device_noinline void svm_node_vertex_color_bump_dx(KernelGlobals kg,
|
|||
float4 dx;
|
||||
float4 vertex_color = primitive_surface_attribute_float4(kg, sd, descriptor, &dx, NULL);
|
||||
vertex_color += dx;
|
||||
stack_store_float3(stack, color_offset, float4_to_float3(vertex_color));
|
||||
stack_store_float(stack, alpha_offset, vertex_color.w);
|
||||
stack_store_float3(svm, color_offset, float4_to_float3(vertex_color));
|
||||
stack_store_float(svm, alpha_offset, vertex_color.w);
|
||||
}
|
||||
else {
|
||||
float3 dx;
|
||||
float3 vertex_color = primitive_surface_attribute_float3(kg, sd, descriptor, &dx, NULL);
|
||||
vertex_color += dx;
|
||||
stack_store_float3(stack, color_offset, vertex_color);
|
||||
stack_store_float(stack, alpha_offset, 1.0f);
|
||||
stack_store_float3(svm, color_offset, vertex_color);
|
||||
stack_store_float(svm, alpha_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, color_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
stack_store_float(stack, alpha_offset, 0.0f);
|
||||
stack_store_float3(svm, color_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
stack_store_float(svm, alpha_offset, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_noinline void svm_node_vertex_color_bump_dy(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint layer_id,
|
||||
uint color_offset,
|
||||
uint alpha_offset)
|
||||
|
@ -75,20 +75,20 @@ ccl_device_noinline void svm_node_vertex_color_bump_dy(KernelGlobals kg,
|
|||
float4 dy;
|
||||
float4 vertex_color = primitive_surface_attribute_float4(kg, sd, descriptor, NULL, &dy);
|
||||
vertex_color += dy;
|
||||
stack_store_float3(stack, color_offset, float4_to_float3(vertex_color));
|
||||
stack_store_float(stack, alpha_offset, vertex_color.w);
|
||||
stack_store_float3(svm, color_offset, float4_to_float3(vertex_color));
|
||||
stack_store_float(svm, alpha_offset, vertex_color.w);
|
||||
}
|
||||
else {
|
||||
float3 dy;
|
||||
float3 vertex_color = primitive_surface_attribute_float3(kg, sd, descriptor, NULL, &dy);
|
||||
vertex_color += dy;
|
||||
stack_store_float3(stack, color_offset, vertex_color);
|
||||
stack_store_float(stack, alpha_offset, 1.0f);
|
||||
stack_store_float3(svm, color_offset, vertex_color);
|
||||
stack_store_float(svm, alpha_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, color_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
stack_store_float(stack, alpha_offset, 0.0f);
|
||||
stack_store_float3(svm, color_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
stack_store_float(svm, alpha_offset, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -980,7 +980,7 @@ ccl_device float fractal_voronoi_distance_to_edge(ccl_private const VoronoiParam
|
|||
}
|
||||
|
||||
ccl_device void svm_voronoi_output(const uint4 stack_offsets,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
const float distance,
|
||||
const float3 color,
|
||||
const float3 position,
|
||||
|
@ -996,30 +996,29 @@ ccl_device void svm_voronoi_output(const uint4 stack_offsets,
|
|||
stack_offsets.w, &position_stack_offset, &w_out_stack_offset, &radius_stack_offset);
|
||||
|
||||
if (stack_valid(distance_stack_offset))
|
||||
stack_store_float(stack, distance_stack_offset, distance);
|
||||
stack_store_float(svm, distance_stack_offset, distance);
|
||||
if (stack_valid(color_stack_offset))
|
||||
stack_store_float3(stack, color_stack_offset, color);
|
||||
stack_store_float3(svm, color_stack_offset, color);
|
||||
if (stack_valid(position_stack_offset))
|
||||
stack_store_float3(stack, position_stack_offset, position);
|
||||
stack_store_float3(svm, position_stack_offset, position);
|
||||
if (stack_valid(w_out_stack_offset))
|
||||
stack_store_float(stack, w_out_stack_offset, w);
|
||||
stack_store_float(svm, w_out_stack_offset, w);
|
||||
if (stack_valid(radius_stack_offset))
|
||||
stack_store_float(stack, radius_stack_offset, radius);
|
||||
stack_store_float(svm, radius_stack_offset, radius);
|
||||
}
|
||||
|
||||
template<uint node_feature_mask>
|
||||
ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
uint dimensions,
|
||||
uint feature,
|
||||
uint metric,
|
||||
int offset)
|
||||
ccl_device_noinline void svm_node_tex_voronoi(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint dimensions,
|
||||
uint feature,
|
||||
uint metric)
|
||||
{
|
||||
/* Read node defaults and stack offsets. */
|
||||
uint4 stack_offsets = read_node(kg, &offset);
|
||||
uint4 defaults1 = read_node(kg, &offset);
|
||||
uint4 defaults2 = read_node(kg, &offset);
|
||||
uint4 stack_offsets = read_node(kg, svm);
|
||||
uint4 defaults1 = read_node(kg, svm);
|
||||
uint4 defaults2 = read_node(kg, svm);
|
||||
|
||||
uint coord_stack_offset, w_stack_offset, scale_stack_offset, detail_stack_offset;
|
||||
uint roughness_stack_offset, lacunarity_stack_offset, smoothness_stack_offset,
|
||||
|
@ -1039,19 +1038,19 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
|||
svm_unpack_node_uchar2(stack_offsets.z, &randomness_stack_offset, &normalize);
|
||||
|
||||
/* Read from stack. */
|
||||
float3 coord = stack_load_float3(stack, coord_stack_offset);
|
||||
float w = stack_load_float_default(stack, w_stack_offset, defaults1.x);
|
||||
float3 coord = stack_load_float3(svm, coord_stack_offset);
|
||||
float w = stack_load_float_default(svm, w_stack_offset, defaults1.x);
|
||||
|
||||
VoronoiParams params;
|
||||
params.feature = (NodeVoronoiFeature)feature;
|
||||
params.metric = (NodeVoronoiDistanceMetric)metric;
|
||||
params.scale = stack_load_float_default(stack, scale_stack_offset, defaults1.y);
|
||||
params.detail = stack_load_float_default(stack, detail_stack_offset, defaults1.z);
|
||||
params.roughness = stack_load_float_default(stack, roughness_stack_offset, defaults1.w);
|
||||
params.lacunarity = stack_load_float_default(stack, smoothness_stack_offset, defaults2.x);
|
||||
params.smoothness = stack_load_float_default(stack, smoothness_stack_offset, defaults2.y);
|
||||
params.exponent = stack_load_float_default(stack, exponent_stack_offset, defaults2.z);
|
||||
params.randomness = stack_load_float_default(stack, randomness_stack_offset, defaults2.w);
|
||||
params.scale = stack_load_float_default(svm, scale_stack_offset, defaults1.y);
|
||||
params.detail = stack_load_float_default(svm, detail_stack_offset, defaults1.z);
|
||||
params.roughness = stack_load_float_default(svm, roughness_stack_offset, defaults1.w);
|
||||
params.lacunarity = stack_load_float_default(svm, smoothness_stack_offset, defaults2.x);
|
||||
params.smoothness = stack_load_float_default(svm, smoothness_stack_offset, defaults2.y);
|
||||
params.exponent = stack_load_float_default(svm, exponent_stack_offset, defaults2.z);
|
||||
params.randomness = stack_load_float_default(svm, randomness_stack_offset, defaults2.w);
|
||||
params.max_distance = 0.0f;
|
||||
params.normalize = normalize;
|
||||
|
||||
|
@ -1083,7 +1082,7 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
|
||||
svm_voronoi_output(stack_offsets, stack, distance, zero_float3(), zero_float3(), 0.0f, 0.0f);
|
||||
svm_voronoi_output(stack_offsets, svm, distance, zero_float3(), zero_float3(), 0.0f, 0.0f);
|
||||
break;
|
||||
}
|
||||
case NODE_VORONOI_N_SPHERE_RADIUS: {
|
||||
|
@ -1103,7 +1102,7 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
|
||||
svm_voronoi_output(stack_offsets, stack, 0.0f, zero_float3(), zero_float3(), 0.0f, radius);
|
||||
svm_voronoi_output(stack_offsets, svm, 0.0f, zero_float3(), zero_float3(), 0.0f, radius);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -1153,7 +1152,7 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
|||
}
|
||||
|
||||
svm_voronoi_output(stack_offsets,
|
||||
stack,
|
||||
svm,
|
||||
output.distance,
|
||||
output.color,
|
||||
float4_to_float3(output.position),
|
||||
|
@ -1162,8 +1161,6 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -10,8 +10,10 @@ CCL_NAMESPACE_BEGIN
|
|||
* sampler.
|
||||
*/
|
||||
template<uint node_feature_mask>
|
||||
ccl_device_noinline int svm_node_tex_voxel(
|
||||
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
||||
ccl_device_noinline void svm_node_tex_voxel(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint co_offset, density_out_offset, color_out_offset, space;
|
||||
svm_unpack_node_uchar4(node.z, &co_offset, &density_out_offset, &color_out_offset, &space);
|
||||
|
@ -22,33 +24,32 @@ ccl_device_noinline int svm_node_tex_voxel(
|
|||
IF_KERNEL_NODES_FEATURE(VOLUME)
|
||||
{
|
||||
int id = node.y;
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float3 co = stack_load_float3(svm, co_offset);
|
||||
if (space == NODE_TEX_VOXEL_SPACE_OBJECT) {
|
||||
co = volume_normalized_position(kg, sd, co);
|
||||
}
|
||||
else {
|
||||
kernel_assert(space == NODE_TEX_VOXEL_SPACE_WORLD);
|
||||
Transform tfm;
|
||||
tfm.x = read_node_float(kg, &offset);
|
||||
tfm.y = read_node_float(kg, &offset);
|
||||
tfm.z = read_node_float(kg, &offset);
|
||||
tfm.x = read_node_float(kg, svm);
|
||||
tfm.y = read_node_float(kg, svm);
|
||||
tfm.z = read_node_float(kg, svm);
|
||||
co = transform_point(&tfm, co);
|
||||
}
|
||||
|
||||
r = kernel_tex_image_interp_3d(kg, id, co, INTERPOLATION_NONE);
|
||||
}
|
||||
else if (space != NODE_TEX_VOXEL_SPACE_OBJECT) {
|
||||
read_node_float(kg, &offset);
|
||||
read_node_float(kg, &offset);
|
||||
read_node_float(kg, &offset);
|
||||
read_node_float(kg, svm);
|
||||
read_node_float(kg, svm);
|
||||
read_node_float(kg, svm);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (stack_valid(density_out_offset))
|
||||
stack_store_float(stack, density_out_offset, r.w);
|
||||
stack_store_float(svm, density_out_offset, r.w);
|
||||
if (stack_valid(color_out_offset))
|
||||
stack_store_float3(stack, color_out_offset, make_float3(r.x, r.y, r.z));
|
||||
return offset;
|
||||
stack_store_float3(svm, color_out_offset, make_float3(r.x, r.y, r.z));
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -72,11 +72,13 @@ ccl_device_noinline_cpu float svm_wave(NodeWaveType type,
|
|||
}
|
||||
}
|
||||
|
||||
ccl_device_noinline int svm_node_tex_wave(
|
||||
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
||||
ccl_device_noinline void svm_node_tex_wave(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint4 node2 = read_node(kg, &offset);
|
||||
uint4 node3 = read_node(kg, &offset);
|
||||
uint4 node2 = read_node(kg, svm);
|
||||
uint4 node3 = read_node(kg, svm);
|
||||
|
||||
/* RNA properties */
|
||||
uint type_offset, bands_dir_offset, rings_dir_offset, profile_offset;
|
||||
|
@ -92,13 +94,13 @@ ccl_device_noinline int svm_node_tex_wave(
|
|||
node.w, &detail_offset, &dscale_offset, &droughness_offset, &phase_offset);
|
||||
svm_unpack_node_uchar2(node2.x, &color_offset, &fac_offset);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float scale = stack_load_float_default(stack, scale_offset, node2.y);
|
||||
float distortion = stack_load_float_default(stack, distortion_offset, node2.z);
|
||||
float detail = stack_load_float_default(stack, detail_offset, node2.w);
|
||||
float dscale = stack_load_float_default(stack, dscale_offset, node3.x);
|
||||
float droughness = stack_load_float_default(stack, droughness_offset, node3.y);
|
||||
float phase = stack_load_float_default(stack, phase_offset, node3.z);
|
||||
float3 co = stack_load_float3(svm, co_offset);
|
||||
float scale = stack_load_float_default(svm, scale_offset, node2.y);
|
||||
float distortion = stack_load_float_default(svm, distortion_offset, node2.z);
|
||||
float detail = stack_load_float_default(svm, detail_offset, node2.w);
|
||||
float dscale = stack_load_float_default(svm, dscale_offset, node3.x);
|
||||
float droughness = stack_load_float_default(svm, droughness_offset, node3.y);
|
||||
float phase = stack_load_float_default(svm, phase_offset, node3.z);
|
||||
|
||||
float f = svm_wave((NodeWaveType)type_offset,
|
||||
(NodeWaveBandsDirection)bands_dir_offset,
|
||||
|
@ -112,10 +114,9 @@ ccl_device_noinline int svm_node_tex_wave(
|
|||
phase);
|
||||
|
||||
if (stack_valid(fac_offset))
|
||||
stack_store_float(stack, fac_offset, f);
|
||||
stack_store_float(svm, fac_offset, f);
|
||||
if (stack_valid(color_offset))
|
||||
stack_store_float3(stack, color_offset, make_float3(f, f, f));
|
||||
return offset;
|
||||
stack_store_float3(svm, color_offset, make_float3(f, f, f));
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -13,11 +13,11 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_wavelength(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint wavelength,
|
||||
uint color_out)
|
||||
{
|
||||
float lambda_nm = stack_load_float(stack, wavelength);
|
||||
float lambda_nm = stack_load_float(svm, wavelength);
|
||||
float ii = (lambda_nm - 380.0f) * (1.0f / 5.0f); // scaled 0..80
|
||||
int i = float_to_int(ii);
|
||||
float3 color;
|
||||
|
@ -37,7 +37,7 @@ ccl_device_noinline void svm_node_wavelength(KernelGlobals kg,
|
|||
/* Clamp to zero if values are smaller */
|
||||
color = max(color, make_float3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
stack_store_float3(stack, color_out, color);
|
||||
stack_store_float3(svm, color_out, color);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -8,7 +8,7 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
ccl_device_noinline void svm_node_tex_white_noise(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint dimensions,
|
||||
uint inputs_stack_offsets,
|
||||
uint ouptuts_stack_offsets)
|
||||
|
@ -17,8 +17,8 @@ ccl_device_noinline void svm_node_tex_white_noise(KernelGlobals kg,
|
|||
svm_unpack_node_uchar2(inputs_stack_offsets, &vector_stack_offset, &w_stack_offset);
|
||||
svm_unpack_node_uchar2(ouptuts_stack_offsets, &value_stack_offset, &color_stack_offset);
|
||||
|
||||
float3 vector = stack_load_float3(stack, vector_stack_offset);
|
||||
float w = stack_load_float(stack, w_stack_offset);
|
||||
float3 vector = stack_load_float3(svm, vector_stack_offset);
|
||||
float w = stack_load_float(svm, w_stack_offset);
|
||||
|
||||
if (stack_valid(color_stack_offset)) {
|
||||
float3 color;
|
||||
|
@ -40,7 +40,7 @@ ccl_device_noinline void svm_node_tex_white_noise(KernelGlobals kg,
|
|||
kernel_assert(0);
|
||||
break;
|
||||
}
|
||||
stack_store_float3(stack, color_stack_offset, color);
|
||||
stack_store_float3(svm, color_stack_offset, color);
|
||||
}
|
||||
|
||||
if (stack_valid(value_stack_offset)) {
|
||||
|
@ -63,7 +63,7 @@ ccl_device_noinline void svm_node_tex_white_noise(KernelGlobals kg,
|
|||
kernel_assert(0);
|
||||
break;
|
||||
}
|
||||
stack_store_float(stack, value_stack_offset, value);
|
||||
stack_store_float(svm, value_stack_offset, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ ccl_device_inline float wireframe(KernelGlobals kg,
|
|||
|
||||
ccl_device_noinline void svm_node_wireframe(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
ccl_private SVMState *svm,
|
||||
uint4 node)
|
||||
{
|
||||
uint in_size = node.y;
|
||||
|
@ -82,7 +82,7 @@ ccl_device_noinline void svm_node_wireframe(KernelGlobals kg,
|
|||
svm_unpack_node_uchar2(node.w, &use_pixel_size, &bump_offset);
|
||||
|
||||
/* Input Data */
|
||||
float size = stack_load_float(stack, in_size);
|
||||
float size = stack_load_float(svm, in_size);
|
||||
int pixel_size = (int)use_pixel_size;
|
||||
|
||||
/* Calculate wireframe */
|
||||
|
@ -100,7 +100,7 @@ ccl_device_noinline void svm_node_wireframe(KernelGlobals kg,
|
|||
}
|
||||
|
||||
if (stack_valid(out_fac))
|
||||
stack_store_float(stack, out_fac, f);
|
||||
stack_store_float(svm, out_fac, f);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -192,6 +192,7 @@ static float3 output_estimate_emission(ShaderOutput *output, bool &is_constant)
|
|||
|
||||
return estimate1 + estimate2;
|
||||
}
|
||||
/* TODO Layer */
|
||||
else if (node->type == MixClosureNode::get_node_type()) {
|
||||
/* Mix Closure. */
|
||||
ShaderInput *fac_in = node->input("Fac");
|
||||
|
|
|
@ -1043,7 +1043,46 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight
|
|||
* avoid building a closure tree and then flattening it, and instead write it
|
||||
* directly to an array */
|
||||
|
||||
if (node->special_type == SHADER_SPECIAL_TYPE_COMBINE_CLOSURE) {
|
||||
if (node->type == LayerClosureNode::get_node_type()) {
|
||||
/* The layer closure works by first executing the top layer subtree, then computing
|
||||
* the base weight from the albedo of all top layer closures, and then executing
|
||||
* the base layer subtree with that weight.
|
||||
* To implement that in SVM, we need the following order of nodes:
|
||||
* - LayerClosureAccumulateNode, which allocates space on the stack to store the
|
||||
* accumulated albedo and sets a flag telling closure nodes to write to it
|
||||
* - Top Layer subtree (using the layer node's input weight)
|
||||
* - LayerClosureWeightNode, which reads the accumulated albedo and the layer node's
|
||||
* input weight and outputs the base layer subtree weight
|
||||
* - Base Layer subtree (using the output from above)
|
||||
* In order to get this ordering, we can make the SVM compiler recurse into the top
|
||||
* layer before the base layer, taking care of that. The LayerClosureWeightNode will
|
||||
* automatically be compiled before the base layer, since it's a dependency.
|
||||
* To ensure that the LayerClosureAccumulateNode is compiled before the top layer,
|
||||
* we make it a fake dependency by connecting the top layer weight input to an output
|
||||
* of the Accumulate node. In reality, this just passes through the input Weight, but
|
||||
* it's enough to make the ordering work. */
|
||||
ShaderInput *base_in = node->input("Base");
|
||||
ShaderInput *top_in = node->input("Top");
|
||||
|
||||
LayerClosureAccumulateNode *accumulate_node = create_node<LayerClosureAccumulateNode>();
|
||||
add(accumulate_node);
|
||||
|
||||
LayerClosureWeightNode *weight_node = create_node<LayerClosureWeightNode>();
|
||||
add(weight_node);
|
||||
|
||||
connect(accumulate_node->output("Albedo"), weight_node->input("Albedo"));
|
||||
|
||||
if (weight_out) {
|
||||
connect(weight_out, weight_node->input("Weight"));
|
||||
connect(weight_out, accumulate_node->input("Weight"));
|
||||
}
|
||||
|
||||
if (base_in->link)
|
||||
transform_multi_closure(base_in->link->parent, weight_node->output("BaseWeight"), volume);
|
||||
if (top_in->link)
|
||||
transform_multi_closure(top_in->link->parent, accumulate_node->output("TopWeight"), volume);
|
||||
}
|
||||
else if (node->special_type == SHADER_SPECIAL_TYPE_COMBINE_CLOSURE) {
|
||||
ShaderInput *fin = node->input("Fac");
|
||||
ShaderInput *cl1in = node->input("Closure1");
|
||||
ShaderInput *cl2in = node->input("Closure2");
|
||||
|
|
|
@ -4728,6 +4728,107 @@ void MixClosureWeightNode::compile(OSLCompiler & /*compiler*/)
|
|||
assert(0);
|
||||
}
|
||||
|
||||
/* Layer Closure */
|
||||
|
||||
NODE_DEFINE(LayerClosureNode)
|
||||
{
|
||||
NodeType *type = NodeType::add("layer_closure", create, NodeType::SHADER);
|
||||
|
||||
SOCKET_IN_CLOSURE(base, "Base");
|
||||
SOCKET_IN_CLOSURE(top, "Top");
|
||||
SOCKET_OUT_CLOSURE(closure, "Closure");
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
LayerClosureNode::LayerClosureNode() : ShaderNode(get_node_type()) {}
|
||||
|
||||
void LayerClosureNode::compile(SVMCompiler & /*compiler*/)
|
||||
{
|
||||
/* handled in the SVM compiler */
|
||||
}
|
||||
|
||||
void LayerClosureNode::compile(OSLCompiler &compiler)
|
||||
{
|
||||
compiler.add(this, "node_layer_closure");
|
||||
}
|
||||
|
||||
void LayerClosureNode::constant_fold(const ConstantFolder &folder)
|
||||
{
|
||||
ShaderInput *base_in = input("Base");
|
||||
ShaderInput *top_in = input("Top");
|
||||
|
||||
/* remove useless layer closures nodes */
|
||||
if (!base_in->link) {
|
||||
folder.bypass_or_discard(top_in);
|
||||
}
|
||||
else if (!top_in->link) {
|
||||
folder.bypass_or_discard(base_in);
|
||||
}
|
||||
/* We could theoretically also check for top layers that are known to be opaque
|
||||
* and skip the base in that case, but that's quite ugly to get right. */
|
||||
}
|
||||
|
||||
NODE_DEFINE(LayerClosureAccumulateNode)
|
||||
{
|
||||
NodeType *type = NodeType::add("layer_closure_accumulate", create, NodeType::SHADER);
|
||||
|
||||
SOCKET_IN_FLOAT(weight, "Weight", 1.0f);
|
||||
SOCKET_OUT_COLOR(albedo, "Albedo");
|
||||
SOCKET_OUT_FLOAT(weight_top, "TopWeight");
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
LayerClosureAccumulateNode::LayerClosureAccumulateNode() : ShaderNode(get_node_type()) {}
|
||||
|
||||
void LayerClosureAccumulateNode::compile(SVMCompiler &compiler)
|
||||
{
|
||||
ShaderInput *weight_in = input("Weight");
|
||||
ShaderOutput *albedo_out = output("Albedo");
|
||||
ShaderOutput *weight_top_out = output("TopWeight");
|
||||
|
||||
compiler.add_node(NODE_LAYER_CLOSURE_ACCUMULATE,
|
||||
compiler.stack_assign(weight_in),
|
||||
compiler.stack_assign(albedo_out),
|
||||
compiler.stack_assign(weight_top_out));
|
||||
}
|
||||
|
||||
void LayerClosureAccumulateNode::compile(OSLCompiler & /*compiler*/)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
NODE_DEFINE(LayerClosureWeightNode)
|
||||
{
|
||||
NodeType *type = NodeType::add("layer_closure_weight", create, NodeType::SHADER);
|
||||
|
||||
SOCKET_IN_FLOAT(weight, "Weight", 1.0f);
|
||||
SOCKET_IN_COLOR(albedo, "Albedo", one_float3());
|
||||
SOCKET_OUT_FLOAT(weight_base, "BaseWeight");
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
LayerClosureWeightNode::LayerClosureWeightNode() : ShaderNode(get_node_type()) {}
|
||||
|
||||
void LayerClosureWeightNode::compile(SVMCompiler &compiler)
|
||||
{
|
||||
ShaderInput *weight_in = input("Weight");
|
||||
ShaderInput *albedo_in = input("Albedo");
|
||||
ShaderOutput *weight_base_out = output("BaseWeight");
|
||||
|
||||
compiler.add_node(NODE_LAYER_CLOSURE,
|
||||
compiler.stack_assign(weight_in),
|
||||
compiler.stack_assign(albedo_in),
|
||||
compiler.stack_assign(weight_base_out));
|
||||
}
|
||||
|
||||
void LayerClosureWeightNode::compile(OSLCompiler & /*compiler*/)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* Invert */
|
||||
|
||||
NODE_DEFINE(InvertNode)
|
||||
|
|
|
@ -1059,6 +1059,27 @@ class MixClosureWeightNode : public ShaderNode {
|
|||
NODE_SOCKET_API(float, fac)
|
||||
};
|
||||
|
||||
class LayerClosureNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(LayerClosureNode)
|
||||
void constant_fold(const ConstantFolder &folder);
|
||||
};
|
||||
|
||||
class LayerClosureAccumulateNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(LayerClosureAccumulateNode)
|
||||
|
||||
NODE_SOCKET_API(float, weight)
|
||||
};
|
||||
|
||||
class LayerClosureWeightNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(LayerClosureWeightNode)
|
||||
|
||||
NODE_SOCKET_API(float, weight)
|
||||
NODE_SOCKET_API(float3, albedo)
|
||||
};
|
||||
|
||||
class InvertNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(InvertNode)
|
||||
|
|
|
@ -567,7 +567,16 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
|||
|
||||
state->closure_done.insert(node);
|
||||
|
||||
if (node->special_type == SHADER_SPECIAL_TYPE_COMBINE_CLOSURE) {
|
||||
if (node->type == LayerClosureNode::get_node_type()) {
|
||||
ShaderInput *base_in = node->input("Base");
|
||||
ShaderInput *top_in = node->input("Top");
|
||||
|
||||
if (top_in->link)
|
||||
generate_multi_closure(root_node, top_in->link->parent, state);
|
||||
if (base_in->link)
|
||||
generate_multi_closure(root_node, base_in->link->parent, state);
|
||||
}
|
||||
else if (node->special_type == SHADER_SPECIAL_TYPE_COMBINE_CLOSURE) {
|
||||
/* weighting is already taken care of in ShaderGraph::transform_multi_closure */
|
||||
ShaderInput *cl1in = node->input("Closure1");
|
||||
ShaderInput *cl2in = node->input("Closure2");
|
||||
|
|
|
@ -187,6 +187,7 @@ shader_node_categories = [
|
|||
ShaderNodeCategory("SH_NEW_SHADER", "Shader", items=[
|
||||
NodeItem("ShaderNodeMixShader", poll=eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeAddShader", poll=eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeLayerShader", poll=eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfDiffuse", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfPrincipled", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfGlossy", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
|
|
|
@ -1023,6 +1023,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
|
|||
#define SH_NODE_COMBINE_COLOR 711
|
||||
#define SH_NODE_SEPARATE_COLOR 712
|
||||
#define SH_NODE_MIX 713
|
||||
#define SH_NODE_LAYER_SHADER 714
|
||||
|
||||
/** \} */
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ DefNode(ShaderNode, SH_NODE_FRESNEL, 0, "FRE
|
|||
DefNode(ShaderNode, SH_NODE_LAYER_WEIGHT, 0, "LAYER_WEIGHT", LayerWeight, "Layer Weight", "Produce a blending factor depending on the angle between the surface normal and the view direction.\nTypically used for layering shaders with the Mix Shader node")
|
||||
DefNode(ShaderNode, SH_NODE_MIX_SHADER, 0, "MIX_SHADER", MixShader, "Mix Shader", "Mix two shaders together. Typically used for material layering")
|
||||
DefNode(ShaderNode, SH_NODE_ADD_SHADER, 0, "ADD_SHADER", AddShader, "Add Shader", "Add two Shaders together")
|
||||
DefNode(ShaderNode, SH_NODE_LAYER_SHADER, 0, "LAYER_SHADER", LayerShader, "Layer Shader", "Layer one Shader over another while conserving energy")
|
||||
DefNode(ShaderNode, SH_NODE_ATTRIBUTE, def_sh_attribute, "ATTRIBUTE", Attribute, "Attribute", "Retrieve attributes attached to objects or geometry")
|
||||
DefNode(ShaderNode, SH_NODE_AMBIENT_OCCLUSION, def_sh_ambient_occlusion,"AMBIENT_OCCLUSION", AmbientOcclusion, "Ambient Occlusion", "Compute how much the hemisphere above the shading point is occluded, for example to add weathering effects to corners.\nNote: For Cycles, this may slow down renders significantly")
|
||||
DefNode(ShaderNode, SH_NODE_BACKGROUND, 0, "BACKGROUND", Background, "Background", "Add background light emission.\nNote: This node should only be used for the world surface output")
|
||||
|
|
|
@ -54,6 +54,7 @@ set(SRC
|
|||
nodes/node_shader_hueSatVal.cc
|
||||
nodes/node_shader_ies_light.cc
|
||||
nodes/node_shader_invert.cc
|
||||
nodes/node_shader_layer_shader.cc
|
||||
nodes/node_shader_layer_weight.cc
|
||||
nodes/node_shader_light_falloff.cc
|
||||
nodes/node_shader_light_path.cc
|
||||
|
|
|
@ -50,6 +50,7 @@ void register_shader_nodes()
|
|||
register_node_type_sh_holdout();
|
||||
register_node_type_sh_hue_sat();
|
||||
register_node_type_sh_invert();
|
||||
register_node_type_sh_layer_shader();
|
||||
register_node_type_sh_layer_weight();
|
||||
register_node_type_sh_light_falloff();
|
||||
register_node_type_sh_light_path();
|
||||
|
|
|
@ -48,6 +48,7 @@ void register_node_type_sh_hair_info();
|
|||
void register_node_type_sh_holdout();
|
||||
void register_node_type_sh_hue_sat();
|
||||
void register_node_type_sh_invert();
|
||||
void register_node_type_sh_layer_shader();
|
||||
void register_node_type_sh_layer_weight();
|
||||
void register_node_type_sh_light_falloff();
|
||||
void register_node_type_sh_light_path();
|
||||
|
|
|
@ -674,6 +674,8 @@ static void ntree_weight_tree_merge_weight(bNodeTree *ntree,
|
|||
*tosock = addsock_out;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
|
||||
static bool ntree_weight_tree_tag_nodes(bNode *fromnode, bNode *tonode, void *userdata)
|
||||
{
|
||||
int *node_count = (int *)userdata;
|
||||
|
@ -939,6 +941,7 @@ static bool closure_node_filter(const bNode *node)
|
|||
switch (node->type) {
|
||||
case SH_NODE_ADD_SHADER:
|
||||
case SH_NODE_MIX_SHADER:
|
||||
case SH_NODE_LAYER_SHADER:
|
||||
case SH_NODE_BACKGROUND:
|
||||
case SH_NODE_BSDF_DIFFUSE:
|
||||
case SH_NODE_BSDF_GLASS:
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* SPDX-FileCopyrightText: 2005 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_shader_layer_shader_cc {
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Shader>("Base");
|
||||
b.add_input<decl::Shader>("Top");
|
||||
b.add_output<decl::Shader>("Shader");
|
||||
}
|
||||
|
||||
static int node_shader_gpu_layer_shader(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
/* TODO */
|
||||
return GPU_stack_link(mat, node, "node_add_shader", in, out);
|
||||
}
|
||||
|
||||
} // namespace blender::nodes::node_shader_layer_shader_cc
|
||||
|
||||
/* node type definition */
|
||||
void register_node_type_sh_layer_shader()
|
||||
{
|
||||
namespace file_ns = blender::nodes::node_shader_layer_shader_cc;
|
||||
|
||||
static bNodeType ntype;
|
||||
|
||||
sh_node_type_base(&ntype, SH_NODE_LAYER_SHADER, "Layer Shader", NODE_CLASS_SHADER);
|
||||
ntype.declare = file_ns::node_declare;
|
||||
ntype.gpu_fn = file_ns::node_shader_gpu_layer_shader;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
Loading…
Reference in New Issue