mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-08-10 23:11:30 +02:00
Trying to solve the ambient issue
This commit is contained in:
parent
9e3a13795a
commit
4559e75f90
7 changed files with 89 additions and 56 deletions
|
@ -116,5 +116,10 @@ void Light::setShowContour(float show) {
|
||||||
editSchema()._control.w = show;
|
editSchema()._control.w = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Light::setAmbientSphere(const gpu::SphericalHarmonics& sphere) {
|
||||||
|
editSchema()._ambientSphere = sphere;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Light::setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) {
|
||||||
|
editSchema()._ambientSphere.assignPreset(preset);
|
||||||
|
}
|
||||||
|
|
|
@ -94,10 +94,10 @@ public:
|
||||||
void setAmbientIntensity(float intensity);
|
void setAmbientIntensity(float intensity);
|
||||||
float getAmbientIntensity() const { return getSchema()._ambientIntensity; }
|
float getAmbientIntensity() const { return getSchema()._ambientIntensity; }
|
||||||
|
|
||||||
// Spherical Harmonics storing the Ambien lighting approximation used for the Sun typed light
|
// Spherical Harmonics storing the Ambient lighting approximation used for the Sun typed light
|
||||||
void setAmbientSphere(const gpu::SphericalHarmonics& sphere) { _ambientSphere = sphere; }
|
void setAmbientSphere(const gpu::SphericalHarmonics& sphere);
|
||||||
const gpu::SphericalHarmonics& getAmbientSphere() const { return _ambientSphere; }
|
const gpu::SphericalHarmonics& getAmbientSphere() const { return getSchema()._ambientSphere; }
|
||||||
void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) { _ambientSphere.assignPreset(preset); }
|
void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset);
|
||||||
|
|
||||||
// Schema to access the attribute values of the light
|
// Schema to access the attribute values of the light
|
||||||
class Schema {
|
class Schema {
|
||||||
|
@ -112,6 +112,8 @@ public:
|
||||||
Vec4 _shadow{0.0f};
|
Vec4 _shadow{0.0f};
|
||||||
|
|
||||||
Vec4 _control{0.0f, 0.0f, 0.0f, 0.0f};
|
Vec4 _control{0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
|
gpu::SphericalHarmonics _ambientSphere;
|
||||||
};
|
};
|
||||||
|
|
||||||
const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; }
|
const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; }
|
||||||
|
@ -121,7 +123,6 @@ protected:
|
||||||
Flags _flags;
|
Flags _flags;
|
||||||
UniformBufferView _schemaBuffer;
|
UniformBufferView _schemaBuffer;
|
||||||
Transform _transform;
|
Transform _transform;
|
||||||
gpu::SphericalHarmonics _ambientSphere;
|
|
||||||
|
|
||||||
const Schema& getSchema() const { return _schemaBuffer.get<Schema>(); }
|
const Schema& getSchema() const { return _schemaBuffer.get<Schema>(); }
|
||||||
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
|
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
|
||||||
|
|
|
@ -11,6 +11,42 @@
|
||||||
<@if not MODEL_LIGHT_SLH@>
|
<@if not MODEL_LIGHT_SLH@>
|
||||||
<@def MODEL_LIGHT_SLH@>
|
<@def MODEL_LIGHT_SLH@>
|
||||||
|
|
||||||
|
struct SphericalHarmonics {
|
||||||
|
vec4 L00;
|
||||||
|
vec4 L1m1;
|
||||||
|
vec4 L10;
|
||||||
|
vec4 L11;
|
||||||
|
vec4 L2m2;
|
||||||
|
vec4 L2m1;
|
||||||
|
vec4 L20;
|
||||||
|
vec4 L21;
|
||||||
|
vec4 L22;
|
||||||
|
};
|
||||||
|
|
||||||
|
vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) {
|
||||||
|
|
||||||
|
/vec3 dir = direction.xyz; // we don;t understand why yet but we need to use z as vertical axis?
|
||||||
|
vec3 dir = direction.xyz; // we don;t understand why yet but we need to use z as vertical axis?
|
||||||
|
|
||||||
|
const float C1 = 0.429043;
|
||||||
|
const float C2 = 0.511664;
|
||||||
|
const float C3 = 0.743125;
|
||||||
|
const float C4 = 0.886227;
|
||||||
|
const float C5 = 0.247708;
|
||||||
|
|
||||||
|
vec4 value = C1 * sh.L22 * (dir.x * dir.x - dir.y * dir.y) +
|
||||||
|
C3 * sh.L20 * dir.z * dir.z +
|
||||||
|
C4 * sh.L00 - C5 * sh.L20 +
|
||||||
|
2.0 * C1 * ( sh.L2m2 * dir.x * dir.y +
|
||||||
|
sh.L21 * dir.x * dir.z +
|
||||||
|
sh.L2m1 * dir.y * dir.z ) +
|
||||||
|
2.0 * C2 * ( sh.L11 * dir.x +
|
||||||
|
sh.L1m1 * dir.y +
|
||||||
|
sh.L10 * dir.z ) ;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Light {
|
struct Light {
|
||||||
vec4 _position;
|
vec4 _position;
|
||||||
vec4 _direction;
|
vec4 _direction;
|
||||||
|
@ -20,6 +56,8 @@ struct Light {
|
||||||
|
|
||||||
vec4 _shadow;
|
vec4 _shadow;
|
||||||
vec4 _control;
|
vec4 _control;
|
||||||
|
|
||||||
|
SphericalHarmonics _ambientSphere;
|
||||||
};
|
};
|
||||||
|
|
||||||
vec3 getLightPosition(Light l) { return l._position.xyz; }
|
vec3 getLightPosition(Light l) { return l._position.xyz; }
|
||||||
|
@ -65,6 +103,10 @@ float getLightShowContour(Light l) {
|
||||||
return l._control.w;
|
return l._control.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SphericalHarmonics getLightAmbientSphere(Light l) {
|
||||||
|
return l._ambientSphere;
|
||||||
|
}
|
||||||
|
|
||||||
<@if GPU_FEATURE_PROFILE == GPU_CORE @>
|
<@if GPU_FEATURE_PROFILE == GPU_CORE @>
|
||||||
uniform lightBuffer {
|
uniform lightBuffer {
|
||||||
Light light;
|
Light light;
|
||||||
|
|
|
@ -26,46 +26,6 @@ vec4 evalSkyboxLight(vec3 direction, float lod) {
|
||||||
|
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func declareSphericalHarmonics()@>
|
|
||||||
struct SphericalHarmonics {
|
|
||||||
vec4 L00;
|
|
||||||
vec4 L1m1;
|
|
||||||
vec4 L10;
|
|
||||||
vec4 L11;
|
|
||||||
vec4 L2m2;
|
|
||||||
vec4 L2m1;
|
|
||||||
vec4 L20;
|
|
||||||
vec4 L21;
|
|
||||||
vec4 L22;
|
|
||||||
};
|
|
||||||
|
|
||||||
vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) {
|
|
||||||
|
|
||||||
vec3 dir = direction.xzy; // we don;t understand why yet but we need to use z as vertical axis?
|
|
||||||
|
|
||||||
const float C1 = 0.429043;
|
|
||||||
const float C2 = 0.511664;
|
|
||||||
const float C3 = 0.743125;
|
|
||||||
const float C4 = 0.886227;
|
|
||||||
const float C5 = 0.247708;
|
|
||||||
|
|
||||||
vec4 value = C1 * sh.L22 * (dir.x * dir.x - dir.y * dir.y) +
|
|
||||||
C3 * sh.L20 * dir.z * dir.z +
|
|
||||||
C4 * sh.L00 - C5 * sh.L20 +
|
|
||||||
2.0 * C1 * ( sh.L2m2 * dir.x * dir.y +
|
|
||||||
sh.L21 * dir.x * dir.z +
|
|
||||||
sh.L2m1 * dir.y * dir.z ) +
|
|
||||||
2.0 * C2 * ( sh.L11 * dir.x +
|
|
||||||
sh.L1m1 * dir.y +
|
|
||||||
sh.L10 * dir.z ) ;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need one SH
|
|
||||||
uniform SphericalHarmonics ambientSphere;
|
|
||||||
|
|
||||||
<@endfunc@>
|
|
||||||
|
|
||||||
// Everything about light
|
// Everything about light
|
||||||
<@include model/Light.slh@>
|
<@include model/Light.slh@>
|
||||||
|
|
||||||
|
@ -91,8 +51,6 @@ vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obsc
|
||||||
|
|
||||||
<@func declareEvalAmbientSphereGlobalColor()@>
|
<@func declareEvalAmbientSphereGlobalColor()@>
|
||||||
|
|
||||||
<$declareSphericalHarmonics()$>
|
|
||||||
|
|
||||||
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
||||||
// Need the light now
|
// Need the light now
|
||||||
Light light = getLight();
|
Light light = getLight();
|
||||||
|
@ -102,7 +60,7 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa
|
||||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||||
|
|
||||||
vec3 ambientNormal = fragNormal.xyz;
|
vec3 ambientNormal = fragNormal.xyz;
|
||||||
vec3 color = diffuse.rgb * evalSphericalLight(ambientSphere, ambientNormal).xyz * obscurance * getLightAmbientIntensity(light);
|
vec3 color = diffuse.rgb * evalSphericalLight(getLightAmbientSphere(light), ambientNormal).xyz * obscurance * getLightAmbientIntensity(light);
|
||||||
|
|
||||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||||
|
|
||||||
|
@ -115,7 +73,6 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa
|
||||||
<@func declareEvalSkyboxGlobalColor()@>
|
<@func declareEvalSkyboxGlobalColor()@>
|
||||||
|
|
||||||
<$declareSkyboxMap()$>
|
<$declareSkyboxMap()$>
|
||||||
<$declareSphericalHarmonics()$>
|
|
||||||
|
|
||||||
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
||||||
// Need the light now
|
// Need the light now
|
||||||
|
@ -125,7 +82,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
||||||
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
|
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
|
||||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||||
|
|
||||||
vec3 color = diffuse.rgb * evalSphericalLight(ambientSphere, fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
|
vec3 color = diffuse.rgb * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
|
||||||
|
|
||||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||||
|
|
||||||
|
|
|
@ -343,6 +343,8 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Setup the global lighting
|
{ // Setup the global lighting
|
||||||
|
setupKeyLightBatch(batch, locations->lightBufferUnit, SKYBOX_MAP_UNIT);
|
||||||
|
/*
|
||||||
auto globalLight = _allocatedLights[_globalLights.front()];
|
auto globalLight = _allocatedLights[_globalLights.front()];
|
||||||
|
|
||||||
if (locations->ambientSphere >= 0) {
|
if (locations->ambientSphere >= 0) {
|
||||||
|
@ -361,7 +363,7 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
||||||
|
|
||||||
if (locations->lightBufferUnit >= 0) {
|
if (locations->lightBufferUnit >= 0) {
|
||||||
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
|
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
|
||||||
}
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,10 +513,29 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeferredLightingEffect::setupBatch(gpu::Batch& batch, int lightBufferUnit) {
|
void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int skyboxCubemapUnit) {
|
||||||
PerformanceTimer perfTimer("DLE->setupBatch()");
|
PerformanceTimer perfTimer("DLE->setupBatch()");
|
||||||
auto globalLight = _allocatedLights[_globalLights.front()];
|
auto globalLight = _allocatedLights[_globalLights.front()];
|
||||||
batch.setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer());
|
|
||||||
|
if (lightBufferUnit >= 0) {
|
||||||
|
batch.setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap());
|
||||||
|
|
||||||
|
/* if (ambientSphereBufferUnit >= 0) {
|
||||||
|
gpu::SphericalHarmonics sh = globalLight->getAmbientSphere();
|
||||||
|
if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) {
|
||||||
|
sh = (*_skybox->getCubemap()->getIrradiance());
|
||||||
|
}
|
||||||
|
for (int i =0; i <gpu::SphericalHarmonics::NUM_COEFFICIENTS; i++) {
|
||||||
|
batch._glUniform4fv(ambientSphereBufferUnit + i, 1, (const float*)(&sh) + i * 4);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (useSkyboxCubemap && (skyboxCubemapUnit >= 0)) {
|
||||||
|
batch.setResourceTexture(skyboxCubemapUnit, _skybox->getCubemap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) {
|
static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) {
|
||||||
|
@ -593,6 +614,11 @@ void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const gl
|
||||||
|
|
||||||
void DeferredLightingEffect::setGlobalSkybox(const model::SkyboxPointer& skybox) {
|
void DeferredLightingEffect::setGlobalSkybox(const model::SkyboxPointer& skybox) {
|
||||||
_skybox = skybox;
|
_skybox = skybox;
|
||||||
|
auto light = _allocatedLights.front();
|
||||||
|
|
||||||
|
if (_skybox && _skybox->getCubemap() && _skybox->getCubemap()->isDefined() && _skybox->getCubemap()->getIrradiance()) {
|
||||||
|
light->setAmbientSphere( (*_skybox->getCubemap()->getIrradiance()) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
|
model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
void prepare(RenderArgs* args);
|
void prepare(RenderArgs* args);
|
||||||
void render(const render::RenderContextPointer& renderContext);
|
void render(const render::RenderContextPointer& renderContext);
|
||||||
|
|
||||||
void setupBatch(gpu::Batch& batch, int lightBufferUnit);
|
void setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int skyboxCubemapUnit);
|
||||||
|
|
||||||
// update global lighting
|
// update global lighting
|
||||||
void setAmbientLightMode(int preset);
|
void setAmbientLightMode(int preset);
|
||||||
|
|
|
@ -96,7 +96,9 @@ void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
||||||
batchSetter(pipeline, batch);
|
batchSetter(pipeline, batch);
|
||||||
// Set the light
|
// Set the light
|
||||||
if (pipeline.locations->lightBufferUnit >= 0) {
|
if (pipeline.locations->lightBufferUnit >= 0) {
|
||||||
DependencyManager::get<DeferredLightingEffect>()->setupBatch(batch, pipeline.locations->lightBufferUnit);
|
DependencyManager::get<DeferredLightingEffect>()->setupKeyLightBatch(batch,
|
||||||
|
pipeline.locations->lightBufferUnit,
|
||||||
|
-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue