mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 05:37:13 +02:00
Streamlining the lighting phase for better performances
This commit is contained in:
parent
ed12b5ffb9
commit
96935504a1
8 changed files with 59 additions and 55 deletions
|
@ -37,6 +37,13 @@ Light& Light::operator= (const Light& light) {
|
||||||
Light::~Light() {
|
Light::~Light() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Light::setType(Type type) {
|
||||||
|
editSchema()._control.x = float(type);
|
||||||
|
updateLightRadius();
|
||||||
|
updateVolumeGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Light::setPosition(const Vec3& position) {
|
void Light::setPosition(const Vec3& position) {
|
||||||
_transform.setTranslation(position);
|
_transform.setTranslation(position);
|
||||||
editSchema()._position = Vec4(position, 1.f);
|
editSchema()._position = Vec4(position, 1.f);
|
||||||
|
@ -82,6 +89,7 @@ void Light::setMaximumRadius(float radius) {
|
||||||
}
|
}
|
||||||
editSchema()._attenuation.y = radius;
|
editSchema()._attenuation.y = radius;
|
||||||
updateLightRadius();
|
updateLightRadius();
|
||||||
|
updateVolumeGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::updateLightRadius() {
|
void Light::updateLightRadius() {
|
||||||
|
@ -117,6 +125,8 @@ void Light::setSpotAngle(float angle) {
|
||||||
editSchema()._spot.x = (float) std::abs(cosAngle);
|
editSchema()._spot.x = (float) std::abs(cosAngle);
|
||||||
editSchema()._spot.y = (float) std::abs(sinAngle);
|
editSchema()._spot.y = (float) std::abs(sinAngle);
|
||||||
editSchema()._spot.z = (float) angle;
|
editSchema()._spot.z = (float) angle;
|
||||||
|
|
||||||
|
updateVolumeGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::setSpotExponent(float exponent) {
|
void Light::setSpotExponent(float exponent) {
|
||||||
|
@ -153,3 +163,15 @@ void Light::setAmbientMap(gpu::TexturePointer ambientMap) {
|
||||||
void Light::setAmbientMapNumMips(uint16_t numMips) {
|
void Light::setAmbientMapNumMips(uint16_t numMips) {
|
||||||
editSchema()._ambientMapNumMips = (float)numMips;
|
editSchema()._ambientMapNumMips = (float)numMips;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Light::updateVolumeGeometry() {
|
||||||
|
// enlarge the scales slightly to account for tesselation
|
||||||
|
const float SCALE_EXPANSION = 0.05f;
|
||||||
|
glm::vec4 volumeGeometry(0.0f, 0.0f, 0.0f, 1.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;
|
||||||
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
Light& operator= (const Light& light);
|
Light& operator= (const Light& light);
|
||||||
virtual ~Light();
|
virtual ~Light();
|
||||||
|
|
||||||
void setType(Type type) { editSchema()._control.x = float(type); }
|
void setType(Type type);
|
||||||
Type getType() const { return Type((int) getSchema()._control.x); }
|
Type getType() const { return Type((int) getSchema()._control.x); }
|
||||||
|
|
||||||
void setPosition(const Vec3& position);
|
void setPosition(const Vec3& position);
|
||||||
|
@ -126,9 +126,12 @@ public:
|
||||||
Vec4 _spot{0.0f, 0.0f, 0.0f, 0.0f};
|
Vec4 _spot{0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
Vec4 _shadow{0.0f};
|
Vec4 _shadow{0.0f};
|
||||||
|
|
||||||
|
|
||||||
float _ambientMapNumMips{ 0.0f };
|
float _ambientMapNumMips{ 0.0f };
|
||||||
Vec3 _control{ 0.0f, 0.0f, 0.0f };
|
Vec3 _control{ 0.0f, 0.0f, 0.0f };
|
||||||
|
|
||||||
|
Vec4 _volumeGeometry { 1.f };
|
||||||
|
|
||||||
gpu::SphericalHarmonics _ambientSphere;
|
gpu::SphericalHarmonics _ambientSphere;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -146,6 +149,8 @@ protected:
|
||||||
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
|
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
|
||||||
|
|
||||||
void updateLightRadius();
|
void updateLightRadius();
|
||||||
|
void updateVolumeGeometry();
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr< Light > LightPointer;
|
typedef std::shared_ptr< Light > LightPointer;
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ struct Light {
|
||||||
vec4 _shadow;
|
vec4 _shadow;
|
||||||
vec4 _control;
|
vec4 _control;
|
||||||
|
|
||||||
|
vec4 _volumeGeometry;
|
||||||
|
|
||||||
SphericalHarmonics _ambientSphere;
|
SphericalHarmonics _ambientSphere;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,6 +100,10 @@ float getLightShowContour(Light l) {
|
||||||
return l._control.w;
|
return l._control.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 getLightVolumeGeometry(Light l) {
|
||||||
|
return l._volumeGeometry;
|
||||||
|
}
|
||||||
|
|
||||||
// Light is the light source its self, d is the light's distance calculated as length(unnormalized light vector).
|
// 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 evalLightAttenuation(Light l, float d) {
|
||||||
float radius = getLightRadius(l);
|
float radius = getLightRadius(l);
|
||||||
|
|
|
@ -594,18 +594,18 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
||||||
// IN DEBUG: light->setShowContour(true);
|
// IN DEBUG: light->setShowContour(true);
|
||||||
batch.setUniformBuffer(deferredLightingEffect->_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
batch.setUniformBuffer(deferredLightingEffect->_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
||||||
|
|
||||||
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
|
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
|
||||||
glm::vec4 sphereParam(expandedRadius, 0.0f, 0.0f, 1.0f);
|
// glm::vec4 sphereParam(expandedRadius, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
|
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
|
||||||
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
|
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
|
||||||
/* if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) {
|
/* if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) {
|
||||||
sphereParam.w = 0.0f;
|
sphereParam.w = 0.0f;
|
||||||
batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->sphereParam, 1, reinterpret_cast< const float* >(&sphereParam));
|
batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->sphereParam, 1, reinterpret_cast< const float* >(&sphereParam));
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
} else*/ {
|
} else*/ {
|
||||||
sphereParam.w = 1.0f;
|
// sphereParam.w = 1.0f;
|
||||||
batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->sphereParam, 1, reinterpret_cast< const float* >(&sphereParam));
|
// batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->sphereParam, 1, reinterpret_cast< const float* >(&sphereParam));
|
||||||
|
|
||||||
Transform model;
|
Transform model;
|
||||||
model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
|
model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
|
||||||
|
@ -638,7 +638,7 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
||||||
// light->setShowContour(true);
|
// light->setShowContour(true);
|
||||||
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
||||||
|
|
||||||
auto eyeLightPos = eyePoint - light->getPosition();
|
/* auto eyeLightPos = eyePoint - light->getPosition();
|
||||||
auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection());
|
auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection());
|
||||||
|
|
||||||
const float TANGENT_LENGTH_SCALE = 0.666f;
|
const float TANGENT_LENGTH_SCALE = 0.666f;
|
||||||
|
@ -648,19 +648,19 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
||||||
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
|
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
|
||||||
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
|
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
|
||||||
const float OVER_CONSERVATIVE_SCALE = 1.1f;
|
const float OVER_CONSERVATIVE_SCALE = 1.1f;
|
||||||
/* if ((eyeHalfPlaneDistance > -nearRadius) &&
|
if ((eyeHalfPlaneDistance > -nearRadius) &&
|
||||||
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < (expandedRadius * OVER_CONSERVATIVE_SCALE) + nearRadius)) {
|
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < (expandedRadius * OVER_CONSERVATIVE_SCALE) + nearRadius)) {
|
||||||
coneParam.w = 0.0f;
|
coneParam.w = 0.0f;
|
||||||
batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
} else*/ {
|
} else*/ {
|
||||||
coneParam.w = 1.0f;
|
// coneParam.w = 1.0f;
|
||||||
batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
// batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
||||||
|
|
||||||
Transform model;
|
Transform model;
|
||||||
model.setTranslation(light->getPosition());
|
model.setTranslation(light->getPosition());
|
||||||
model.postRotate(light->getOrientation());
|
model.postRotate(light->getOrientation());
|
||||||
model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
|
// model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
|
||||||
|
|
||||||
batch.setModelTransform(model);
|
batch.setModelTransform(model);
|
||||||
|
|
||||||
|
|
|
@ -18,17 +18,21 @@
|
||||||
|
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
uniform vec4 sphereParam;
|
<!<@include model/Light.slh@>!>
|
||||||
|
|
||||||
|
|
||||||
out vec4 _texCoord0;
|
out vec4 _texCoord0;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
if (sphereParam.w != 0.0) {
|
vec4 sphereVertex = inPosition;
|
||||||
|
// vec4 sphereParam = getLightVolumeGeometry(getLight());
|
||||||
|
|
||||||
// standard transform
|
// sphereVertex.xyz *= sphereParam.w;
|
||||||
|
|
||||||
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>;
|
<$transformModelToClipPos(cam, obj, sphereVertex, gl_Position)$>;
|
||||||
|
|
||||||
vec4 projected = gl_Position / gl_Position.w;
|
vec4 projected = gl_Position / gl_Position.w;
|
||||||
projected.xy = (projected.xy + 1.0) * 0.5;
|
projected.xy = (projected.xy + 1.0) * 0.5;
|
||||||
|
@ -37,21 +41,4 @@ void main(void) {
|
||||||
projected.x = 0.5 * (projected.x + cam_getStereoSide());
|
projected.x = 0.5 * (projected.x + cam_getStereoSide());
|
||||||
}
|
}
|
||||||
_texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w;
|
_texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w;
|
||||||
} else {
|
|
||||||
const float depth = -1.0; //Draw at near plane
|
|
||||||
const vec4 UNIT_QUAD[4] = vec4[4](
|
|
||||||
vec4(-1.0, -1.0, depth, 1.0),
|
|
||||||
vec4(1.0, -1.0, depth, 1.0),
|
|
||||||
vec4(-1.0, 1.0, depth, 1.0),
|
|
||||||
vec4(1.0, 1.0, depth, 1.0)
|
|
||||||
);
|
|
||||||
vec4 pos = UNIT_QUAD[gl_VertexID];
|
|
||||||
|
|
||||||
_texCoord0 = vec4((pos.xy + 1) * 0.5, 0.0, 1.0);
|
|
||||||
|
|
||||||
if (cam_isStereo()) {
|
|
||||||
_texCoord0.x = 0.5 * (_texCoord0.x + cam_getStereoSide());
|
|
||||||
}
|
|
||||||
gl_Position = pos;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,15 @@
|
||||||
|
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
uniform vec4 coneParam;
|
<@include model/Light.slh@>
|
||||||
|
|
||||||
|
|
||||||
out vec4 _texCoord0;
|
out vec4 _texCoord0;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 coneVertex = inPosition;
|
vec4 coneVertex = inPosition;
|
||||||
if (coneParam.w != 0.0) {
|
// if (coneParam.w != 0.0) {
|
||||||
|
vec4 coneParam = getLightVolumeGeometry(getLight());
|
||||||
if(coneVertex.z >= 0.0) {
|
if(coneVertex.z >= 0.0) {
|
||||||
// Evaluate the true position of the spot volume
|
// Evaluate the true position of the spot volume
|
||||||
vec2 dir = float(coneVertex.z < 0.5f) * (coneParam.xy
|
vec2 dir = float(coneVertex.z < 0.5f) * (coneParam.xy
|
||||||
|
@ -38,6 +40,7 @@ void main(void) {
|
||||||
coneVertex.z = 0.0;
|
coneVertex.z = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coneVertex.xyz *= coneParam.w;
|
||||||
|
|
||||||
// standard transform
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
|
@ -50,7 +53,7 @@ void main(void) {
|
||||||
projected.x = 0.5 * (projected.x + cam_getStereoSide());
|
projected.x = 0.5 * (projected.x + cam_getStereoSide());
|
||||||
}
|
}
|
||||||
_texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w;
|
_texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w;
|
||||||
} else {
|
/* } else {
|
||||||
const float depth = -1.0; //Draw at near plane
|
const float depth = -1.0; //Draw at near plane
|
||||||
const vec4 UNIT_QUAD[4] = vec4[4](
|
const vec4 UNIT_QUAD[4] = vec4[4](
|
||||||
vec4(-1.0, -1.0, depth, 1.0),
|
vec4(-1.0, -1.0, depth, 1.0),
|
||||||
|
@ -65,5 +68,5 @@ void main(void) {
|
||||||
_texCoord0.x = 0.5 * (_texCoord0.x + cam_getStereoSide());
|
_texCoord0.x = 0.5 * (_texCoord0.x + cam_getStereoSide());
|
||||||
}
|
}
|
||||||
gl_Position = pos;
|
gl_Position = pos;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,12 +45,6 @@ void main(void) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill if in front of the light volume
|
|
||||||
/* float depth = frag.depthVal;
|
|
||||||
if (depth < gl_FragCoord.z) {
|
|
||||||
discard;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Need the light now
|
// Need the light now
|
||||||
Light light = getLight();
|
Light light = getLight();
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@ in vec4 _texCoord0;
|
||||||
out vec4 _fragColor;
|
out vec4 _fragColor;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
/* _fragColor = vec4(1.0, 0.0, 0.0, 1.0);//
|
|
||||||
return;*/
|
|
||||||
DeferredFrameTransform deferredTransform = getDeferredFrameTransform();
|
DeferredFrameTransform deferredTransform = getDeferredFrameTransform();
|
||||||
|
|
||||||
// Grab the fragment data from the uv
|
// Grab the fragment data from the uv
|
||||||
|
@ -45,12 +43,6 @@ void main(void) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill if in front of the light volume
|
|
||||||
float depth = frag.depthVal;
|
|
||||||
/* if (depth < gl_FragCoord.z) {
|
|
||||||
discard;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Need the light now
|
// Need the light now
|
||||||
Light light = getLight();
|
Light light = getLight();
|
||||||
|
|
||||||
|
@ -66,11 +58,6 @@ void main(void) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Frag to eye vec
|
// Frag to eye vec
|
||||||
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
||||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||||
|
|
Loading…
Reference in a new issue