Cycles Volume Render: add flags to quickly detect when objects have a volume shader.
This commit is contained in:
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
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue