[Bf-blender-cvs] [d8da415d63b] cycles_embree: Cycles: Laid some foundation for embree ray accelerator: flags, UI and CMake
Stefan Werner
noreply at git.blender.org
Mon Sep 10 14:23:34 CEST 2018
Commit: d8da415d63b092f707cb25bb25b2105f90996fd7
Author: Stefan Werner
Date: Mon Sep 10 13:52:33 2018 +0200
Branches: cycles_embree
https://developer.blender.org/rBd8da415d63b092f707cb25bb25b2105f90996fd7
Cycles: Laid some foundation for embree ray accelerator: flags, UI and CMake
Cycles: more work on embree integration - triangle meshes now support deformation motion blur
Cycles: Progress with embree integration, still incomplete however
Cycles: Embree accelerator now supports instanced triangle meshes
Cycles: Embree support for ribbon line segments and subsurface scattering
Cycles: Added volume support for embree
Cycles: added memory and progress callbacks to embree
Cycles: embree hair now uses curve and not line segments, no more intersection filters for closest hit queries
Cycles: improvements to hair rendering using embree
Cycles: Added support for BVH refitting/dynamic meshes with embree
Cycles: improved defaults for embree option, enable embree in the UI only when a CPU device is selected
Cycles: prevented interactive rendering from crashing with Embree when objects are made invisible - RTCScenes now only get deleted by the top level BVH
Cycles: fixed some warnings in embree integration
Cycles: fixed Windows build with Embree
Cycles: Added Embree to Unix CMake files
Cycles: fixed Embree transparent shadow ray intersection to terminate properly when opaque objects are hit
Cycles: Added runtime checks for Embree build. If Embree is not configured correctly, it will print warnings to the console.
Cycles: Fixed parametric coordinates for hair intersections with Embree
Cycles: Extended Embree integration
Implemented ribbon curves and thick curves for hair.
Embree now obeys the static/dynamic BVH setting.
Cycles: removed use of constexpr to stay compatible with pre-C++11 compilers
Cycles: Set the compact flag on Embree to save memory
Cycles: Fixed wrong Embree line intersections
Line segments should not go through the backfacing test.
Cycles: Code style cleanup
Cycles: Fixed a crash when setting up Embree hair curves
Cycles: Fixed Embree Volume rendering when the camera is inside a volume
Cycles: Matched motion interpolation to Embree's interpolation
When Embree is turned on, the transform matrices of motion steps are now interpolated linearly (the wrong way). Cycles itself has a better way of interpolating, but when mixing it with Embree's direct matrix interpolation, it results in artefacts.
Cycles: Removed scaling from Embree's object motion blur.
Cycles native drops scaling from motion interpolation, the scale of the center of the frame gets reused to all motion positions. Embree could interpolate scaling too, but mixing the two then causes trouble with secondary rays, as Cycles does its own transformation interpolation in the intersection refinement. For now, restrict Embree to the common denominator, hopefully soon we can reintroduce scaling motion blur to Cycles.
Revert "Cycles: Removed scaling from Embree's object motion blur."
This reverts commit 3194e05d3f27124924f81b70400fb45fe022d9e4.
Merge branch 'master' of git.blender.org:blender into cycles_embree
# Conflicts:
# intern/cycles/bvh/bvh.cpp
# intern/cycles/device/device.cpp
# intern/cycles/device/device.h
# intern/cycles/device/device_cpu.cpp
# intern/cycles/kernel/geom/geom_object.h
# intern/cycles/render/mesh.cpp
# intern/cycles/render/scene.h
Merge branch 'master' of git.blender.org:blender into cycles_embree
Merge branch 'master' of git.blender.org:blender into cycles_embree
Merge branch 'master' of git.blender.org:blender into cycles_embree
Merge branch 'cycles_embree' of git.blender.org:blender into cycles_embree
Merge branch 'master' of git.blender.org:blender into cycles_embree
# Conflicts:
# intern/cycles/blender/addon/properties.py
Cycles: Updated Embree integration to version 3.2
Cycles: Raised thread stack size to 1MB for macOS to be consistent with Windows.
Embree BVH builds would run out of stack space in the default of 512kB.
This means macOS builds have to stay with pthreads and can't use std::thread.
Revert "Cycles: Raised thread stack size to 1MB for macOS to be consistent with Windows."
This reverts commit 151b5a9a1e568476c6886709b460edbf0936f7f7.
Set thread stack size on macOS to 1MB for Embree builds.
Merge branch 'master' of git.blender.org:blender into cycles_embree
Cycles: Fixes for transparent shadows and SSS when using Embree.
Cycles: Small fixes for Embree.
Cycles: Code formatting in Embree integration.
Cycles: Switched Embree curves to Hermite basis. Unforunately, Embree 3.2.0 has a bug with Hermite basis ribbons, so those won't render correctly at the moment.
Cycles: Improved stability with Embree memory callback
Cycles: Code style fixes for Embree, removing some unused data.
Cycles: Some more cleanup in Embree integration, added intersection filter to do backfacing hair correctly.
Merge branch 'master' of git.blender.org:blender into cycles_embree
# Conflicts:
# intern/cycles/blender/blender_sync.cpp
# intern/cycles/bvh/bvh.cpp
# intern/cycles/device/device_cpu.cpp
# intern/cycles/kernel/kernel_types.h
Cycles: Embree now traverses only the object subtree for local intersection tests.
Cycles: Some cleanup of Embree integration.
Cycles: Some style fixes for Embree integration.
Cycles: Some more cleanup/commenting for Embree integration.
Differential Revision: https://developer.blender.org/D3682
===================================================================
M intern/cycles/bvh/bvh_embree.cpp
===================================================================
diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index d0dac07c7e2..2122d09ec7e 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2017, Blender Foundation.
+ * Copyright 2018, Blender Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,24 @@
* limitations under the License.
*/
+/* This class implemens a ray accelerator for Cycles using Intel's Embree library.
+ * It supports triangles, curves, object and deformation blur and instancing.
+ * Not supported are thick line segments, those have no native equivalent in Embree.
+ * They could be implemented using Embree's thick curves, at the expense of wasted memory.
+ * User defined intersections for Embree could also be an option, but since Embree only uses aligned BVHs
+ * for user geometry, this would come with reduced performance and/or higher memory usage.
+ *
+ * Since Embree allows object to be either curves or triangles but not both, Cycles object IDs are maapped
+ * to Embree IDs by multiplying by two and adding one for curves.
+ *
+ * This implementation shares RTCDevices between Cycles instances. Eventually each instance should get
+ * a separate RTCDevice to correctly keep track of memory usage.
+ *
+ * Vertex and index buffers are duplicated between Cycles device arrays and Embree. These could be merged,
+ * which would requrie changes to intersection refinement, shader setup, mesh light sampling and a few
+ * other places in Cycles where direct access to vertex data is required.
+ */
+
#ifdef WITH_EMBREE
#include <pmmintrin.h>
@@ -46,6 +64,7 @@ CCL_NAMESPACE_BEGIN
void rtc_filter_func(const RTCFilterFunctionNArguments *args);
void rtc_filter_func(const RTCFilterFunctionNArguments *args)
{
+ /* Current implementation in Cycles assumes only single-ray intersection queries. */
assert(args->N == 1);
const RTCRay *ray = (RTCRay*)args->ray;
@@ -83,120 +102,122 @@ void rtc_filter_occluded_func(const RTCFilterFunctionNArguments* args)
}
}
- if(ctx->type == CCLIntersectContext::RAY_SHADOW_ALL) {
- /* Append the intersection to the end of the array. */
- if(ctx->num_hits < ctx->max_hits) {
- Intersection current_isect;
- kernel_embree_convert_hit(kg, ray, hit, ¤t_isect);
- for(size_t i = 0; i < ctx->max_hits; ++i) {
- if(current_isect.object == ctx->isect_s[i].object &&
- current_isect.prim == ctx->isect_s[i].prim &&
- current_isect.t == ctx->isect_s[i].t) {
- /* This intersection was already recorded, skip it. */
+ switch(ctx->type) {
+ case CCLIntersectContext::RAY_SHADOW_ALL: {
+ /* Append the intersection to the end of the array. */
+ if(ctx->num_hits < ctx->max_hits) {
+ Intersection current_isect;
+ kernel_embree_convert_hit(kg, ray, hit, ¤t_isect);
+ for(size_t i = 0; i < ctx->max_hits; ++i) {
+ if(current_isect.object == ctx->isect_s[i].object &&
+ current_isect.prim == ctx->isect_s[i].prim &&
+ current_isect.t == ctx->isect_s[i].t) {
+ /* This intersection was already recorded, skip it. */
+ *args->valid = 0;
+ break;
+ }
+ }
+ Intersection *isect = &ctx->isect_s[ctx->num_hits];
+ ctx->num_hits++;
+ *isect = current_isect;
+ int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ int shader = 0;
+ if(kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
+ shader = kernel_tex_fetch(__tri_shader, prim);
+ }
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
+ int flag = kernel_tex_fetch(__shaders, shader & SHADER_MASK).flags;
+ /* If no transparent shadows, all light is blocked. */
+ if(flag & (SD_HAS_TRANSPARENT_SHADOW)) {
+ /* This tells Embree to continue tracing. */
*args->valid = 0;
- return;
}
}
- Intersection *isect = &ctx->isect_s[ctx->num_hits];
- ctx->num_hits++;
- *isect = current_isect;
- int prim = kernel_tex_fetch(__prim_index, isect->prim);
- int shader = 0;
- if(kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
- shader = kernel_tex_fetch(__tri_shader, prim);
- }
else {
- float4 str = kernel_tex_fetch(__curves, prim);
- shader = __float_as_int(str.z);
+ /* Increase the number of hits beyond ray.max_hits
+ * so that the caller can detect this as opaque. */
+ ctx->num_hits++;
}
- int flag = kernel_tex_fetch(__shaders, shader & SHADER_MASK).flags;
- /* If no transparent shadows, all light is blocked. */
- if(flag & (SD_HAS_TRANSPARENT_SHADOW)) {
- /* This tells Embree to continue tracing. */
- *args->valid = 0;
- }
- }
- else {
- /* Increase the number of hits beyond ray.max_hits
- * so that the caller can detect this as opaque. */
- ctx->num_hits++;
- }
- return;
- }
- else if(ctx->type == CCLIntersectContext::RAY_SSS) {
- /* No intersection information requested, just return a hit. */
- if(ctx->max_hits == 0) {
- return;
+ break;
}
-
- /* See triangle_intersect_subsurface() for the native equivalent. */
- for(int i = min(ctx->max_hits, ctx->ss_isect->num_hits) - 1; i >= 0; --i) {
- if(ctx->ss_isect->hits[i].t == ray->tfar) {
- /* This tells Embree to continue tracing. */
- *args->valid = 0;
- return;
+ case CCLIntersectContext::RAY_SSS: {
+ /* No intersection information requested, just return a hit. */
+ if(ctx->max_hits == 0) {
+ break;
}
- }
- ctx->ss_isect->num_hits++;
- int hit_idx;
+ /* See triangle_intersect_subsurface() for the native equivalent. */
+ for(int i = min(ctx->max_hits, ctx->ss_isect->num_hits) - 1; i >= 0; --i) {
+ if(ctx->ss_isect->hits[i].t == ray->tfar) {
+ /* This tells Embree to continue tracing. */
+ *args->valid = 0;
+ break;
+ }
+ }
- if(ctx->ss_isect->num_hits <= ctx->max_hits) {
- hit_idx = ctx->ss_isect->num_hits - 1;
- }
- else {
- /* reservoir sampling: if we are at the maximum number of
- * hits, randomly replace element or skip it */
- hit_idx = lcg_step_uint(ctx->lcg_state) % ctx->ss_isect->num_hits;
+ ctx->ss_isect->num_hits++;
+ int hit_idx;
- if(hit_idx >= ctx->max_hits) {
- /* This tells Embree to continue tracing. */
- *args->valid = 0;
- return;
+ if(ctx->ss_isect->num_hits <= ctx->max_hits) {
+ hit_idx = ctx->ss_isect->num_hits - 1;
}
- }
- /* record intersection */
- kernel_embree_convert_local_hit(kg, ray, hit, &ctx->ss_isect->hits[hit_idx], ctx->sss_object_id);
- ctx->ss_isect->Ng[hit_idx].x = hit->Ng_x;
- ctx->ss_isect->Ng[hit_idx].y = hit->Ng_y;
- ctx->ss_isect->Ng[hit_idx].z = hit->Ng_z;
- ctx->ss_isect->Ng[hit_idx] = normalize(ctx->ss_isect->Ng[hit_idx]);
- /* this tells Embree to continue tracing */
- *args->valid = 0;
- return;
- }
- else if(ctx->type == CCLIntersectContext::RAY_VOLUME_ALL) {
- /* Append the intersection to the end of the array. */
- if(ctx->num_hits < ctx->max_hits) {
- Intersection current_isect;
- kernel_embree_convert_hit(kg, ray, hit, ¤t_isect);
- for(size_t i = 0; i < ctx->max_hits; ++i) {
- if(current_isect.object == ctx->isect_s[i].object &&
- current_isect.prim == ctx->isect_s[i].prim &&
- current_isect.t == ctx->isect_s[i].t) {
- /* This intersection was already recorded, skip it. */
+ else {
+ /* reservoir sampling: if we are at the maximum number of
+ * hits, randomly replace element or skip it */
+ hit_idx = lcg_step_uint(ctx->lcg_state) % ctx->ss_isect->num_hits;
+
+ if(hit_idx >= ctx->max_hits) {
+ /* This tells Embree to continue tracing. */
*args->valid = 0;
- return;
+ break;
}
}
- Intersection *isect = &ctx->isect_s[ctx->num_hits];
- ctx->num_hits++;
- *isect = current_isect;
- /* Only primitives from volume object. */
- uint tri_object = (isect->object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, isect->prim) : isect->object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- ctx->num_hits--;
- }
- /* This tells Embree to continue tracing. */
+ /* record intersection */
+ kernel_embree_convert_local_hit(kg, ray, hit, &ctx->ss_isect->hits[hit_idx], ctx->sss_object_id);
+ ctx->ss_isect->Ng[hit_idx].x = hit->Ng_x;
+ ctx->ss_isect->Ng[hit_idx].y = hit->Ng_y;
+ ctx->ss_isect->Ng[hit_idx].z = hit->Ng_z;
+ ctx->ss_isect->Ng[hit_idx] = normalize(ctx->ss_isect->Ng[hit_idx]);
+ /* this tells Embree to continue tracing */
*args->valid = 0;
- return;
+ break;
+ }
+ case CCLIntersectContext::RAY_VOLUME_ALL: {
+ /* Append the intersection to the end of the array. */
+ if(ctx->num_hits < ctx->max_hits) {
+ Intersection current_isect;
+ kernel_embree_convert_hit(kg, ray, hit, ¤t_isect);
+ for(size_t i = 0; i < ctx->max_hits; ++i) {
+ if(current_isect.object == ctx->isect_s[i].object &&
+ current_isect.prim == ctx->isect_s[i].prim &&
+ current_isect.t == ctx->isect_s[i].t) {
+ /* This intersection was already recorded, skip it. */
+ *args->valid = 0;
+ break;
+ }
+ }
+ Intersection *isect = &ctx->isect_s[ctx->num_hits];
+ ctx->num_hits++;
+ *isect = current_isect;
+ /* Only primitives from volume object. */
+ uint tri_object = (isect->object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, isect->prim) : isect->object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ ctx->num_hits--;
+ }
+ /* This tells Embree to continue tracing. */
+ *args->valid = 0;
+ break;
+ }
}
- return;
+ case CCLIntersectContext::RAY_REGULAR:
+ /* nothing to do here. */
+ break;
}
-
- return;
}
static size_t unaccounted_mem = 0;
@@ -605,11 +626,11 @@ void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh* mesh
if(use_curves) {
rtc_tangents = (float4*)rtcSetNewGeometryBuffer(geom_id, RTC_BUFFER_TYPE_TANGENT, t,
RTC_FORMAT_FLOAT4
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list