Blender V5.0
volume_fournier_forand.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2024 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include "kernel/types.h"
8
10
12
13/* FOURNIER-FORAND CLOSURE */
14
17
18 /* Precomputed coefficients, based on B and IOR */
19 float c1, c2, c3;
20};
21static_assert(sizeof(ShaderVolumeClosure) >= sizeof(FournierForandVolume),
22 "FournierForandVolume is too large!");
23
25 float B,
26 float IOR)
27{
29
30 /* clamp backscatter fraction to avoid delta function */
31 B = min(fabsf(B), 0.5f - 1e-3f);
32 IOR = max(IOR, 1.0f + 1e-3f);
33 const float3 coeffs = phase_fournier_forand_coeffs(B, IOR);
34 volume->c1 = coeffs.x;
35 volume->c2 = coeffs.y;
36 volume->c3 = coeffs.z;
37
38 return SD_SCATTER;
39}
40
43 const float3 wo,
44 ccl_private float *pdf)
45{
47 const float3 coeffs = make_float3(volume->c1, volume->c2, volume->c3);
48
49 /* note that wi points towards the viewer */
50 const float cos_theta = dot(-sd->wi, wo);
51 *pdf = phase_fournier_forand(cos_theta, coeffs);
52
53 return make_spectrum(*pdf);
54}
55
58 const float2 rand,
61 ccl_private float *pdf)
62{
64 const float3 coeffs = make_float3(volume->c1, volume->c2, volume->c3);
65
66 /* note that wi points towards the viewer and so is used negated */
67 *wo = phase_fournier_forand_sample(-sd->wi, coeffs, rand, pdf);
68 *eval = make_spectrum(*pdf); /* perfect importance sampling */
69
71}
72
ccl_device_inline float cos_theta(const float3 w)
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
#define make_spectrum(f)
#define ccl_private
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
@ CLOSURE_VOLUME_FOURNIER_FORAND_ID
@ SD_SCATTER
@ LABEL_VOLUME_SCATTER
#define B
#define fabsf
#define ccl_device
#define min(a, b)
Definition sort.cc:36
float z
Definition sky_math.h:136
float y
Definition sky_math.h:136
float x
Definition sky_math.h:136
max
Definition text_draw.cc:251
float3 Spectrum
ccl_device Spectrum volume_fournier_forand_eval(const ccl_private ShaderData *sd, const ccl_private ShaderVolumeClosure *svc, const float3 wo, ccl_private float *pdf)
ccl_device int volume_fournier_forand_sample(const ccl_private ShaderData *sd, const ccl_private ShaderVolumeClosure *svc, const float2 rand, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf)
ccl_device int volume_fournier_forand_setup(ccl_private FournierForandVolume *volume, float B, float IOR)
ccl_device_inline float3 phase_fournier_forand_coeffs(const float B, const float IOR)
ccl_device float3 phase_fournier_forand_sample(const float3 D, const float3 coeffs, const float2 rand, ccl_private float *pdf)
ccl_device float phase_fournier_forand(const float cos_theta, const float3 coeffs)