static int setup_pass(lua_State *L, td_engine *engine, int index, td_node *node) { td_pass *pass; td_job_chain *chain; int pass_index; lua_getfield(L, index, "pass"); if (lua_isnil(L, -1)) luaL_error(L, "no pass specified"); pass_index = get_pass_index(L, engine, lua_gettop(L)); lua_pop(L, 1); pass = &engine->passes[pass_index]; /* link this node into the node list of the pass */ chain = td_page_alloc(&engine->alloc, sizeof(td_job_chain)); chain->node = node; chain->next = pass->nodes; pass->nodes = chain; ++pass->node_count; return pass_index; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Update render image, with passes if needed ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, bool do_update_only) { int buf_size = width * height * 4; float* pixels = pass_buffers[0]; if(!pixels) { pixels = new float[buf_size]; pass_buffers[0] = pixels; } float* mb_pixels = mb_pass_buffers[0]; if(motion_blur && !mb_pixels) { mb_pixels = new float[buf_size]; mb_pass_buffers[0] = mb_pixels; } Passes::PassTypes cur_pass_type; if(scene->passes->use_passes) cur_pass_type = scene->passes->cur_pass_type; else cur_pass_type = Passes::COMBINED; if(scene->passes->use_passes && session->server->cur_pass_type != cur_pass_type) session->server->get_image_buffer(session->params.image_stat, session->params.interactive ? 0 : (session->params.hdr_tonemapped ? 2 : 1), cur_pass_type, session->progress); if(motion_blur && mb_type == SUBFRAME && mb_cur_sample > 1) { if(!do_update_only) { for(unsigned int k = 0; k < buf_size; ++k) pixels[k] = (pixels[k] * (mb_cur_sample - 1) + mb_pixels[k]) / (float)mb_cur_sample; } else { if(mb_cur_sample > 2 && mb_cur_sample > mb_sample_in_work) { mb_sample_in_work = mb_cur_sample; for(unsigned int k = 0; k < buf_size; ++k) pixels[k] = (pixels[k] * (mb_cur_sample - 2) + mb_pixels[k]) / (float)(mb_cur_sample - 1); } session->server->get_pass_rect(cur_pass_type, 4, mb_pixels, width, height, (scene->camera->use_border ? scene->camera->border.z - scene->camera->border.x : width), (scene->camera->use_border ? scene->camera->border.w - scene->camera->border.y : height)); } b_rlay.rect(pixels); } else if(session->server->get_pass_rect(cur_pass_type, 4, pixels, width, height, (scene->camera->use_border ? scene->camera->border.z - scene->camera->border.x : width), (scene->camera->use_border ? scene->camera->border.w - scene->camera->border.y : height))) b_rlay.rect(pixels); if(scene->passes->use_passes && (!do_update_only || (motion_blur && mb_type == SUBFRAME && session->params.image_stat.cur_samples >= session->params.samples))) { // Copy each pass BL::RenderLayer::passes_iterator b_iter; for(b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) { BL::RenderPass b_pass(*b_iter); int components = b_pass.channels(); buf_size = width * height * components; // Find matching pass type Passes::PassTypes pass_type = get_octane_pass_type(b_pass); if(pass_type == Passes::COMBINED) continue; else if(pass_type == Passes::PASS_NONE || !session->server->get_image_buffer(session->params.image_stat, session->params.interactive ? 0 : (session->params.hdr_tonemapped ? 2 : 1), pass_type, session->progress)) { if(!do_update_only) { float* pixels = new float[buf_size]; memset(pixels, 0, sizeof(float) * buf_size); b_pass.rect(pixels); delete[] pixels; } continue; } int pass_idx = get_pass_index(pass_type); pixels = pass_buffers[pass_idx]; if(!pixels) { pixels = new float[buf_size]; pass_buffers[pass_idx] = pixels; } mb_pixels = mb_pass_buffers[pass_idx]; if(motion_blur && !mb_pixels) { mb_pixels = new float[buf_size]; mb_pass_buffers[pass_idx] = mb_pixels; } if(motion_blur && mb_type == SUBFRAME && mb_cur_sample > 1) { if(!do_update_only) { for(unsigned int k = 0; k < buf_size; ++k) pixels[k] = (pixels[k] * (mb_cur_sample - 1) + mb_pixels[k]) / (float)mb_cur_sample; } else { if(mb_cur_sample > 2 && mb_cur_sample > mb_sample_in_work) { mb_sample_in_work = mb_cur_sample; for(unsigned int k = 0; k < buf_size; ++k) pixels[k] = (pixels[k] * (mb_cur_sample - 2) + mb_pixels[k]) / (float)(mb_cur_sample - 1); } session->server->get_pass_rect(pass_type, components, mb_pixels, width, height, (scene->camera->use_border ? scene->camera->border.z - scene->camera->border.x : width), (scene->camera->use_border ? scene->camera->border.w - scene->camera->border.y : height)); } b_pass.rect(pixels); } else { if(session->server->get_pass_rect(pass_type, components, pixels, width, height, (scene->camera->use_border ? scene->camera->border.z - scene->camera->border.x : width), (scene->camera->use_border ? scene->camera->border.w - scene->camera->border.y : height))) b_pass.rect(pixels); } } //for(b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) } //if(scene->passes->use_passes && (!do_update_only || motion_blur && mb_type == SUBFRAME)) // Tag result as updated b_engine.update_result(b_rr); } //do_write_update_render_result()