PDA

View Full Version : Solid volume



haggi
April 13th, 2008, 23:55
Hi,

I'm just experimenting with volume shaders and I try to create a quite simple one to test how it works.
Now I have some success but I have shadow problems. This is an image of my volume shader without any shadows:

http://www.render3d.de/data/volume_withoutShadow.jpg

And this one is created if I use raytraced shadows:

http://www.render3d.de/data/volume_withShadow.jpg

The volume object is a cube.
The mi files is located here http://www.render3d.de/data/volume.rar

This is the code I used. Maybe anyone has an idea whats happening here? The problem occurs with any shadow mode.
The normals I use seems to be clean if I convert them as rgb values. I have no idea what the problem is. Any ideas?



#include "shader.h"

struct volumeShader01_p{
miColor color;
miTag volumeTexture;
miTag surfaceShader;
};

extern "C" DLLEXPORT int volumeShader01_version()
{
return (1);
}

extern "C" DLLEXPORT miBoolean volumeShader01(
miColor *result,
miState *state,
volumeShader01_p *paras)
{

if (state->type == miRAY_SHADOW || state->type == miRAY_DISPLACE )
return(miTRUE);

miTag surfaceShader = *mi_eval_tag( &paras->surfaceShader );
miScalar incr = 0.1;
miVector point = state->org;
miVector center;
center.x = center.y = center.z = 0.0;
miScalar dist = 0.0;
miScalar density = 0.45;
miVector dir = state->dir;
miScalar radi = 5.0;
miScalar densitySum = 0.0;

if (state->dist == 0.0)
return miTRUE;

miState myState = *state;

while (dist < state->dist )
{
miVector p;

mi_vector_to_world(state, &point, &point);
mi_vector_to_world(state, &dir, &dir);
p&#46;x = point&#46;x + dir&#46;x * dist;
p&#46;y = point&#46;y + dir&#46;y * dist;
p&#46;z = point&#46;z + dir&#46;z * dist;
miColor col;
miScalar radius = mi_vector_dist( &center, &p);

if ( radius > radi )
{
densitySum += 0&#46;0;
}else{
densitySum += incr * density;
}

if (densitySum > 1&#46;0)
{
miVector normal;
mi_vector_sub( &normal, &p, &center);
mi_vector_normalize( &normal);
mi_vector_from_world(state, &p, &p);
mi_vector_from_world(state, &normal, &normal);
state->org = p;
state->normal = normal;
state->normal_geom = normal;
mi_call_shader_x(&col, miSHADER_MATERIAL, state, surfaceShader, NULL);
*result = col;
return miTRUE;
}
dist += incr;
}
*state = myState;
return miTRUE;
}

bart
April 14th, 2008, 18:03
Hi Haggi,

BTW, the source for Andy's book is now on line at http://www.writingshaders.com.

Here is a similar shader (which you may recall), but we use color passed in through a color argument, rather than call the shader.

http://www.writingshaders.com/shader_pa ... olume.html (http://www.writingshaders.com/shader_pages/threshold_volume.html)

For debugging it, could you do something similar, make a color input, and put your illumination shader in that to pass the color in rather than using the explicit shader call?

If that works, it is something that needs to be set up properly in the state, ... maybe state->pri or something similar, to my recollection.

haggi
April 14th, 2008, 23:24
Thanks, I'll try it.