Initial Grease Pencil 3.0 stage #106848
|
@ -38,6 +38,8 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
light->name = b_light.name().c_str();
|
||||||
|
|
||||||
/* type */
|
/* type */
|
||||||
switch (b_light.type()) {
|
switch (b_light.type()) {
|
||||||
case BL::Light::type_POINT: {
|
case BL::Light::type_POINT: {
|
||||||
|
|
|
@ -396,7 +396,7 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc,
|
||||||
* - Purely reflective closures can't have refraction.
|
* - Purely reflective closures can't have refraction.
|
||||||
* - Purely refractive closures can't have reflection.
|
* - Purely refractive closures can't have reflection.
|
||||||
*/
|
*/
|
||||||
if ((cos_NI <= 0) || (alpha_x * alpha_y <= 1e-7f) || ((cos_NgO < 0.0f) != is_refraction) ||
|
if ((cos_NI <= 0) || (alpha_x * alpha_y <= 5e-7f) || ((cos_NgO < 0.0f) != is_refraction) ||
|
||||||
(is_refraction && !m_refractive) || (!is_refraction && m_refractive && !m_glass))
|
(is_refraction && !m_refractive) || (!is_refraction && m_refractive && !m_glass))
|
||||||
{
|
{
|
||||||
*pdf = 0.0f;
|
*pdf = 0.0f;
|
||||||
|
@ -478,7 +478,7 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
|
||||||
const bool m_refractive = CLOSURE_IS_REFRACTIVE(bsdf->type);
|
const bool m_refractive = CLOSURE_IS_REFRACTIVE(bsdf->type);
|
||||||
const float alpha_x = bsdf->alpha_x;
|
const float alpha_x = bsdf->alpha_x;
|
||||||
const float alpha_y = bsdf->alpha_y;
|
const float alpha_y = bsdf->alpha_y;
|
||||||
bool m_singular = (m_type == MicrofacetType::SHARP) || (alpha_x * alpha_y <= 1e-7f);
|
bool m_singular = (m_type == MicrofacetType::SHARP) || (alpha_x * alpha_y <= 5e-7f);
|
||||||
|
|
||||||
const float3 N = bsdf->N;
|
const float3 N = bsdf->N;
|
||||||
const float cos_NI = dot(N, wi);
|
const float cos_NI = dot(N, wi);
|
||||||
|
|
|
@ -32,6 +32,14 @@ ccl_device_inline void integrate_camera_sample(KernelGlobals kg,
|
||||||
path_rng_3D(kg, rng_hash, sample, PRNG_LENS_TIME) :
|
path_rng_3D(kg, rng_hash, sample, PRNG_LENS_TIME) :
|
||||||
zero_float3();
|
zero_float3();
|
||||||
|
|
||||||
|
/* We use x for time and y,z for lens because in practice with Sobol
|
||||||
|
* sampling this seems to give better convergence when an object is
|
||||||
|
* both motion blurred and out of focus, without significantly harming
|
||||||
|
* convergence for focal blur alone. This is a little surprising,
|
||||||
|
* because one would expect using x,y for lens (the 2d part) would be
|
||||||
|
* best, since x,y are the best stratified. Since it's not entirely
|
||||||
|
* clear why this is, this is probably worth revisiting at some point
|
||||||
|
* to investigate further. */
|
||||||
const float rand_time = rand_time_lens.x;
|
const float rand_time = rand_time_lens.x;
|
||||||
const float2 rand_lens = make_float2(rand_time_lens.y, rand_time_lens.z);
|
const float2 rand_lens = make_float2(rand_time_lens.y, rand_time_lens.z);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,20 @@ CCL_NAMESPACE_BEGIN
|
||||||
* this single threaded on a CPU for repeatable results. */
|
* this single threaded on a CPU for repeatable results. */
|
||||||
//#define __DEBUG_CORRELATION__
|
//#define __DEBUG_CORRELATION__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The `path_rng_*()` functions below use a shuffled scrambled Sobol
|
||||||
|
* sequence to generate their samples. Sobol samplers have a property
|
||||||
|
* that is worth being aware of when choosing how to use the sample
|
||||||
|
* dimensions:
|
||||||
|
*
|
||||||
|
* 1. In general, earlier sets of dimensions are better stratified. So
|
||||||
|
* prefer e.g. x,y over y,z over z,w for the things that are most
|
||||||
|
* important to sample well.
|
||||||
|
* 2. As a rule of thumb, dimensions that are closer to each other are
|
||||||
|
* better stratified than dimensions that are far. So prefer e.g.
|
||||||
|
* x,y over x,z.
|
||||||
|
*/
|
||||||
|
|
||||||
ccl_device_forceinline float path_rng_1D(KernelGlobals kg,
|
ccl_device_forceinline float path_rng_1D(KernelGlobals kg,
|
||||||
uint rng_hash,
|
uint rng_hash,
|
||||||
int sample,
|
int sample,
|
||||||
|
|
|
@ -174,6 +174,24 @@ bool Light::has_contribution(Scene *scene)
|
||||||
return !is_zero(effective_shader->emission_estimate);
|
return !is_zero(effective_shader->emission_estimate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Light::has_light_linking() const
|
||||||
|
{
|
||||||
|
if (get_light_set_membership() != LIGHT_LINK_MASK_ALL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Light::has_shadow_linking() const
|
||||||
|
{
|
||||||
|
if (get_shadow_set_membership() != LIGHT_LINK_MASK_ALL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Light Manager */
|
/* Light Manager */
|
||||||
|
|
||||||
LightManager::LightManager()
|
LightManager::LightManager()
|
||||||
|
|
|
@ -82,6 +82,10 @@ class Light : public Node {
|
||||||
/* Check whether the light has contribution the scene. */
|
/* Check whether the light has contribution the scene. */
|
||||||
bool has_contribution(Scene *scene);
|
bool has_contribution(Scene *scene);
|
||||||
|
|
||||||
|
/* Check whether this light participates in light or shadow linking. */
|
||||||
|
bool has_light_linking() const;
|
||||||
|
bool has_shadow_linking() const;
|
||||||
|
|
||||||
friend class LightManager;
|
friend class LightManager;
|
||||||
friend class LightTree;
|
friend class LightTree;
|
||||||
};
|
};
|
||||||
|
|
|
@ -276,6 +276,7 @@ struct LightTreeNode {
|
||||||
__forceinline void add(const LightTreeEmitter &emitter)
|
__forceinline void add(const LightTreeEmitter &emitter)
|
||||||
{
|
{
|
||||||
measure.add(emitter.measure);
|
measure.add(emitter.measure);
|
||||||
|
light_link.add(emitter.light_set_membership);
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline Leaf &get_leaf()
|
__forceinline Leaf &get_leaf()
|
||||||
|
|
|
@ -403,6 +403,32 @@ bool Object::usable_as_light() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Object::has_light_linking() const
|
||||||
|
{
|
||||||
|
if (get_receiver_light_set()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_light_set_membership() != LIGHT_LINK_MASK_ALL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Object::has_shadow_linking() const
|
||||||
|
{
|
||||||
|
if (get_blocker_shadow_set()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_shadow_set_membership() != LIGHT_LINK_MASK_ALL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Object Manager */
|
/* Object Manager */
|
||||||
|
|
||||||
ObjectManager::ObjectManager()
|
ObjectManager::ObjectManager()
|
||||||
|
|
|
@ -113,6 +113,11 @@ class Object : public Node {
|
||||||
/* Check whether this object can be used as light-emissive. */
|
/* Check whether this object can be used as light-emissive. */
|
||||||
bool usable_as_light() const;
|
bool usable_as_light() const;
|
||||||
|
|
||||||
|
/* Check whether the object participates in light or shadow linking, either as a receiver/blocker
|
||||||
|
* or emitter. */
|
||||||
|
bool has_light_linking() const;
|
||||||
|
bool has_shadow_linking() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Specifies the position of the object in scene->objects and
|
/* Specifies the position of the object in scene->objects and
|
||||||
* in the device vectors. Gets set in device_update. */
|
* in the device vectors. Gets set in device_update. */
|
||||||
|
|
|
@ -491,10 +491,10 @@ void Scene::update_kernel_features()
|
||||||
else if (geom->is_pointcloud()) {
|
else if (geom->is_pointcloud()) {
|
||||||
kernel_features |= KERNEL_FEATURE_POINTCLOUD;
|
kernel_features |= KERNEL_FEATURE_POINTCLOUD;
|
||||||
}
|
}
|
||||||
if (object->get_receiver_light_set()) {
|
if (object->has_light_linking()) {
|
||||||
kernel_features |= KERNEL_FEATURE_LIGHT_LINKING;
|
kernel_features |= KERNEL_FEATURE_LIGHT_LINKING;
|
||||||
}
|
}
|
||||||
if (object->get_blocker_shadow_set()) {
|
if (object->has_shadow_linking()) {
|
||||||
kernel_features |= KERNEL_FEATURE_SHADOW_LINKING;
|
kernel_features |= KERNEL_FEATURE_SHADOW_LINKING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -503,6 +503,13 @@ void Scene::update_kernel_features()
|
||||||
if (light->get_use_caustics()) {
|
if (light->get_use_caustics()) {
|
||||||
has_caustics_light = true;
|
has_caustics_light = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (light->has_light_linking()) {
|
||||||
|
kernel_features |= KERNEL_FEATURE_LIGHT_LINKING;
|
||||||
|
}
|
||||||
|
if (light->has_shadow_linking()) {
|
||||||
|
kernel_features |= KERNEL_FEATURE_SHADOW_LINKING;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dscene.data.integrator.use_caustics = false;
|
dscene.data.integrator.use_caustics = false;
|
||||||
|
|
|
@ -4207,7 +4207,7 @@ void BKE_lib_override_library_main_operations_restore(Main *bmain, int *r_report
|
||||||
ID *id;
|
ID *id;
|
||||||
|
|
||||||
FOREACH_MAIN_ID_BEGIN (bmain, id) {
|
FOREACH_MAIN_ID_BEGIN (bmain, id) {
|
||||||
if (!(!ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
|
if (!(!ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY_REAL(id) && id->override_library->runtime &&
|
||||||
(id->override_library->runtime->tag & LIBOVERRIDE_TAG_NEEDS_RESTORE) != 0))
|
(id->override_library->runtime->tag & LIBOVERRIDE_TAG_NEEDS_RESTORE) != 0))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -106,7 +106,7 @@ struct Object *DEG_get_original_object(struct Object *object);
|
||||||
struct ID *DEG_get_original_id(struct ID *id);
|
struct ID *DEG_get_original_id(struct ID *id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether given ID is an original,
|
* Check whether given ID is an original.
|
||||||
*
|
*
|
||||||
* Original IDs are considered all the IDs which are not covered by copy-on-write system and are
|
* Original IDs are considered all the IDs which are not covered by copy-on-write system and are
|
||||||
* not out-of-main localized data-blocks.
|
* not out-of-main localized data-blocks.
|
||||||
|
|
|
@ -61,6 +61,13 @@ template<class T> static inline const T *get_original(const T *id)
|
||||||
return reinterpret_cast<T *>(DEG_get_original_id(const_cast<ID *>(&id->id)));
|
return reinterpret_cast<T *>(DEG_get_original_id(const_cast<ID *>(&id->id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check whether the ID is suitable to be an input of the dependency graph. */
|
||||||
|
/* TODO(sergey): Move the function and check to a more generic place. */
|
||||||
|
bool is_valid_input_id(const ID &id)
|
||||||
|
{
|
||||||
|
return (id.tag & LIB_TAG_LOCALIZED) || DEG_is_original_id(&id);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace blender::deg::light_linking {
|
namespace blender::deg::light_linking {
|
||||||
|
@ -153,7 +160,7 @@ void EmitterDataMap::clear()
|
||||||
|
|
||||||
EmitterData *EmitterDataMap::ensure_data_if_possible(const Scene &scene, const Object &emitter)
|
EmitterData *EmitterDataMap::ensure_data_if_possible(const Scene &scene, const Object &emitter)
|
||||||
{
|
{
|
||||||
BLI_assert(DEG_is_original_id(&emitter.id));
|
BLI_assert(is_valid_input_id(emitter.id));
|
||||||
|
|
||||||
const Collection *collection = get_collection(emitter);
|
const Collection *collection = get_collection(emitter);
|
||||||
BLI_assert(collection);
|
BLI_assert(collection);
|
||||||
|
@ -209,7 +216,7 @@ const EmitterData *EmitterDataMap::get_data(const Object &emitter) const
|
||||||
|
|
||||||
bool EmitterDataMap::can_skip_emitter(const Object &emitter) const
|
bool EmitterDataMap::can_skip_emitter(const Object &emitter) const
|
||||||
{
|
{
|
||||||
BLI_assert(DEG_is_original_id(&emitter.id));
|
BLI_assert(is_valid_input_id(emitter.id));
|
||||||
|
|
||||||
const Collection *collection = get_collection(emitter);
|
const Collection *collection = get_collection(emitter);
|
||||||
|
|
||||||
|
@ -249,7 +256,7 @@ void LinkingData::link_object(const EmitterData &emitter_data,
|
||||||
|
|
||||||
LightSet &LinkingData::ensure_light_set_for(const Object &object)
|
LightSet &LinkingData::ensure_light_set_for(const Object &object)
|
||||||
{
|
{
|
||||||
BLI_assert(DEG_is_original_id(&object.id));
|
BLI_assert(is_valid_input_id(object.id));
|
||||||
|
|
||||||
return light_linked_sets_.lookup_or_add_as(&object);
|
return light_linked_sets_.lookup_or_add_as(&object);
|
||||||
}
|
}
|
||||||
|
@ -363,7 +370,7 @@ void Cache::clear()
|
||||||
|
|
||||||
void Cache::add_emitter(const Scene &scene, const Object &emitter)
|
void Cache::add_emitter(const Scene &scene, const Object &emitter)
|
||||||
{
|
{
|
||||||
BLI_assert(DEG_is_original_id(&emitter.id));
|
BLI_assert(is_valid_input_id(emitter.id));
|
||||||
|
|
||||||
add_light_linking_emitter(scene, emitter);
|
add_light_linking_emitter(scene, emitter);
|
||||||
add_shadow_linking_emitter(scene, emitter);
|
add_shadow_linking_emitter(scene, emitter);
|
||||||
|
@ -371,7 +378,7 @@ void Cache::add_emitter(const Scene &scene, const Object &emitter)
|
||||||
|
|
||||||
void Cache::add_light_linking_emitter(const Scene &scene, const Object &emitter)
|
void Cache::add_light_linking_emitter(const Scene &scene, const Object &emitter)
|
||||||
{
|
{
|
||||||
BLI_assert(DEG_is_original_id(&emitter.id));
|
BLI_assert(is_valid_input_id(emitter.id));
|
||||||
|
|
||||||
if (light_emitter_data_map_.can_skip_emitter(emitter)) {
|
if (light_emitter_data_map_.can_skip_emitter(emitter)) {
|
||||||
return;
|
return;
|
||||||
|
@ -390,7 +397,7 @@ void Cache::add_light_linking_emitter(const Scene &scene, const Object &emitter)
|
||||||
|
|
||||||
void Cache::add_shadow_linking_emitter(const Scene &scene, const Object &emitter)
|
void Cache::add_shadow_linking_emitter(const Scene &scene, const Object &emitter)
|
||||||
{
|
{
|
||||||
BLI_assert(DEG_is_original_id(&emitter.id));
|
BLI_assert(is_valid_input_id(emitter.id));
|
||||||
|
|
||||||
if (shadow_emitter_data_map_.can_skip_emitter(emitter)) {
|
if (shadow_emitter_data_map_.can_skip_emitter(emitter)) {
|
||||||
return;
|
return;
|
||||||
|
@ -411,7 +418,7 @@ void Cache::add_receiver_object(const EmitterData &emitter_data,
|
||||||
const CollectionLightLinking &collection_light_linking,
|
const CollectionLightLinking &collection_light_linking,
|
||||||
const Object &receiver)
|
const Object &receiver)
|
||||||
{
|
{
|
||||||
BLI_assert(DEG_is_original_id(&receiver.id));
|
BLI_assert(is_valid_input_id(receiver.id));
|
||||||
|
|
||||||
if (!can_link_to_emitter(receiver)) {
|
if (!can_link_to_emitter(receiver)) {
|
||||||
return;
|
return;
|
||||||
|
@ -425,7 +432,7 @@ void Cache::add_blocker_object(const EmitterData &emitter_data,
|
||||||
const CollectionLightLinking &collection_light_linking,
|
const CollectionLightLinking &collection_light_linking,
|
||||||
const Object &blocker)
|
const Object &blocker)
|
||||||
{
|
{
|
||||||
BLI_assert(DEG_is_original_id(&blocker.id));
|
BLI_assert(is_valid_input_id(blocker.id));
|
||||||
|
|
||||||
if (!can_link_to_emitter(blocker)) {
|
if (!can_link_to_emitter(blocker)) {
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue