Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Ebb <matt@mke3.net>2008-10-13 09:22:31 +0400
committerMatt Ebb <matt@mke3.net>2008-10-13 09:22:31 +0400
commitd6808c2b4b9d53f5481e96d4041e67b20f1d56f0 (patch)
treee6b753203124e3f52bdc1dd859ee5d320dc3b2eb /source/blender/render/intern
parentc0ddd5fd4914f7876cdf36225566d795e415bbf1 (diff)
* 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
Diffstat (limited to 'source/blender/render/intern')
-rw-r--r--source/blender/render/intern/include/pointdensity.h1
-rw-r--r--source/blender/render/intern/include/rendercore.h2
-rw-r--r--source/blender/render/intern/include/volumetric.h3
-rw-r--r--source/blender/render/intern/source/convertblender.c2
-rw-r--r--source/blender/render/intern/source/rayshade.c33
-rw-r--r--source/blender/render/intern/source/volumetric.c60
6 files changed, 87 insertions, 14 deletions
diff --git a/source/blender/render/intern/include/pointdensity.h b/source/blender/render/intern/include/pointdensity.h
index 9c21cc0c253..93cdef3b14e 100644
--- a/source/blender/render/intern/include/pointdensity.h
+++ b/source/blender/render/intern/include/pointdensity.h
@@ -37,6 +37,7 @@ struct Render;
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 */
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index 4b28529a147..972071764d2 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -48,6 +48,7 @@ struct RenderPart;
struct RenderLayer;
struct ObjectRen;
struct ListBase;
+struct Isect;
/* ------------------------------------------------------------------------- */
@@ -98,6 +99,7 @@ extern void makeraytree(Render *re);
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);
diff --git a/source/blender/render/intern/include/volumetric.h b/source/blender/render/intern/include/volumetric.h
index 8db3fa63f98..290be427f01 100644
--- a/source/blender/render/intern/include/volumetric.h
+++ b/source/blender/render/intern/include/volumetric.h
@@ -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
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 4b663c6caa6..0660d9e0b24 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -965,8 +965,6 @@ static Material *give_render_material(Render *re, Object *ob, int nr)
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;
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index c431340d770..d06bbcf3300 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -54,6 +54,7 @@
#include "pixelshading.h"
#include "shading.h"
#include "texture.h"
+#include "volumetric.h"
#include "RE_raytrace.h"
@@ -262,21 +263,28 @@ void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
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 @@ static void addAlphaLight(float *shadfac, float *col, float alpha, float filter)
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,11 +1311,16 @@ static void ray_trace_shadow_tra(Isect *is, int depth, int traflag)
shi.mat_override= NULL;*/
shade_ray(is, &shi, &shr);
- 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);
+ 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);
+ }
if(depth>0 && is->col[3]>0.0f) {
diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c
index e0006a24fba..3b44e1bb87f 100644
--- a/source/blender/render/intern/source/volumetric.c
+++ b/source/blender/render/intern/source/volumetric.c
@@ -149,6 +149,8 @@ float vol_get_stepsize(struct ShadeInput *shi, int context)
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 @@ void vol_get_attenuation(ShadeInput *shi, float *tau, float *co, float *endco, f
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 @@ static void shade_intersection(ShadeInput *shi, float *col, Isect *is)
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 @@ void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr)
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;
+ }
+
+}
+