Skip to content
This repository has been archived by the owner on Jul 18, 2020. It is now read-only.

Commit

Permalink
IMPORTANT CHANGES to Volumetrics for proper raytracing of volumes
Browse files Browse the repository at this point in the history
Problems with volumes and transparent objects have been reported in the bug tracker several times:
http://yafaray.org/node/289
http://yafaray.org/node/666

After some investigation, I believe the rendering of volumes is incorrectly designed. Currently, volumes are rendering separatedly from the normal "surface" objects, and the volume rendered image just rudimentary added to the "surface" rendering in integrator.cc. This causes that volumes are not included in the normal recursive raytracing and therefore volumes are not properly integrated with the other objects.

So, I've removed the volume rendering from integrator.cc and I've implemented it as part of the normal integrators raytracing.

The tests I've made look good for now and now transparent objects are not causing problems. In fact, this should allow to create scenes mixing mirrors, transparency, etc, and volumes that were not possible before.

However, this is a very important and structural change that could have deep repercusions in the rendering, so I would advise to test it thoroughly to make sure no new issues happen now.
  • Loading branch information
DavidBluecame committed Oct 11, 2015
1 parent d6f1c2c commit 0451d94
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 22 deletions.
29 changes: 26 additions & 3 deletions src/integrators/bidirpath.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ class YAFRAYPLUGIN_EXPORT biDirIntegrator_t: public tiledIntegrator_t
float fNumLights;
std::map <const light_t*, CFLOAT> invLightPowerD;
imageFilm_t *lightImage;
bool transpBackground; //! Render background as transparent
bool transpRefractedBackground; //! Render refractions of background as transparent
};

biDirIntegrator_t::biDirIntegrator_t(bool transpShad, int shadowDepth): trShad(transpShad), sDepth(shadowDepth),
Expand Down Expand Up @@ -262,7 +264,11 @@ colorA_t biDirIntegrator_t::integrate(renderState_t &state, diffRay_t &ray) cons
color_t col(0.f);
surfacePoint_t sp;
ray_t testray = ray;

float alpha;

if(transpBackground) alpha=0.0;
else alpha=1.0;

if(scene->intersect(testray, sp))
{
static int dbg=0;
Expand Down Expand Up @@ -410,12 +416,20 @@ colorA_t biDirIntegrator_t::integrate(renderState_t &state, diffRay_t &ray) cons
}
else
{
if(background)
if(background && !transpRefractedBackground)
{
col += (*background)(ray, state, false);
}
}
return col;

color_t colVolTransmittance = scene->volIntegrator->transmittance(state, ray);
color_t colVolIntegration = scene->volIntegrator->integrate(state, ray);

if(transpBackground) alpha = std::max(alpha, 1.f-colVolTransmittance.R);

col = (col * colVolTransmittance) + colVolIntegration;

return colorA_t(col, alpha);
}

/* ============================================================
Expand Down Expand Up @@ -927,7 +941,16 @@ color_t biDirIntegrator_t::evalPathE(renderState_t &state, int s, pathData_t &pd

integrator_t* biDirIntegrator_t::factory(paraMap_t &params, renderEnvironment_t &render)
{
bool bg_transp = true;
bool bg_transp_refract = true;

params.getParam("bg_transp", bg_transp);
params.getParam("bg_transp_refract", bg_transp_refract);

biDirIntegrator_t *inte = new biDirIntegrator_t();
// Background settings
inte->transpBackground = bg_transp;
inte->transpRefractedBackground = bg_transp_refract;
return inte;
}

Expand Down
10 changes: 9 additions & 1 deletion src/integrators/directlight.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,19 @@ colorA_t directLighting_t::integrate(renderState_t &state, diffRay_t &ray) const
}
else // Nothing hit, return background if any
{
if(background) col += (*background)(ray, state, false);
if(background && !transpRefractedBackground) col += (*background)(ray, state, false);
}

state.userdata = o_udat;
state.includeLights = oldIncludeLights;

color_t colVolTransmittance = scene->volIntegrator->transmittance(state, ray);
color_t colVolIntegration = scene->volIntegrator->integrate(state, ray);

if(transpBackground) alpha = std::max(alpha, 1.f-colVolTransmittance.R);

col = (col * colVolTransmittance) + colVolIntegration;

return colorA_t(col, alpha);
}

Expand Down
10 changes: 9 additions & 1 deletion src/integrators/pathtracer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,21 @@ colorA_t pathIntegrator_t::integrate(renderState_t &state, diffRay_t &ray/*, sam
}
else //nothing hit, return background
{
if(background)
if(background && !transpRefractedBackground)
{
col += (*background)(ray, state, false);
}
}

state.userdata = o_udat;

color_t colVolTransmittance = scene->volIntegrator->transmittance(state, ray);
color_t colVolIntegration = scene->volIntegrator->integrate(state, ray);

if(transpBackground) alpha = std::max(alpha, 1.f-colVolTransmittance.R);

col = (col * colVolTransmittance) + colVolIntegration;

return colorA_t(col, alpha);
}

Expand Down
9 changes: 8 additions & 1 deletion src/integrators/photonintegr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -873,12 +873,19 @@ colorA_t photonIntegrator_t::integrate(renderState_t &state, diffRay_t &ray) con
}
else //nothing hit, return background
{
if(background) col += (*background)(ray, state, false);
if(background && !transpRefractedBackground) col += (*background)(ray, state, false);
}

state.userdata = o_udat;
state.includeLights = oldIncludeLights;

color_t colVolTransmittance = scene->volIntegrator->transmittance(state, ray);
color_t colVolIntegration = scene->volIntegrator->integrate(state, ray);

if(transpBackground) alpha = std::max(alpha, 1.f-colVolTransmittance.R);

col = (col * colVolTransmittance) + colVolIntegration;

return colorA_t(col, alpha);
}

Expand Down
19 changes: 9 additions & 10 deletions src/integrators/sppm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,6 @@ bool SPPM::renderTile(renderArea_t &a, int n_samples, int offset, bool adaptive,
HitPoint &hp = hitPoints[index];

GatherInfo gInfo = traceGatherRay(rstate, c_ray, hp); // L_o
gInfo.photonFlux *= scene->volIntegrator->transmittance(rstate, c_ray);
//needed fix for a volumetric boundary alpha issue because
// when col.A = T.A * L_o.A + L_v.A, col.A amount is > 1.0
colorA_t volTransmitt = scene->volIntegrator->transmittance(rstate, c_ray);
colorA_t volIntegrate = scene->volIntegrator->integrate(rstate, c_ray); // Now using it to simulate for volIntegrator not using PPM, need more tests
volIntegrate.A = 1.f - volTransmitt.A;
gInfo.constantRandiance *= volTransmitt; // T
gInfo.constantRandiance += volIntegrate; // L_v
hp.constantRandiance += gInfo.constantRandiance; // accumulate the constant radiance for later usage.

// progressive refinement
Expand Down Expand Up @@ -815,7 +807,7 @@ GatherInfo SPPM::traceGatherRay(yafaray::renderState_t &state, yafaray::diffRay_

else //nothing hit, return background
{
if(background)
if(background && !transpRefractedBackground)
{
gInfo.constantRandiance += (*background)(ray, state, false);
}
Expand All @@ -824,6 +816,13 @@ GatherInfo SPPM::traceGatherRay(yafaray::renderState_t &state, yafaray::diffRay_
state.userdata = o_udat;
state.includeLights = oldIncludeLights;

colorA_t colVolTransmittance = scene->volIntegrator->transmittance(state, ray);
colorA_t colVolIntegration = scene->volIntegrator->integrate(state, ray);

if(transpBackground) alpha = std::max(alpha, 1.f-colVolTransmittance.R);

gInfo.constantRandiance = (gInfo.constantRandiance * colVolTransmittance) + colVolIntegration;

gInfo.constantRandiance.A = alpha; // a small trick for just hold the alpha value.

return gInfo;
Expand Down Expand Up @@ -886,7 +885,7 @@ integrator_t* SPPM::factory(paraMap_t &params, renderEnvironment_t &render)
params.getParam("bg_transp", bg_transp);
params.getParam("bg_transp_refract", bg_transp_refract);

SPPM* ite = new SPPM(numPhotons, _passNum,transpShad, shadowDepth);
SPPM* ite = new SPPM(numPhotons, _passNum, transpShad, shadowDepth);
ite->rDepth = raydepth;
ite->maxBounces = bounces;
ite->initialFactor = times;
Expand Down
8 changes: 2 additions & 6 deletions src/yafraycore/integrator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -293,12 +293,8 @@ bool tiledIntegrator_t::renderTile(renderArea_t &a, int n_samples, int offset, b
c_ray.ydir = d_ray.dir;
c_ray.time = rstate.time;
c_ray.hasDifferentials = true;
// col = T * L_o + L_v
colorA_t colIntegration = integrate(rstate, c_ray); // L_o
colorA_t colVolTransmittance = scene->volIntegrator->transmittance(rstate, c_ray); // T
colorA_t colVolIntegration = scene->volIntegrator->integrate(rstate, c_ray); // L_v
colVolIntegration.A = 1.f-colVolTransmittance.A; //Fix for Volumetrics Alpha artifacts. For the Alpha of the volume itself, I will use the inverse of the Aplha calculated by the transmittance calculation. It seems to give good results for volumes rendered on top of other objects, volumes rendered on top of an opaque background and volumes rendered on top of transparent background (for later compositing).
colorA_t col = (colIntegration*colVolTransmittance)+colVolIntegration;

colorA_t col = integrate(rstate, c_ray);
imageFilm->addSample(wt * col, j, i, dx, dy, &a);

if(do_depth)
Expand Down

0 comments on commit 0451d94

Please sign in to comment.