[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