Trying to solve the ambient issue

This commit is contained in:
samcake 2016-02-12 18:22:01 -08:00
parent 9e3a13795a
commit 4559e75f90
7 changed files with 89 additions and 56 deletions

View file

@ -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);
}

View file

@ -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>(); }

View file

@ -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;

View file

@ -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);

View file

@ -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() {

View file

@ -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);

View file

@ -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);
}
}