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( ¶s->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.x = point.x + dir.x * dist;
p.y = point.y + dir.y * dist;
p.z = point.z + dir.z * dist;
miColor col;
miScalar radius = mi_vector_dist( ¢er, &p);
if ( radius > radi )
{
densitySum += 0.0;
}else{
densitySum += incr * density;
}
if (densitySum > 1.0)
{
miVector normal;
mi_vector_sub( &normal, &p, ¢er);
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;
}
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( ¶s->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.x = point.x + dir.x * dist;
p.y = point.y + dir.y * dist;
p.z = point.z + dir.z * dist;
miColor col;
miScalar radius = mi_vector_dist( ¢er, &p);
if ( radius > radi )
{
densitySum += 0.0;
}else{
densitySum += incr * density;
}
if (densitySum > 1.0)
{
miVector normal;
mi_vector_sub( &normal, &p, ¢er);
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;
}