mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-08-08 00:38:38 +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;
|
||||
}
|
||||
|
||||
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);
|
||||
float getAmbientIntensity() const { return getSchema()._ambientIntensity; }
|
||||
|
||||
// Spherical Harmonics storing the Ambien lighting approximation used for the Sun typed light
|
||||
void setAmbientSphere(const gpu::SphericalHarmonics& sphere) { _ambientSphere = sphere; }
|
||||
const gpu::SphericalHarmonics& getAmbientSphere() const { return _ambientSphere; }
|
||||
void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) { _ambientSphere.assignPreset(preset); }
|
||||
// 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; }
|
||||
void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset);
|
||||
|
||||
// Schema to access the attribute values of the light
|
||||
class Schema {
|
||||
|
@ -112,6 +112,8 @@ public:
|
|||
Vec4 _shadow{0.0f};
|
||||
|
||||
Vec4 _control{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
gpu::SphericalHarmonics _ambientSphere;
|
||||
};
|
||||
|
||||
const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; }
|
||||
|
@ -121,7 +123,6 @@ protected:
|
|||
Flags _flags;
|
||||
UniformBufferView _schemaBuffer;
|
||||
Transform _transform;
|
||||
gpu::SphericalHarmonics _ambientSphere;
|
||||
|
||||
const Schema& getSchema() const { return _schemaBuffer.get<Schema>(); }
|
||||
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
|
||||
|
|
|
@ -11,6 +11,42 @@
|
|||
<@if not 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 {
|
||||
vec4 _position;
|
||||
vec4 _direction;
|
||||
|
@ -20,6 +56,8 @@ struct Light {
|
|||
|
||||
vec4 _shadow;
|
||||
vec4 _control;
|
||||
|
||||
SphericalHarmonics _ambientSphere;
|
||||
};
|
||||
|
||||
vec3 getLightPosition(Light l) { return l._position.xyz; }
|
||||
|
@ -65,6 +103,10 @@ float getLightShowContour(Light l) {
|
|||
return l._control.w;
|
||||
}
|
||||
|
||||
SphericalHarmonics getLightAmbientSphere(Light l) {
|
||||
return l._ambientSphere;
|
||||
}
|
||||
|
||||
<@if GPU_FEATURE_PROFILE == GPU_CORE @>
|
||||
uniform lightBuffer {
|
||||
Light light;
|
||||
|
|
|
@ -26,46 +26,6 @@ vec4 evalSkyboxLight(vec3 direction, float lod) {
|
|||
|
||||
<@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
|
||||
<@include model/Light.slh@>
|
||||
|
||||
|
@ -91,8 +51,6 @@ vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obsc
|
|||
|
||||
<@func declareEvalAmbientSphereGlobalColor()@>
|
||||
|
||||
<$declareSphericalHarmonics()$>
|
||||
|
||||
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
|
@ -102,7 +60,7 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa
|
|||
vec3 fragEyeDir = normalize(fragEyeVector.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);
|
||||
|
||||
|
@ -115,7 +73,6 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa
|
|||
<@func declareEvalSkyboxGlobalColor()@>
|
||||
|
||||
<$declareSkyboxMap()$>
|
||||
<$declareSphericalHarmonics()$>
|
||||
|
||||
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
||||
// Need the light now
|
||||
|
@ -125,7 +82,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
|
||||
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);
|
||||
|
||||
|
|
|
@ -343,6 +343,8 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
|||
}
|
||||
|
||||
{ // Setup the global lighting
|
||||
setupKeyLightBatch(batch, locations->lightBufferUnit, SKYBOX_MAP_UNIT);
|
||||
/*
|
||||
auto globalLight = _allocatedLights[_globalLights.front()];
|
||||
|
||||
if (locations->ambientSphere >= 0) {
|
||||
|
@ -361,7 +363,7 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
|||
|
||||
if (locations->lightBufferUnit >= 0) {
|
||||
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()");
|
||||
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) {
|
||||
|
@ -593,6 +614,11 @@ void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const gl
|
|||
|
||||
void DeferredLightingEffect::setGlobalSkybox(const model::SkyboxPointer& 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() {
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
void prepare(RenderArgs* args);
|
||||
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
|
||||
void setAmbientLightMode(int preset);
|
||||
|
|
|
@ -96,7 +96,9 @@ void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
|||
batchSetter(pipeline, batch);
|
||||
// Set the light
|
||||
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