Cycles Volume Render: add flags to quickly detect when objects have a volume shader.

This commit is contained in:
Brecht Van Lommel
2013-12-28 02:27:48 +01:00
parent a35db17cee
commit 37c4d6a50a
5 changed files with 42 additions and 16 deletions

View File

@@ -225,7 +225,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int
ccl_device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, int bounce) ccl_device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, int bounce)
{ {
#ifdef __BACKGROUND__ #ifdef __BACKGROUND__
int shader = kernel_data.background.shader; int shader = kernel_data.background.surface_shader;
/* use visibility flag to skip lights */ /* use visibility flag to skip lights */
if(shader & SHADER_EXCLUDE_ANY) { if(shader & SHADER_EXCLUDE_ANY) {

View File

@@ -376,7 +376,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
sd->N = -ray->D; sd->N = -ray->D;
sd->Ng = -ray->D; sd->Ng = -ray->D;
sd->I = -ray->D; sd->I = -ray->D;
sd->shader = kernel_data.background.shader; sd->shader = kernel_data.background.surface_shader;
sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
#ifdef __OBJECT_MOTION__ #ifdef __OBJECT_MOTION__
sd->time = ray->time; sd->time = ray->time;

View File

@@ -46,6 +46,8 @@ CCL_NAMESPACE_BEGIN
#define TEX_NUM_FLOAT_IMAGES 5 #define TEX_NUM_FLOAT_IMAGES 5
#define SHADER_NO_ID -1
/* device capabilities */ /* device capabilities */
#ifdef __KERNEL_CPU__ #ifdef __KERNEL_CPU__
#define __KERNEL_SHADING__ #define __KERNEL_SHADING__
@@ -502,13 +504,14 @@ enum ShaderDataFlag {
SD_USE_MIS = 512, /* direct light sample */ SD_USE_MIS = 512, /* direct light sample */
SD_HAS_TRANSPARENT_SHADOW = 1024, /* has transparent shadow */ SD_HAS_TRANSPARENT_SHADOW = 1024, /* has transparent shadow */
SD_HAS_VOLUME = 2048, /* has volume shader */ SD_HAS_VOLUME = 2048, /* has volume shader */
SD_HOMOGENEOUS_VOLUME = 4096, /* has homogeneous volume */ SD_HAS_ONLY_VOLUME = 4096, /* has only volume shader, no surface */
SD_HAS_BSSRDF_BUMP = 8192, /* bssrdf normal uses bump */ SD_HOMOGENEOUS_VOLUME = 8192, /* has homogeneous volume */
SD_HAS_BSSRDF_BUMP = 16384, /* bssrdf normal uses bump */
/* object flags */ /* object flags */
SD_HOLDOUT_MASK = 16384, /* holdout for camera rays */ SD_HOLDOUT_MASK = 32768, /* holdout for camera rays */
SD_OBJECT_MOTION = 32768, /* has object motion blur */ SD_OBJECT_MOTION = 65536, /* has object motion blur */
SD_TRANSFORM_APPLIED = 65536 /* vertices have transform applied */ SD_TRANSFORM_APPLIED = 131072 /* vertices have transform applied */
}; };
struct KernelGlobals; struct KernelGlobals;
@@ -704,12 +707,15 @@ typedef struct KernelFilm {
typedef struct KernelBackground { typedef struct KernelBackground {
/* only shader index */ /* only shader index */
int shader; int surface_shader;
int volume_shader;
int transparent; int transparent;
int pad;
/* ambient occlusion */ /* ambient occlusion */
float ao_factor; float ao_factor;
float ao_distance; float ao_distance;
float ao_pad1, ao_pad2;
} KernelBackground; } KernelBackground;
typedef struct KernelIntegrator { typedef struct KernelIntegrator {
@@ -765,8 +771,8 @@ typedef struct KernelIntegrator {
/* sampler */ /* sampler */
int sampling_pattern; int sampling_pattern;
/* padding */ /* volume render */
int pad; int use_volumes;
} KernelIntegrator; } KernelIntegrator;
typedef struct KernelBVH { typedef struct KernelBVH {

View File

@@ -65,16 +65,21 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
kbackground->ao_distance = ao_distance; kbackground->ao_distance = ao_distance;
kbackground->transparent = transparent; kbackground->transparent = transparent;
kbackground->shader = scene->shader_manager->get_shader_id(shader); kbackground->surface_shader = scene->shader_manager->get_shader_id(shader);
if(scene->shaders[shader]->has_volume)
kbackground->volume_shader = kbackground->surface_shader;
else
kbackground->volume_shader = SHADER_NO_ID;
if(!(visibility & PATH_RAY_DIFFUSE)) if(!(visibility & PATH_RAY_DIFFUSE))
kbackground->shader |= SHADER_EXCLUDE_DIFFUSE; kbackground->surface_shader |= SHADER_EXCLUDE_DIFFUSE;
if(!(visibility & PATH_RAY_GLOSSY)) if(!(visibility & PATH_RAY_GLOSSY))
kbackground->shader |= SHADER_EXCLUDE_GLOSSY; kbackground->surface_shader |= SHADER_EXCLUDE_GLOSSY;
if(!(visibility & PATH_RAY_TRANSMIT)) if(!(visibility & PATH_RAY_TRANSMIT))
kbackground->shader |= SHADER_EXCLUDE_TRANSMIT; kbackground->surface_shader |= SHADER_EXCLUDE_TRANSMIT;
if(!(visibility & PATH_RAY_CAMERA)) if(!(visibility & PATH_RAY_CAMERA))
kbackground->shader |= SHADER_EXCLUDE_CAMERA; kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
need_update = false; need_update = false;
} }

View File

@@ -218,6 +218,7 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
uint *shader_flag = dscene->shader_flag.resize(shader_flag_size); uint *shader_flag = dscene->shader_flag.resize(shader_flag_size);
uint i = 0; uint i = 0;
bool has_converter_blackbody = false; bool has_converter_blackbody = false;
bool has_volumes = false;
foreach(Shader *shader, scene->shaders) { foreach(Shader *shader, scene->shaders) {
uint flag = 0; uint flag = 0;
@@ -226,8 +227,19 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
flag |= SD_USE_MIS; flag |= SD_USE_MIS;
if(shader->has_surface_transparent && shader->use_transparent_shadow) if(shader->has_surface_transparent && shader->use_transparent_shadow)
flag |= SD_HAS_TRANSPARENT_SHADOW; flag |= SD_HAS_TRANSPARENT_SHADOW;
if(shader->has_volume) if(shader->has_volume) {
flag |= SD_HAS_VOLUME; flag |= SD_HAS_VOLUME;
has_volumes = true;
/* in this case we can assume transparent surface */
if(!shader->has_surface)
flag |= SD_HAS_ONLY_VOLUME;
/* todo: this could check more fine grained, to skip useless volumes
* enclosed inside an opaque bsdf, although we still need to handle
* the case with camera inside volumes too */
flag |= SD_HAS_TRANSPARENT_SHADOW;
}
if(shader->homogeneous_volume) if(shader->homogeneous_volume)
flag |= SD_HOMOGENEOUS_VOLUME; flag |= SD_HOMOGENEOUS_VOLUME;
if(shader->has_bssrdf_bump) if(shader->has_bssrdf_bump)
@@ -263,6 +275,9 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
blackbody_table_offset = TABLE_OFFSET_INVALID; blackbody_table_offset = TABLE_OFFSET_INVALID;
} }
/* volumes */
KernelIntegrator *kintegrator = &dscene->data.integrator;
kintegrator->use_volumes = has_volumes;
} }
void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scene *scene) void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scene *scene)