work in progress, gathering th eindvidual parameters of the deferred pass into a single UBO that is bound once for all the deferred lighting passes

This commit is contained in:
Sam Gateau 2015-09-14 15:49:05 -07:00
parent 3690d5a4c2
commit 00688172dd
17 changed files with 139 additions and 87 deletions

View file

@ -73,14 +73,14 @@ void StereoDisplayPlugin::activate() {
[this](bool clicked) { updateScreen(); }, true, checked, "Screens");
_screenActions[i] = action;
}
CONTAINER->setFullscreen(qApp->primaryScreen());
// CONTAINER->setFullscreen(qApp->primaryScreen());
WindowOpenGLDisplayPlugin::activate();
}
void StereoDisplayPlugin::updateScreen() {
for (uint32_t i = 0; i < _screenActions.size(); ++i) {
if (_screenActions[i]->isChecked()) {
CONTAINER->setFullscreen(qApp->screens().at(i));
// CONTAINER->setFullscreen(qApp->screens().at(i));
break;
}
}

View file

@ -25,17 +25,34 @@ uniform sampler2D specularMap;
// the depth texture
uniform sampler2D depthMap;
// the distance to the near clip plane
uniform float near;
// scale factor for depth: (far - near) / far
uniform float depthScale;
struct DeferredTransform {
// the distance to the near clip plane
// scale factor for depth: (far - near) / far
vec4 nearVal_depthScale_spareAB;
// offset for depth texture coordinates
// scale for depth texture coordinates
vec4 depthTexCoordOffset_scale;
// offset for depth texture coordinates
uniform vec2 depthTexCoordOffset;
mat4 viewInverse;
};
layout(std140) uniform deferredTransformBuffer {
DeferredTransform _deferredTransform;
};
DeferredTransform getDeferredTransform() {
return _deferredTransform;
}
// scale for depth texture coordinates
uniform vec2 depthTexCoordScale;
vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) {
vec2 nearVal_depthScale = deferredTransform.nearVal_depthScale_spareAB.xy;
vec2 depthTexCoordOffset = deferredTransform.depthTexCoordOffset_scale.xy;
vec2 depthTexCoordScale = deferredTransform.depthTexCoordOffset_scale.zw;
// compute the view space position using the depth
float z = nearVal_depthScale.x / (depthVal * nearVal_depthScale.y - 1.0);
return vec4((depthTexCoordOffset + texcoord * depthTexCoordScale) * z, z, 1.0);
}
struct DeferredFragment {
float depthVal;
@ -51,6 +68,9 @@ struct DeferredFragment {
};
DeferredFragment unpackDeferredFragment(vec2 texcoord) {
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag;
frag.depthVal = texture(depthMap, texcoord).r;
frag.normalVal = texture(normalMap, texcoord);
@ -63,10 +83,13 @@ DeferredFragment unpackDeferredFragment(vec2 texcoord) {
}
texcoord.x *= 2.0;
}
// compute the view space position using the depth
float z = near / (frag.depthVal * depthScale - 1.0);
frag.position = vec4((depthTexCoordOffset + texcoord * depthTexCoordScale) * z, z, 1.0);
frag.position = evalEyePositionFromZ(deferredTransform, frag.depthVal, texcoord);
// compute the view space position using the depth
/* float z = near / (frag.depthVal * depthScale - 1.0);
frag.position = vec4((depthTexCoordOffset + texcoord * depthTexCoordScale) * z, z, 1.0);
*/
// Unpack the normal from the map
frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0));

View file

@ -62,10 +62,8 @@ uniform SphericalHarmonics ambientSphere;
// Everything about light
<@include model/Light.slh@>
// The view Matrix
uniform mat4 invViewMat;
vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
vec3 evalAmbienGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
// Need the light now
Light light = getLight();
@ -82,7 +80,7 @@ vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal,
return color;
}
vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
vec3 evalAmbienSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
// Need the light now
Light light = getLight();
@ -100,7 +98,7 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no
return color;
}
vec3 evalSkyboxGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
// Need the light now
Light light = getLight();
@ -117,7 +115,7 @@ vec3 evalSkyboxGlobalColor(float shadowAttenuation, vec3 position, vec3 normal,
return color;
}
vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) {
vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) {
Light light = getLight();

View file

@ -11,6 +11,8 @@
<@if not DEFERRED_LIGHTING_SLH@>
<@def DEFERRED_LIGHTING_SLH@>
<@func declareEvalPBRShading()@>
// Frag Shading returns the diffuse amount as W and the specular rgb as xyz
vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) {
// Diffuse Lighting
@ -33,6 +35,9 @@ vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 sp
return vec4(reflect, diffuse);
}
<@endfunc@>
<@func declareEvalBlinnRShading()@>
vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) {
// Diffuse Lighting
@ -49,6 +54,12 @@ vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3
return vec4(reflect, diffuse);
}
<@endfunc@>
<$declareEvalPBRShading()$>
vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) {
/*if (gl_FragCoord.x > 1000) {

View file

@ -53,18 +53,14 @@ static const std::string glowIntensityShaderHandle = "glowIntensity";
struct LightLocations {
int shadowDistances;
int shadowScale;
int nearLocation;
int depthScale;
int depthTexCoordOffset;
int depthTexCoordScale;
int radius;
int ambientSphere;
int lightBufferUnit;
int atmosphereBufferUnit;
int invViewMat;
int texcoordMat;
int coneParam;
int stereo;
int deferredTransformBuffer;
};
static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations);
@ -278,9 +274,9 @@ void DeferredLightingEffect::render(RenderArgs* args) {
gpu::Batch batch;
// Allocate the parameters buffer used by all the deferred shaders
if (!_parametersBuffer._buffer) {
Parameters parameters[2];
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(2 * sizeof(Parameters), (const gpu::Byte*) &parameters));
if (!_deferredTransformBuffer._buffer) {
DeferredTransform parameters[2];
_deferredTransformBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(2 * sizeof(DeferredTransform), (const gpu::Byte*) &parameters));
}
// Framebuffer copy operations cannot function as multipass stereo operations.
@ -318,8 +314,29 @@ void DeferredLightingEffect::render(RenderArgs* args) {
bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap());
// Fetch the ViewMatrix;
glm::mat4 invViewMat;
invViewMat = args->_viewFrustum->getView();
// glm::mat4 invViewMat;
// invViewMat = args->_viewFrustum->getView();
auto viewFrustum = args->_viewFrustum;
{
float left, right, bottom, top, nearVal, farVal;
glm::vec4 nearClipPlane, farClipPlane;
viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
float depthScale = (farVal - nearVal) / farVal;
float nearScale = -1.0f / nearVal;
float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
auto leftParameters = _deferredTransformBuffer.edit<DeferredTransform>(0);
leftParameters.nearVal = nearVal;
leftParameters.depthScale = depthScale;
leftParameters.depthTexCoordOffset = glm::vec2(depthTexCoordOffsetS, depthTexCoordOffsetT);
leftParameters.depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT);
leftParameters.viewInverse = viewFrustum->getView();
}
batch.setUniformBuffer(DEFERRED_TRANSFORM_BUFFER_SLOT, _deferredTransformBuffer);
auto& program = _directionalLight;
LightLocationsPtr locations = _directionalLightLocations;
@ -395,25 +412,9 @@ void DeferredLightingEffect::render(RenderArgs* args) {
if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) {
batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer());
}
batch._glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
// batch._glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
}
float left, right, bottom, top, nearVal, farVal;
glm::vec4 nearClipPlane, farClipPlane;
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
batch._glUniform1f(locations->nearLocation, nearVal);
float depthScale = (farVal - nearVal) / farVal;
batch._glUniform1f(locations->depthScale, depthScale);
float nearScale = -1.0f / nearVal;
float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
batch._glUniform2f(locations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT);
batch._glUniform2f(locations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT);
bool stereo = args->_context->isStereo();
batch._glUniform1f(locations->stereo, stereo ? 1 : 0);
@ -469,18 +470,15 @@ void DeferredLightingEffect::render(RenderArgs* args) {
if (!_pointLights.empty()) {
batch.setPipeline(_pointLight);
batch._glUniform1f(_pointLightLocations->nearLocation, nearVal);
batch._glUniform1f(_pointLightLocations->depthScale, depthScale);
batch._glUniform2f(_pointLightLocations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT);
batch._glUniform2f(_pointLightLocations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT);
batch._glUniformMatrix4fv(_pointLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
// batch._glUniformMatrix4fv(_pointLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
for (auto lightID : _pointLights) {
auto& light = _allocatedLights[lightID];
// IN DEBUG: light->setShowContour(true);
// IN DEBUG:
light->setShowContour(true);
if (_pointLightLocations->lightBufferUnit >= 0) {
batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
}
@ -517,18 +515,15 @@ void DeferredLightingEffect::render(RenderArgs* args) {
if (!_spotLights.empty()) {
batch.setPipeline(_spotLight);
batch._glUniform1f(_spotLightLocations->nearLocation, nearVal);
batch._glUniform1f(_spotLightLocations->depthScale, depthScale);
batch._glUniform2f(_spotLightLocations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT);
batch._glUniform2f(_spotLightLocations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT);
batch._glUniformMatrix4fv(_spotLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
// batch._glUniformMatrix4fv(_spotLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
for (auto lightID : _spotLights) {
auto light = _allocatedLights[lightID];
// IN DEBUG: light->setShowContour(true);
// IN DEBUG:
light->setShowContour(true);
batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
@ -656,23 +651,23 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
const int ATMOSPHERE_GPU_SLOT = 4;
slotBindings.insert(gpu::Shader::Binding(std::string("atmosphereBufferUnit"), ATMOSPHERE_GPU_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("deferredTransformBuffer"), DeferredLightingEffect::DEFERRED_TRANSFORM_BUFFER_SLOT));
gpu::Shader::makeProgram(*program, slotBindings);
locations->stereo = program->getUniforms().findLocation("stereoMode");
locations->shadowDistances = program->getUniforms().findLocation("shadowDistances");
locations->shadowScale = program->getUniforms().findLocation("shadowScale");
locations->nearLocation = program->getUniforms().findLocation("near");
locations->depthScale = program->getUniforms().findLocation("depthScale");
locations->depthTexCoordOffset = program->getUniforms().findLocation("depthTexCoordOffset");
locations->depthTexCoordScale = program->getUniforms().findLocation("depthTexCoordScale");
locations->radius = program->getUniforms().findLocation("radius");
locations->ambientSphere = program->getUniforms().findLocation("ambientSphere.L00");
locations->invViewMat = program->getUniforms().findLocation("invViewMat");
locations->texcoordMat = program->getUniforms().findLocation("texcoordMat");
locations->coneParam = program->getUniforms().findLocation("coneParam");
locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
locations->atmosphereBufferUnit = program->getBuffers().findLocation("atmosphereBufferUnit");
locations->deferredTransformBuffer = program->getBuffers().findLocation("deferredTransformBuffer");
auto state = std::make_shared<gpu::State>();
if (lightVolume) {

View file

@ -32,6 +32,7 @@ class DeferredLightingEffect : public Dependency {
public:
static const int NORMAL_FITTING_MAP_SLOT = 10;
static const int DEFERRED_TRANSFORM_BUFFER_SLOT = 7;
void init(AbstractViewStateInterface* viewState);
@ -153,7 +154,7 @@ private:
model::SkyboxPointer _skybox;
// Class describing the uniform buffer with all the parameters common to the deferred shaders
class Parameters {
class DeferredTransform {
public:
float nearVal{ 1.0f };
@ -162,13 +163,12 @@ private:
glm::vec2 depthTexCoordOffset{ 0.0f };
glm::vec2 depthTexCoordScale{ 1.0f };
Parameters() {}
glm::mat4 viewInverse;
DeferredTransform() {}
};
typedef gpu::BufferView UniformBufferView;
UniformBufferView _parametersBuffer;
const UniformBufferView& getParametersBuffer() const { return _parametersBuffer; }
UniformBufferView _deferredTransformBuffer;
};
class SimpleProgramKey {

View file

@ -27,6 +27,7 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
vec3 color = evalLightmappedColor(
getDeferredTransform().viewInverse,
1.0,
frag.normal,
frag.diffuse,
@ -34,7 +35,9 @@ void main(void) {
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbienSphereGlobalColor(1.0,
vec3 color = evalAmbienSphereGlobalColor(
getDeferredTransform().viewInverse,
1.0,
frag.position.xyz,
frag.normal,
frag.diffuse,

View file

@ -33,13 +33,16 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
} else {
vec3 color = evalAmbienSphereGlobalColor(shadowAttenuation,
vec3 color = evalAmbienSphereGlobalColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,

View file

@ -33,13 +33,16 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
} else {
vec3 color = evalAmbienSphereGlobalColor(shadowAttenuation,
vec3 color = evalAmbienSphereGlobalColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,

View file

@ -26,13 +26,16 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4( evalLightmappedColor(
getDeferredTransform().viewInverse,
1.0,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
} else {
vec3 color = evalAmbienGlobalColor(1.0,
vec3 color = evalAmbienGlobalColor(
getDeferredTransform().viewInverse,
1.0,
frag.position.xyz,
frag.normal,
frag.diffuse,

View file

@ -33,13 +33,16 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
} else {
vec3 color = evalAmbienGlobalColor(shadowAttenuation,
vec3 color = evalAmbienGlobalColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,

View file

@ -33,13 +33,16 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
} else {
vec3 color = evalAmbienGlobalColor(shadowAttenuation,
vec3 color = evalAmbienGlobalColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,

View file

@ -27,6 +27,7 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
vec3 color = evalLightmappedColor(
getDeferredTransform().viewInverse,
1.0,
frag.normal,
frag.diffuse,
@ -34,7 +35,9 @@ void main(void) {
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalSkyboxGlobalColor(1.0,
vec3 color = evalSkyboxGlobalColor(
getDeferredTransform().viewInverse,
1.0,
frag.position.xyz,
frag.normal,
frag.diffuse,

View file

@ -33,13 +33,16 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
} else {
vec3 color = evalSkyboxGlobalColor(shadowAttenuation,
vec3 color = evalSkyboxGlobalColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,

View file

@ -33,13 +33,16 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
} else {
vec3 color = evalSkyboxGlobalColor(shadowAttenuation,
vec3 color = evalSkyboxGlobalColor(
getDeferredTransform().viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,

View file

@ -21,8 +21,6 @@
// Everything about light
<@include model/Light.slh@>
// The view Matrix
uniform mat4 invViewMat;
in vec4 _texCoord0;
out vec4 _fragColor;
@ -31,7 +29,9 @@ void main(void) {
// Grab the fragment data from the uv
vec2 texCoord = _texCoord0.st / _texCoord0.q;
DeferredFragment frag = unpackDeferredFragment(texCoord);
mat4 invViewMat = getDeferredTransform().viewInverse;
// Kill if in front of the light volume
float depth = frag.depthVal;
if (depth < gl_FragCoord.z) {

View file

@ -21,10 +21,6 @@
// Everything about light
<@include model/Light.slh@>
// The view Matrix
uniform mat4 invViewMat;
in vec4 _texCoord0;
out vec4 _fragColor;
@ -33,6 +29,8 @@ void main(void) {
vec2 texCoord = _texCoord0.st / _texCoord0.q;
DeferredFragment frag = unpackDeferredFragment(texCoord);
mat4 invViewMat = getDeferredTransform().viewInverse;
// Kill if in front of the light volume
float depth = frag.depthVal;
if (depth < gl_FragCoord.z) {