[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, &current_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, &current_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, &current_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, &current_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