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
Notes: blender-bot 2023-02-14 11:01:33 +01:00
Referenced by issue #39089, Double render times with Cycles 2.69 vs 2.70RC
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)
{
#ifdef __BACKGROUND__
int shader = kernel_data.background.shader;
int shader = kernel_data.background.surface_shader;
/* use visibility flag to skip lights */
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->Ng = -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);
#ifdef __OBJECT_MOTION__
sd->time = ray->time;

View File

@ -46,6 +46,8 @@ CCL_NAMESPACE_BEGIN
#define TEX_NUM_FLOAT_IMAGES 5
#define SHADER_NO_ID -1
/* device capabilities */
#ifdef __KERNEL_CPU__
#define __KERNEL_SHADING__
@ -502,13 +504,14 @@ enum ShaderDataFlag {
SD_USE_MIS = 512, /* direct light sample */
SD_HAS_TRANSPARENT_SHADOW = 1024, /* has transparent shadow */
SD_HAS_VOLUME = 2048, /* has volume shader */
SD_HOMOGENEOUS_VOLUME = 4096, /* has homogeneous volume */
SD_HAS_BSSRDF_BUMP = 8192, /* bssrdf normal uses bump */
SD_HAS_ONLY_VOLUME = 4096, /* has only volume shader, no surface */
SD_HOMOGENEOUS_VOLUME = 8192, /* has homogeneous volume */
SD_HAS_BSSRDF_BUMP = 16384, /* bssrdf normal uses bump */
/* object flags */
SD_HOLDOUT_MASK = 16384, /* holdout for camera rays */
SD_OBJECT_MOTION = 32768, /* has object motion blur */
SD_TRANSFORM_APPLIED = 65536 /* vertices have transform applied */
SD_HOLDOUT_MASK = 32768, /* holdout for camera rays */
SD_OBJECT_MOTION = 65536, /* has object motion blur */
SD_TRANSFORM_APPLIED = 131072 /* vertices have transform applied */
};
struct KernelGlobals;
@ -704,12 +707,15 @@ typedef struct KernelFilm {
typedef struct KernelBackground {
/* only shader index */
int shader;
int surface_shader;
int volume_shader;
int transparent;
int pad;
/* ambient occlusion */
float ao_factor;
float ao_distance;
float ao_pad1, ao_pad2;
} KernelBackground;
typedef struct KernelIntegrator {
@ -765,8 +771,8 @@ typedef struct KernelIntegrator {
/* sampler */
int sampling_pattern;
/* padding */
int pad;
/* volume render */
int use_volumes;
} KernelIntegrator;
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->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))
kbackground->shader |= SHADER_EXCLUDE_DIFFUSE;
kbackground->surface_shader |= SHADER_EXCLUDE_DIFFUSE;
if(!(visibility & PATH_RAY_GLOSSY))
kbackground->shader |= SHADER_EXCLUDE_GLOSSY;
kbackground->surface_shader |= SHADER_EXCLUDE_GLOSSY;
if(!(visibility & PATH_RAY_TRANSMIT))
kbackground->shader |= SHADER_EXCLUDE_TRANSMIT;
kbackground->surface_shader |= SHADER_EXCLUDE_TRANSMIT;
if(!(visibility & PATH_RAY_CAMERA))
kbackground->shader |= SHADER_EXCLUDE_CAMERA;
kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
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 i = 0;
bool has_converter_blackbody = false;
bool has_volumes = false;
foreach(Shader *shader, scene->shaders) {
uint flag = 0;
@ -226,8 +227,19 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
flag |= SD_USE_MIS;
if(shader->has_surface_transparent && shader->use_transparent_shadow)
flag |= SD_HAS_TRANSPARENT_SHADOW;
if(shader->has_volume)
if(shader->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)
flag |= SD_HOMOGENEOUS_VOLUME;
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;
}
/* volumes */
KernelIntegrator *kintegrator = &dscene->data.integrator;
kintegrator->use_volumes = has_volumes;
}
void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scene *scene)