373 lines
9.6 KiB
C++
373 lines
9.6 KiB
C++
//
|
|
// VROLight.h
|
|
// ViroRenderer
|
|
//
|
|
// Created by Raj Advani on 12/7/15.
|
|
// Copyright © 2015 Viro Media. All rights reserved.
|
|
//
|
|
|
|
#ifndef VROLight_h
|
|
#define VROLight_h
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <atomic>
|
|
#include <memory>
|
|
#include <limits>
|
|
#include "VROVector3f.h"
|
|
#include "VROVector4f.h"
|
|
#include "VROMatrix4f.h"
|
|
#include "VROAnimatable.h"
|
|
|
|
static std::atomic_int sLightId;
|
|
class VROTexture;
|
|
class VROPencil;
|
|
class VROLightingUBO;
|
|
|
|
enum class VROLightType {
|
|
Ambient,
|
|
Directional,
|
|
Omni,
|
|
Spot
|
|
};
|
|
|
|
enum class VROShadowMode {
|
|
Forward,
|
|
Deferred,
|
|
Modulated
|
|
};
|
|
|
|
class VROLight : public VROAnimatable {
|
|
|
|
public:
|
|
|
|
static uint32_t hashLights(const std::vector<std::shared_ptr<VROLight>> &lights);
|
|
|
|
VROLight(VROLightType type);
|
|
~VROLight() {}
|
|
|
|
uint32_t getLightId() const {
|
|
return _lightId;
|
|
}
|
|
|
|
VROLightType getType() const {
|
|
return _type;
|
|
}
|
|
|
|
#pragma mark - Light Properties
|
|
|
|
void setColor(VROVector3f color);
|
|
VROVector3f getColor() const {
|
|
return _color;
|
|
}
|
|
|
|
void setIntensity(float intensity);
|
|
float getIntensity() const {
|
|
return _intensity;
|
|
}
|
|
|
|
void setTemperature(float temperature);
|
|
float getTemperature() const {
|
|
return _temperature;
|
|
}
|
|
VROVector3f getColorFromTemperature() const {
|
|
return _colorFromTemperature;
|
|
}
|
|
|
|
void setName(std::string name) {
|
|
this->_name = name;
|
|
}
|
|
std::string getName() const {
|
|
return _name;
|
|
}
|
|
|
|
void setPosition(VROVector3f position);
|
|
VROVector3f getPosition() const {
|
|
return _position;
|
|
}
|
|
|
|
void setDirection(VROVector3f direction);
|
|
VROVector3f getDirection() const {
|
|
return _direction;
|
|
}
|
|
|
|
void setAttenuationStartDistance(float attenuationStartDistance);
|
|
float getAttenuationStartDistance() const {
|
|
return _attenuationStartDistance;
|
|
}
|
|
|
|
void setAttenuationEndDistance(float attenuationEndDistance);
|
|
float getAttenuationEndDistance() const {
|
|
return _attenuationEndDistance;
|
|
}
|
|
|
|
void setAttenuationFalloffExponent(float attenuationFalloffExponent);
|
|
float getAttenuationFalloffExponent() const {
|
|
return _attenuationFalloffExponent;
|
|
}
|
|
|
|
void setSpotInnerAngle(float spotInnerAngle);
|
|
float getSpotInnerAngle() const {
|
|
return _spotInnerAngle;
|
|
}
|
|
|
|
void setSpotOuterAngle(float spotOuterAngle);
|
|
float getSpotOuterAngle() const {
|
|
return _spotOuterAngle;
|
|
}
|
|
|
|
void setInfluenceBitMask(int influenceBitMask) {
|
|
_influenceBitMask = influenceBitMask;
|
|
}
|
|
int getInfluenceBitMask() const {
|
|
return _influenceBitMask;
|
|
}
|
|
|
|
#pragma mark - Shadow Properties
|
|
|
|
void setCastsShadow(bool castsShadow);
|
|
bool getCastsShadow() const {
|
|
return _castsShadow;
|
|
}
|
|
|
|
void setShadowOpacity(float shadowOpacity);
|
|
float getShadowOpacity() const {
|
|
return _shadowOpacity;
|
|
}
|
|
|
|
void setShadowMapSize(int shadowMapSize) {
|
|
_shadowMapSize = shadowMapSize;
|
|
}
|
|
int getShadowMapSize() const {
|
|
return _shadowMapSize;
|
|
}
|
|
|
|
void setShadowBias(float shadowBias) {
|
|
_updatedFragmentData = true;
|
|
_shadowBias = shadowBias;
|
|
}
|
|
float getShadowBias() const {
|
|
return _shadowBias;
|
|
}
|
|
|
|
void setShadowOrthographicSize(float size) {
|
|
_shadowOrthographicSize = size;
|
|
}
|
|
float getShadowOrthographicSize() const {
|
|
return _shadowOrthographicSize;
|
|
}
|
|
|
|
void setShadowNearZ(float nearZ) {
|
|
_shadowNearZ = nearZ;
|
|
}
|
|
float getShadowNearZ() const {
|
|
return _shadowNearZ;
|
|
}
|
|
|
|
void setShadowFarZ(float farZ) {
|
|
_shadowFarZ = farZ;
|
|
}
|
|
float getShadowFarZ() const {
|
|
return _shadowFarZ;
|
|
}
|
|
|
|
#pragma mark - Light Implementation
|
|
|
|
/*
|
|
Lights hold onto their UBOs so that they can propagate their
|
|
updates to them. Each time a light is updated, it pushes the
|
|
update to all of its parent UBOs.
|
|
*/
|
|
void addUBO(std::shared_ptr<VROLightingUBO> ubo) {
|
|
_ubos.push_back(ubo);
|
|
}
|
|
void propagateFragmentUpdates();
|
|
void propagateVertexUpdates();
|
|
|
|
void setTransformedPosition(VROVector3f position);
|
|
VROVector3f getTransformedPosition() const {
|
|
return _transformedPosition;
|
|
}
|
|
|
|
#pragma mark - Shadow Implementation
|
|
|
|
int getShadowMapIndex() const {
|
|
return _shadowMapIndex;
|
|
}
|
|
void setShadowMapIndex(int shadowMapIndex) {
|
|
_updatedFragmentData = true;
|
|
_shadowMapIndex = shadowMapIndex;
|
|
}
|
|
|
|
VROMatrix4f getShadowViewMatrix() const {
|
|
return _shadowViewMatrix;
|
|
}
|
|
VROMatrix4f getShadowProjectionMatrix() const {
|
|
return _shadowProjectionMatrix;
|
|
}
|
|
|
|
void setShadowViewMatrix(VROMatrix4f shadowViewMatrix) {
|
|
_updatedVertexData = true;
|
|
_shadowViewMatrix = shadowViewMatrix;
|
|
}
|
|
void setShadowProjectionMatrix(VROMatrix4f shadowProjectionMatrix) {
|
|
_updatedVertexData = true;
|
|
_shadowProjectionMatrix = shadowProjectionMatrix;
|
|
}
|
|
|
|
#pragma mark - Debugging
|
|
|
|
void drawLightFrustum(std::shared_ptr<VROPencil> pencil);
|
|
|
|
private:
|
|
|
|
uint32_t _lightId;
|
|
VROLightType _type;
|
|
|
|
/*
|
|
RGB color of the light.
|
|
*/
|
|
VROVector3f _color;
|
|
|
|
/*
|
|
Luminous flux of the light, ranging from 0 to 1000. Modulates the color of the
|
|
light.
|
|
*/
|
|
float _intensity;
|
|
|
|
/*
|
|
The temperature of the light, in Kelvin. Viro will derive a hue from this temperature
|
|
and multiply it by _color. To model a physical light, you can leave _color set to
|
|
(1.0, 1.0, 1.0) and set the temperature only. The default value is 6500K, which
|
|
represents pure white light.
|
|
*/
|
|
float _temperature;
|
|
|
|
/*
|
|
The color as derived from _temperature.
|
|
*/
|
|
VROVector3f _colorFromTemperature;
|
|
|
|
std::string _name;
|
|
bool _updatedFragmentData;
|
|
bool _updatedVertexData;
|
|
|
|
/*
|
|
The position of the light. For omnidirectional and spotlights, this represents
|
|
the position from which the light emanates. For directional lights there is no
|
|
position, but we still use this field to indicate where the directional light's
|
|
shadow map should be centered.
|
|
*/
|
|
VROVector3f _position;
|
|
|
|
/*
|
|
Attenuation parameters for omni and spot lights.
|
|
*/
|
|
float _attenuationStartDistance;
|
|
float _attenuationEndDistance;
|
|
float _attenuationFalloffExponent;
|
|
|
|
/*
|
|
Diffuse parameters.
|
|
*/
|
|
VROVector3f _direction;
|
|
|
|
/*
|
|
Spot parameters. The inner angle is the angle from edge to edge of
|
|
the 'full strength' light cone. The lighting is at maximum intensity
|
|
within this cone, and begins to attenuate outside of it.
|
|
|
|
The outer angle is the angle from edge to edge of the "attenuated"
|
|
light cone. The lighting declines in strength betewen the inner angle
|
|
and outer angle. Outside of the outer angle the light attenuates to
|
|
zero, resulting in no light.
|
|
|
|
Both of these are specified in degrees.
|
|
*/
|
|
float _spotInnerAngle;
|
|
float _spotOuterAngle;
|
|
|
|
/*
|
|
Internal. The position of the light after all its supernode
|
|
transforms have been applied.
|
|
*/
|
|
VROVector3f _transformedPosition;
|
|
|
|
/*
|
|
Weak refs to all UBOs that use this light. Needed so that when this
|
|
light is updated, we can flag the UBO as a whole as requiring an
|
|
update.
|
|
*/
|
|
std::vector<std::weak_ptr<VROLightingUBO>> _ubos;
|
|
|
|
/*
|
|
True if this light casts shadows.
|
|
*/
|
|
bool _castsShadow;
|
|
|
|
/*
|
|
The opacity of the shadow. 1.0 implies a pitch black shadow.
|
|
*/
|
|
float _shadowOpacity;
|
|
|
|
/*
|
|
The size of the depth map to use to render shadows. Larger sizes produce
|
|
more detailed shadows at higher cost to rendering performance. Lower sizes
|
|
are faster but result in pixelation at the edges.
|
|
*/
|
|
int _shadowMapSize;
|
|
|
|
/*
|
|
The amount of bias to apply to the Z coordinate when performing the shadow
|
|
depth comparison. This reduces shadow acne, but large biases can increase
|
|
"peter panning".
|
|
*/
|
|
float _shadowBias;
|
|
|
|
/*
|
|
This property only applies to directional lights, where an orthographic
|
|
projection is used to render the shadow map. The orthographic size determines
|
|
the width and height of the area, centered at _position, that should be rendered
|
|
to the shadow map.
|
|
|
|
A larger value means more of the scene will be shadowed, but
|
|
at lower resolution.
|
|
*/
|
|
float _shadowOrthographicSize;
|
|
|
|
/*
|
|
The near and far clipping planes to use when rendering shadows. Shadows are
|
|
only cast by surfaces within these planes.
|
|
*/
|
|
float _shadowNearZ, _shadowFarZ;
|
|
|
|
/*
|
|
The index into the shadow render target's texture array where we can find this
|
|
light's shadow map.
|
|
*/
|
|
int _shadowMapIndex;
|
|
|
|
/*
|
|
Bit mask that is ANDed with each node's lightReceivingBitMask and shadowCastingBitMask
|
|
to determine what objects are illuminated by, and cast shadows from, this light.
|
|
|
|
Default is 1.
|
|
*/
|
|
int _influenceBitMask;
|
|
|
|
/*
|
|
The view and projection matrices used to transform any point in world
|
|
space into its corresponding texcoord in the light's shadow depth map.
|
|
*/
|
|
VROMatrix4f _shadowViewMatrix;
|
|
VROMatrix4f _shadowProjectionMatrix;
|
|
|
|
/*
|
|
Derive the RGB color (hue) from the given temperature in Kelvin.
|
|
*/
|
|
VROVector3f deriveRGBFromTemperature(float temperature);
|
|
|
|
};
|
|
|
|
#endif /* VROLight_h */
|