[Bf-blender-cvs] [68593ab] temp-cycles-microdisplacement: Add geometry cache ; geom

Mai Lavelle noreply at git.blender.org
Tue Apr 12 18:45:51 CEST 2016


Commit: 68593ab7bf2f2d4fdbddf2b8ffb4371ed450a543
Author: Mai Lavelle
Date:   Wed Feb 24 12:46:10 2016 -0500
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rB68593ab7bf2f2d4fdbddf2b8ffb4371ed450a543

Add geometry cache ; geom

===================================================================

A	intern/cycles/kernel/geom/geom_cache_triangle.h
A	intern/cycles/kernel/geom/geom_subpatch.h
M	intern/cycles/kernel/kernel_shader.h
M	intern/cycles/kernel/kernel_subsurface.h
M	intern/cycles/kernel/osl/osl_services.cpp
M	intern/cycles/kernel/svm/svm_wireframe.h

===================================================================

diff --git a/intern/cycles/kernel/geom/geom_cache_triangle.h b/intern/cycles/kernel/geom/geom_cache_triangle.h
new file mode 100644
index 0000000..e9bb625
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_cache_triangle.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2011-2016 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device_inline bool cache_triangle_patch_is_quad(KernelGlobals *kg, const ShaderData *sd) {
+	return !(ccl_fetch(sd, cache_triangle).patch & 0x80000000);
+}
+
+ccl_device_inline float3 cache_triangle_refine(KernelGlobals *kg,
+                                         ShaderData *sd,
+                                         const Intersection *isect,
+                                         const Ray *ray)
+{
+	float3 P = ray->P;
+	float3 D = ray->D;
+	float t = isect->t;
+
+#ifdef __INTERSECTION_REFINE__
+	if(isect->object != OBJECT_NONE) {
+		if(UNLIKELY(t == 0.0f)) {
+			return P;
+		}
+#ifdef __OBJECT_MOTION__
+		Transform tfm = ccl_fetch(sd, ob_itfm);
+#else
+		Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+#endif
+
+		P = transform_point(&tfm, P);
+		D = transform_direction(&tfm, D*t);
+		D = normalize_len(D, &t);
+	}
+
+	P = P + D*t;
+
+	const float3 tri_a = sd->cache_triangle.verts[0],
+	             tri_b = sd->cache_triangle.verts[1],
+	             tri_c = sd->cache_triangle.verts[2];
+	float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z);
+	float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z);
+	float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
+	float3 qvec = cross(tvec, edge1);
+	float3 pvec = cross(D, edge2);
+	float rt = dot(edge2, qvec) / dot(edge1, pvec);
+
+	P = P + D*rt;
+
+	if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+		Transform tfm = ccl_fetch(sd, ob_tfm);
+#else
+		Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+#endif
+
+		P = transform_point(&tfm, P);
+	}
+
+	return P;
+#else
+	return P + D*t;
+#endif
+}
+
+/* Same as above, except that isect->t is assumed to be in object space for
+ * instancing.
+ */
+ccl_device_inline float3 cache_triangle_refine_subsurface(KernelGlobals *kg,
+                                                    ShaderData *sd,
+                                                    CacheTriangle* cache_triangle,
+                                                    const Intersection *isect,
+                                                    const Ray *ray)
+{
+	float3 P = ray->P;
+	float3 D = ray->D;
+	float t = isect->t;
+
+	if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+		Transform tfm = ccl_fetch(sd, ob_itfm);
+#else
+		Transform tfm = object_fetch_transform(kg,
+		                                       isect->object,
+		                                       OBJECT_INVERSE_TRANSFORM);
+#endif
+
+		P = transform_point(&tfm, P);
+		D = transform_direction(&tfm, D);
+		D = normalize(D);
+	}
+
+	P = P + D*t;
+
+#ifdef __INTERSECTION_REFINE__
+	const float3 tri_a = cache_triangle->verts[0],
+	             tri_b = cache_triangle->verts[1],
+	             tri_c = cache_triangle->verts[2];
+	float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z);
+	float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z);
+	float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
+	float3 qvec = cross(tvec, edge1);
+	float3 pvec = cross(D, edge2);
+	float rt = dot(edge2, qvec) / dot(edge1, pvec);
+
+	P = P + D*rt;
+#endif  /* __INTERSECTION_REFINE__ */
+
+	if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+		Transform tfm = ccl_fetch(sd, ob_tfm);
+#else
+		Transform tfm = object_fetch_transform(kg,
+		                                       isect->object,
+		                                       OBJECT_TRANSFORM);
+#endif
+
+		P = transform_point(&tfm, P);
+	}
+
+	return P;
+}
+
+
+ccl_device_noinline void cache_triangle_shader_setup(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, bool subsurface)
+{
+	ccl_fetch(sd, cache_triangle) = isect->cache_triangle;
+	CacheTriangle* tri = &ccl_fetch(sd, cache_triangle);
+
+	ccl_fetch(sd, shader) = tri->shader;
+
+	/* compute refined position */
+#ifdef __SUBSURFACE__
+	if(!subsurface)
+#endif
+		ccl_fetch(sd, P) = cache_triangle_refine(kg, sd, isect, ray);
+#ifdef __SUBSURFACE__
+	else
+		ccl_fetch(sd, P) = cache_triangle_refine_subsurface(kg, sd, &sd->cache_triangle, isect, ray);
+#endif
+
+	/* compute face normal */
+	float3 Ng;
+	if(ccl_fetch(sd, flag) & SD_NEGATIVE_SCALE_APPLIED)
+		Ng = normalize(cross(tri->verts[2] - tri->verts[0], tri->verts[1] - tri->verts[0]));
+	else
+		Ng = normalize(cross(tri->verts[1] - tri->verts[0], tri->verts[2] - tri->verts[0]));
+
+	ccl_fetch(sd, Ng) = Ng;
+	if(ccl_fetch(sd, shader) & SHADER_SMOOTH_NORMAL)
+		ccl_fetch(sd, N) = normalize(isect->u*tri->normals[0] + isect->v*tri->normals[1] + (1.0f-isect->u-isect->v)*tri->normals[2]);
+	else
+		ccl_fetch(sd, N) = Ng;
+
+	/* compute derivatives of P w.r.t. uv */
+#ifdef __DPDU__
+	ccl_fetch(sd, dPdu) = (tri->verts[0] - tri->verts[2]);
+	ccl_fetch(sd, dPdv) = (tri->verts[1] - tri->verts[2]);
+#endif
+}
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/geom/geom_subpatch.h b/intern/cycles/kernel/geom/geom_subpatch.h
new file mode 100644
index 0000000..051b416
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_subpatch.h
@@ -0,0 +1,506 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device_inline bool subpatch_is_quad(TessellatedSubPatch* patch) {
+	return !(patch->uv[3].x == -1);
+}
+
+/* Workaround stupidness of CUDA/OpenCL which doesn't allow to access indexed
+ * component of float3 value.
+ */
+#ifndef __KERNEL_CPU__
+#  define IDX(vec, idx) \
+    ((idx == 0) ? ((vec).x) : ( (idx == 1) ? ((vec).y) : ((vec).z) ))
+#else
+#  define IDX(vec, idx) ((vec)[idx])
+#endif
+
+ccl_device_inline bool subpatch_triangle_intersect(KernelGlobals *kg,
+                                                   const IsectPrecalc *isect_precalc,
+                                                   Intersection *isect,
+                                                   float3 P,
+                                                   const float4 tri_a,
+                                                   const float4 tri_b,
+                                                   const float4 tri_c)
+{
+	const int kx = isect_precalc->kx;
+	const int ky = isect_precalc->ky;
+	const int kz = isect_precalc->kz;
+	const float Sx = isect_precalc->Sx;
+	const float Sy = isect_precalc->Sy;
+	const float Sz = isect_precalc->Sz;
+
+	/* Calculate vertices relative to ray origin. */
+	const float3 A = make_float3(tri_a.x - P.x, tri_a.y - P.y, tri_a.z - P.z);
+	const float3 B = make_float3(tri_b.x - P.x, tri_b.y - P.y, tri_b.z - P.z);
+	const float3 C = make_float3(tri_c.x - P.x, tri_c.y - P.y, tri_c.z - P.z);
+
+	const float A_kx = IDX(A, kx), A_ky = IDX(A, ky), A_kz = IDX(A, kz);
+	const float B_kx = IDX(B, kx), B_ky = IDX(B, ky), B_kz = IDX(B, kz);
+	const float C_kx = IDX(C, kx), C_ky = IDX(C, ky), C_kz = IDX(C, kz);
+
+	/* Perform shear and scale of vertices. */
+	const float Ax = A_kx - Sx * A_kz;
+	const float Ay = A_ky - Sy * A_kz;
+	const float Bx = B_kx - Sx * B_kz;
+	const float By = B_ky - Sy * B_kz;
+	const float Cx = C_kx - Sx * C_kz;
+	const float Cy = C_ky - Sy * C_kz;
+
+	/* Calculate scaled barycentric coordinates. */
+	float U = Cx * By - Cy * Bx;
+	float V = Ax * Cy - Ay * Cx;
+	float W = Bx * Ay - By * Ax;
+	if((U < 0.0f || V < 0.0f || W < 0.0f) &&
+	   (U > 0.0f || V > 0.0f || W > 0.0f))
+	{
+		return false;
+	}
+
+	/* Calculate determinant. */
+	float det = U + V + W;
+	if(UNLIKELY(det == 0.0f)) {
+		return false;
+	}
+
+	/* Calculate scaled z-coordinates of vertices and use them to calculate
+	 * the hit distance.
+	 */
+	const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz;
+	const int sign_det = (__float_as_int(det) & 0x80000000);
+	const float sign_T = xor_signmask(T, sign_det);
+	if((sign_T < 0.0f) ||
+	   (sign_T > isect->t * xor_signmask(det, sign_det)))
+	{
+		return false;
+	}
+
+	/* Normalize U, V, W, and T. */
+	const float inv_det = 1.0f / det;
+	isect->u = U * inv_det;
+	isect->v = V * inv_det;
+	isect->t = T * inv_det;
+	return true;
+}
+
+/* Special ray intersection routines for subsurface scattering. In that case we
+ * only want to intersect with primitives in the same object, and if case of
+ * multiple hits we pick a single random primitive as the intersection point.
+ */
+
+#ifdef __SUBSURFACE__
+ccl_device_inline Intersection* subpatch_triangle_intersect_subsurface(
+        KernelGlobals *kg,
+        const IsectPrecalc *isect_precalc,
+        SubsurfaceIntersection *ss_isect,
+        float3 P,
+        float tmax,
+        uint *lcg_state,
+        int max_hits,
+        const float4 tri_a,
+        const float4 tri_b,
+        const float4 tri_c)
+{
+	const int kx = isect_precalc->kx;
+	const int ky = isect_precalc->ky;
+	const int kz 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list