mirror of
https://github.com/lubosz/overte.git
synced 2025-04-14 17:26:16 +02:00
pack all the lights in a single buffer and shade the opaque with a single full screen path
This commit is contained in:
parent
4bc8a83c08
commit
b81dfefbeb
5 changed files with 123 additions and 46 deletions
|
@ -60,6 +60,11 @@ struct Light {
|
|||
|
||||
SphericalHarmonics _ambientSphere;
|
||||
};
|
||||
const int LIGHT_SPOT = 2;
|
||||
|
||||
bool light_isSpot(Light l) {
|
||||
return bool(l._control.y >= 2.f);
|
||||
}
|
||||
|
||||
vec3 getLightPosition(Light l) { return l._position.xyz; }
|
||||
vec3 getLightDirection(Light l) { return l._direction.xyz; } // direction is -Z axis
|
||||
|
|
|
@ -97,7 +97,7 @@ void DeferredLightingEffect::init() {
|
|||
loadLightProgram(deferred_light_vert, directional_skybox_light_shadow_frag, false, _directionalSkyboxLightShadow, _directionalSkyboxLightShadowLocations);
|
||||
|
||||
loadLightProgram(deferred_light_limited_vert, point_light_frag, true, _pointLight, _pointLightLocations);
|
||||
loadLightProgram(deferred_light_spot_vert, spot_light_frag, true, _spotLight, _spotLightLocations);
|
||||
loadLightProgram(deferred_light_vert, spot_light_frag, false, _spotLight, _spotLightLocations);
|
||||
|
||||
// Allocate a global light representing the Global Directional light casting shadow (the sun) and the ambient light
|
||||
_allocatedLights.push_back(std::make_shared<model::Light>());
|
||||
|
@ -571,6 +571,11 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c
|
|||
|
||||
}
|
||||
|
||||
RenderDeferredLocals::RenderDeferredLocals() :
|
||||
_spotLightsBuffer(std::make_shared<gpu::Buffer>()) {
|
||||
|
||||
}
|
||||
|
||||
void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext,
|
||||
const DeferredFrameTransformPointer& frameTransform,
|
||||
const DeferredFramebufferPointer& deferredFramebuffer,
|
||||
|
@ -585,6 +590,8 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
|||
}
|
||||
auto args = renderContext->args;
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
// Framebuffer copy operations cannot function as multipass stereo operations.
|
||||
batch.enableStereo(false);
|
||||
|
||||
// THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)
|
||||
auto viewport = args->_viewport;
|
||||
|
@ -609,9 +616,46 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
|||
|
||||
auto textureFrameTransform = gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(deferredFramebuffer->getFrameSize(), viewport);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewTransform, true);
|
||||
// batch.setProjectionTransform(projMat);
|
||||
// batch.setViewTransform(viewTransform, true);
|
||||
|
||||
// gather lights
|
||||
auto& srcPointLights = deferredLightingEffect->_pointLights;
|
||||
auto& srcSpotLights = deferredLightingEffect->_spotLights;
|
||||
std::vector<int> lightIndices(srcPointLights.size() + srcSpotLights.size() + 1);
|
||||
lightIndices[0] = 0;
|
||||
|
||||
if (points && !srcPointLights.empty()) {
|
||||
memcpy(lightIndices.data() + (lightIndices[0] + 1), srcPointLights.data(), srcPointLights.size() * sizeof(int));
|
||||
lightIndices[0] += srcPointLights.size();
|
||||
}
|
||||
if (spots && !srcSpotLights.empty()) {
|
||||
memcpy(lightIndices.data() + (lightIndices[0] + 1), srcSpotLights.data(), srcSpotLights.size() * sizeof(int));
|
||||
lightIndices[0] += srcSpotLights.size();
|
||||
}
|
||||
|
||||
if (lightIndices[0] > 0) {
|
||||
_spotLightsBuffer._buffer->setData(lightIndices.size() * sizeof(int), (const gpu::Byte*) lightIndices.data());
|
||||
_spotLightsBuffer._size = lightIndices.size() * sizeof(int);
|
||||
|
||||
// Spot light pipeline
|
||||
batch.setPipeline(deferredLightingEffect->_spotLight);
|
||||
batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform));
|
||||
|
||||
// Spot mesh
|
||||
auto mesh = deferredLightingEffect->getSpotLightMesh();
|
||||
batch.setIndexBuffer(mesh->getIndexBuffer());
|
||||
batch.setInputBuffer(0, mesh->getVertexBuffer());
|
||||
batch.setInputFormat(mesh->getVertexFormat());
|
||||
auto& conePart = mesh->getPartBuffer().get<model::Mesh::Part>(0);
|
||||
|
||||
|
||||
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, deferredLightingEffect->getLightStage()._lightArrayBuffer);
|
||||
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightIndexBufferUnit, _spotLightsBuffer);
|
||||
// batch.drawIndexedInstanced(deferredLightingEffect->_spotLights.size(), model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex);
|
||||
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
/*
|
||||
// Splat Point lights
|
||||
if (points && !deferredLightingEffect->_pointLights.empty()) {
|
||||
// POint light pipeline
|
||||
|
@ -645,9 +689,11 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
|||
|
||||
// Splat spot lights
|
||||
if (spots && !deferredLightingEffect->_spotLights.empty()) {
|
||||
|
||||
|
||||
_spotLightsBuffer._buffer->setData(deferredLightingEffect->_spotLights.size() * sizeof(int), (const gpu::Byte*) deferredLightingEffect->_spotLights.data());
|
||||
std::vector<int> again(deferredLightingEffect->_spotLights.size() + 1);
|
||||
again[0] = deferredLightingEffect->_spotLights.size();
|
||||
memcpy(again.data() + 1, deferredLightingEffect->_spotLights.data(), deferredLightingEffect->_spotLights.size() * sizeof(int));
|
||||
_spotLightsBuffer._buffer->setData(again.size() * sizeof(int), (const gpu::Byte*) again.data());
|
||||
_spotLightsBuffer._size = again.size() * sizeof(int);
|
||||
|
||||
// Spot light pipeline
|
||||
batch.setPipeline(deferredLightingEffect->_spotLight);
|
||||
|
@ -663,7 +709,9 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
|||
|
||||
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, deferredLightingEffect->getLightStage()._lightArrayBuffer);
|
||||
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightIndexBufferUnit, _spotLightsBuffer);
|
||||
batch.drawIndexedInstanced(deferredLightingEffect->_spotLights.size(), model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex);
|
||||
// batch.drawIndexedInstanced(deferredLightingEffect->_spotLights.size(), model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex);
|
||||
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
/*
|
||||
for (auto lightID : deferredLightingEffect->_spotLights) {
|
||||
auto light = deferredLightingEffect->getLightStage().getLight(lightID);
|
||||
|
|
|
@ -161,6 +161,8 @@ public:
|
|||
|
||||
gpu::BufferView _spotLightsBuffer;
|
||||
|
||||
RenderDeferredLocals();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -21,12 +21,16 @@
|
|||
<@include model/Light.slh@>
|
||||
<$declareLightBuffer(32)$>
|
||||
|
||||
uniform lightIndexBuffer {
|
||||
int lightIndex[32];
|
||||
};
|
||||
out vec4 _texCoord0;
|
||||
flat out int instanceID;
|
||||
|
||||
void main(void) {
|
||||
vec4 coneVertex = inPosition;
|
||||
|
||||
Light light = getLight(gl_InstanceID);
|
||||
instanceID = lightIndex[gl_InstanceID];
|
||||
Light light = getLight(instanceID);
|
||||
vec3 lightPos = getLightPosition(light);
|
||||
vec4 coneParam = getLightVolumeGeometry(light);
|
||||
|
||||
|
|
|
@ -20,75 +20,93 @@
|
|||
// Everything about light
|
||||
<@include model/Light.slh@>
|
||||
<$declareLightBuffer(32)$>
|
||||
|
||||
uniform lightIndexBuffer {
|
||||
int lightIndex[32];
|
||||
};
|
||||
<@include LightingModel.slh@>
|
||||
|
||||
<@include LightPoint.slh@>
|
||||
<$declareLightingPoint(supportScattering)$>
|
||||
<@include LightSpot.slh@>
|
||||
<$declareLightingSpot(supportScattering)$>
|
||||
|
||||
uniform vec4 texcoordFrameTransform;
|
||||
//uniform vec4 texcoordFrameTransform;
|
||||
|
||||
|
||||
|
||||
in vec4 _texCoord0;
|
||||
//flat in int instanceID;
|
||||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
// DeferredFrameTransform deferredTransform = getDeferredFrameTransform();
|
||||
|
||||
// Grab the fragment data from the uv
|
||||
vec2 texCoord = _texCoord0.st / _texCoord0.q;
|
||||
vec2 texCoord = _texCoord0.st;/* / _texCoord0.q;
|
||||
texCoord *= texcoordFrameTransform.zw;
|
||||
texCoord += texcoordFrameTransform.xy;
|
||||
texCoord += texcoordFrameTransform.xy;*/
|
||||
|
||||
vec4 fragPosition = unpackDeferredPositionFromZeye(texCoord);
|
||||
|
||||
// Need the light now
|
||||
Light light = getLight(0);
|
||||
|
||||
// Frag pos in world
|
||||
mat4 invViewMat = getViewInverse();
|
||||
vec4 fragPos = invViewMat * fragPosition;
|
||||
|
||||
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
|
||||
vec4 fragLightVecLen2;
|
||||
vec4 fragLightDirLen;
|
||||
float cosSpotAngle;
|
||||
if (!clipFragToLightVolumeSpot(light, fragPos.xyz, fragLightVecLen2, fragLightDirLen, cosSpotAngle)) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// _fragColor.rgb = vec3(0.0, 1.0, 1.0);
|
||||
// return;
|
||||
|
||||
DeferredFragment frag = unpackDeferredFragmentNoPositionNoAmbient(texCoord);
|
||||
// frag.depthVal = depthValue;
|
||||
frag.position = fragPosition;
|
||||
|
||||
if (frag.mode == FRAG_MODE_UNLIT) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// Frag to eye vec
|
||||
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
|
||||
// frag.depthVal = depthValue;
|
||||
frag.position = fragPosition;
|
||||
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
vec4 midNormalCurvature;
|
||||
vec4 lowNormalCurvature;
|
||||
if (frag.mode == FRAG_MODE_SCATTERING) {
|
||||
unpackMidLowNormalCurvature(texCoord, midNormalCurvature, lowNormalCurvature);
|
||||
}
|
||||
evalLightingSpot(diffuse, specular, light,
|
||||
fragLightDirLen.xyzw, cosSpotAngle, fragEyeDir, frag.normal, frag.roughness,
|
||||
frag.metallic, frag.fresnel, frag.albedo, 1.0,
|
||||
frag.scattering, midNormalCurvature, lowNormalCurvature);
|
||||
|
||||
_fragColor.rgb += diffuse;
|
||||
_fragColor.rgb += specular;
|
||||
// Frag pos in world
|
||||
mat4 invViewMat = getViewInverse();
|
||||
vec4 fragPos = invViewMat * fragPosition;
|
||||
|
||||
// _fragColor.rgb = vec3(0.0, 1.0, 1.0);
|
||||
// Frag to eye vec
|
||||
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
|
||||
int numLights = lightIndex[0];
|
||||
for (int i = 0; i < numLights; i++) {
|
||||
// Need the light now
|
||||
Light light = getLight(lightIndex[i + 1]);
|
||||
bool isSpot = light_isSpot(light);
|
||||
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
|
||||
vec4 fragLightVecLen2;
|
||||
vec4 fragLightDirLen;
|
||||
float cosSpotAngle;
|
||||
if (isSpot) {
|
||||
if (!clipFragToLightVolumeSpot(light, fragPos.xyz, fragLightVecLen2, fragLightDirLen, cosSpotAngle)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (!clipFragToLightVolumePoint(light, fragPos.xyz, fragLightVecLen2)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
|
||||
if (isSpot) {
|
||||
evalLightingSpot(diffuse, specular, light,
|
||||
fragLightDirLen.xyzw, cosSpotAngle, fragEyeDir, frag.normal, frag.roughness,
|
||||
frag.metallic, frag.fresnel, frag.albedo, 1.0,
|
||||
frag.scattering, midNormalCurvature, lowNormalCurvature);
|
||||
} else {
|
||||
evalLightingPoint(diffuse, specular, light,
|
||||
fragLightVecLen2.xyz, fragEyeDir, frag.normal, frag.roughness,
|
||||
frag.metallic, frag.fresnel, frag.albedo, 1.0,
|
||||
frag.scattering, midNormalCurvature, lowNormalCurvature);
|
||||
}
|
||||
|
||||
_fragColor.rgb += diffuse;
|
||||
_fragColor.rgb += specular;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue