1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
// Copyright 2009 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "MetallicPaint.ih"
#include "render/Material.ih"
#include "render/bsdfs/DielectricLayer.ih"
#include "render/bsdfs/Lambert.ih"
#include "render/bsdfs/MicrofacetConductor.ih"
#include "render/bsdfs/MultiBSDF.ih"
#include "texture/TextureParam.ih"
// c++ shared
#include "MetallicPaintShared.h"
///////////////////////////////////////////////////////////////////////////////
// Implementation
OSPRAY_BEGIN_ISPC_NAMESPACE
struct MetallicPaint_MultiBSDF
{
DEFINE_MULTIBSDF(2);
BSDF lambert;
MicrofacetConductor microfacetConductor;
};
struct MetallicPaint_BSDF
{
DielectricLayer dielectricLayer;
MetallicPaint_MultiBSDF multi;
};
SYCL_EXTERNAL const varying BSDF *uniform MetallicPaint_getBSDF(
const uniform Material *uniform super,
uniform ShadingContext *uniform ctx,
const DifferentialGeometry &dg,
const Ray &,
const Medium &,
const uniform FeatureFlagsHandler &)
{
const uniform MetallicPaint *uniform self =
(const uniform MetallicPaint *uniform)super;
varying LinearSpace3f *uniform shadingFrame =
LinearSpace3f_create(ctx, frame(dg.Ns));
// Allocate memory and initialize material BSDF
varying MetallicPaint_BSDF *uniform bsdf =
(varying MetallicPaint_BSDF * uniform)
ShadingContext_alloc(ctx, sizeof(MetallicPaint_BSDF));
varying MultiBSDF *uniform bsdfMulti =
(varying MultiBSDF * uniform) & bsdf->multi;
MultiBSDF_Constructor(bsdfMulti, 2);
const vec3f color = self->baseColor * make_vec3f(dg.color)
* get3f(self->baseColorMap, dg, make_vec3f(1.f));
Lambert_Constructor(&bsdf->multi.lambert, shadingFrame, color);
MultiBSDF_add(bsdfMulti, 0, &bsdf->multi.lambert, 1.f, luminance(color));
if (self->flakeAmount > 0.f) {
const vec3f r = self->flakeColor;
const vec3f g = make_vec3f(self->flakeAmount);
Fresnel *uniform fresnel = FresnelSchlick_create(ctx, r, g);
MicrofacetConductor_Constructor(&bsdf->multi.microfacetConductor,
super->microfacetAlbedoTables,
shadingFrame,
fresnel,
self->flakeSpread,
0.f);
MultiBSDF_add(bsdfMulti,
1,
(varying BSDF * uniform) & bsdf->multi.microfacetConductor,
1.f,
luminance(r));
}
DielectricLayer_Constructor(&bsdf->dielectricLayer,
shadingFrame,
&bsdf->multi.super,
self->eta,
make_vec3f(1.0f),
1.0f,
1.0f);
bsdf->dielectricLayer.super.bsdfType = BSDF_TYPE_METALLICPAINT;
return &bsdf->dielectricLayer.super;
}
inline BSDF_EvalRes MultiBSDF_eval(
const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi)
{
const varying MetallicPaint_MultiBSDF *uniform self =
(const varying MetallicPaint_MultiBSDF *uniform)super;
MULTIBSDF_EVAL_BEGIN();
MULTIBSDF_EVAL_CHILD(0, &self->lambert, Lambert_eval);
MULTIBSDF_EVAL_CHILD(1, &self->microfacetConductor, MicrofacetConductor_eval);
MULTIBSDF_EVAL_END();
return MULTIBSDF_EVAL_GET();
}
inline BSDF_SampleRes MultiBSDF_sample(const varying BSDF *uniform super,
const vec3f &wo,
const vec2f &s,
float ss)
{
const varying MetallicPaint_MultiBSDF *uniform self =
(const varying MetallicPaint_MultiBSDF *uniform)super;
MULTIBSDF_SAMPLE_BEGIN();
MULTIBSDF_SAMPLE_CHILD(0, &self->lambert, Lambert_sample);
MULTIBSDF_SAMPLE_CHILD(
1, &self->microfacetConductor, MicrofacetConductor_sample);
MULTIBSDF_SAMPLE_EVAL();
MULTIBSDF_EVAL_CHILD(0, &self->lambert, Lambert_eval);
MULTIBSDF_EVAL_CHILD(1, &self->microfacetConductor, MicrofacetConductor_eval);
MULTIBSDF_SAMPLE_END();
return MULTIBSDF_SAMPLE_GET();
}
SYCL_EXTERNAL BSDF_EvalRes MetallicPaint_BSDF_eval(
const varying BSDF *uniform super, const vec3f &wo, const vec3f &wi)
{
const varying MetallicPaint_BSDF *uniform self =
(const varying MetallicPaint_BSDF *uniform)super;
DIELECTRICLAYER_EVAL(self->dielectricLayer,
self->multi.super.scatteringType,
&self->multi.super,
MultiBSDF_eval);
return DIELECTRICLAYER_EVAL_GET();
}
SYCL_EXTERNAL BSDF_SampleRes MetallicPaint_BSDF_sample(
const varying BSDF *uniform super,
const vec3f &wo,
const vec2f &s,
float ss)
{
const varying MetallicPaint_BSDF *uniform self =
(const varying MetallicPaint_BSDF *uniform)super;
DIELECTRICLAYER_SAMPLE(self->dielectricLayer,
self->multi.super.scatteringType,
&self->multi.super,
MultiBSDF_sample);
return DIELECTRICLAYER_SAMPLE_GET();
}
///////////////////////////////////////////////////////////////////////////////
// External API
export void *uniform MetallicPaint_getBSDF_addr()
{
return (void *uniform)MetallicPaint_getBSDF;
}
OSPRAY_END_ISPC_NAMESPACE
|