void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile, bool do_update_only) { RenderBuffers *buffers = rtile.buffers; /* copy data from device */ if(!buffers->copy_from_device()) return; BufferParams& params = buffers->params; float exposure = scene->film->exposure; vector<float> pixels(params.width*params.height*4); if (!do_update_only) { /* 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); /* find matching pass type */ PassType pass_type = get_pass_type(b_pass); int components = b_pass.channels(); /* copy pixels */ if(!buffers->get_pass_rect(pass_type, exposure, rtile.sample, components, &pixels[0])) memset(&pixels[0], 0, pixels.size()*sizeof(float)); b_pass.rect(&pixels[0]); } } /* copy combined pass */ if(buffers->get_pass_rect(PASS_COMBINED, exposure, rtile.sample, 4, &pixels[0])) b_rlay.rect(&pixels[0]); /* tag result as updated */ b_engine.update_result(b_rr); }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 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()