REvisiting the full lighting code to optimize the perf

This commit is contained in:
samcake 2016-09-29 19:06:26 -07:00
parent bb5493106f
commit 2a0e67ee2a
15 changed files with 186 additions and 168 deletions

View file

@ -26,7 +26,7 @@
#include "SoundCache.h"
#include "AudioSRC.h"
int audioInjectorPtrMetaTypeId = qRegisterMetaType<AudioInjector*>();
//int audioInjectorPtrMetaTypeId = qRegisterMetaType<AudioInjector*>();
AbstractAudioInterface* AudioInjector::_localAudioInterface{ nullptr };

View file

@ -13,22 +13,19 @@
using namespace model;
Light::Light() {
// only if created from nothing shall we create the Buffer to store the properties
Schema schema;
_schemaBuffer = std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema);
updateLightRadius();
}
Light::Light(const Light& light) :
_flags(light._flags),
_schemaBuffer(light._schemaBuffer),
_transform(light._transform)
{
}
Light& Light::operator= (const Light& light) {
_flags = (light._flags);
_schemaBuffer = (light._schemaBuffer);
_lightSchemaBuffer = (light._lightSchemaBuffer);
_ambientSchemaBuffer = (light._ambientSchemaBuffer);
_transform = (light._transform);
return (*this);
@ -38,15 +35,22 @@ Light::~Light() {
}
void Light::setType(Type type) {
editSchema()._control.x = float(type);
updateLightRadius();
if (_type != type) {
_type = type;
if (type != SPOT) {
_lightSchemaBuffer.edit().volume.spotCos = -1.f;
} else {
_lightSchemaBuffer.edit().volume.spotCos = _spotCos;
}
updateLightRadius();
}
updateVolumeGeometry();
}
void Light::setPosition(const Vec3& position) {
_transform.setTranslation(position);
editSchema()._position = Vec4(position, 1.f);
_lightSchemaBuffer.edit().volume.position = position;
}
void Light::setOrientation(const glm::quat& orientation) {
@ -55,39 +59,35 @@ void Light::setOrientation(const glm::quat& orientation) {
}
void Light::setDirection(const Vec3& direction) {
editSchema()._direction = glm::normalize(direction);
_lightSchemaBuffer.edit().volume.direction = (direction);
}
const Vec3& Light::getDirection() const {
return getSchema()._direction;
return _lightSchemaBuffer->volume.direction;
}
void Light::setColor(const Color& color) {
editSchema()._color = color;
_lightSchemaBuffer.edit().irradiance.color = color;
updateLightRadius();
}
void Light::setIntensity(float intensity) {
editSchema()._intensity = intensity;
_lightSchemaBuffer.edit().irradiance.intensity = intensity;
updateLightRadius();
}
void Light::setAmbientIntensity(float intensity) {
editSchema()._ambientIntensity = intensity;
}
void Light::setFalloffRadius(float radius) {
if (radius <= 0.0f) {
radius = 0.1f;
}
editSchema()._attenuation.x = radius;
_lightSchemaBuffer.edit().irradiance.falloffRadius = radius;
updateLightRadius();
}
void Light::setMaximumRadius(float radius) {
if (radius <= 0.f) {
radius = 1.0f;
}
editSchema()._attenuation.y = radius;
_lightSchemaBuffer.edit().volume.radius = radius;
updateLightRadius();
updateVolumeGeometry();
}
@ -106,7 +106,7 @@ void Light::updateLightRadius() {
float cutoffRadius = getFalloffRadius() * ((glm::sqrt(intensity / MIN_CUTOFF_INTENSITY) - 1) - 1);
// If it is less than max radius, store it to buffer to avoid extra shading
editSchema()._attenuation.z = std::min(getMaximumRadius(), cutoffRadius);
_lightSchemaBuffer.edit().irradiance.cutoffRadius = std::min(getMaximumRadius(), cutoffRadius);
}
#include <math.h>
@ -119,12 +119,13 @@ void Light::setSpotAngle(float angle) {
if (dangle > glm::half_pi<double>()) {
dangle = glm::half_pi<double>();
}
auto cosAngle = cos(dangle);
auto sinAngle = sin(dangle);
editSchema()._spot.x = (float) std::abs(cosAngle);
editSchema()._spot.y = (float) std::abs(sinAngle);
editSchema()._spot.z = (float) angle;
_spotCos = (float)std::abs(cosAngle);
if (isSpot()) {
_lightSchemaBuffer.edit().volume.spotCos = _spotCos;
}
updateVolumeGeometry();
}
@ -133,22 +134,20 @@ void Light::setSpotExponent(float exponent) {
if (exponent <= 0.f) {
exponent = 0.0f;
}
editSchema()._spot.w = exponent;
_lightSchemaBuffer.edit().irradiance.falloffSpot = exponent;
}
void Light::setShowContour(float show) {
if (show <= 0.f) {
show = 0.0f;
}
editSchema()._control.z = show;
void Light::setAmbientIntensity(float intensity) {
_ambientSchemaBuffer.edit().intensity = intensity;
}
void Light::setAmbientSphere(const gpu::SphericalHarmonics& sphere) {
editSchema()._ambientSphere = sphere;
_ambientSchemaBuffer.edit().ambientSphere = sphere;
}
void Light::setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) {
editSchema()._ambientSphere.assignPreset(preset);
_ambientSchemaBuffer.edit().ambientSphere.assignPreset(preset);
}
void Light::setAmbientMap(gpu::TexturePointer ambientMap) {
@ -161,17 +160,17 @@ void Light::setAmbientMap(gpu::TexturePointer ambientMap) {
}
void Light::setAmbientMapNumMips(uint16_t numMips) {
editSchema()._ambientMapNumMips = (float)numMips;
_ambientSchemaBuffer.edit().mapNumMips = (float)numMips;
}
void Light::updateVolumeGeometry() {
// enlarge the scales slightly to account for tesselation
const float SCALE_EXPANSION = 0.05f;
/* const float SCALE_EXPANSION = 0.05f;
glm::vec4 volumeGeometry(0.0f, 0.0f, 0.0f, getMaximumRadius() * (1.0f + SCALE_EXPANSION));
if (getType() == SPOT) {
const float TANGENT_LENGTH_SCALE = 0.666f;
volumeGeometry = glm::vec4(getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * getSpotAngle()), volumeGeometry.w);
}
editSchema()._volumeGeometry = volumeGeometry;
editSchema()._volumeGeometry = volumeGeometry;*/
}

View file

@ -31,37 +31,38 @@ class Light {
public:
struct LightVolume {
vec3 position;
float radius;
vec3 direction;
float spotCos;
vec3 position { 0.f };
float radius { 1.0f };
vec3 direction { 0.f, 0.f, -1.f };
float spotCos { -1.f };
bool isPoint() { return bool(spotCos < 0.f); }
bool isSpot() { return bool(spotCos >= 0.f); }
bool isPoint() const { return bool(spotCos < 0.f); }
bool isSpot() const { return bool(spotCos >= 0.f); }
vec3 getPosition() { return position; }
float getRadius() { return radius; }
float getRadiusSquare() { return radius * radius; }
vec3 getDirection() { return direction; }
vec3 getPosition() const { return position; }
float getRadius() const { return radius; }
float getRadiusSquare() const { return radius * radius; }
vec3 getDirection() const { return direction; }
float getSpotAngleCos() { return spotCos; }
float getSpotAngleCos() const { return spotCos; }
vec2 getSpotAngleCosSin() const { return vec2(spotCos, sqrt(1.f - spotCos * spotCos)); }
};
struct LightIrradiance {
vec3 color;
float intensity;
float falloffRadius;
float falloffSpot;
vec3 color { 1.f };
float intensity { 1.f };
float falloffRadius { 0.1f };
float cutoffRadius { 0.1f };
float falloffSpot { 1.f };
float spare1;
float spare2;
vec3 getColor() { return color; }
float getIntensity() { return intensity; }
vec3 getIrradiance() { return color * intensity; }
float getFalloffRadius() { return falloffRadius; }
float getFalloffRadiusSquare() { return falloffRadius * falloffRadius; }
float getFalloffSpot() { return falloffSpot; }
vec3 getColor() const { return color; }
float getIntensity() const { return intensity; }
vec3 getIrradiance() const { return color * intensity; }
float getFalloffRadius() const { return falloffRadius; }
float getCutoffRadius() const { return cutoffRadius; }
float getFalloffSpot() const { return falloffSpot; }
};
@ -93,7 +94,7 @@ public:
virtual ~Light();
void setType(Type type);
Type getType() const { return Type((int) getSchema()._control.x); }
Type getType() const { return _type; }
void setPosition(const Vec3& position);
const Vec3& getPosition() const { return _transform.getTranslation(); }
@ -104,10 +105,10 @@ public:
void setOrientation(const Quat& orientation);
const glm::quat& getOrientation() const { return _transform.getRotation(); }
const Color& getColor() const { return getSchema()._color; }
const Color& getColor() const { return _lightSchemaBuffer->irradiance.color; }
void setColor(const Color& color);
float getIntensity() const { return getSchema()._intensity; }
float getIntensity() const { return _lightSchemaBuffer->irradiance.intensity; }
void setIntensity(float intensity);
bool isRanged() const { return (getType() == POINT) || (getType() == SPOT ); }
@ -116,44 +117,58 @@ public:
// expressed in meters. It is used only to calculate the falloff curve of the light.
// Actual rendered lights will all have surface radii approaching 0.
void setFalloffRadius(float radius);
float getFalloffRadius() const { return getSchema()._attenuation.x; }
float getFalloffRadius() const { return _lightSchemaBuffer->irradiance.falloffRadius; }
// Maximum radius is the cutoff radius of the light energy, expressed in meters.
// It is used to bound light entities, and *will not* affect the falloff curve of the light.
// Setting it low will result in a noticeable cutoff.
void setMaximumRadius(float radius);
float getMaximumRadius() const { return getSchema()._attenuation.y; }
float getMaximumRadius() const { return _lightSchemaBuffer->volume.radius; }
// Spot properties
bool isSpot() const { return getType() == SPOT; }
void setSpotAngle(float angle);
float getSpotAngle() const { return getSchema()._spot.z; }
glm::vec2 getSpotAngleCosSin() const { return glm::vec2(getSchema()._spot.x, getSchema()._spot.y); }
float getSpotAngle() const { return acos(_lightSchemaBuffer->volume.getSpotAngleCos()); }
glm::vec2 getSpotAngleCosSin() const { return _lightSchemaBuffer->volume.getSpotAngleCosSin(); }
void setSpotExponent(float exponent);
float getSpotExponent() const { return getSchema()._spot.w; }
// For editing purpose, show the light volume contour.
// Set to non 0 to show it, the value is used as the intensity of the contour color
void setShowContour(float show);
float getShowContour() const { return getSchema()._control.z; }
float getSpotExponent() const { return _lightSchemaBuffer->irradiance.falloffSpot; }
// If the light has an ambient (Indirect) component, then the Ambientintensity can be used to control its contribution to the lighting
void setAmbientIntensity(float intensity);
float getAmbientIntensity() const { return getSchema()._ambientIntensity; }
float getAmbientIntensity() const { return _ambientSchemaBuffer->intensity; }
// Spherical Harmonics storing the Ambient lighting approximation used for the Sun typed light
void setAmbientSphere(const gpu::SphericalHarmonics& sphere);
const gpu::SphericalHarmonics& getAmbientSphere() const { return getSchema()._ambientSphere; }
const gpu::SphericalHarmonics& getAmbientSphere() const { return _ambientSchemaBuffer->ambientSphere; }
void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset);
void setAmbientMap(gpu::TexturePointer ambientMap);
gpu::TexturePointer getAmbientMap() const { return _ambientMap; }
void setAmbientMapNumMips(uint16_t numMips);
uint16_t getAmbientMapNumMips() const { return (uint16_t) getSchema()._ambientMapNumMips; }
uint16_t getAmbientMapNumMips() const { return (uint16_t) _ambientSchemaBuffer->mapNumMips; }
// LIght Schema
class LightSchema {
public:
LightVolume volume;
LightIrradiance irradiance;
};
class AmbientSchema {
public:
float intensity { 0.f };
float mapNumMips { 0.f };
float spare1;
float spare2;
gpu::SphericalHarmonics ambientSphere;
};
using LightSchemaBuffer = gpu::StructBuffer<LightSchema>;
using AmbientSchemaBuffer = gpu::StructBuffer<AmbientSchema>;
// Schema to access the attribute values of the light
class Schema {
/* class Schema {
public:
Vec4 _position{0.0f, 0.0f, 0.0f, 1.0f};
Vec3 _direction{0.0f, 0.0f, -1.0f};
@ -172,19 +187,23 @@ public:
gpu::SphericalHarmonics _ambientSphere;
};
const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; }
*/
const LightSchemaBuffer& getLightSchemaBuffer() const { return _lightSchemaBuffer; }
const AmbientSchemaBuffer& getAmbientSchemaBuffer() const { return _ambientSchemaBuffer; }
protected:
Flags _flags{ 0 };
UniformBufferView _schemaBuffer;
LightSchemaBuffer _lightSchemaBuffer;
AmbientSchemaBuffer _ambientSchemaBuffer;
Transform _transform;
gpu::TexturePointer _ambientMap;
const Schema& getSchema() const { return _schemaBuffer.get<Schema>(); }
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
Type _type { SUN };
float _spotCos { -1.0f }; // stored here to be able to reset the spot angle when turning the type spot on/off
void updateLightRadius();
void updateVolumeGeometry();

View file

@ -23,26 +23,6 @@ struct Light {
LightIrradiance irradiance;
};
// Light is the light source its self, d is the light's distance calculated as length(unnormalized light vector).
float evalLightAttenuation(Light l, float d) {
float radius = lightIrradiance_getFalloffRadius(l.irradiance);
float cutoff = lightVolume_getRadius(l.volume);
float denom = d / radius + 1.0;
float attenuation = 1.0 / (denom * denom);
// "Fade" the edges of light sources to make things look a bit more attractive.
// Note: this tends to look a bit odd at lower exponents.
attenuation *= min(1, max(0, -(d - cutoff)));
return attenuation;
}
float evalLightSpotAttenuation(Light l, float cosA) {
return pow(cosA, lightIrradiance_getFalloffSpot(l.irradiance));
}
bool light_isSpot(Light l) { return lightVolume_isSpot(l.volume); }
vec3 getLightPosition(Light l) { return lightVolume_getPosition(l.volume); }

View file

@ -14,21 +14,39 @@
#define LightIrradianceConstRef LightIrradiance
struct LightIrradiance {
vec3 color;
float intensity;
float falloffRadius;
float falloffSpot;
float spare1;
float spare2;
vec4 colorIntensity;
// falloffRadius, cutoffRadius, falloffSpot, spare
vec4 attenuation;
};
vec3 lightIrradiance_getColor(LightIrradianceConstRef li) { return li.color; }
float lightIrradiance_getIntensity(LightIrradianceConstRef li) { return li.intensity; }
vec3 lightIrradiance_getIrradiance(LightIrradianceConstRef li) { return li.color * li.intensity; }
float lightIrradiance_getFalloffRadius(LightIrradianceConstRef li) { return li.falloffRadius; }
float lightIrradiance_getFalloffRadiusSquare(LightIrradianceConstRef li) { return li.falloffRadius * li.falloffRadius; }
float lightIrradiance_getFalloffSpot(LightIrradianceConstRef li) { return li.falloffSpot; }
vec3 lightIrradiance_getColor(LightIrradiance li) { return li.colorIntensity.xyz; }
float lightIrradiance_getIntensity(LightIrradiance li) { return li.colorIntensity.w; }
vec3 lightIrradiance_getIrradiance(LightIrradiance li) { return li.colorIntensity.xyz * li.colorIntensity.w; }
float lightIrradiance_getFalloffRadius(LightIrradiance li) { return li.attenuation.x; }
float lightIrradiance_getCutoffRadius(LightIrradiance li) { return li.attenuation.y; }
float lightIrradiance_getFalloffSpot(LightIrradiance li) { return li.attenuation.z; }
// Light is the light source its self, d is the light's distance calculated as length(unnormalized light vector).
float lightIrradiance_evalLightAttenuation(LightIrradiance li, float d) {
float radius = lightIrradiance_getFalloffRadius(li);
float cutoff = lightIrradiance_getCutoffRadius(li);
float denom = d / radius + 1.0;
float attenuation = 1.0 / (denom * denom);
// "Fade" the edges of light sources to make things look a bit more attractive.
// Note: this tends to look a bit odd at lower exponents.
attenuation *= min(1, max(0, -(d - cutoff)));
return attenuation;
}
float lightIrradiance_evalLightSpotAttenuation(LightIrradiance li, float cosA) {
return pow(cosA, lightIrradiance_getFalloffSpot(li));
}
#endif

View file

@ -16,37 +16,33 @@
#define LightVolumeConstRef LightVolume
struct LightVolume {
vec3 position;
float radius;
vec3 direction;
float spotCos;
vec4 positionRadius;
vec4 directionSpotCos;
};
bool lightVolume_isPoint(LightVolumeConstRef lv) { return bool(lv.spotCos < 0.f); }
bool lightVolume_isSpot(LightVolumeConstRef lv) { return bool(lv.spotCos >= 0.f); }
bool lightVolume_isPoint(LightVolume lv) { return bool(lv.directionSpotCos.w < 0.f); }
bool lightVolume_isSpot(LightVolume lv) { return bool(lv.directionSpotCos.w >= 0.f); }
vec3 lightVolume_getPosition(LightVolumeConstRef lv) { return lv.position; }
float lightVolume_getRadius(LightVolumeConstRef lv) { return lv.radius; }
float lightVolume_getRadiusSquare(LightVolumeConstRef lv) { return lv.radius * lv.radius; }
vec3 lightVolume_getDirection(LightVolumeConstRef lv) { return lv.direction; } // direction is -Z axis
vec3 lightVolume_getPosition(LightVolume lv) { return lv.positionRadius.xyz; }
float lightVolume_getRadius(LightVolume lv) { return lv.positionRadius.w; }
float lightVolume_getRadiusSquare(LightVolume lv) { return lv.positionRadius.w * lv.positionRadius.w; }
vec3 lightVolume_getDirection(LightVolume lv) { return lv.directionSpotCos.xyz; } // direction is -Z axis
float lightVolume_getSpotAngleCos(LightVolumeConstRef lv) { return lv.spotCos; }
vec2 lightVolume_getSpotOutsideNormal2(LightVolumeConstRef lv) { return vec2(-sqrt(1.0 - lv.spotCos * lv.spotCos), lv.spotCos); }
float lightVolume_getSpotAngleCos(LightVolume lv) { return lv.directionSpotCos.w; }
vec2 lightVolume_getSpotOutsideNormal2(LightVolume lv) { return vec2(-sqrt(1.0 - lv.directionSpotCos.w * lv.directionSpotCos.w), lv.directionSpotCos.w); }
bool lightVolume_clipFragToLightVolumePoint(LightVolume lv, vec3 fragPos, vec4 fragLightVecLen2) {
fragLightVecLen2 = vec4(lightVolume_getPosition(lv) - fragPos.xyz, 1.0f);
bool lightVolume_clipFragToLightVolumePoint(LightVolume lv, vec3 fragPos, out vec4 fragLightVecLen2) {
fragLightVecLen2.xyz = lightVolume_getPosition(lv) - fragPos.xyz;
fragLightVecLen2.w = dot(fragLightVecLen2.xyz, fragLightVecLen2.xyz);
// Kill if too far from the light center
if (fragLightVecLen2.w > lightVolume_getRadiusSquare(lv)) {
return false;
}
return true;
return (fragLightVecLen2.w <= lightVolume_getRadiusSquare(lv));
}
bool lightVolume_clipFragToLightVolumeSpot(LightVolume lv, vec3 fragPos, vec4 fragLightVecLen2, vec4 fragLightDirLen, float cosSpotAngle) {
fragLightVecLen2 = vec4(lightVolume_getPosition(lv) - fragPos.xyz, 1.0f);
bool lightVolume_clipFragToLightVolumeSpot(LightVolume lv, vec3 fragPos, out vec4 fragLightVecLen2, out vec4 fragLightDirLen, out float cosSpotAngle) {
fragLightVecLen2.xyz = lightVolume_getPosition(lv) - fragPos.xyz;
fragLightVecLen2.w = dot(fragLightVecLen2.xyz, fragLightVecLen2.xyz);
// Kill if too far from the light center
@ -67,6 +63,16 @@ bool lightVolume_clipFragToLightVolumeSpot(LightVolume lv, vec3 fragPos, vec4 fr
return true;
}
bool lightVolume_clipFragToLightVolumeSpotSide(LightVolume lv, vec4 fragLightVecLen2, out vec4 fragLightDirLen, out float cosSpotAngle) {
// Allright we re valid in the volume
fragLightDirLen.w = length(fragLightVecLen2.xyz);
fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w;
// Kill if not in the spot light (ah ah !)
cosSpotAngle = max(-dot(fragLightDirLen.xyz, lightVolume_getDirection(lv)), 0.0);
return (cosSpotAngle >= lightVolume_getSpotAngleCos(lv));
}
#endif

View file

@ -187,7 +187,7 @@ void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBuff
auto keyLight = _allocatedLights[_globalLights.front()];
if (lightBufferUnit >= 0) {
batch.setUniformBuffer(lightBufferUnit, keyLight->getSchemaBuffer());
batch.setUniformBuffer(lightBufferUnit, keyLight->getLightSchemaBuffer());
}
if (keyLight->getAmbientMap() && (skyboxCubemapUnit >= 0)) {
@ -727,8 +727,6 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
// Bind the global list of lights and the visible lights this frame
batch.setUniformBuffer(deferredLightingEffect->_localLightLocations->lightBufferUnit, lightClusters->_lightStage->_lightArrayBuffer);
batch.setUniformBuffer(deferredLightingEffect->_localLightLocations->lightIndexBufferUnit, lightClusters->_lightIndicesBuffer);
batch.setUniformBuffer(LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT, lightClusters->_frustumGridBuffer);
batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, lightClusters->_clusterGridBuffer);

View file

@ -64,9 +64,11 @@ ivec2 clusterGrid_getCluster(int index) {
int clusterGrid_getClusterLightId(int index, ivec2 cluster) {
int arrayElement = cluster.y + index;
int element = _clusterGridContent[arrayElement >> 1];
int element = _clusterGridContent[arrayElement];
return element;
// int element = _clusterGridContent[arrayElement >> 1];
return (((arrayElement & 0x00000001) == 1) ? (element >> 16) : element) & 0x0000FFFF;
// return (((arrayElement & 0x00000001) == 1) ? (element >> 16) : element) & 0x0000FFFF;
}
<@endif@>

View file

@ -76,7 +76,7 @@ const glm::uvec4 LightClusters::MAX_GRID_DIMENSIONS { 32, 32, 31, 16384 };
LightClusters::LightClusters() :
_lightIndicesBuffer(std::make_shared<gpu::Buffer>()),
_clusterGridBuffer(std::make_shared<gpu::Buffer>(), gpu::Element::INDEX_INT32),
_clusterContentBuffer(std::make_shared<gpu::Buffer>(), gpu::Element::INDEX_UINT16) {
_clusterContentBuffer(std::make_shared<gpu::Buffer>(), gpu::Element::INDEX_INT32) {
auto dims = _frustumGridBuffer.edit().dims;
_frustumGridBuffer.edit().dims = ivec3(0); // make sure we go through the full reset of the dimensionts ion the setDImensions call
setDimensions(dims, MAX_GRID_DIMENSIONS.w);
@ -109,7 +109,7 @@ void LightClusters::setDimensions(glm::uvec3 gridDims, uint32_t listBudget) {
_clusterGridBuffer._size = _clusterGridBuffer._buffer->resize(_numClusters * sizeof(uint32_t));
}
auto configListBudget = std::min(MAX_GRID_DIMENSIONS.w, listBudget) * 2;
auto configListBudget = std::min(MAX_GRID_DIMENSIONS.w, listBudget);
if (configListBudget != _clusterContentBuffer.getNumElements()) {
_clusterContent.clear();
_clusterContent.resize(configListBudget, INVALID_LIGHT);

View file

@ -94,7 +94,7 @@ public:
const uint32_t EMPTY_CLUSTER { 0x0000FFFF };
const LightID INVALID_LIGHT { LightStage::INVALID_INDEX };
using LightIndex = uint16_t;
using LightIndex = uint32_t;
std::vector<uint32_t> _clusterGrid;
std::vector<LightIndex> _clusterContent;

View file

@ -24,7 +24,7 @@ void evalLightingPoint(out vec3 diffuse, out vec3 specular, Light light,
vec3 fragLightDir = fragLightVec / fragLightDistance;
// Eval attenuation
float radialAttenuation = evalLightAttenuation(light, fragLightDistance);
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
vec3 lightEnergy = radialAttenuation * shadow * getLightIrradiance(light);
// Eval shading

View file

@ -23,9 +23,10 @@ void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light,
float fragLightDistance = fragLightDirLen.w;
vec3 fragLightDir = fragLightDirLen.xyz;
// Eval attenuation
float radialAttenuation = evalLightAttenuation(light, fragLightDistance);
float angularAttenuation = evalLightSpotAttenuation(light, cosSpotAngle);
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
float angularAttenuation = lightIrradiance_evalLightSpotAttenuation(light.irradiance, cosSpotAngle);
vec3 lightEnergy = angularAttenuation * radialAttenuation * shadow *getLightIrradiance(light);
// Eval shading

View file

@ -134,22 +134,22 @@ LightStage::LightPointer LightStage::removeLight(Index index) {
}
void LightStage::updateLightArrayBuffer(Index lightId) {
auto lightSize = sizeof(model::Light::LightSchema);
if (!_lightArrayBuffer) {
_lightArrayBuffer = std::make_shared<gpu::Buffer>();
}
assert(checkLightId(lightId));
auto lightSize = sizeof(model::Light::Schema);
if (lightId > (Index) _lightArrayBuffer->getNumTypedElements<model::Light::Schema>()) {
if (lightId > (Index)_lightArrayBuffer->getNumTypedElements<model::Light::LightSchema>()) {
_lightArrayBuffer->resize(lightSize * (lightId + 10));
}
// lightArray is big enough so we can remap
auto light = _lights._elements[lightId];
if (light) {
auto lightSchema = light->getSchemaBuffer().get<model::Light::Schema>();
_lightArrayBuffer->setSubData<model::Light::Schema>(lightId, lightSchema);
const auto& lightSchema = light->getLightSchemaBuffer().get();
_lightArrayBuffer->setSubData<model::Light::LightSchema>(lightId, lightSchema);
} else {
// this should not happen ?
}

View file

@ -568,7 +568,7 @@ void DebugSubsurfaceScattering::run(const render::SceneContextPointer& sceneCont
batch.setUniformBuffer(ScatteringTask_FrameTransformSlot, frameTransform->getFrameTransformBuffer());
batch.setUniformBuffer(ScatteringTask_ParamSlot, scatteringResource->getParametersBuffer());
if (light) {
batch.setUniformBuffer(ScatteringTask_LightSlot, light->getSchemaBuffer());
batch.setUniformBuffer(ScatteringTask_LightSlot, light->getLightSchemaBuffer());
}
batch.setResourceTexture(ScatteringTask_ScatteringTableSlot, scatteringTable);
batch.setResourceTexture(ScatteringTask_CurvatureMapSlot, curvatureFramebuffer->getRenderBuffer(0));

View file

@ -20,9 +20,6 @@
// Everything about light
<@include model/Light.slh@>
<$declareLightBuffer(128)$>
uniform lightIndexBuffer {
int lightIndex[128];
};
<@include LightingModel.slh@>
@ -94,33 +91,31 @@ void main(void) {
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
/* int theLightIndex = clusterGrid_getClusterLightId(0, cluster);
if (theLightIndex == 65535) {
discard;
}
Light light = getLight(theLightIndex);
int numLights = lightIndex[0];*/
for (int i = 0; i < numLights; i++) {
int numLightTouching = 0;
for (int i = 0; i < numLights && numLightTouching < 16; i++) {
// Need the light now
int theLightIndex = clusterGrid_getClusterLightId(i, cluster);
Light light = getLight(theLightIndex);
bool isSpot = light_isSpot(light);
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
vec4 fragLightVecLen2;
vec4 fragLightDirLen;
float cosSpotAngle;
if (isSpot) {
if (!lightVolume_clipFragToLightVolumeSpot(light.volume, fragPos.xyz, fragLightVecLen2, fragLightDirLen, cosSpotAngle)) {
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragPos.xyz, fragLightVecLen2)) {
continue;
}
if (isSpot && !lightVolume_clipFragToLightVolumeSpotSide(light.volume, fragLightVecLen2, fragLightDirLen, cosSpotAngle)) {
continue;
}
} else {
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragPos.xyz, fragLightVecLen2)) {
continue;
}
}
if (dot(frag.normal, normalize(fragLightVecLen2.xyz)) < 0.0) {
//_fragColor.rgb += vec3(0.0, 0.0, 1.0 / 16.0);
continue;
}
numLightTouching++;
/*
vec3 diffuse;
vec3 specular;
@ -135,11 +130,11 @@ void main(void) {
frag.metallic, frag.fresnel, frag.albedo, 1.0,
frag.scattering, midNormalCurvature, lowNormalCurvature);
}
_fragColor.rgb += diffuse;
_fragColor.rgb += specular;
*/
_fragColor.rgb += vec3(1.0/16.0, 0.0, 0.0);
}
// _fragColor.rgb += vec3(0.05, 0.0, 0.0);
}