Couldn´t denoising be triggered once the render has finished?
In fact I would love to have that option for the actual blender denoiser, the feeling is that denoising tile by tile is slower.
Cheers.
Couldn´t denoising be triggered once the render has finished?
In fact I would love to have that option for the actual blender denoiser, the feeling is that denoising tile by tile is slower.
Cheers.
I also can imagine that the “AI” needs to work on the complete render result to “understand” caustics and other scatterings that produce a lot of noise correctly.
Cheers
I also wonder if it is possible to put the Denoiser in a compositing node, so it can be mixed with the noisy render if some noise is desired for the project like for example in a atomic war scene
Hey Brecht,
Ive looked today at the session.cpp and session::release_tile
Am I missing something but assumed there would be a system already added to read the buffers needed but couldn’t find anything (could easily be missing something here as dont know blenders code base well and only a learner coder)
So ive added the ability to read out render buffers fron session.cpp
This is what im thinking to add:
blender_session.h
I then added this:
void read_render_tile(RenderTile& rtile);
====================================================
void write_render_result(BL::RenderResult& b_rr,
BL::RenderLayer& b_rlay,
RenderTile& rtile);
void write_render_tile(RenderTile& rtile);
void read_render_tile(RenderTile& rtile);
====================================================
then added bool do_read_only:
void do_write_update_render_tile(RenderTile& rtile,
bool do_update_only,
bool do_read_only,
bool highlight);
=====================================================
blender_session.cpp
then added bool do_read_only:
void BlenderSession::do_write_update_render_tile(RenderTile& rtile,
bool do_update_only,
bool do_read_only,
bool highlight)
then added this:
if (do_read_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 for buffer read *out */
PassType pass_type = BlenderSync::get_pass_type(b_pass);
int components = b_pass.channels();
/*In original code get_pass_rect we also have exposure, samples, but as were just looking to copy as image */
/*i dont think exposure or samples will be needed*/
rtile.buffers->read_pass_rect(pass_type, components, (float*)b_pass.rect());
}
end_render_result(b_engine, b_rr, false, false, false);
}
else if (do_update_only) {
then add:
void BlenderSession::read_render_tile(RenderTile& rtile)
{
do_write_update_render_tile(rtile, false, true, false);
}
and change:
void BlenderSession::write_render_tile(RenderTile& rtile)
{
do_write_update_render_tile(rtile, false, false);
}
to:
void BlenderSession::write_render_tile(RenderTile& rtile)
{
do_write_update_render_tile(rtile, false, false, false);
}
then under BlenderSession::update_render_tile I add:
if(!b_engine.is_preview())
do_write_update_render_tile(rtile, true, false, highlight);
else
do_write_update_render_tile(rtile, false, false, false);
}
and then under BlenderSession::render() add this:
/* set callback to read out render results */
session->read_render_tile_cb = function_bind(&BlenderSession::read_render_tile, this, _1);
and then:
/* clear render buffer read callback */
session->read_render_tile_cb = function_null;
============================================================================
buffers.h
then added:
bool read_pass_rect(PassType type, int components, float *pixels);
============================================================================
buffers.cpp
then added:
bool RenderBuffers::read_pass_rect(PassType type, int components, float *pixels)
{
if (buffer.data() == NULL) {
return false;
}
int pass_offset = 0;
for (size_t j = 0; j < params.passes.size(); j++) {
Pass & pass = params.passes[j];
if (pass.type != type) {
pass_offset += pass.components;
continue;
}
float *out = buffer.data() + pass_offset;
int pass_stride = params.get_passes_size();
/*Not sure if Brecht would want more than just buffer width/height here and maybe the full tile params. NEED FEEDBACK*/
int size = params.width*params.height;
assert(pass.components == components);
for (int i = 0; i < size; i++, out += pass_stride, pixels += components) {
for (int j = 0; j < components; j++) {
out[j] = pixels[j];
}
}
return true;
}
return false;
}
===========================================================
session.h
add:
function<void(RenderTile&)> read_render_tile_cb;
===========================================================
session.cpp
add:
if(read_render_tile_cb) {
/* This will read any passes needed as input for render buffer access. */
read_render_tile_cb(rtile);
rtile.buffers->buffer.copy_to_device();
}
else {
/* This will tag tile as IN PROGRESS in blender-side render pipeline,
* which is needed to highlight currently rendering tile before first
* sample was processed for it. */
update_tile_sample(rtile);
}
Is this OK, or is adding this functionality over kill. To be honest having a method now to read render buffers seems handy no matter what so thinking of creating a .diff to upload as this could be helpfull for other things lke if people want to build addons that do things to render buffers for post pro etc
This is difficult to follow, please use diffs:
https://wiki.blender.org/wiki/Tools/Patches
I have trouble understanding what this code is trying to do, I’m not sure why the Blender session is involved at all.
yep I wasn’t sure at all if this was what i needed. What im trying to do is just access the render buffers for Combined,Normal,Diffcol to pass the buffers into optix denoiser from session.cpp Session::release_tile
when I looked at rendertile_write and update I wasnt sure if there was a way to read those combined,normal,diffcol buffers from within session.cpp so the code above was meant to add read buffer access to do_write_update_render_tile.
I thought that this would then create ouput buffers of all passes requested but with only image data not other settings like exposure,samples.
if (do_read_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 for buffer read *out */
PassType pass_type = BlenderSync::get_pass_type(b_pass);
int components = b_pass.channels();
/*In original code get_pass_rect we also have exposure, samples, but as were just looking to copy as image */
/*i dont think exposure or samples will be needed*/
rtile.buffers->read_pass_rect(pass_type, components, (float*)b_pass.rect());
}
end_render_result(b_engine, b_rr, false, false, false);
}
I looked at your update patch for texture baking to do this but applied to renderbuffers
I thought then that would make passing the buffers in session.cpp to the optix denoiser easier, but im guessing thats a mistake.
How would you of passed the combined,normal,diffcol to the optix buffers in session::release_tile? a few lines of code how you would do this would be a great help
Have i just over complicated everything, should it be just as simple as just using rtile.buffers->copy_to_device() ?
Do something like this:
float exposure = scene->film->exposure
int sample = rtile.sample;
rtile.buffers->get_pass_rect(PASS_COMBINED, exposure, sample, 4, pixels, "Combined"):
rtile.buffers->get_pass_rect(PASS_NORMAL, exposure, sample, 3, normal_pixels, "Normal"):
...
yeah I was massively over complicating this, cheers Brecht
Did you get it working? I would be interested to see/test the code.
What’s the status on this? I’m really interested in seeing OptiX as part of 2.8x. If its on a separate branch, how do I access it/is there an up to date diff?
The OptiX denoiser won’t be a part of 2.80 due to license incompatibility.
Are you sure about that?
Well that’s sad
I believe Ton’s tweet was about Optix Ray Tracing not the Optix Denoise.
Can it be in a stand-alone program though? Since cycles is not GPL.
Theoretically yes, practically that makes no sense for Blender.
But having the OIDN (The Intel denoiser) why do you want Optix?
I mean… optix works only in Nvidia cards, and it’s the same as OIDN with the exception that OIDN works in any CPU and it’s a compositing node, with is cooler
Also you already have Optix Denoiser as an addon.
Cheers!
Hi, there are pre build binaries including standalone called “denoise”.
It only work with .pfm image files.
A user with python knowledge and imagemagic can easy include it in to any Blender version.
Cheers, mib
It is already included, there is a patch by Stefan Werner that implements OIDN in Blender
EDIT: It’s not yet in master, but it seems it will be