diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2014-05-08 00:26:24 +0400 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2014-05-08 21:38:43 +0400 |
commit | 672cebf19a8b7fe8f9ac0f732fd6e8a0df239c7f (patch) | |
tree | e83cb1f1a1f5bf80dbf2a6fe46e549f873863022 /intern | |
parent | 31cb7e395e656e4a1590e1c9c4531e8a4b4f32ea (diff) |
Cycles-Bake: displacement support (fix T40068)
Code with contribution from Brecht Van Lommel.
Reviewers: brecht
Differential Revision: https://developer.blender.org/D510
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_displace.h | 17 | ||||
-rw-r--r-- | intern/cycles/render/bake.cpp | 29 | ||||
-rw-r--r-- | intern/cycles/render/bake.h | 7 |
4 files changed, 49 insertions, 6 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 6f959d42680..01a5acd8982 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -487,7 +487,7 @@ static void populate_bake_data(BakeData *data, BL::BakePixel pixel_array, const int i; for(i=0; i < num_pixels; i++) { - data->set(i, bp.primitive_id(), bp.uv()); + data->set(i, bp.primitive_id(), bp.uv(), bp.du_dx(), bp.du_dy(), bp.dv_dx(), bp.dv_dy()); bp = bp.next(); } } diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h index e54a16ac118..4727e90a231 100644 --- a/intern/cycles/kernel/kernel_displace.h +++ b/intern/cycles/kernel/kernel_displace.h @@ -102,7 +102,9 @@ ccl_device bool is_light_pass(ShaderEvalType type) ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output, ShaderEvalType type, int i) { ShaderData sd; - uint4 in = input[i]; + uint4 in = input[i * 2]; + uint4 diff = input[i * 2 + 1]; + float3 out; int object = in.x; @@ -114,6 +116,11 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, float u = __uint_as_float(in.z); float v = __uint_as_float(in.w); + float dudx = __uint_as_float(diff.x); + float dudy = __uint_as_float(diff.y); + float dvdx = __uint_as_float(diff.z); + float dvdy = __uint_as_float(diff.w); + int shader; float3 P, Ng; @@ -132,6 +139,14 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, shader_setup_from_sample(kg, &sd, P, Ng, I, shader, object, prim, u, v, t, time, bounce, transparent_bounce); sd.I = sd.N; + /* update differentials */ + sd.dP.dx = sd.dPdu * dudx + sd.dPdv * dvdx; + sd.dP.dy = sd.dPdu * dudy + sd.dPdv * dvdy; + sd.du.dx = dudx; + sd.du.dy = dudy; + sd.dv.dx = dvdx; + sd.dv.dy = dvdy; + if(is_light_pass(type)) { RNG rng = cmj_hash(i, 0); compute_light_pass(kg, &sd, &L, rng, (type == SHADER_EVAL_COMBINED), diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp index 2e3022e2c02..aa317ab672f 100644 --- a/intern/cycles/render/bake.cpp +++ b/intern/cycles/render/bake.cpp @@ -26,6 +26,10 @@ m_num_pixels(num_pixels) m_primitive.resize(num_pixels); m_u.resize(num_pixels); m_v.resize(num_pixels); + m_dudx.resize(num_pixels); + m_dudy.resize(num_pixels); + m_dvdx.resize(num_pixels); + m_dvdy.resize(num_pixels); } BakeData::~BakeData() @@ -33,13 +37,21 @@ BakeData::~BakeData() m_primitive.clear(); m_u.clear(); m_v.clear(); + m_dudx.clear(); + m_dudy.clear(); + m_dvdx.clear(); + m_dvdy.clear(); } -void BakeData::set(int i, int prim, float uv[2]) +void BakeData::set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy) { m_primitive[i] = (prim == -1 ? -1 : m_tri_offset + prim); m_u[i] = uv[0]; m_v[i] = uv[1]; + m_dudx[i] = dudx; + m_dudy[i] = dudy; + m_dvdx[i] = dvdx; + m_dvdy[i] = dvdy; } int BakeData::object() @@ -67,6 +79,16 @@ uint4 BakeData::data(int i) ); } +uint4 BakeData::differentials(int i) +{ + return make_uint4( + __float_as_int(m_dudx[i]), + __float_as_int(m_dudy[i]), + __float_as_int(m_dvdx[i]), + __float_as_int(m_dvdy[i]) + ); +} + BakeManager::BakeManager() { m_bake_data = NULL; @@ -102,11 +124,12 @@ bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progre /* setup input for device task */ device_vector<uint4> d_input; - uint4 *d_input_data = d_input.resize(limit); + uint4 *d_input_data = d_input.resize(limit * 2); size_t d_input_size = 0; for(size_t i = 0; i < limit; i++) { d_input_data[d_input_size++] = bake_data->data(i); + d_input_data[d_input_size++] = bake_data->differentials(i); } if(d_input_size == 0) @@ -114,7 +137,7 @@ bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progre /* run device task */ device_vector<float4> d_output; - d_output.resize(d_input_size); + d_output.resize(limit); /* needs to be up to data for attribute access */ device->const_copy_to("__data", &dscene->data, sizeof(dscene->data)); diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h index 830a9513065..ea403f7d39a 100644 --- a/intern/cycles/render/bake.h +++ b/intern/cycles/render/bake.h @@ -29,10 +29,11 @@ public: BakeData(const int object, const int tri_offset, const int num_pixels); ~BakeData(); - void set(int i, int prim, float uv[2]); + void set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy); int object(); int size(); uint4 data(int i); + uint4 differentials(int i); bool is_valid(int i); private: @@ -42,6 +43,10 @@ private: vector<int>m_primitive; vector<float>m_u; vector<float>m_v; + vector<float>m_dudx; + vector<float>m_dudy; + vector<float>m_dvdx; + vector<float>m_dvdy; }; class BakeManager { |