[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17055] branches/sim_physics/source/ blender/render/intern: * Raytraced shadow casting for volumes
Matt Ebb
matt at mke3.net
Mon Oct 13 07:22:31 CEST 2008
Revision: 17055
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17055
Author: broken
Date: 2008-10-13 07:22:31 +0200 (Mon, 13 Oct 2008)
Log Message:
-----------
* Raytraced shadow casting for volumes
This is a first version and still has a couple of things undefined or
unimplemented, such as external objects casting shadows on or within volumes,
however volume->solid shadows are going ok.
http://mke3.net/blender/devel/rendering/volumetrics/shadows_test_02.mov
http://mke3.net/blender/devel/rendering/volumetrics/vol_test_shad3.blend
As with other transparent raytraced shadows in Blender ,in order to make it work,
you must enable 'TraShad' on the material *receiving* the shadow. It would be
nice to make this a bit easier to use, since there's not much chance you want a
volume material to be casting solid shadows, but that's a bigger issue in the
renderer outside this scope.
The volume shadows are working from the same physical basis of absorption, and
support coloured absorption:
http://mke3.net/blender/devel/rendering/volumetrics/vol_shad_absorption.png
They also work properly with multi-sampled (i.e. QMC) soft shadows:
http://mke3.net/blender/devel/rendering/volumetrics/vol_shad_sharp.png
http://mke3.net/blender/devel/rendering/volumetrics/vol_shad_soft.png
And by popular request the test file:
http://mke3.net/blender/devel/rendering/volumetrics/vol_test_shad_clouds.blend
Modified Paths:
--------------
branches/sim_physics/source/blender/render/intern/include/pointdensity.h
branches/sim_physics/source/blender/render/intern/include/rendercore.h
branches/sim_physics/source/blender/render/intern/include/volumetric.h
branches/sim_physics/source/blender/render/intern/source/convertblender.c
branches/sim_physics/source/blender/render/intern/source/rayshade.c
branches/sim_physics/source/blender/render/intern/source/volumetric.c
Modified: branches/sim_physics/source/blender/render/intern/include/pointdensity.h
===================================================================
--- branches/sim_physics/source/blender/render/intern/include/pointdensity.h 2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/include/pointdensity.h 2008-10-13 05:22:31 UTC (rev 17055)
@@ -37,6 +37,7 @@
struct TexResult;
void make_pointdensities(struct Render *re);
+void free_pointdensities(struct Render *re);
int pointdensitytex(struct Tex *tex, float *texvec, struct TexResult *texres);
#endif /* POINTDENSITY_H */
Modified: branches/sim_physics/source/blender/render/intern/include/rendercore.h
===================================================================
--- branches/sim_physics/source/blender/render/intern/include/rendercore.h 2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/include/rendercore.h 2008-10-13 05:22:31 UTC (rev 17055)
@@ -48,6 +48,7 @@
struct RenderLayer;
struct ObjectRen;
struct ListBase;
+struct Isect;
/* ------------------------------------------------------------------------- */
@@ -98,6 +99,7 @@
extern void ray_shadow(ShadeInput *, LampRen *, float *);
extern void ray_trace(ShadeInput *, ShadeResult *);
+extern void ray_trace_shadow_tra(struct Isect *is, int depth, int traflag);
extern void ray_ao(ShadeInput *, float *);
extern void init_jitter_plane(LampRen *lar);
extern void init_ao_sphere(struct World *wrld);
Modified: branches/sim_physics/source/blender/render/intern/include/volumetric.h
===================================================================
--- branches/sim_physics/source/blender/render/intern/include/volumetric.h 2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/include/volumetric.h 2008-10-13 05:22:31 UTC (rev 17055)
@@ -26,4 +26,5 @@
* ***** END GPL LICENSE BLOCK *****
*/
-void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr);
\ No newline at end of file
+void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr);
+void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is);
\ No newline at end of file
Modified: branches/sim_physics/source/blender/render/intern/source/convertblender.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/convertblender.c 2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/source/convertblender.c 2008-10-13 05:22:31 UTC (rev 17055)
@@ -965,8 +965,6 @@
if(ma->nodetree && ma->use_nodes)
flag_render_node_material(re, ma->nodetree);
- if (ma->material_type == MA_VOLUME) re->r.mode |= R_RAYTRACE;
-
check_material_is_textured(ma);
return ma;
Modified: branches/sim_physics/source/blender/render/intern/source/rayshade.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/rayshade.c 2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/source/rayshade.c 2008-10-13 05:22:31 UTC (rev 17055)
@@ -54,6 +54,7 @@
#include "pixelshading.h"
#include "shading.h"
#include "texture.h"
+#include "volumetric.h"
#include "RE_raytrace.h"
@@ -262,21 +263,28 @@
shade_input_set_shade_texco(shi);
- if(is->mode==RE_RAY_SHADOW_TRA)
+ if (shi->mat->material_type == MA_VOLUME) {
+ if(ELEM(is->mode, RE_RAY_SHADOW, RE_RAY_SHADOW_TRA)) {
+ volume_trace_shadow(shi, shr, is);
+ } else {
+ shade_volume_loop(shi, shr);
+ }
+ }
+ else if(is->mode==RE_RAY_SHADOW_TRA)
if(shi->mat->nodetree && shi->mat->use_nodes) {
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
}
- else
+ else {
shade_color(shi, shr);
+ }
else {
if(shi->mat->nodetree && shi->mat->use_nodes) {
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
}
else {
- if (shi->mat->material_type == MA_SOLID) shade_material_loop(shi, shr);
- else if (shi->mat->material_type == MA_VOLUME) shade_volume_loop(shi, shr);
+ shade_material_loop(shi, shr);
}
/* raytrace likes to separate the spec color */
VECSUB(shr->diff, shr->combined, shr->spec);
@@ -1274,7 +1282,7 @@
shadfac[3]= (1.0f-alpha)*shadfac[3];
}
-static void ray_trace_shadow_tra(Isect *is, int depth, int traflag)
+void ray_trace_shadow_tra(Isect *is, int depth, int traflag)
{
/* ray to lamp, find first face that intersects, check alpha properties,
if it has col[3]>0.0f continue. so exit when alpha is full */
@@ -1303,12 +1311,17 @@
shi.mat_override= NULL;*/
shade_ray(is, &shi, &shr);
- if (traflag & RAY_TRA)
- d= shade_by_transmission(is, &shi, &shr);
+ if (shi.mat->material_type == MA_SOLID) {
+ if (traflag & RAY_TRA)
+ d= shade_by_transmission(is, &shi, &shr);
+
+ /* mix colors based on shadfac (rgb + amount of light factor) */
+ addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter);
+ } else {
+ // MA_VOLUME
+ addAlphaLight(is->col, shr.combined, shr.alpha, 1.0f);
+ }
- /* mix colors based on shadfac (rgb + amount of light factor) */
- addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter);
-
if(depth>0 && is->col[3]>0.0f) {
/* adapt isect struct */
Modified: branches/sim_physics/source/blender/render/intern/source/volumetric.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/volumetric.c 2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/source/volumetric.c 2008-10-13 05:22:31 UTC (rev 17055)
@@ -149,6 +149,8 @@
else if (context == STEPSIZE_SHADE)
return shi->mat->vol_shade_stepsize;
}
+
+ return shi->mat->vol_stepsize;
}
float vol_get_density(struct ShadeInput *shi, float *co)
@@ -247,6 +249,8 @@
dist = VecLenf(co, endco);
nsteps = (int)ceil(dist / stepsize);
+ if (density < -0.001f) density = vol_get_density(shi, co);
+
if (nsteps == 1) {
/* homogenous volume within the sampled distance */
tau[0] = tau[1] = tau[2] = dist * density;
@@ -485,7 +489,7 @@
shi_new.mask= shi->mask;
shi_new.osatex= shi->osatex;
shi_new.thread= shi->thread;
- shi_new.depth= shi->depth;
+ shi_new.depth= 1;
shi_new.volume_depth= shi->volume_depth + 1;
shi_new.xs= shi->xs;
shi_new.ys= shi->ys;
@@ -597,3 +601,57 @@
shr->combined[3] = shr->alpha = 1.0f;
}
}
+
+void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is)
+{
+ float hitco[3], col[4] = {0.f,0.f,0.f,0.f};
+ float tr[3] = {1.0,1.0,1.0};
+ float tau[3] = {0.0,0.0,0.0};
+ Isect is;
+ float shade_stepsize = vol_get_stepsize(shi, STEPSIZE_SHADE);
+
+ memset(shr, 0, sizeof(ShadeResult));
+
+ /* if 1st hit normal is facing away from the camera,
+ * then we're inside the volume already. */
+ if (shi->flippednor) {
+
+ vol_get_attenuation(shi, tau, last_is->start, shi->co, -1.0f, shade_stepsize);
+ tr[0] = exp(-tau[0]);
+ tr[1] = exp(-tau[1]);
+ tr[2] = exp(-tau[2]);
+
+ shr->combined[0] = tr[0];
+ shr->combined[1] = tr[1];
+ shr->combined[2] = tr[2];
+
+ shr->combined[3] = 1.0f -(tr[0] + tr[1] + tr[2]) * 0.333f;
+ shr->alpha = shr->combined[3];
+ }
+ /* trace to find a backface, the other side bounds of the volume */
+ /* (ray intersect ignores front faces here) */
+ else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH, 0)) {
+ float dist = VecLenf(shi->co, hitco);
+
+ vol_get_attenuation(shi, tau, shi->co, hitco, -1.0f, shade_stepsize);
+ tr[0] = exp(-tau[0]);
+ tr[1] = exp(-tau[1]);
+ tr[2] = exp(-tau[2]);
+
+ shr->combined[0] = tr[0];
+ shr->combined[1] = tr[1];
+ shr->combined[2] = tr[2];
+
+ shr->combined[3] = 1.0f -(tr[0] + tr[1] + tr[2]) * 0.333f;
+ shr->alpha = shr->combined[3];
+
+ }
+ else {
+ shr->combined[0] = 0.0f;
+ shr->combined[1] = 0.0f;
+ shr->combined[2] = 0.0f;
+ shr->combined[3] = shr->alpha = 0.0f;
+ }
+
+}
+
More information about the Bf-blender-cvs
mailing list