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
245 globalLight->setAmbientMap(light->getAmbientMap());245 globalLight->setAmbientMap(light->getAmbientMap());
246}246}
247 247
248#include <shared/Shapes.h>
249
250model::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
248model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {287model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
249 if (!_spotLightMesh) {288 if (!_spotLightMesh) {
250 _spotLightMesh = std::make_shared<model::Mesh>();289 _spotLightMesh = std::make_shared<model::Mesh>();
251 290
252 int slices = 32;291 int slices = 16;
253 int rings = 3;292 int rings = 3;
254 int vertices = 2 + rings * slices;293 int vertices = 2 + rings * slices;
255 int originVertex = vertices - 2;294 int originVertex = vertices - 2;
@@ -544,41 +583,30 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, · 288 unmodified lines
544 gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {583 gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
545 584
546 // THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)585 // 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;
548 587
549 // The view frustum is the mono frustum base588 // The view frustum is the mono frustum base
550 auto viewFrustum = args->getViewFrustum();589 auto viewFrustum = args->getViewFrustum();
551 590
552 // Eval the mono projection591 // Eval the mono projection
553 mat4 monoProjMat;592 mat4 projMat;
554 viewFrustum.evalProjectionMatrix(monoProjMat);593 viewFrustum.evalProjectionMatrix(projMat);
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);
563 594
564 auto geometryCache = DependencyManager::get<GeometryCache>();595 // The view transform
596 Transform viewTransform;
597 viewFrustum.evalViewTransform(viewTransform);
565 598
566 auto eyePoint = viewFrustum.getPosition();
567 float nearRadius = glm::distance(eyePoint, viewFrustum.getNearTopLeft());
568 599
569 auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();600 auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
570 601
571 // Render in this side's viewport602 // Render in this viewport
572 batch.setViewportTransform(monoViewport);603 batch.setViewportTransform(viewport);
573 batch.setStateScissorRect(monoViewport);604 batch.setStateScissorRect(viewport);
574 605
575 // enlarge the scales slightly to account for tesselation606 auto textureFrameTransform = gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(deferredFramebuffer->getFrameSize(), viewport);
576 const float SCALE_EXPANSION = 0.05f;
577 607
578 auto textureFrameTransform = gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(deferredFramebuffer->getFrameSize(), monoViewport);608 batch.setProjectionTransform(projMat);
579 609 batch.setViewTransform(viewTransform, true);
580 batch.setProjectionTransform(monoProjMat);
581 batch.setViewTransform(monoViewTransform, true);
582 610
583 // Splat Point lights611 // Splat Point lights
584 if (points && !deferredLightingEffect->_pointLights.empty()) {612 if (points && !deferredLightingEffect->_pointLights.empty()) {
@@ -586,32 +614,26 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, · 1 unmodified line
586 batch.setPipeline(deferredLightingEffect->_pointLight);614 batch.setPipeline(deferredLightingEffect->_pointLight);
587 batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform));615 batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform));
588 616
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
589 for (auto lightID : deferredLightingEffect->_pointLights) {624 for (auto lightID : deferredLightingEffect->_pointLights) {
590 auto light = deferredLightingEffect->getLightStage().getLight(lightID);625 auto light = deferredLightingEffect->getLightStage().getLight(lightID);
591 if (!light) {626 if (!light) {
592 continue;627 continue;
593 }628 }
594 // IN DEBUG: light->setShowContour(true);
595 batch.setUniformBuffer(deferredLightingEffect->_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());629 batch.setUniformBuffer(deferredLightingEffect->_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
596 630 {
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
610 Transform model;631 Transform model;
611 model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));632 model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
612 batch.setModelTransform(model.postScale(expandedRadius));633 batch.setModelTransform(model);
613 batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);634
614 geometryCache->renderSphere(batch);635 batch.drawIndexed(model::Mesh::topologyToPrimitive(spherePart._topology), spherePart._numIndices, spherePart._startIndex);
636
615 }637 }
616 }638 }
617 }639 }
@@ -634,34 +656,12 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, · 16 unmodified lines
634 if (!light) {656 if (!light) {
635 continue;657 continue;
636 }658 }
637 // IN DEBUG:
638 // light->setShowContour(true);
639 batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());659 batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
640 660 {
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));
659 661
660 Transform model;662 Transform model;
661 model.setTranslation(light->getPosition());663 model.setTranslation(light->getPosition());
662 model.postRotate(light->getOrientation());664 model.postRotate(light->getOrientation());
663 // model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
664
665 batch.setModelTransform(model);665 batch.setModelTransform(model);
666 666
667 batch.drawIndexed(model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex);667 batch.drawIndexed(model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex);