Blender V4.3
ao.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include "kernel/bvh/bvh.h"
8
10
11#ifdef __SHADER_RAYTRACE__
12
13# ifdef __KERNEL_OPTIX__
14extern "C" __device__ float __direct_callable__svm_node_ao(
15# else
16ccl_device float svm_ao(
17# endif
21 float3 N,
22 float max_dist,
23 int num_samples,
24 int flags)
25{
26 if (flags & NODE_AO_GLOBAL_RADIUS) {
27 max_dist = kernel_data.integrator.ao_bounces_distance;
28 }
29
30 /* Early out if no sampling needed. */
31 if (max_dist <= 0.0f || num_samples < 1 || sd->object == OBJECT_NONE) {
32 return 1.0f;
33 }
34
35 /* Can't ray-trace from shaders like displacement, before BVH exists. */
36 if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) {
37 return 1.0f;
38 }
39
40 if (flags & NODE_AO_INSIDE) {
41 N = -N;
42 }
43
44 float3 T, B;
45 make_orthonormals(N, &T, &B);
46
47 /* TODO: support ray-tracing in shadow shader evaluation? */
48 RNGState rng_state;
49 path_state_rng_load(state, &rng_state);
50
51 int unoccluded = 0;
52 for (int sample = 0; sample < num_samples; sample++) {
53 const float2 rand_disk = path_branched_rng_2D(
54 kg, &rng_state, sample, num_samples, PRNG_SURFACE_AO);
55
56 float2 d = sample_uniform_disk(rand_disk);
57 float3 D = make_float3(d.x, d.y, safe_sqrtf(1.0f - dot(d, d)));
58
59 /* Create ray. */
60 Ray ray;
61 ray.P = sd->P;
62 ray.D = D.x * T + D.y * B + D.z * N;
63 ray.tmin = 0.0f;
64 ray.tmax = max_dist;
65 ray.time = sd->time;
66 ray.self.object = sd->object;
67 ray.self.prim = sd->prim;
68 ray.self.light_object = OBJECT_NONE;
69 ray.self.light_prim = PRIM_NONE;
70 ray.self.light = LAMP_NONE;
73
74 if (flags & NODE_AO_ONLY_LOCAL) {
75 if (!scene_intersect_local(kg, &ray, NULL, sd->object, NULL, 0)) {
76 unoccluded++;
77 }
78 }
79 else {
81 unoccluded++;
82 }
83 }
84 }
85
86 return ((float)unoccluded) / num_samples;
87}
88
89template<uint node_feature_mask, typename ConstIntegratorGenericState>
90# if defined(__KERNEL_OPTIX__)
92# else
94# endif
95 void
96 svm_node_ao(KernelGlobals kg,
97 ConstIntegratorGenericState state,
99 ccl_private float *stack,
100 uint4 node)
101{
102 uint flags, dist_offset, normal_offset, out_ao_offset;
103 svm_unpack_node_uchar4(node.y, &flags, &dist_offset, &normal_offset, &out_ao_offset);
104
105 uint color_offset, out_color_offset, samples;
106 svm_unpack_node_uchar3(node.z, &color_offset, &out_color_offset, &samples);
107
108 float ao = 1.0f;
109
111 {
112 float dist = stack_load_float_default(stack, dist_offset, node.w);
113 float3 normal = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
114
115# ifdef __KERNEL_OPTIX__
116 ao = optixDirectCall<float>(0, kg, state, sd, normal, dist, samples, flags);
117# else
118 ao = svm_ao(kg, state, sd, normal, dist, samples, flags);
119# endif
120 }
121
122 if (stack_valid(out_ao_offset)) {
123 stack_store_float(stack, out_ao_offset, ao);
124 }
125
126 if (stack_valid(out_color_offset)) {
127 float3 color = stack_load_float3(stack, color_offset);
128 stack_store_float3(stack, out_color_offset, ao * color);
129 }
130}
131
132#endif /* __SHADER_RAYTRACE__ */
133
MINLINE float safe_sqrtf(float a)
unsigned int uint
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define ccl_device
#define ccl_private
#define ccl_device_inline
#define ccl_device_noinline
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define NULL
#define __device__
ccl_device_forceinline float differential_zero_compact()
ccl_device_intersect bool scene_intersect_shadow(KernelGlobals kg, ccl_private const Ray *ray, const uint visibility)
ccl_device_inline void stack_store_float3(ccl_private float *stack, uint a, float3 f)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(ccl_private float *stack, uint a)
ccl_device_forceinline void svm_unpack_node_uchar3(uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z)
ccl_device_inline float stack_load_float_default(ccl_private float *stack, uint a, uint value)
ccl_device_inline void stack_store_float(ccl_private float *stack, uint a, float f)
ccl_device_forceinline void svm_unpack_node_uchar4(uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z, ccl_private uint *w)
ccl_device_inline bool stack_valid(uint a)
@ NODE_AO_INSIDE
@ NODE_AO_GLOBAL_RADIUS
@ NODE_AO_ONLY_LOCAL
#define IF_KERNEL_NODES_FEATURE(feature)
@ PRNG_SURFACE_AO
#define PRIM_NONE
@ PATH_RAY_SHADOW_OPAQUE
#define OBJECT_NONE
ShaderData
@ BVH_LAYOUT_NONE
#define LAMP_NONE
static ulong state[N]
#define N
#define T
#define B
ccl_device_inline void path_state_rng_load(ConstIntegratorState state, ccl_private RNGState *rng_state)
Definition path_state.h:315
ccl_device_inline float2 path_branched_rng_2D(KernelGlobals kg, ccl_private const RNGState *rng_state, const int branch, const int num_branches, const int dimension)
Definition path_state.h:375
CCL_NAMESPACE_BEGIN ccl_device float2 sample_uniform_disk(const float2 rand)
const IntegratorStateCPU *ccl_restrict ConstIntegratorState
Definition state.h:229
float3 P
float x
float y
float x
Definition sky_float3.h:27
ccl_device_inline void make_orthonormals(const float3 N, ccl_private float3 *a, ccl_private float3 *b)
Definition util/math.h:593