Blender  V3.3
init_from_bake.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
6 #include "kernel/camera/camera.h"
7 
10 
12 
13 #include "kernel/sample/pattern.h"
14 
15 #include "kernel/geom/geom.h"
16 
18 
19 /* This helps with AA but it's not the real solution as it does not AA the geometry
20  * but it's better than nothing, thus committed. */
22 {
23  /* use mirror repeat (like opengl texture) so that if the barycentric
24  * coordinate goes past the end of the triangle it is not always clamped
25  * to the same value, gives ugly patterns */
26  u /= max;
27  float fu = floorf(u);
28  u = u - fu;
29 
30  return ((((int)fu) & 1) ? 1.0f - u : u) * max;
31 }
32 
33 /* Offset towards center of triangle to avoid ray-tracing precision issues. */
35  const int prim,
36  const float u,
37  const float v)
38 {
39  float3 tri_verts[3];
40  triangle_vertices(kg, prim, tri_verts);
41 
42  /* Empirically determined values, by no means perfect. */
43  const float position_offset = 1e-4f;
44  const float uv_offset = 1e-5f;
45 
46  /* Offset position towards center, amount relative to absolute size of position coordinates. */
47  const float3 P = u * tri_verts[0] + v * tri_verts[1] + (1.0f - u - v) * tri_verts[2];
48  const float3 center = (tri_verts[0] + tri_verts[1] + tri_verts[2]) / 3.0f;
49  const float3 to_center = center - P;
50 
51  const float3 offset_P = P + normalize(to_center) *
52  min(len(to_center),
53  max(reduce_max(fabs(P)), 1.0f) * position_offset);
54 
55  /* Compute barycentric coordinates at new position. */
56  const float3 v1 = tri_verts[1] - tri_verts[0];
57  const float3 v2 = tri_verts[2] - tri_verts[0];
58  const float3 vP = offset_P - tri_verts[0];
59 
60  const float d11 = dot(v1, v1);
61  const float d12 = dot(v1, v2);
62  const float d22 = dot(v2, v2);
63  const float dP1 = dot(vP, v1);
64  const float dP2 = dot(vP, v2);
65 
66  const float denom = d11 * d22 - d12 * d12;
67  if (denom == 0.0f) {
68  return make_float2(0.0f, 0.0f);
69  }
70 
71  const float offset_v = clamp((d22 * dP1 - d12 * dP2) / denom, uv_offset, 1.0f - uv_offset);
72  const float offset_w = clamp((d11 * dP2 - d12 * dP1) / denom, uv_offset, 1.0f - uv_offset);
73  const float offset_u = clamp(1.0f - offset_v - offset_w, uv_offset, 1.0f - uv_offset);
74 
75  return make_float2(offset_u, offset_v);
76 }
77 
78 /* Return false to indicate that this pixel is finished.
79  * Used by CPU implementation to not attempt to sample pixel for multiple samples once its known
80  * that the pixel did converge. */
85  const int x,
86  const int y,
87  const int scheduled_sample)
88 {
90 
91  /* Initialize path state to give basic buffer access and allow early outputs. */
93 
94  /* Check whether the pixel has converged and should not be sampled anymore. */
96  return false;
97  }
98 
99  /* Always count the sample, even if the camera sample will reject the ray. */
100  const int sample = kernel_accum_sample(
101  kg, state, render_buffer, scheduled_sample, tile->sample_offset);
102 
103  /* Setup render buffers. */
104  const int index = INTEGRATOR_STATE(state, path, render_pixel_index);
105  const int pass_stride = kernel_data.film.pass_stride;
106  ccl_global float *buffer = render_buffer + (uint64_t)index * pass_stride;
107 
108  ccl_global float *primitive = buffer + kernel_data.film.pass_bake_primitive;
109  ccl_global float *differential = buffer + kernel_data.film.pass_bake_differential;
110 
111  const int seed = __float_as_uint(primitive[0]);
112  int prim = __float_as_uint(primitive[1]);
113  if (prim == -1) {
114  /* Accumulate transparency for empty pixels. */
115  kernel_accum_transparent(kg, state, 0, 1.0f, buffer);
116  return true;
117  }
118 
119  prim += kernel_data.bake.tri_offset;
120 
121  /* Random number generator. */
122  const uint rng_hash = hash_uint(seed) ^ kernel_data.integrator.seed;
123 
124  float filter_x, filter_y;
125  if (sample == 0) {
126  filter_x = filter_y = 0.5f;
127  }
128  else {
129  path_rng_2D(kg, rng_hash, sample, PRNG_FILTER_U, &filter_x, &filter_y);
130  }
131 
132  /* Initialize path state for path integration. */
133  path_state_init_integrator(kg, state, sample, rng_hash);
134 
135  /* Barycentric UV. */
136  float u = primitive[2];
137  float v = primitive[3];
138 
139  float dudx = differential[0];
140  float dudy = differential[1];
141  float dvdx = differential[2];
142  float dvdy = differential[3];
143 
144  /* Exactly at vertex? Nudge inwards to avoid self-intersection. */
145  if ((u == 0.0f || u == 1.0f) && (v == 0.0f || v == 1.0f)) {
146  const float2 uv = bake_offset_towards_center(kg, prim, u, v);
147  u = uv.x;
148  v = uv.y;
149  }
150 
151  /* Sub-pixel offset. */
152  if (sample > 0) {
153  u = bake_clamp_mirror_repeat(u + dudx * (filter_x - 0.5f) + dudy * (filter_y - 0.5f), 1.0f);
154  v = bake_clamp_mirror_repeat(v + dvdx * (filter_x - 0.5f) + dvdy * (filter_y - 0.5f),
155  1.0f - u);
156  }
157 
158  /* Convert from Blender to Cycles/Embree/OptiX barycentric convention. */
159  const float tmp = u;
160  u = v;
161  v = 1.0f - tmp - v;
162 
163  const float tmpdx = dudx;
164  const float tmpdy = dudy;
165  dudx = dvdx;
166  dudy = dvdy;
167  dvdx = -tmpdx - dvdx;
168  dvdy = -tmpdy - dvdy;
169 
170  /* Position and normal on triangle. */
171  const int object = kernel_data.bake.object_index;
172  float3 P, Ng;
173  int shader;
174  triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
175 
176  const int object_flag = kernel_data_fetch(object_flag, object);
177  if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
179  P = transform_point_auto(&tfm, P);
180  }
181 
182  if (kernel_data.film.pass_background != PASS_UNUSED) {
183  /* Environment baking. */
184 
185  /* Setup and write ray. */
187  ray.P = zero_float3();
188  ray.D = normalize(P);
189  ray.tmin = 0.0f;
190  ray.tmax = FLT_MAX;
191  ray.time = 0.5f;
192  ray.dP = differential_zero_compact();
193  ray.dD = differential_zero_compact();
195 
196  /* Setup next kernel to execute. */
198  }
199  else {
200  /* Surface baking. */
201  float3 N = (shader & SHADER_SMOOTH_NORMAL) ? triangle_smooth_normal(kg, Ng, prim, u, v) : Ng;
202 
203  if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
206  Ng = normalize(transform_direction_transposed(&itfm, Ng));
207  }
208 
209  const int shader_index = shader & SHADER_MASK;
210  const int shader_flags = kernel_data_fetch(shaders, shader_index).flags;
211 
212  /* Fast path for position and normal passes not affected by shaders. */
213  if (kernel_data.film.pass_position != PASS_UNUSED) {
214  kernel_write_pass_float3(buffer + kernel_data.film.pass_position, P);
215  return true;
216  }
217  else if (kernel_data.film.pass_normal != PASS_UNUSED && !(shader_flags & SD_HAS_BUMP)) {
218  kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, N);
219  return true;
220  }
221 
222  /* Setup ray. */
224  ray.P = P + N;
225  ray.D = -N;
226  ray.tmin = 0.0f;
227  ray.tmax = FLT_MAX;
228  ray.time = 0.5f;
229 
230  /* Setup differentials. */
231  float3 dPdu, dPdv;
232  triangle_dPdudv(kg, prim, &dPdu, &dPdv);
233  if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
235  dPdu = transform_direction(&tfm, dPdu);
236  dPdv = transform_direction(&tfm, dPdv);
237  }
238 
239  differential3 dP;
240  dP.dx = dPdu * dudx + dPdv * dvdx;
241  dP.dy = dPdu * dudy + dPdv * dvdy;
242  ray.dP = differential_make_compact(dP);
243  ray.dD = differential_zero_compact();
244 
245  /* Write ray. */
247 
248  /* Setup and write intersection. */
250  isect.object = kernel_data.bake.object_index;
251  isect.prim = prim;
252  isect.u = u;
253  isect.v = v;
254  isect.t = 1.0f;
255  isect.type = PRIMITIVE_TRIANGLE;
256  integrator_state_write_isect(kg, state, &isect);
257 
258  /* Setup next kernel to execute. */
259  const bool use_caustics = kernel_data.integrator.use_caustics &&
260  (object_flag & SD_OBJECT_CAUSTICS);
261  const bool use_raytrace_kernel = (shader_flags & SD_HAS_RAYTRACE);
262 
263  if (use_caustics) {
266  }
267  else if (use_raytrace_kernel) {
270  }
271  else {
273  }
274  }
275 
276  return true;
277 }
278 
unsigned int uint
Definition: BLI_sys_types.h:67
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
ccl_device_inline void kernel_accum_transparent(KernelGlobals kg, ConstIntegratorState state, const uint32_t path_flag, const float transparent, ccl_global float *ccl_restrict buffer)
Definition: accumulate.h:535
ccl_device_inline int kernel_accum_sample(KernelGlobals kg, ConstIntegratorState state, ccl_global float *ccl_restrict render_buffer, int sample, int sample_offset)
Definition: accumulate.h:138
__forceinline int reduce_max(const avxi &v)
Definition: avxi.h:692
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static unsigned long seed
Definition: btSoftBody.h:39
#define ccl_restrict
Definition: cuda/compat.h:50
#define ccl_optional_struct_init
Definition: cuda/compat.h:53
#define ccl_device
Definition: cuda/compat.h:32
#define ccl_device_inline
Definition: cuda/compat.h:34
#define ccl_global
Definition: cuda/compat.h:43
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
ccl_device_forceinline float differential_make_compact(const differential3 D)
Definition: differential.h:117
ccl_device_forceinline float differential_zero_compact()
Definition: differential.h:112
int len
Definition: draw_manager.c:108
ccl_device_inline uint hash_uint(uint kx)
Definition: hash.h:59
ccl_device const float2 bake_offset_towards_center(KernelGlobals kg, const int prim, const float u, const float v)
CCL_NAMESPACE_BEGIN ccl_device_inline float bake_clamp_mirror_repeat(float u, float max)
ccl_device bool integrator_init_from_bake(KernelGlobals kg, IntegratorState state, ccl_global const KernelWorkTile *ccl_restrict tile, ccl_global float *render_buffer, const int x, const int y, const int scheduled_sample)
#define transform_point_auto
ccl_device_inline float3 transform_direction(ccl_private const Transform *t, const float3 a)
ccl_device_inline float3 transform_direction_transposed(ccl_private const Transform *t, const float3 a)
ccl_global float * buffer
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
const uint64_t render_pixel_index
ccl_global const KernelWorkTile * tile
const int state
ccl_gpu_kernel_postfix ccl_global float int int int int int int int pass_stride
CCL_NAMESPACE_BEGIN ccl_device_forceinline bool kernel_need_sample_pixel(KernelGlobals kg, ConstIntegratorState state, ccl_global float *render_buffer)
@ OBJECT_INVERSE_TRANSFORM
@ OBJECT_TRANSFORM
ccl_device_inline Transform object_fetch_transform(KernelGlobals kg, int object, enum ObjectTransform type)
@ SD_HAS_BUMP
Definition: kernel/types.h:782
@ SD_HAS_RAYTRACE
Definition: kernel/types.h:792
#define PASS_UNUSED
Definition: kernel/types.h:44
@ PRIMITIVE_TRIANGLE
Definition: kernel/types.h:551
@ PRNG_FILTER_U
Definition: kernel/types.h:154
@ SHADER_SMOOTH_NORMAL
Definition: kernel/types.h:435
@ SHADER_MASK
Definition: kernel/types.h:449
@ SD_OBJECT_CAUSTICS
Definition: kernel/types.h:829
@ SD_OBJECT_TRANSFORM_APPLIED
Definition: kernel/types.h:808
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE
@ DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND
#define PROFILING_INIT(kg, event)
ccl_device_inline float2 fabs(const float2 &a)
Definition: math_float2.h:222
ccl_device_inline float3 zero_float3()
Definition: math_float3.h:80
static float P(float k)
Definition: math_interp.c:25
#define N
#define make_float2(x, y)
Definition: metal/compat.h:203
#define floorf(x)
Definition: metal/compat.h:224
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
T clamp(const T &a, const T &min, const T &max)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
ccl_device_inline void path_state_init(IntegratorState state, ccl_global const KernelWorkTile *ccl_restrict tile, const int x, const int y)
Definition: path_state.h:24
ccl_device_inline void path_state_init_integrator(KernelGlobals kg, IntegratorState state, const int sample, const uint rng_hash)
Definition: path_state.h:37
ccl_device_forceinline void path_rng_2D(KernelGlobals kg, uint rng_hash, int sample, int dimension, ccl_private float *fx, ccl_private float *fy)
Definition: pattern.h:76
#define min(a, b)
Definition: sort.c:35
IntegratorStateCPU *ccl_restrict IntegratorState
Definition: state.h:147
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition: state.h:154
ccl_device_forceinline void integrator_path_init_sorted(KernelGlobals kg, IntegratorState state, const DeviceKernel next_kernel, const uint32_t key)
Definition: state_flow.h:142
ccl_device_forceinline void integrator_path_init(KernelGlobals kg, IntegratorState state, const DeviceKernel next_kernel)
Definition: state_flow.h:135
ccl_device_forceinline void integrator_state_write_isect(KernelGlobals kg, IntegratorState state, ccl_private const Intersection *ccl_restrict isect)
Definition: state_util.h:68
CCL_NAMESPACE_BEGIN ccl_device_forceinline void integrator_state_write_ray(KernelGlobals kg, IntegratorState state, ccl_private const Ray *ccl_restrict ray)
Definition: state_util.h:14
unsigned __int64 uint64_t
Definition: stdint.h:90
float x
Definition: types_float2.h:15
float y
Definition: types_float2.h:15
float max
ccl_device_inline float3 triangle_smooth_normal(KernelGlobals kg, float3 Ng, int prim, float u, float v)
Definition: triangle.h:92
ccl_device_inline void triangle_point_normal(KernelGlobals kg, int object, int prim, float u, float v, ccl_private float3 *P, ccl_private float3 *Ng, ccl_private int *shader)
Definition: triangle.h:33
ccl_device_inline void triangle_vertices(KernelGlobals kg, int prim, float3 P[3])
Definition: triangle.h:65
ccl_device_inline void triangle_dPdudv(KernelGlobals kg, int prim, ccl_private float3 *dPdu, ccl_private float3 *dPdv)
Definition: triangle.h:128
ccl_device_inline uint __float_as_uint(float f)
Definition: util/math.h:263
@ PROFILING_RAY_SETUP
ccl_device_inline void kernel_write_pass_float3(ccl_global float *ccl_restrict buffer, float3 value)
Definition: write_passes.h:21