Cycles-Bake: displacement support (fix T40068)
Code with contribution from Brecht Van Lommel. Reviewers: brecht Differential Revision: https://developer.blender.org/D510
This commit is contained in:
parent
31cb7e395e
commit
672cebf19a
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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));
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user