mirror of
https://github.com/overte-org/overte.git
synced 2025-04-15 08:48:43 +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() {
|
||||
}
|
||||
|
||||
void Light::setType(Type type) {
|
||||
editSchema()._control.x = float(type);
|
||||
updateLightRadius();
|
||||
updateVolumeGeometry();
|
||||
}
|
||||
|
||||
|
||||
void Light::setPosition(const Vec3& position) {
|
||||
_transform.setTranslation(position);
|
||||
editSchema()._position = Vec4(position, 1.f);
|
||||
|
@ -82,6 +89,7 @@ void Light::setMaximumRadius(float radius) {
|
|||
}
|
||||
editSchema()._attenuation.y = radius;
|
||||
updateLightRadius();
|
||||
updateVolumeGeometry();
|
||||
}
|
||||
|
||||
void Light::updateLightRadius() {
|
||||
|
@ -117,6 +125,8 @@ void Light::setSpotAngle(float angle) {
|
|||
editSchema()._spot.x = (float) std::abs(cosAngle);
|
||||
editSchema()._spot.y = (float) std::abs(sinAngle);
|
||||
editSchema()._spot.z = (float) angle;
|
||||
|
||||
updateVolumeGeometry();
|
||||
}
|
||||
|
||||
void Light::setSpotExponent(float exponent) {
|
||||
|
@ -153,3 +163,15 @@ void Light::setAmbientMap(gpu::TexturePointer ambientMap) {
|
|||
void Light::setAmbientMapNumMips(uint16_t 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);
|
||||
virtual ~Light();
|
||||
|
||||
void setType(Type type) { editSchema()._control.x = float(type); }
|
||||
void setType(Type type);
|
||||
Type getType() const { return Type((int) getSchema()._control.x); }
|
||||
|
||||
void setPosition(const Vec3& position);
|
||||
|
@ -126,9 +126,12 @@ public:
|
|||
Vec4 _spot{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
Vec4 _shadow{0.0f};
|
||||
|
||||
|
||||
float _ambientMapNumMips{ 0.0f };
|
||||
Vec3 _control{ 0.0f, 0.0f, 0.0f };
|
||||
|
||||
Vec4 _volumeGeometry { 1.f };
|
||||
|
||||
gpu::SphericalHarmonics _ambientSphere;
|
||||
};
|
||||
|
||||
|
@ -146,6 +149,8 @@ protected:
|
|||
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
|
||||
|
||||
void updateLightRadius();
|
||||
void updateVolumeGeometry();
|
||||
|
||||
};
|
||||
typedef std::shared_ptr< Light > LightPointer;
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ struct Light {
|
|||
vec4 _shadow;
|
||||
vec4 _control;
|
||||
|
||||
vec4 _volumeGeometry;
|
||||
|
||||
SphericalHarmonics _ambientSphere;
|
||||
};
|
||||
|
||||
|
@ -98,6 +100,10 @@ float getLightShowContour(Light l) {
|
|||
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).
|
||||
float evalLightAttenuation(Light l, float d) {
|
||||
float radius = getLightRadius(l);
|
||||
|
|
|
@ -594,18 +594,18 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
|||
// IN DEBUG: light->setShowContour(true);
|
||||
batch.setUniformBuffer(deferredLightingEffect->_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
||||
|
||||
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
|
||||
glm::vec4 sphereParam(expandedRadius, 0.0f, 0.0f, 1.0f);
|
||||
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
|
||||
// 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,
|
||||
// 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;
|
||||
batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->sphereParam, 1, reinterpret_cast< const float* >(&sphereParam));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
} else*/ {
|
||||
sphereParam.w = 1.0f;
|
||||
batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->sphereParam, 1, reinterpret_cast< const float* >(&sphereParam));
|
||||
// sphereParam.w = 1.0f;
|
||||
// batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->sphereParam, 1, reinterpret_cast< const float* >(&sphereParam));
|
||||
|
||||
Transform model;
|
||||
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);
|
||||
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
||||
|
||||
auto eyeLightPos = eyePoint - light->getPosition();
|
||||
/* auto eyeLightPos = eyePoint - light->getPosition();
|
||||
auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection());
|
||||
|
||||
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,
|
||||
// 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;
|
||||
/* if ((eyeHalfPlaneDistance > -nearRadius) &&
|
||||
if ((eyeHalfPlaneDistance > -nearRadius) &&
|
||||
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < (expandedRadius * OVER_CONSERVATIVE_SCALE) + nearRadius)) {
|
||||
coneParam.w = 0.0f;
|
||||
batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
} else*/ {
|
||||
coneParam.w = 1.0f;
|
||||
batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
||||
// coneParam.w = 1.0f;
|
||||
// batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
||||
|
||||
Transform model;
|
||||
model.setTranslation(light->getPosition());
|
||||
model.postRotate(light->getOrientation());
|
||||
model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
|
||||
// model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
|
||||
|
||||
batch.setModelTransform(model);
|
||||
|
||||
|
|
|
@ -18,17 +18,21 @@
|
|||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
uniform vec4 sphereParam;
|
||||
<!<@include model/Light.slh@>!>
|
||||
|
||||
|
||||
out vec4 _texCoord0;
|
||||
|
||||
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();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>;
|
||||
<$transformModelToClipPos(cam, obj, sphereVertex, gl_Position)$>;
|
||||
|
||||
vec4 projected = gl_Position / gl_Position.w;
|
||||
projected.xy = (projected.xy + 1.0) * 0.5;
|
||||
|
@ -37,21 +41,4 @@ void main(void) {
|
|||
projected.x = 0.5 * (projected.x + cam_getStereoSide());
|
||||
}
|
||||
_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()$>
|
||||
|
||||
uniform vec4 coneParam;
|
||||
<@include model/Light.slh@>
|
||||
|
||||
|
||||
out vec4 _texCoord0;
|
||||
|
||||
void main(void) {
|
||||
vec4 coneVertex = inPosition;
|
||||
if (coneParam.w != 0.0) {
|
||||
// if (coneParam.w != 0.0) {
|
||||
vec4 coneParam = getLightVolumeGeometry(getLight());
|
||||
if(coneVertex.z >= 0.0) {
|
||||
// Evaluate the true position of the spot volume
|
||||
vec2 dir = float(coneVertex.z < 0.5f) * (coneParam.xy
|
||||
|
@ -38,6 +40,7 @@ void main(void) {
|
|||
coneVertex.z = 0.0;
|
||||
}
|
||||
|
||||
coneVertex.xyz *= coneParam.w;
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
@ -50,7 +53,7 @@ void main(void) {
|
|||
projected.x = 0.5 * (projected.x + cam_getStereoSide());
|
||||
}
|
||||
_texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w;
|
||||
} else {
|
||||
/* } 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),
|
||||
|
@ -65,5 +68,5 @@ void main(void) {
|
|||
_texCoord0.x = 0.5 * (_texCoord0.x + cam_getStereoSide());
|
||||
}
|
||||
gl_Position = pos;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -45,12 +45,6 @@ void main(void) {
|
|||
discard;
|
||||
}
|
||||
|
||||
// Kill if in front of the light volume
|
||||
/* float depth = frag.depthVal;
|
||||
if (depth < gl_FragCoord.z) {
|
||||
discard;
|
||||
}*/
|
||||
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
|
||||
|
|
|
@ -31,8 +31,6 @@ in vec4 _texCoord0;
|
|||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
/* _fragColor = vec4(1.0, 0.0, 0.0, 1.0);//
|
||||
return;*/
|
||||
DeferredFrameTransform deferredTransform = getDeferredFrameTransform();
|
||||
|
||||
// Grab the fragment data from the uv
|
||||
|
@ -45,12 +43,6 @@ void main(void) {
|
|||
discard;
|
||||
}
|
||||
|
||||
// Kill if in front of the light volume
|
||||
float depth = frag.depthVal;
|
||||
/* if (depth < gl_FragCoord.z) {
|
||||
discard;
|
||||
}*/
|
||||
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
|
||||
|
@ -66,11 +58,6 @@ void main(void) {
|
|||
discard;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Frag to eye vec
|
||||
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
|
|
Loading…
Reference in a new issue