[Bf-blender-cvs] [aa7f326] temp-cycles-microdisplacement: Enable displacement for geometry cache

Mai Lavelle noreply at git.blender.org
Tue Apr 12 18:46:00 CEST 2016


Commit: aa7f326a9f55c18850fb92c5fab45991b54a8be2
Author: Mai Lavelle
Date:   Sat Mar 12 01:14:45 2016 -0500
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rBaa7f326a9f55c18850fb92c5fab45991b54a8be2

Enable displacement for geometry cache

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

M	intern/cycles/kernel/geom/geom_cache.cpp
M	intern/cycles/kernel/geom/geom_cache.h
M	intern/cycles/kernel/geom/geom_cache_triangle.h
M	intern/cycles/kernel/kernel_bake.h
M	intern/cycles/kernel/kernel_emission.h
M	intern/cycles/kernel/kernel_shader.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h
M	intern/cycles/render/mesh_displace.cpp
M	intern/cycles/render/object.cpp

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

diff --git a/intern/cycles/kernel/geom/geom_cache.cpp b/intern/cycles/kernel/geom/geom_cache.cpp
index c6d9ce2..d1499b8 100644
--- a/intern/cycles/kernel/geom/geom_cache.cpp
+++ b/intern/cycles/kernel/geom/geom_cache.cpp
@@ -140,6 +140,31 @@ static void geom_cache_update_subpatch_size(GeomCache* geom_cache, int object, i
 	mesh->subpatches[prim].cached_tessellated_size = size;
 }
 
+static void _geom_cache_sample_subpatch_vert(TessellatedSubPatch *subpatch, int vert, float3 *P, float3 *N, float *u, float *v, int *shader)
+{
+	float4* _v = &subpatch->data[subpatch->vert_offset+vert*2];
+	float4* _n = &subpatch->data[subpatch->vert_offset+vert*2+1];
+
+	*P = float4_to_float3(*_v);
+	*N = float4_to_float3(*_n);
+	*shader = subpatch->shader;
+
+	/* uv within patch */
+	float2 uv = make_float2(_v->w, _n->w);
+#if 0
+	if(subpatch_is_quad(subpatch)) {
+		uv = interp(interp(subpatch->uv[0], subpatch->uv[1], uv.x),
+				           interp(subpatch->uv[2], subpatch->uv[3], uv.x), uv.y);
+	}
+	else {
+		uv = uv.x*subpatch->uv[0] + uv.y*subpatch->uv[1] + (1.0f-uv.x-uv.y)*subpatch->uv[2];
+	}
+#endif
+
+	*u = uv.x;
+	*v = uv.y;
+}
+
 TessellatedSubPatch* geom_cache_get_subpatch(KernelGlobals *kg, int object, int prim)
 {
 	GeomCache* geom_cache = kg->geom_cache;
@@ -151,6 +176,12 @@ TessellatedSubPatch* geom_cache_get_subpatch(KernelGlobals *kg, int object, int
 	GeomCache::lru_t::ref_t ref;
 
 	if(!lru->find_or_lock(key, ref, tdata->lru_tdata)) {
+		bool sample_displacement = false;
+		if(object & 0x80000000) {
+			object &= 0x7fffffff;
+			sample_displacement = true;
+		}
+
 		// get patch size
 		uint num_verts, num_tris, bvh_size = 0;
 		int total_size = -1;
@@ -182,15 +213,52 @@ TessellatedSubPatch* geom_cache_get_subpatch(KernelGlobals *kg, int object, int
 		geom_cache_dice_subpatch(geom_cache, subpatch, object, prim);
 
 		// displace
-		// TODO(mai): implement
+		if(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_HAS_DISPLACEMENT) {
+			for(int i = 0; i < num_verts; i++) {
+				float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
+				float u, v;
+				int shader;
+
+				_geom_cache_sample_subpatch_vert(subpatch, i, &P, &Ng, &u, &v, &shader);
+
+				shader |= SHADER_SMOOTH_NORMAL;
+
+				ShaderData sd;
+				shader_setup_from_sample(kg, &sd, P, Ng, I, shader, object, prim, PRIMITIVE_CACHE_TRIANGLE,
+					u, v, 0.0f, TIME_INVALID);
+
+				// TODO(mai): move this into shader_setup_from_sample
+				sd.cache_triangle.patch = subpatch->patch;
+				for(int j = 0; j < 4; j++) {
+					sd.cache_triangle.v[j] = subpatch->v[j];
+				}
 
-		// build bvh
-		bvh_size = subpatch_build_bvh(subpatch, bvh_size);
+				/* evaluate */
+				PathState state = {0};
+				shader_eval_displacement(kg, &sd, &state, SHADER_CONTEXT_MAIN);
 
-		// update size for next time
-		if(total_size < 0) {
-			size = sizeof(TessellatedSubPatch) + sizeof(float4)*(num_verts*2 + subpatch->num_triangles + bvh_size);
-			geom_cache_update_subpatch_size(geom_cache, object, prim, size);
+				float4* vert = &subpatch->data[subpatch->vert_offset+i*2];
+
+				if(!sample_displacement) {
+					*vert = make_float4(sd.P.x, sd.P.y, sd.P.z, vert->w);
+				}
+				else {
+					*vert = make_float4(sd.P.x-vert->x, sd.P.y-vert->y, sd.P.z-vert->z, vert->w);
+				}
+
+				*(vert+1) = make_float4(sd.N.x, sd.N.y, sd.N.z, (vert+1)->w);
+			}
+		}
+
+		if(!sample_displacement) {
+			// build bvh
+			bvh_size = subpatch_build_bvh(subpatch, bvh_size);
+
+			// update size for next time
+			if(total_size < 0) {
+				size = sizeof(TessellatedSubPatch) + sizeof(float4)*(num_verts*2 + subpatch->num_triangles + bvh_size);
+				geom_cache_update_subpatch_size(geom_cache, object, prim, size);
+			}
 		}
 
 		// signal subpatch completion
@@ -212,6 +280,20 @@ void geom_cache_release_subpatch(KernelGlobals *kg, TessellatedSubPatch *subpatc
 	ref.dec(); /* extra unref to cause subpatch to dellocated when scope ends (if ref not held elsewhere) */
 }
 
+void geom_cache_sample_subpatch_vert(KernelGlobals *kg, int object, int prim, int vert, float3 *P, float3 *N, float *u, float *v, int *shader)
+{
+	TessellatedSubPatch* subpatch = geom_cache_get_subpatch(kg, object, prim);
+	_geom_cache_sample_subpatch_vert(subpatch, vert, P, N, u, v, shader);
+	geom_cache_release_subpatch(kg, subpatch);
+}
+
+void geom_cache_sample_subpatch_vert_displacement(KernelGlobals *kg, int object, int prim, int vert, float3 *dP)
+{
+	TessellatedSubPatch* subpatch = geom_cache_get_subpatch(kg, object | 0x80000000, prim);
+	*dP = float4_to_float3(subpatch->data[subpatch->vert_offset + vert*2]);
+	geom_cache_release_subpatch(kg, subpatch);
+}
+
 CCL_NAMESPACE_END
 
 
diff --git a/intern/cycles/kernel/geom/geom_cache.h b/intern/cycles/kernel/geom/geom_cache.h
index 5f423ca..17cd5ba 100644
--- a/intern/cycles/kernel/geom/geom_cache.h
+++ b/intern/cycles/kernel/geom/geom_cache.h
@@ -20,6 +20,7 @@ struct GeomCache;
 
 GeomCache* geom_cache_create();
 void geom_cache_release(GeomCache *geom_cache);
+
 void geom_cache_set_scene(GeomCache *geom_cache, void *scene);
 void geom_cache_thread_init(KernelGlobals *kg, GeomCache *geom_cache);
 void geom_cache_clear(GeomCache *geom_cache);
@@ -28,6 +29,10 @@ void geom_cache_set_max_size(GeomCache * geom_cache, uint max_size);
 TessellatedSubPatch* geom_cache_get_subpatch(KernelGlobals *kg, int object, int prim);
 void geom_cache_release_subpatch(KernelGlobals *kg, TessellatedSubPatch *subpatch);
 
+void geom_cache_sample_subpatch_vert(KernelGlobals *kg, int object, int prim, int vert, float3 *P, float3 *N,
+                                     float *u, float *v, int *shader);
+void geom_cache_sample_subpatch_vert_displacement(KernelGlobals *kg, int object, int prim, int vert, float3 *dP);
+
 CCL_NAMESPACE_END
 
 
diff --git a/intern/cycles/kernel/geom/geom_cache_triangle.h b/intern/cycles/kernel/geom/geom_cache_triangle.h
index e9bb625..6005998 100644
--- a/intern/cycles/kernel/geom/geom_cache_triangle.h
+++ b/intern/cycles/kernel/geom/geom_cache_triangle.h
@@ -133,6 +133,10 @@ ccl_device_inline float3 cache_triangle_refine_subsurface(KernelGlobals *kg,
 	return P;
 }
 
+ccl_device_inline float3 cache_triangle_smooth_normal(KernelGlobals *kg, CacheTriangle *tri, float u, float v)
+{
+	return normalize(u*tri->normals[0] + v*tri->normals[1] + (1.0f-u-v)*tri->normals[2]);
+}
 
 ccl_device_noinline void cache_triangle_shader_setup(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, bool subsurface)
 {
@@ -160,7 +164,7 @@ ccl_device_noinline void cache_triangle_shader_setup(KernelGlobals *kg, ShaderDa
 
 	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]);
+		ccl_fetch(sd, N) = cache_triangle_smooth_normal(kg, tri, isect->u, isect->v);
 	else
 		ccl_fetch(sd, N) = Ng;
 
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index 8e7a2c1..3f13e0e 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -309,7 +309,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
 	/* light passes */
 	PathRadiance L;
 
-	shader_setup_from_sample(kg, &sd, P, Ng, I, shader, object, prim, u, v, t, time);
+	shader_setup_from_sample(kg, &sd, P, Ng, I, shader, object, prim, PRIMITIVE_TRIANGLE, u, v, t, time);
 	sd.I = sd.N;
 
 	/* update differentials */
@@ -502,15 +502,22 @@ ccl_device void kernel_shader_evaluate(KernelGlobals *kg,
 		/* setup shader data */
 		int object = in.x;
 		int prim = in.y;
-		float u = __uint_as_float(in.z);
-		float v = __uint_as_float(in.w);
+		if(prim >= 0) {
+			float u = __uint_as_float(in.z);
+			float v = __uint_as_float(in.w);
 
-		shader_setup_from_displace(kg, &sd, object, prim, u, v);
+			shader_setup_from_displace(kg, &sd, object, prim, u, v);
 
-		/* evaluate */
-		float3 P = sd.P;
-		shader_eval_displacement(kg, &sd, &state, SHADER_CONTEXT_MAIN);
-		out = sd.P - P;
+			/* evaluate */
+			float3 P = sd.P;
+			shader_eval_displacement(kg, &sd, &state, SHADER_CONTEXT_MAIN);
+			out = sd.P - P;
+		}
+		else {
+			prim = -prim-1;
+
+			geom_cache_sample_subpatch_vert_displacement(kg, object, prim, in.z, &out);
+		}
 	}
 	else { // SHADER_EVAL_BACKGROUND
 		/* setup ray */
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 5cf52f9..4e4eaf0 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -55,7 +55,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
 	else
 #endif
 	{
-		shader_setup_from_sample(kg, sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time);
+		shader_setup_from_sample(kg, sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, PRIMITIVE_TRIANGLE, ls->u, ls->v, t, time);
 
 		ls->Ng = ccl_fetch(sd, Ng);
 
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 39c4ce8..3003092 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -237,7 +237,7 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg,
                                          const float3 P,
                                          const float3 Ng,
                                          const float3 I,
-                                         int shader, int object, int prim,
+                                         int shader, int object, int prim, int type,
                                          float u, float v, float t,
                                          float time)
 {
@@ -247,7 +247,7 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg,
 	ccl_fetch(sd, Ng) = Ng;
 	ccl_fetch(sd, I) = I;
 	ccl_fetch(sd, shader) = shader;
-	ccl_fetch(sd, type) = (prim == PRIM_NONE)? PRIMITIVE_NONE: PRIMITIVE_TRIANGLE;
+	ccl_fetch(sd, type) = (prim == PRIM_NONE)? PRIMITIVE_NONE: type;
 
 	/* primitive */
 #ifdef __INSTANCING__
@@ -311,6 +311,28 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg,
 #  endif
 #endif
 	}
+	else if(ccl_fetch(sd, type) & PRIMITIVE_CACHE_TRIANGLE) {
+		CacheTriangle tri;
+
+		tri.patch = 0; /

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list