891 lines
35 KiB
C++
Executable File
891 lines
35 KiB
C++
Executable File
/*
|
|
* Copyright (C) 2017 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef TNT_FILAMENT_LIGHTMANAGER_H
|
|
#define TNT_FILAMENT_LIGHTMANAGER_H
|
|
|
|
#include <filament/FilamentAPI.h>
|
|
#include <filament/Color.h>
|
|
|
|
#include <utils/compiler.h>
|
|
#include <utils/Entity.h>
|
|
#include <utils/EntityInstance.h>
|
|
|
|
#include <math/mathfwd.h>
|
|
|
|
namespace utils {
|
|
class Entity;
|
|
} // namespace utils
|
|
|
|
namespace filament {
|
|
|
|
class Engine;
|
|
class FEngine;
|
|
class FLightManager;
|
|
|
|
/**
|
|
* LightManager allows to create a light source in the scene, such as a sun or street lights.
|
|
*
|
|
* At least one light must be added to a scene in order to see anything
|
|
* (unless the Material.Shading.UNLIT is used).
|
|
*
|
|
*
|
|
* Creation and destruction
|
|
* ========================
|
|
*
|
|
* A Light component is created using the LightManager::Builder and destroyed by calling
|
|
* LightManager::destroy(utils::Entity).
|
|
*
|
|
* ~~~~~~~~~~~{.cpp}
|
|
* filament::Engine* engine = filament::Engine::create();
|
|
* utils::Entity sun = utils::EntityManager.get().create();
|
|
*
|
|
* filament::LightManager::Builder(Type::SUN)
|
|
* .castShadows(true)
|
|
* .build(*engine, sun);
|
|
*
|
|
* engine->getLightManager().destroy(sun);
|
|
* ~~~~~~~~~~~
|
|
*
|
|
*
|
|
* Light types
|
|
* ===========
|
|
*
|
|
* Lights come in three flavors:
|
|
* - directional lights
|
|
* - point lights
|
|
* - spot lights
|
|
*
|
|
*
|
|
* Directional lights
|
|
* ------------------
|
|
*
|
|
* Directional lights have a direction, but don't have a position. All light rays are
|
|
* parallel and come from infinitely far away and from everywhere. Typically a directional light
|
|
* is used to simulate the sun.
|
|
*
|
|
* Directional lights and spot lights are able to cast shadows.
|
|
*
|
|
* To create a directional light use Type.DIRECTIONAL or Type.SUN, both are similar, but the later
|
|
* also draws a sun's disk in the sky and its reflection on glossy objects.
|
|
*
|
|
* @warning Currently, only a single directional light is supported. If several directional lights
|
|
* are added to the scene, the dominant one will be used.
|
|
*
|
|
* @see Builder.direction(), Builder.sunAngularRadius()
|
|
*
|
|
* Point lights
|
|
* ------------
|
|
*
|
|
* Unlike directional lights, point lights have a position but emit light in all directions.
|
|
* The intensity of the light diminishes with the inverse square of the distance to the light.
|
|
* Builder.falloff() controls distance beyond which the light has no more influence.
|
|
*
|
|
* A scene can have multiple point lights.
|
|
*
|
|
* @see Builder.position(), Builder.falloff()
|
|
*
|
|
* Spot lights
|
|
* -----------
|
|
*
|
|
* Spot lights are similar to point lights but the light it emits is limited to a cone defined by
|
|
* Builder.spotLightCone() and the light's direction.
|
|
*
|
|
* A spot light is therefore defined by a position, a direction and inner and outer cones. The
|
|
* spot light's influence is limited to inside the outer cone. The inner cone defines the light's
|
|
* falloff attenuation.
|
|
*
|
|
* A physically correct spot light is a little difficult to use because changing the outer angle
|
|
* of the cone changes the illumination levels, as the same amount of light is spread over a
|
|
* changing volume. The coupling of illumination and the outer cone means that an artist cannot
|
|
* tweak the influence cone of a spot light without also changing the perceived illumination.
|
|
* It therefore makes sense to provide artists with a parameter to disable this coupling. This
|
|
* is the difference between Type.FOCUSED_SPOT and Type.SPOT.
|
|
*
|
|
* @see Builder.position(), Builder.direction(), Builder.falloff(), Builder.spotLightCone()
|
|
*
|
|
* Performance considerations
|
|
* ==========================
|
|
*
|
|
* Generally, adding lights to the scene hurts performance, however filament is designed to be
|
|
* able to handle hundreds of lights in a scene under certain conditions. Here are some tips
|
|
* to keep performances high.
|
|
*
|
|
* 1. Prefer spot lights to point lights and use the smallest outer cone angle possible.
|
|
*
|
|
* 2. Use the smallest possible falloff distance for point and spot lights.
|
|
* Performance is very sensitive to overlapping lights. The falloff distance essentially
|
|
* defines a sphere of influence for the light, so try to position point and spot lights
|
|
* such that they don't overlap too much.
|
|
*
|
|
* On the other hand, a scene can contain hundreds of non overlapping lights without
|
|
* incurring a significant overhead.
|
|
*
|
|
*/
|
|
class UTILS_PUBLIC LightManager : public FilamentAPI {
|
|
struct BuilderDetails;
|
|
|
|
public:
|
|
using Instance = utils::EntityInstance<LightManager>;
|
|
|
|
/**
|
|
* Returns the number of component in the LightManager, not that component are not
|
|
* guaranteed to be active. Use the EntityManager::isAlive() before use if needed.
|
|
*
|
|
* @return number of component in the LightManager
|
|
*/
|
|
size_t getComponentCount() const noexcept;
|
|
|
|
/**
|
|
* Returns the list of Entity for all components. Use getComponentCount() to know the size
|
|
* of the list.
|
|
* @return a pointer to Entity
|
|
*/
|
|
utils::Entity const* getEntities() const noexcept;
|
|
|
|
/**
|
|
* Returns whether a particular Entity is associated with a component of this LightManager
|
|
* @param e An Entity.
|
|
* @return true if this Entity has a component associated with this manager.
|
|
*/
|
|
bool hasComponent(utils::Entity e) const noexcept;
|
|
|
|
/**
|
|
* Gets an Instance representing the Light component associated with the given Entity.
|
|
* @param e An Entity.
|
|
* @return An Instance object, which represents the Light component associated with the Entity e.
|
|
* @note Use Instance::isValid() to make sure the component exists.
|
|
* @see hasComponent()
|
|
*/
|
|
Instance getInstance(utils::Entity e) const noexcept;
|
|
|
|
// destroys this component from the given entity
|
|
void destroy(utils::Entity e) noexcept;
|
|
|
|
|
|
//! Denotes the type of the light being created.
|
|
enum class Type : uint8_t {
|
|
SUN, //!< Directional light that also draws a sun's disk in the sky.
|
|
DIRECTIONAL, //!< Directional light, emits light in a given direction.
|
|
POINT, //!< Point light, emits light from a position, in all directions.
|
|
FOCUSED_SPOT, //!< Physically correct spot light.
|
|
SPOT, //!< Spot light with coupling of outer cone and illumination disabled.
|
|
};
|
|
|
|
/**
|
|
* Control the quality / performance of the shadow map associated to this light
|
|
*/
|
|
struct ShadowOptions {
|
|
/** Size of the shadow map in texels. Must be a power-of-two. */
|
|
uint32_t mapSize = 1024;
|
|
|
|
/**
|
|
* Number of shadow cascades to use for this light. Must be between 1 and 4 (inclusive).
|
|
* A value greater than 1 turns on cascaded shadow mapping (CSM).
|
|
* Only applicable to Type.SUN or Type.DIRECTIONAL lights.
|
|
*
|
|
* When using shadow cascades, cascadeSplitPositions must also be set.
|
|
*
|
|
* @see ShadowOptions::cascadeSplitPositions
|
|
*/
|
|
uint8_t shadowCascades = 1;
|
|
|
|
/**
|
|
* The split positions for shadow cascades.
|
|
*
|
|
* Cascaded shadow mapping (CSM) partitions the camera frustum into cascades. These values
|
|
* determine the planes along the camera's Z axis to split the frustum. The camera near
|
|
* plane is represented by 0.0f and the far plane represented by 1.0f.
|
|
*
|
|
* For example, if using 4 cascades, these values would set a uniform split scheme:
|
|
* { 0.25f, 0.50f, 0.75f }
|
|
*
|
|
* For N cascades, N - 1 split positions will be read from this array.
|
|
*
|
|
* Filament provides utility methods inside LightManager::ShadowCascades to help set these
|
|
* values. For example, to use a uniform split scheme:
|
|
*
|
|
* ~~~~~~~~~~~{.cpp}
|
|
* LightManager::ShadowCascades::computeUniformSplits(options.splitPositions, 4);
|
|
* ~~~~~~~~~~~
|
|
*
|
|
* @see ShadowCascades::computeUniformSplits
|
|
* @see ShadowCascades::computeLogSplits
|
|
* @see ShadowCascades::computePracticalSplits
|
|
*/
|
|
float cascadeSplitPositions[3] = { 0.25f, 0.50f, 0.75f };
|
|
|
|
/** Constant bias in world units (e.g. meters) by which shadows are moved away from the
|
|
* light. 1mm by default.
|
|
*/
|
|
float constantBias = 0.001f;
|
|
|
|
/** Amount by which the maximum sampling error is scaled. The resulting value is used
|
|
* to move the shadow away from the fragment normal. Should be 1.0.
|
|
*/
|
|
float normalBias = 1.0f;
|
|
|
|
/** Distance from the camera after which shadows are clipped. this is used to clip
|
|
* shadows that are too far and wouldn't contribute to the scene much, improving
|
|
* performance and quality. This value is always positive.
|
|
* Use 0.0f to use the camera far distance.
|
|
*/
|
|
float shadowFar = 0.0f;
|
|
|
|
/** Optimize the quality of shadows from this distance from the camera. Shadows will
|
|
* be rendered in front of this distance, but the quality may not be optimal.
|
|
* This value is always positive. Use 0.0f to use the camera near distance.
|
|
* The default of 1m works well with many scenes. The quality of shadows may drop
|
|
* rapidly when this value decreases.
|
|
*/
|
|
float shadowNearHint = 1.0f;
|
|
|
|
/** Optimize the quality of shadows in front of this distance from the camera. Shadows
|
|
* will be rendered behind this distance, but the quality may not be optimal.
|
|
* This value is always positive. Use std::numerical_limits<float>::infinity() to
|
|
* use the camera far distance.
|
|
*/
|
|
float shadowFarHint = 100.0f;
|
|
|
|
/**
|
|
* Controls whether the shadow map should be optimized for resolution or stability.
|
|
* When set to true, all resolution enhancing features that can affect stability are
|
|
* disabling, resulting in significantly lower resolution shadows, albeit stable ones.
|
|
*/
|
|
bool stable = false;
|
|
|
|
/**
|
|
* Constant bias in depth-resolution units by which shadows are moved away from the
|
|
* light. The default value of 0.5 is used to round depth values up.
|
|
* Generally this value shouldn't be changed or at least be small and positive.
|
|
*/
|
|
float polygonOffsetConstant = 0.5f;
|
|
|
|
/**
|
|
* Bias based on the change in depth in depth-resolution units by which shadows are moved
|
|
* away from the light. The default value of 2.0 works well with SHADOW_SAMPLING_PCF_LOW.
|
|
* Generally this value is between 0.5 and the size in texel of the PCF filter.
|
|
* Setting this value correctly is essential for LISPSM shadow-maps.
|
|
*/
|
|
float polygonOffsetSlope = 2.0f;
|
|
|
|
/**
|
|
* Whether screen-space contact shadows are used. This applies regardless of whether a
|
|
* Renderable is a shadow caster.
|
|
* Screen-space contact shadows are typically useful in large scenes.
|
|
* (off by default)
|
|
*/
|
|
bool screenSpaceContactShadows = false;
|
|
|
|
/**
|
|
* Number of ray-marching steps for screen-space contact shadows (8 by default).
|
|
*
|
|
* CAUTION: this parameter is ignored for all lights except the directional/sun light,
|
|
* all other lights use the same value set for the directional/sun light.
|
|
*
|
|
*/
|
|
uint8_t stepCount = 8;
|
|
|
|
/**
|
|
* Maximum shadow-occluder distance for screen-space contact shadows (world units).
|
|
* (30 cm by default)
|
|
*
|
|
* CAUTION: this parameter is ignored for all lights except the directional/sun light,
|
|
* all other lights use the same value set for the directional/sun light.
|
|
*
|
|
*/
|
|
float maxShadowDistance = 0.3;
|
|
|
|
/**
|
|
* Options available when the View's ShadowType is set to VSM.
|
|
*
|
|
* @warning This API is still experimental and subject to change.
|
|
* @see View::setShadowType
|
|
*/
|
|
struct {
|
|
/**
|
|
* The number of MSAA samples to use when rendering VSM shadow maps.
|
|
* Must be a power-of-two and greater than or equal to 1. A value of 1 effectively turns
|
|
* off MSAA.
|
|
* Higher values may not be available depending on the underlying hardware.
|
|
*/
|
|
uint8_t msaaSamples = 1;
|
|
} vsm;
|
|
};
|
|
|
|
struct ShadowCascades {
|
|
/**
|
|
* Utility method to compute ShadowOptions::cascadeSplitPositions according to a uniform
|
|
* split scheme.
|
|
*
|
|
* @param splitPositions a float array of at least size (cascades - 1) to write the split
|
|
* positions into
|
|
* @param cascades the number of shadow cascades, at most 4
|
|
*/
|
|
static void computeUniformSplits(float* splitPositions, uint8_t cascades);
|
|
|
|
/**
|
|
* Utility method to compute ShadowOptions::cascadeSplitPositions according to a logarithmic
|
|
* split scheme.
|
|
*
|
|
* @param splitPositions a float array of at least size (cascades - 1) to write the split
|
|
* positions into
|
|
* @param cascades the number of shadow cascades, at most 4
|
|
* @param near the camera near plane
|
|
* @param far the camera far plane
|
|
*/
|
|
static void computeLogSplits(float* splitPositions, uint8_t cascades,
|
|
float near, float far);
|
|
|
|
/**
|
|
* Utility method to compute ShadowOptions::cascadeSplitPositions according to a practical
|
|
* split scheme.
|
|
*
|
|
* The practical split scheme uses uses a lambda value to interpolate between the logarithmic
|
|
* and uniform split schemes. Start with a lambda value of 0.5f and adjust for your scene.
|
|
*
|
|
* See: Zhang et al 2006, "Parallel-split shadow maps for large-scale virtual environments"
|
|
*
|
|
* @param splitPositions a float array of at least size (cascades - 1) to write the split
|
|
* positions into
|
|
* @param cascades the number of shadow cascades, at most 4
|
|
* @param near the camera near plane
|
|
* @param far the camera far plane
|
|
* @param lambda a float in the range [0, 1] that interpolates between log and
|
|
* uniform split schemes
|
|
*/
|
|
static void computePracticalSplits(float* splitPositions, uint8_t cascades,
|
|
float near, float far, float lambda);
|
|
};
|
|
|
|
//! Use Builder to construct a Light object instance
|
|
class Builder : public BuilderBase<BuilderDetails> {
|
|
friend struct BuilderDetails;
|
|
public:
|
|
/**
|
|
* Creates a light builder and set the light's #Type.
|
|
*
|
|
* @param type #Type of Light object to create.
|
|
*/
|
|
explicit Builder(Type type) noexcept;
|
|
Builder(Builder const& rhs) noexcept;
|
|
Builder(Builder&& rhs) noexcept;
|
|
~Builder() noexcept;
|
|
Builder& operator=(Builder const& rhs) noexcept;
|
|
Builder& operator=(Builder&& rhs) noexcept;
|
|
|
|
/**
|
|
* Whether this Light casts shadows (disabled by default)
|
|
*
|
|
* @param enable Enables or disables casting shadows from this Light.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*
|
|
* @warning
|
|
* - Only a Type.DIRECTIONAL, Type.SUN, Type.SPOT, or Type.FOCUSED_SPOT light can cast shadows
|
|
*/
|
|
Builder& castShadows(bool enable) noexcept;
|
|
|
|
/**
|
|
* Sets the shadow-map options for this light.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*/
|
|
Builder& shadowOptions(const ShadowOptions& options) noexcept;
|
|
|
|
/**
|
|
* Whether this light casts light (enabled by default)
|
|
*
|
|
* @param enable Enables or disables lighting from this Light.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*
|
|
* @note
|
|
* In some situations it can be useful to have a light in the scene that doesn't
|
|
* actually emit light, but does cast shadows.
|
|
*/
|
|
Builder& castLight(bool enable) noexcept;
|
|
|
|
/**
|
|
* Sets the initial position of the light in world space.
|
|
*
|
|
* @param position Light's position in world space. The default is at the origin.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*
|
|
* @note
|
|
* The Light's position is ignored for directional lights (Type.DIRECTIONAL or Type.SUN)
|
|
*/
|
|
Builder& position(const math::float3& position) noexcept;
|
|
|
|
/**
|
|
* Sets the initial direction of a light in world space.
|
|
*
|
|
* @param direction Light's direction in world space. Should be a unit vector.
|
|
* The default is {0,-1,0}.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*
|
|
* @note
|
|
* The Light's direction is ignored for Type.POINT lights.
|
|
*/
|
|
Builder& direction(const math::float3& direction) noexcept;
|
|
|
|
/**
|
|
* Sets the initial color of a light.
|
|
*
|
|
* @param color Color of the light specified in the linear sRGB color-space.
|
|
* The default is white {1,1,1}.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*/
|
|
Builder& color(const LinearColor& color) noexcept;
|
|
|
|
/**
|
|
* Sets the initial intensity of a light.
|
|
* @param intensity This parameter depends on the Light.Type:
|
|
* - For directional lights, it specifies the illuminance in *lux*
|
|
* (or *lumen/m^2*).
|
|
* - For point lights and spot lights, it specifies the luminous power
|
|
* in *lumen*.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*
|
|
* For example, the sun's illuminance is about 100,000 lux.
|
|
*
|
|
* This method overrides any prior calls to intensity or intensityCandela.
|
|
*
|
|
*/
|
|
Builder& intensity(float intensity) noexcept;
|
|
|
|
/**
|
|
* Sets the initial intensity of a spot or point light in candela.
|
|
*
|
|
* @param intensity Luminous intensity in *candela*.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*
|
|
* @note
|
|
* This method is equivalent to calling intensity(float intensity) for directional lights
|
|
* (Type.DIRECTIONAL or Type.SUN).
|
|
*
|
|
* This method overrides any prior calls to intensity or intensityCandela.
|
|
*/
|
|
Builder& intensityCandela(float intensity) noexcept;
|
|
|
|
/**
|
|
* Sets the initial intensity of a light in watts.
|
|
*
|
|
* @param watts Energy consumed by a lightbulb. It is related to the energy produced
|
|
* and ultimately the brightness by the \p efficiency parameter.
|
|
* This value is often available on the packaging of commercial
|
|
* lightbulbs.
|
|
*
|
|
* @param efficiency Efficiency in percent. This depends on the type of lightbulb used.
|
|
*
|
|
* Lightbulb type | Efficiency
|
|
* ----------------:|-----------:
|
|
* Incandescent | 2.2%
|
|
* Halogen | 7.0%
|
|
* LED | 8.7%
|
|
* Fluorescent | 10.7%
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*
|
|
*
|
|
* @note
|
|
* This call is equivalent to `Builder::intensity(efficiency * 683 * watts);`
|
|
*
|
|
* This method overrides any prior calls to intensity or intensityCandela.
|
|
*/
|
|
Builder& intensity(float watts, float efficiency) noexcept;
|
|
|
|
/**
|
|
* Set the falloff distance for point lights and spot lights.
|
|
*
|
|
* At the falloff distance, the light has no more effect on objects.
|
|
*
|
|
* The falloff distance essentially defines a *sphere of influence* around the light, and
|
|
* therefore has an impact on performance. Larger falloffs might reduce performance
|
|
* significantly, especially when many lights are used.
|
|
*
|
|
* Try to avoid having a large number of light's spheres of influence overlap.
|
|
*
|
|
* @param radius Falloff distance in world units. Default is 1 meter.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*
|
|
* @note
|
|
* The Light's falloff is ignored for directional lights (Type.DIRECTIONAL or Type.SUN)
|
|
*/
|
|
Builder& falloff(float radius) noexcept;
|
|
|
|
/**
|
|
* Defines a spot light'st angular falloff attenuation.
|
|
*
|
|
* A spot light is defined by a position, a direction and two cones, \p inner and \p outer.
|
|
* These two cones are used to define the angular falloff attenuation of the spot light
|
|
* and are defined by the angle from the center axis to where the falloff begins (i.e.
|
|
* cones are defined by their half-angle).
|
|
*
|
|
* @param inner inner cone angle in *radians* between 0 and @f$ \pi/2 @f$
|
|
*
|
|
* @param outer outer cone angle in *radians* between \p inner and @f$ \pi/2 @f$
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*
|
|
* @note
|
|
* The spot light cone is ignored for directional and point lights.
|
|
*
|
|
* @see Type.SPOT, Type.FOCUSED_SPOT
|
|
*/
|
|
Builder& spotLightCone(float inner, float outer) noexcept;
|
|
|
|
/**
|
|
* Defines the angular radius of the sun, in degrees, between 0.25° and 20.0°
|
|
*
|
|
* The Sun as seen from Earth has an angular size of 0.526° to 0.545°
|
|
*
|
|
* @param angularRadius sun's radius in degree. Default is 0.545°.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*/
|
|
Builder& sunAngularRadius(float angularRadius) noexcept;
|
|
|
|
/**
|
|
* Defines the halo radius of the sun. The radius of the halo is defined as a
|
|
* multiplier of the sun angular radius.
|
|
*
|
|
* @param haloSize radius multiplier. Default is 10.0.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*/
|
|
Builder& sunHaloSize(float haloSize) noexcept;
|
|
|
|
/**
|
|
* Defines the halo falloff of the sun. The falloff is a dimensionless number
|
|
* used as an exponent.
|
|
*
|
|
* @param haloFalloff halo falloff. Default is 80.0.
|
|
*
|
|
* @return This Builder, for chaining calls.
|
|
*/
|
|
Builder& sunHaloFalloff(float haloFalloff) noexcept;
|
|
|
|
enum Result { Error = -1, Success = 0 };
|
|
|
|
/**
|
|
* Adds the Light component to an entity.
|
|
*
|
|
* @param engine Reference to the filament::Engine to associate this light with.
|
|
* @param entity Entity to add the light component to.
|
|
* @return Success if the component was created successfully, Error otherwise.
|
|
*
|
|
* If exceptions are disabled and an error occurs, this function is a no-op.
|
|
* Success can be checked by looking at the return value.
|
|
*
|
|
* If this component already exists on the given entity, it is first destroyed as if
|
|
* destroy(utils::Entity e) was called.
|
|
*
|
|
* @warning
|
|
* Currently, only 2048 lights can be created on a given Engine.
|
|
*
|
|
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
|
|
* memory or other resources.
|
|
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
|
|
*/
|
|
Result build(Engine& engine, utils::Entity entity);
|
|
|
|
private:
|
|
friend class FEngine;
|
|
friend class FLightManager;
|
|
};
|
|
|
|
static constexpr float EFFICIENCY_INCANDESCENT = 0.0220f; //!< Typical efficiency of an incandescent light bulb (2.2%)
|
|
static constexpr float EFFICIENCY_HALOGEN = 0.0707f; //!< Typical efficiency of an halogen light bulb (7.0%)
|
|
static constexpr float EFFICIENCY_FLUORESCENT = 0.0878f; //!< Typical efficiency of a fluorescent light bulb (8.7%)
|
|
static constexpr float EFFICIENCY_LED = 0.1171f; //!< Typical efficiency of a LED light bulb (11.7%)
|
|
|
|
Type getType(Instance i) const noexcept;
|
|
|
|
/**
|
|
* Helper function that returns if a light is a directional light
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @return true is this light is a type of directional light
|
|
*/
|
|
inline bool isDirectional(Instance i) const noexcept {
|
|
Type type = getType(i);
|
|
return type == Type::DIRECTIONAL || type == Type::SUN;
|
|
}
|
|
|
|
/**
|
|
* Helper function that returns if a light is a point light
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @return true is this light is a type of point light
|
|
*/
|
|
inline bool isPointLight(Instance i) const noexcept {
|
|
return getType(i) == Type::POINT;
|
|
}
|
|
|
|
/**
|
|
* Helper function that returns if a light is a spot light
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @return true is this light is a type of spot light
|
|
*/
|
|
inline bool isSpotLight(Instance i) const noexcept {
|
|
Type type = getType(i);
|
|
return type == Type::SPOT || type == Type::FOCUSED_SPOT;
|
|
}
|
|
|
|
/**
|
|
* Dynamically updates the light's position.
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param position Light's position in world space. The default is at the origin.
|
|
*
|
|
* @see Builder.position()
|
|
*/
|
|
void setPosition(Instance i, const math::float3& position) noexcept;
|
|
|
|
//! returns the light's position in world space
|
|
const math::float3& getPosition(Instance i) const noexcept;
|
|
|
|
/**
|
|
* Dynamically updates the light's direction
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param direction Light's direction in world space. Should be a unit vector.
|
|
* The default is {0,-1,0}.
|
|
*
|
|
* @see Builder.direction()
|
|
*/
|
|
void setDirection(Instance i, const math::float3& direction) noexcept;
|
|
|
|
//! returns the light's direction in world space
|
|
const math::float3& getDirection(Instance i) const noexcept;
|
|
|
|
/**
|
|
* Dynamically updates the light's hue as linear sRGB
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param color Color of the light specified in the linear sRGB color-space.
|
|
* The default is white {1,1,1}.
|
|
*
|
|
* @see Builder.color(), getInstance()
|
|
*/
|
|
void setColor(Instance i, const LinearColor& color) noexcept;
|
|
|
|
/**
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @return the light's color in linear sRGB
|
|
*/
|
|
const math::float3& getColor(Instance i) const noexcept;
|
|
|
|
/**
|
|
* Dynamically updates the light's intensity. The intensity can be negative.
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param intensity This parameter depends on the Light.Type:
|
|
* - For directional lights, it specifies the illuminance in *lux*
|
|
* (or *lumen/m^2*).
|
|
* - For point lights and spot lights, it specifies the luminous power
|
|
* in *lumen*.
|
|
*
|
|
* @see Builder.intensity()
|
|
*/
|
|
void setIntensity(Instance i, float intensity) noexcept;
|
|
|
|
/**
|
|
* Dynamically updates the light's intensity. The intensity can be negative.
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param watts Energy consumed by a lightbulb. It is related to the energy produced
|
|
* and ultimately the brightness by the \p efficiency parameter.
|
|
* This value is often available on the packaging of commercial
|
|
* lightbulbs.
|
|
* @param efficiency Efficiency in percent. This depends on the type of lightbulb used.
|
|
*
|
|
* Lightbulb type | Efficiency
|
|
* ----------------:|-----------:
|
|
* Incandescent | 2.2%
|
|
* Halogen | 7.0%
|
|
* LED | 8.7%
|
|
* Fluorescent | 10.7%
|
|
*
|
|
* @see Builder.intensity(float watts, float efficiency)
|
|
*/
|
|
void setIntensity(Instance i, float watts, float efficiency) noexcept {
|
|
setIntensity(i, watts * 683.0f * efficiency);
|
|
}
|
|
|
|
/**
|
|
* Dynamically updates the light's intensity in candela. The intensity can be negative.
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param intensity Luminous intensity in *candela*.
|
|
*
|
|
* @note
|
|
* This method is equivalent to calling setIntensity(float intensity) for directional lights
|
|
* (Type.DIRECTIONAL or Type.SUN).
|
|
*
|
|
* @see Builder.intensityCandela(float intensity)
|
|
*/
|
|
void setIntensityCandela(Instance i, float intensity) noexcept;
|
|
|
|
/**
|
|
* returns the light's luminous intensity in lumen.
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
*
|
|
* @note for Type.FOCUSED_SPOT lights, the returned value depends on the \p outer cone angle.
|
|
*
|
|
* @return luminous intensity in lumen.
|
|
*/
|
|
float getIntensity(Instance i) const noexcept;
|
|
|
|
/**
|
|
* Set the falloff distance for point lights and spot lights.
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param radius falloff distance in world units. Default is 1 meter.
|
|
*
|
|
* @see Builder.falloff()
|
|
*/
|
|
void setFalloff(Instance i, float radius) noexcept;
|
|
|
|
/**
|
|
* returns the falloff distance of this light.
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @return the falloff distance of this light.
|
|
*/
|
|
float getFalloff(Instance i) const noexcept;
|
|
|
|
/**
|
|
* Dynamically updates a spot light's cone as angles
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param inner inner cone angle in *radians* between 0 and pi/2
|
|
* @param outer outer cone angle in *radians* between inner and pi/2
|
|
*
|
|
* @see Builder.spotLightCone()
|
|
*/
|
|
void setSpotLightCone(Instance i, float inner, float outer) noexcept;
|
|
|
|
float getSpotLightOuterCone(Instance i) const noexcept;
|
|
|
|
/**
|
|
* Dynamically updates the angular radius of a Type.SUN light
|
|
*
|
|
* The Sun as seen from Earth has an angular size of 0.526° to 0.545°
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param angularRadius sun's radius in degrees. Default is 0.545°.
|
|
*/
|
|
void setSunAngularRadius(Instance i, float angularRadius) noexcept;
|
|
|
|
/**
|
|
* returns the angular radius if the sun in degrees.
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @return the angular radius if the sun in degrees.
|
|
*/
|
|
float getSunAngularRadius(Instance i) const noexcept;
|
|
|
|
/**
|
|
* Dynamically updates the halo radius of a Type.SUN light. The radius
|
|
* of the halo is defined as a multiplier of the sun angular radius.
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param haloSize radius multiplier. Default is 10.0.
|
|
*/
|
|
void setSunHaloSize(Instance i, float haloSize) noexcept;
|
|
|
|
/**
|
|
* returns the halo size of a Type.SUN light as a multiplier of the
|
|
* sun angular radius.
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @return the halo size
|
|
*/
|
|
float getSunHaloSize(Instance i) const noexcept;
|
|
|
|
/**
|
|
* Dynamically updates the halo falloff of a Type.SUN light. The falloff
|
|
* is a dimensionless number used as an exponent.
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param haloFalloff halo falloff. Default is 80.0.
|
|
*/
|
|
void setSunHaloFalloff(Instance i, float haloFalloff) noexcept;
|
|
|
|
/**
|
|
* returns the halo falloff of a Type.SUN light as a dimensionless value.
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @return the halo falloff
|
|
*/
|
|
float getSunHaloFalloff(Instance i) const noexcept;
|
|
|
|
/**
|
|
* returns the shadow-map options for a given light
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @return A ShadowOption structure
|
|
*/
|
|
ShadowOptions const& getShadowOptions(Instance i) const noexcept;
|
|
|
|
/**
|
|
* sets the shadow-map options for a given light
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param options A ShadowOption structure
|
|
*/
|
|
void setShadowOptions(Instance i, ShadowOptions const& options) noexcept;
|
|
|
|
/**
|
|
* Whether this Light casts shadows (disabled by default)
|
|
*
|
|
* @param i Instance of the component obtained from getInstance().
|
|
* @param shadowCaster Enables or disables casting shadows from this Light.
|
|
*
|
|
* @warning
|
|
* - Only a Type.DIRECTIONAL, Type.SUN, Type.SPOT, or Type.FOCUSED_SPOT light can cast shadows
|
|
*/
|
|
void setShadowCaster(Instance i, bool shadowCaster) noexcept;
|
|
|
|
/**
|
|
* returns whether this light casts shadows.
|
|
* @param i Instance of the component obtained from getInstance().
|
|
*/
|
|
bool isShadowCaster(Instance i) const noexcept;
|
|
|
|
/**
|
|
* Helper to process all components with a given function
|
|
* @tparam F a void(Entity entity, Instance instance)
|
|
* @param func a function of type F
|
|
*/
|
|
template<typename F>
|
|
void forEachComponent(F func) noexcept {
|
|
utils::Entity const* const pEntity = getEntities();
|
|
for (size_t i = 0, c = getComponentCount(); i < c; i++) {
|
|
// Instance 0 is the invalid instance
|
|
func(pEntity[i], Instance(i + 1));
|
|
}
|
|
}
|
|
};
|
|
|
|
} // namespace filament
|
|
|
|
#endif // TNT_FILAMENT_LIGHTMANAGER_H
|