Files
blender/intern/cycles/scene/light.h
Lukas Stockner ad35453cd1 Cycles: Add support for light groups
Light groups are a type of pass that only contains lighting from a subset of light sources.
They are created in the View layer, and light sources (lamps, objects with emissive materials
and/or the environment) can be assigned to a group.

Currently, each light group ends up generating its own version of the Combined pass.
In the future, additional types of passes (e.g. shadowcatcher) might be getting their own
per-lightgroup versions.

The lightgroup creation and assignment is not Cycles-specific, so Eevee or external render
engines could make use of it in the future.

Note that Lightgroups are identified by their name - therefore, the name of the Lightgroup
in the View Layer and the name that's set in an object's settings must match for it to be
included.
Currently, changing a Lightgroup's name does not update objects - this is planned for the
future, along with other features such as denoising for light groups and viewing them in
preview renders.

Original patch by Alex Fuller (@mistaed), with some polishing by Lukas Stockner (@lukasstockner97).

Differential Revision: https://developer.blender.org/D12871
2022-04-02 06:14:27 +02:00

162 lines
4.0 KiB
C++

/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#ifndef __LIGHT_H__
#define __LIGHT_H__
#include "kernel/types.h"
#include "graph/node.h"
/* included as Light::set_shader defined through NODE_SOCKET_API does not select
* the right Node::set overload as it does not know that Shader is a Node */
#include "scene/shader.h"
#include "util/ies.h"
#include "util/thread.h"
#include "util/types.h"
#include "util/vector.h"
CCL_NAMESPACE_BEGIN
class Device;
class DeviceScene;
class Object;
class Progress;
class Scene;
class Shader;
class Light : public Node {
public:
NODE_DECLARE;
Light();
NODE_SOCKET_API(LightType, light_type)
NODE_SOCKET_API(float3, strength)
NODE_SOCKET_API(float3, co)
NODE_SOCKET_API(float3, dir)
NODE_SOCKET_API(float, size)
NODE_SOCKET_API(float, angle)
NODE_SOCKET_API(float3, axisu)
NODE_SOCKET_API(float, sizeu)
NODE_SOCKET_API(float3, axisv)
NODE_SOCKET_API(float, sizev)
NODE_SOCKET_API(bool, round)
NODE_SOCKET_API(float, spread)
NODE_SOCKET_API(Transform, tfm)
NODE_SOCKET_API(int, map_resolution)
NODE_SOCKET_API(float, spot_angle)
NODE_SOCKET_API(float, spot_smooth)
NODE_SOCKET_API(bool, cast_shadow)
NODE_SOCKET_API(bool, use_mis)
NODE_SOCKET_API(bool, use_camera)
NODE_SOCKET_API(bool, use_diffuse)
NODE_SOCKET_API(bool, use_glossy)
NODE_SOCKET_API(bool, use_transmission)
NODE_SOCKET_API(bool, use_scatter)
NODE_SOCKET_API(bool, use_caustics)
NODE_SOCKET_API(bool, is_shadow_catcher)
NODE_SOCKET_API(bool, is_portal)
NODE_SOCKET_API(bool, is_enabled)
NODE_SOCKET_API(Shader *, shader)
NODE_SOCKET_API(int, max_bounces)
NODE_SOCKET_API(uint, random_id)
NODE_SOCKET_API(ustring, lightgroup)
void tag_update(Scene *scene);
/* Check whether the light has contribution the scene. */
bool has_contribution(Scene *scene);
friend class LightManager;
};
class LightManager {
public:
enum : uint32_t {
MESH_NEED_REBUILD = (1 << 0),
EMISSIVE_MESH_MODIFIED = (1 << 1),
LIGHT_MODIFIED = (1 << 2),
LIGHT_ADDED = (1 << 3),
LIGHT_REMOVED = (1 << 4),
OBJECT_MANAGER = (1 << 5),
SHADER_COMPILED = (1 << 6),
SHADER_MODIFIED = (1 << 7),
/* tag everything in the manager for an update */
UPDATE_ALL = ~0u,
UPDATE_NONE = 0u,
};
/* Need to update background (including multiple importance map) */
bool need_update_background;
LightManager();
~LightManager();
/* IES texture management */
int add_ies(const string &ies);
int add_ies_from_file(const string &filename);
void remove_ies(int slot);
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene, const bool free_background = true);
void tag_update(Scene *scene, uint32_t flag);
bool need_update() const;
/* Check whether there is a background light. */
bool has_background_light(Scene *scene);
protected:
/* Optimization: disable light which is either unsupported or
* which doesn't contribute to the scene or which is only used for MIS
* and scene doesn't need MIS.
*/
void test_enabled_lights(Scene *scene);
void device_update_points(Device *device, DeviceScene *dscene, Scene *scene);
void device_update_distribution(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress);
void device_update_background(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress);
void device_update_ies(DeviceScene *dscene);
/* Check whether light manager can use the object as a light-emissive. */
bool object_usable_as_light(Object *object);
struct IESSlot {
IESFile ies;
uint hash;
int users;
};
vector<IESSlot *> ies_slots;
thread_mutex ies_mutex;
bool last_background_enabled;
int last_background_resolution;
uint32_t update_flags;
};
CCL_NAMESPACE_END
#endif /* __LIGHT_H__ */