History

overall clean up of th elocal light drawing to avoid the in/out pipeline case, still seeing big cost on gpu from the spot lights

samcake committed 10 years ago

Commit e7279121 parent 0c0109e8 files · +111 −124Browse files

Showing the changes to libraries/render-utils/src/DeferredLightingEffect.cpp (1 of 8 files). Show all

Unified · Split

libraries/render-utils/src/DeferredLightingEffect.cpp+65−65
@@ -245,11 +245,50 @@ void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light) { · 244 unmodified lines
245245 globalLight->setAmbientMap(light->getAmbientMap());
246246 }
247247
248+#include <shared/Shapes.h>
249+
250+model::MeshPointer DeferredLightingEffect::getPointLightMesh() {
251+ if (!_pointLightMesh) {
252+ _pointLightMesh = std::make_shared<model::Mesh>();
253+
254+ // let's use a icosahedron
255+ auto solid = geometry::icosahedron();
256+ solid.fitDimension(1.05f); // scaled to 1.05 meters, it will be scaled by the shader accordingly to the light size
257+
258+ int verticesSize = solid.vertices.size() * 3 * sizeof(float);
259+ float* vertexData = (float*) solid.vertices.data();
260+
261+ _pointLightMesh->setVertexBuffer(gpu::BufferView(new gpu::Buffer(verticesSize, (gpu::Byte*) vertexData), gpu::Element::VEC3F_XYZ));
262+
263+ auto nbIndices = solid.faces.size() * 3;
264+
265+ gpu::uint16* indexData = new gpu::uint16[nbIndices];
266+ gpu::uint16* index = indexData;
267+ for (auto face : solid.faces) {
268+ *(index++) = face[0];
269+ *(index++) = face[1];
270+ *(index++) = face[2];
271+ }
272+
273+ _pointLightMesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(sizeof(unsigned short) * nbIndices, (gpu::Byte*) indexData), gpu::Element::INDEX_UINT16));
274+ delete[] indexData;
275+
276+
277+ std::vector<model::Mesh::Part> parts;
278+ parts.push_back(model::Mesh::Part(0, nbIndices, 0, model::Mesh::TRIANGLES));
279+ parts.push_back(model::Mesh::Part(0, nbIndices, 0, model::Mesh::LINE_STRIP)); // outline version
280+
281+
282+ _pointLightMesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
283+ }
284+ return _pointLightMesh;
285+}
286+
248287 model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
249288 if (!_spotLightMesh) {
250289 _spotLightMesh = std::make_shared<model::Mesh>();
251290
252− int slices = 32;
291+ int slices = 16;
253292 int rings = 3;
254293 int vertices = 2 + rings * slices;
255294 int originVertex = vertices - 2;
@@ -544,41 +583,30 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, · 288 unmodified lines
544583 gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
545584
546585 // THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)
547− auto monoViewport = args->_viewport;
586+ auto viewport = args->_viewport;
548587
549588 // The view frustum is the mono frustum base
550589 auto viewFrustum = args->getViewFrustum();
551590
552591 // Eval the mono projection
553− mat4 monoProjMat;
554− viewFrustum.evalProjectionMatrix(monoProjMat);
555−
556− // The mono view transform
557− Transform monoViewTransform;
558− viewFrustum.evalViewTransform(monoViewTransform);
559−
560− // THe mono view matrix coming from the mono view transform
561− glm::mat4 monoViewMat;
562− monoViewTransform.getMatrix(monoViewMat);
592+ mat4 projMat;
593+ viewFrustum.evalProjectionMatrix(projMat);
563594
564− auto geometryCache = DependencyManager::get<GeometryCache>();
595+ // The view transform
596+ Transform viewTransform;
597+ viewFrustum.evalViewTransform(viewTransform);
565598
566− auto eyePoint = viewFrustum.getPosition();
567− float nearRadius = glm::distance(eyePoint, viewFrustum.getNearTopLeft());
568599
569600 auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
570601
571− // Render in this side's viewport
572− batch.setViewportTransform(monoViewport);
573− batch.setStateScissorRect(monoViewport);
602+ // Render in this viewport
603+ batch.setViewportTransform(viewport);
604+ batch.setStateScissorRect(viewport);
574605
575− // enlarge the scales slightly to account for tesselation
576− const float SCALE_EXPANSION = 0.05f;
606+ auto textureFrameTransform = gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(deferredFramebuffer->getFrameSize(), viewport);
577607
578− auto textureFrameTransform = gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(deferredFramebuffer->getFrameSize(), monoViewport);
579−
580− batch.setProjectionTransform(monoProjMat);
581− batch.setViewTransform(monoViewTransform, true);
608+ batch.setProjectionTransform(projMat);
609+ batch.setViewTransform(viewTransform, true);
582610
583611 // Splat Point lights
584612 if (points && !deferredLightingEffect->_pointLights.empty()) {
@@ -586,32 +614,26 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, · 1 unmodified line
586614 batch.setPipeline(deferredLightingEffect->_pointLight);
587615 batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform));
588616
617+ // Pojnt mesh
618+ auto mesh = deferredLightingEffect->getPointLightMesh();
619+ batch.setIndexBuffer(mesh->getIndexBuffer());
620+ batch.setInputBuffer(0, mesh->getVertexBuffer());
621+ batch.setInputFormat(mesh->getVertexFormat());
622+ auto& spherePart = mesh->getPartBuffer().get<model::Mesh::Part>(0);
623+
589624 for (auto lightID : deferredLightingEffect->_pointLights) {
590625 auto light = deferredLightingEffect->getLightStage().getLight(lightID);
591626 if (!light) {
592627 continue;
593628 }
594− // IN DEBUG: light->setShowContour(true);
595629 batch.setUniformBuffer(deferredLightingEffect->_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
596−
597− float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
598− // glm::vec4 sphereParam(expandedRadius, 0.0f, 0.0f, 1.0f);
599−
600− // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
601− // we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
602− /* if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) {
603− sphereParam.w = 0.0f;
604− batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->sphereParam, 1, reinterpret_cast< const float* >(&sphereParam));
605− batch.draw(gpu::TRIANGLE_STRIP, 4);
606− } else*/ {
607− // sphereParam.w = 1.0f;
608− // batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->sphereParam, 1, reinterpret_cast< const float* >(&sphereParam));
609−
630+ {
610631 Transform model;
611632 model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
612− batch.setModelTransform(model.postScale(expandedRadius));
613− batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
614− geometryCache->renderSphere(batch);
633+ batch.setModelTransform(model);
634+
635+ batch.drawIndexed(model::Mesh::topologyToPrimitive(spherePart._topology), spherePart._numIndices, spherePart._startIndex);
636+
615637 }
616638 }
617639 }
@@ -634,34 +656,12 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, · 16 unmodified lines
634656 if (!light) {
635657 continue;
636658 }
637− // IN DEBUG:
638− // light->setShowContour(true);
639659 batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
640−
641− /* auto eyeLightPos = eyePoint - light->getPosition();
642− auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection());
643−
644− const float TANGENT_LENGTH_SCALE = 0.666f;
645− glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f);
646−
647− float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
648− // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
649− // we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
650− const float OVER_CONSERVATIVE_SCALE = 1.1f;
651− if ((eyeHalfPlaneDistance > -nearRadius) &&
652− (glm::distance(eyePoint, glm::vec3(light->getPosition())) < (expandedRadius * OVER_CONSERVATIVE_SCALE) + nearRadius)) {
653− coneParam.w = 0.0f;
654− batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
655− batch.draw(gpu::TRIANGLE_STRIP, 4);
656− } else*/ {
657− // coneParam.w = 1.0f;
658− // batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
660+ {
659661
660662 Transform model;
661663 model.setTranslation(light->getPosition());
662664 model.postRotate(light->getOrientation());
663− // model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
664−
665665 batch.setModelTransform(model);
666666
667667 batch.drawIndexed(model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex);