mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-13 23:46:29 +02:00
Merge pull request #7114 from samcake/hdr
Adding Ambient lighting to transparent surfaces
This commit is contained in:
commit
d5c349abec
8 changed files with 85 additions and 98 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,41 @@
|
|||
<@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;
|
||||
|
||||
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 +55,8 @@ struct Light {
|
|||
|
||||
vec4 _shadow;
|
||||
vec4 _control;
|
||||
|
||||
SphericalHarmonics _ambientSphere;
|
||||
};
|
||||
|
||||
vec3 getLightPosition(Light l) { return l._position.xyz; }
|
||||
|
@ -65,6 +102,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);
|
||||
|
||||
|
|
|
@ -344,26 +344,7 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
|||
}
|
||||
|
||||
{ // Setup the global lighting
|
||||
auto globalLight = _allocatedLights[_globalLights.front()];
|
||||
|
||||
if (locations->ambientSphere >= 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(locations->ambientSphere + i, 1, (const float*) (&sh) + i * 4);
|
||||
}
|
||||
}
|
||||
|
||||
if (useSkyboxCubemap) {
|
||||
batch.setResourceTexture(SKYBOX_MAP_UNIT, _skybox->getCubemap());
|
||||
}
|
||||
|
||||
if (locations->lightBufferUnit >= 0) {
|
||||
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
|
||||
}
|
||||
|
||||
setupKeyLightBatch(batch, locations->lightBufferUnit, SKYBOX_MAP_UNIT);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -512,10 +493,18 @@ 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 (useSkyboxCubemap && (skyboxCubemapUnit >= 0)) {
|
||||
batch.setResourceTexture(skyboxCubemapUnit, _skybox->getCubemap());
|
||||
}
|
||||
}
|
||||
|
||||
static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) {
|
||||
|
@ -594,6 +583,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// model_translucent.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/19/14.
|
||||
// Created by Sam Gateau on 2/15/2016.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
|
@ -14,31 +14,13 @@
|
|||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
<@include DeferredLighting.slh@>
|
||||
<@include model/Light.slh@>
|
||||
<@include DeferredGlobalLight.slh@>
|
||||
<$declareEvalAmbientSphereGlobalColor()$>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss, float opacity) {
|
||||
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragNormal;
|
||||
<$transformEyeToWorldDir(cam, normal, fragNormal)$>
|
||||
vec3 fragEyeVectorView = normalize(-position);
|
||||
vec3 fragEyeDir;
|
||||
<$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$>
|
||||
|
||||
vec3 color = opacity * diffuse.rgb * getLightColor(light) * getLightAmbientIntensity(light);
|
||||
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||
|
||||
color += vec3(diffuse * shading.w * opacity + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
|
||||
|
||||
return vec4(color, opacity);
|
||||
}
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
|
@ -61,11 +43,16 @@ void main(void) {
|
|||
float fragGloss = getMaterialShininess(mat) / 128;
|
||||
float fragOpacity = getMaterialOpacity(mat) * diffuse.a * _alpha;
|
||||
|
||||
_fragColor = evalGlobalColor(1.0,
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
||||
_fragColor = vec4(evalAmbientSphereGlobalColor(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
1.0,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
fragDiffuse,
|
||||
fragSpecular,
|
||||
fragGloss,
|
||||
fragGloss),
|
||||
fragOpacity);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue