diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 8f0e7ace83..4f14b76ac0 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -24,7 +24,7 @@ #include "FramebufferCache.h" #include "deferred_light_vert.h" -#include "deferred_light_limited_vert.h" +#include "deferred_light_point_vert.h" #include "deferred_light_spot_vert.h" #include "directional_light_frag.h" @@ -76,6 +76,7 @@ enum DeferredShader_BufferSlot { }; static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations); +static void loadLightVolumeProgram(const char* vertSource, const char* fragSource, bool front, gpu::PipelinePointer& program, LightLocationsPtr& locations); void DeferredLightingEffect::init() { _directionalLightLocations = std::make_shared(); @@ -99,8 +100,11 @@ void DeferredLightingEffect::init() { loadLightProgram(deferred_light_vert, directional_skybox_light_shadow_frag, false, _directionalSkyboxLightShadow, _directionalSkyboxLightShadowLocations); loadLightProgram(deferred_light_vert, local_lights_shading_frag, false, _localLight, _localLightLocations); - loadLightProgram(deferred_light_limited_vert, point_light_frag, true, _pointLight, _pointLightLocations); - loadLightProgram(deferred_light_vert, spot_light_frag, false, _spotLight, _spotLightLocations); + + loadLightVolumeProgram(deferred_light_point_vert, point_light_frag, false, _pointLightBack, _pointLightLocations); + loadLightVolumeProgram(deferred_light_point_vert, point_light_frag, true, _pointLightFront, _pointLightLocations); + loadLightVolumeProgram(deferred_light_spot_vert, spot_light_frag, false, _spotLightBack, _spotLightLocations); + loadLightVolumeProgram(deferred_light_spot_vert, spot_light_frag, true, _spotLightFront, _spotLightLocations); // Allocate a global light representing the Global Directional light casting shadow (the sun) and the ambient light _allocatedLights.push_back(std::make_shared()); @@ -240,6 +244,77 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo } + +static void loadLightVolumeProgram(const char* vertSource, const char* fragSource, bool front, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) { + auto VS = gpu::Shader::createVertex(std::string(vertSource)); + auto PS = gpu::Shader::createPixel(std::string(fragSource)); + + gpu::ShaderPointer program = gpu::Shader::createProgram(VS, PS); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), DEFERRED_BUFFER_COLOR_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), DEFERRED_BUFFER_NORMAL_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), DEFERRED_BUFFER_EMISSIVE_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), DEFERRED_BUFFER_DEPTH_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("obscuranceMap"), DEFERRED_BUFFER_OBSCURANCE_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("shadowMap"), SHADOW_MAP_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), SKYBOX_MAP_UNIT)); + + slotBindings.insert(gpu::Shader::Binding(std::string("linearZeyeMap"), DEFERRED_BUFFER_LINEAR_DEPTH_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("curvatureMap"), DEFERRED_BUFFER_CURVATURE_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("diffusedCurvatureMap"), DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("scatteringLUT"), SCATTERING_LUT_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("scatteringSpecularBeckmann"), SCATTERING_SPECULAR_UNIT)); + + + slotBindings.insert(gpu::Shader::Binding(std::string("cameraCorrectionBuffer"), CAMERA_CORRECTION_BUFFER_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), LIGHTING_MODEL_BUFFER_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("subsurfaceScatteringParametersBuffer"), SCATTERING_PARAMETERS_BUFFER_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightIndexBuffer"), LIGHT_INDEX_GPU_SLOT)); + + + gpu::Shader::makeProgram(*program, slotBindings); + + locations->radius = program->getUniforms().findLocation("radius"); + locations->ambientSphere = program->getUniforms().findLocation("ambientSphere.L00"); + + locations->texcoordFrameTransform = program->getUniforms().findLocation("texcoordFrameTransform"); + + locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer"); + locations->lightIndexBufferUnit = program->getBuffers().findLocation("lightIndexBuffer"); + locations->deferredFrameTransformBuffer = program->getBuffers().findLocation("deferredFrameTransformBuffer"); + locations->subsurfaceScatteringParametersBuffer = program->getBuffers().findLocation("subsurfaceScatteringParametersBuffer"); + locations->shadowTransformBuffer = program->getBuffers().findLocation("shadowTransformBuffer"); + + auto state = std::make_shared(); + state->setColorWriteMask(true, true, true, false); + // state->setColorWriteMask(false, false, false, false); + + // Stencil test all the light passes for objects pixels only, not the background + + if (front) { + state->setCullMode(gpu::State::CULL_FRONT); + state->setDepthTest(true, false, gpu::LESS_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_INCR)); + + //state->setDepthClampEnable(true); + // TODO: We should use DepthClamp and avoid changing geometry for inside /outside cases + // additive blending + // state->setBlendFunction(true, gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + + } else { + state->setCullMode(gpu::State::CULL_BACK); + state->setDepthTest(true, false, gpu::GREATER_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_INCR)); + // additive blending + // state->setBlendFunction(true, gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + } + pipeline = gpu::Pipeline::create(program, state); + +} + void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light) { auto globalLight = _allocatedLights.front(); globalLight->setDirection(light->getDirection()); @@ -618,7 +693,12 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, // gather lights auto& srcPointLights = deferredLightingEffect->_pointLights; auto& srcSpotLights = deferredLightingEffect->_spotLights; - std::vector lightIndices(srcPointLights.size() + srcSpotLights.size() + 1); + int numPointLights = (int) srcPointLights.size(); + int offsetPointLights = 0; + int numSpotLights = (int) srcSpotLights.size(); + int offsetSpotLights = numPointLights; + + std::vector lightIndices(numPointLights + numSpotLights + 1); lightIndices[0] = 0; if (points && !srcPointLights.empty()) { @@ -634,13 +714,56 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, _localLightsBuffer._buffer->setData(lightIndices.size() * sizeof(int), (const gpu::Byte*) lightIndices.data()); _localLightsBuffer._size = lightIndices.size() * sizeof(int); - // Spot light pipeline - batch.setPipeline(deferredLightingEffect->_localLight); - batch._glUniform4fv(deferredLightingEffect->_localLightLocations->texcoordFrameTransform, 1, reinterpret_cast(&textureFrameTransform)); - // Bind the global list of lights and the visible lights this frame batch.setUniformBuffer(deferredLightingEffect->_localLightLocations->lightBufferUnit, deferredLightingEffect->getLightStage()._lightArrayBuffer); batch.setUniformBuffer(deferredLightingEffect->_localLightLocations->lightIndexBufferUnit, _localLightsBuffer); + + + // before we get to the real lighting, let s try to cull down the number of pixels + { + /* if (numPointLights > 0) { + auto mesh = deferredLightingEffect->getPointLightMesh(); + batch.setIndexBuffer(mesh->getIndexBuffer()); + batch.setInputBuffer(0, mesh->getVertexBuffer()); + batch.setInputFormat(mesh->getVertexFormat()); + auto& pointPart = mesh->getPartBuffer().get(0); + + // Point light pipeline + batch.setPipeline(deferredLightingEffect->_pointLightBack); + batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->texcoordFrameTransform, 1, reinterpret_cast(&textureFrameTransform)); + + batch.drawIndexedInstanced(numPointLights, model::Mesh::topologyToPrimitive(pointPart._topology), pointPart._numIndices, pointPart._startIndex, offsetPointLights); + + batch.setPipeline(deferredLightingEffect->_pointLightFront); + batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->texcoordFrameTransform, 1, reinterpret_cast(&textureFrameTransform)); + + batch.drawIndexedInstanced(numPointLights, model::Mesh::topologyToPrimitive(pointPart._topology), pointPart._numIndices, pointPart._startIndex, offsetPointLights); + } */ + /* + if (numSpotLights > 0) { + auto mesh = deferredLightingEffect->getSpotLightMesh(); + batch.setIndexBuffer(mesh->getIndexBuffer()); + batch.setInputBuffer(0, mesh->getVertexBuffer()); + batch.setInputFormat(mesh->getVertexFormat()); + auto& conePart = mesh->getPartBuffer().get(0); + + // Spot light pipeline + batch.setPipeline(deferredLightingEffect->_spotLightBack); + batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->texcoordFrameTransform, 1, reinterpret_cast(&textureFrameTransform)); + + batch.drawIndexedInstanced(numSpotLights, model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex, offsetSpotLights); + + batch.setPipeline(deferredLightingEffect->_spotLightFront); + batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->texcoordFrameTransform, 1, reinterpret_cast(&textureFrameTransform)); + + batch.drawIndexedInstanced(numSpotLights, model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex, offsetSpotLights); + }*/ + } + + // Local light pipeline + batch.setPipeline(deferredLightingEffect->_localLight); + batch._glUniform4fv(deferredLightingEffect->_localLightLocations->texcoordFrameTransform, 1, reinterpret_cast(&textureFrameTransform)); + batch.draw(gpu::TRIANGLE_STRIP, 4); } } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 0cff4c355c..cbf5ff6ab3 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -88,8 +88,10 @@ private: gpu::PipelinePointer _localLight; - gpu::PipelinePointer _pointLight; - gpu::PipelinePointer _spotLight; + gpu::PipelinePointer _pointLightBack; + gpu::PipelinePointer _pointLightFront; + gpu::PipelinePointer _spotLightBack; + gpu::PipelinePointer _spotLightFront; LightLocationsPtr _directionalSkyboxLightLocations; LightLocationsPtr _directionalAmbientSphereLightLocations; diff --git a/libraries/render-utils/src/deferred_light_limited.slv b/libraries/render-utils/src/deferred_light_point.slv similarity index 82% rename from libraries/render-utils/src/deferred_light_limited.slv rename to libraries/render-utils/src/deferred_light_point.slv index 4598447335..f6d4de3954 100644 --- a/libraries/render-utils/src/deferred_light_limited.slv +++ b/libraries/render-utils/src/deferred_light_point.slv @@ -19,14 +19,21 @@ <$declareStandardTransform()$> <@include model/Light.slh@> -<$declareLightBuffer()$> +<$declareLightBuffer(120)$> + +uniform lightIndexBuffer { + int lightIndex[120]; +}; out vec4 _texCoord0; void main(void) { + + instanceID = lightIndex[gl_InstanceID]; + Light light = getLight(instanceID); vec4 sphereVertex = inPosition; - vec4 sphereParam = getLightVolumeGeometry(getLight()); + vec4 sphereParam = getLightVolumeGeometry(light); sphereVertex.xyz *= sphereParam.w; diff --git a/libraries/render-utils/src/deferred_light_spot.slv b/libraries/render-utils/src/deferred_light_spot.slv index e99142d8ea..cd70724e1f 100755 --- a/libraries/render-utils/src/deferred_light_spot.slv +++ b/libraries/render-utils/src/deferred_light_spot.slv @@ -19,10 +19,10 @@ <$declareStandardTransform()$> <@include model/Light.slh@> -<$declareLightBuffer(32)$> +<$declareLightBuffer(120)$> uniform lightIndexBuffer { - int lightIndex[32]; + int lightIndex[120]; }; out vec4 _texCoord0; flat out int instanceID; diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 018d6ca79b..239cbd5c91 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -11,7 +11,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - + @@ -29,10 +29,13 @@ uniform vec4 texcoordFrameTransform; -in vec4 _texCoord0; +in vec4 _texCoord0;!> out vec4 _fragColor; void main(void) { + _fragColor = vec4(1.0, 1.0, 1.0, 1.0); + + } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index d12db826c0..9d71832f15 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -13,7 +13,7 @@ // // Everything about deferred buffer -<@include DeferredBufferRead.slh@> + <$declareDeferredCurvature()$> @@ -31,21 +31,23 @@ uniform lightIndexBuffer { <$declareLightingSpot(supportScattering)$> //uniform vec4 texcoordFrameTransform; +!> - -in vec4 _texCoord0; +//in vec4 _texCoord0; //flat in int instanceID; out vec4 _fragColor; void main(void) { + _fragColor = vec4(1.0, 1.0, 1.0, 1.0); + // DeferredFrameTransform deferredTransform = getDeferredFrameTransform(); - + // Grab the fragment data from the uv - vec2 texCoord = _texCoord0.st;/* / _texCoord0.q; - texCoord *= texcoordFrameTransform.zw; + //vec2 texCoord = _texCoord0.st;/* / _texCoord0.q; + /*texCoord *= texcoordFrameTransform.zw; texCoord += texcoordFrameTransform.xy;*/ - + /* vec4 fragPosition = unpackDeferredPositionFromZeye(texCoord); DeferredFragment frag = unpackDeferredFragmentNoPosition(texCoord); @@ -108,5 +110,6 @@ void main(void) { _fragColor.rgb += diffuse; _fragColor.rgb += specular; } + */ } diff --git a/tests/shaders/src/main.cpp b/tests/shaders/src/main.cpp index 9744d8c78d..8a239f0728 100644 --- a/tests/shaders/src/main.cpp +++ b/tests/shaders/src/main.cpp @@ -28,7 +28,8 @@ #include #include -#include +#include +#include #include #include @@ -157,8 +158,8 @@ void QTestWindow::draw() { testShaderBuild(deferred_light_vert, directional_light_frag); testShaderBuild(deferred_light_vert, directional_ambient_light_frag); testShaderBuild(deferred_light_vert, directional_skybox_light_frag); - testShaderBuild(deferred_light_limited_vert, point_light_frag); - testShaderBuild(deferred_light_limited_vert, spot_light_frag); + testShaderBuild(deferred_light_point_vert, point_light_frag); + testShaderBuild(deferred_light_spot_vert, spot_light_frag); testShaderBuild(standardTransformPNTC_vert, standardDrawTexture_frag); testShaderBuild(standardTransformPNTC_vert, DrawTextureOpaque_frag);