Showing the changes to libraries/render-utils/src/DeferredLightingEffect.cpp (1 of 8 files). Show all
Unified · Split
| @@ -245,11 +245,50 @@ void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light) { · 244 unmodified lines | ||
| 245 | 245 | globalLight->setAmbientMap(light->getAmbientMap()); |
| 246 | 246 | } |
| 247 | 247 | |
| 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 | + | |
| 248 | 287 | model::MeshPointer DeferredLightingEffect::getSpotLightMesh() { |
| 249 | 288 | if (!_spotLightMesh) { |
| 250 | 289 | _spotLightMesh = std::make_shared<model::Mesh>(); |
| 251 | 290 | |
| 252 | − int slices = 32; | |
| 291 | + int slices = 16; | |
| 253 | 292 | int rings = 3; |
| 254 | 293 | int vertices = 2 + rings * slices; |
| 255 | 294 | int originVertex = vertices - 2; |
| @@ -544,41 +583,30 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, · 288 unmodified lines | ||
| 544 | 583 | gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { |
| 545 | 584 | |
| 546 | 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 | 588 | // The view frustum is the mono frustum base |
| 550 | 589 | auto viewFrustum = args->getViewFrustum(); |
| 551 | 590 | |
| 552 | 591 | // 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); | |
| 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 | 600 | auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>(); |
| 570 | 601 | |
| 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); | |
| 574 | 605 | |
| 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); | |
| 577 | 607 | |
| 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); | |
| 582 | 610 | |
| 583 | 611 | // Splat Point lights |
| 584 | 612 | if (points && !deferredLightingEffect->_pointLights.empty()) { |
| @@ -586,32 +614,26 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, · 1 unmodified line | ||
| 586 | 614 | batch.setPipeline(deferredLightingEffect->_pointLight); |
| 587 | 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 | 624 | for (auto lightID : deferredLightingEffect->_pointLights) { |
| 590 | 625 | auto light = deferredLightingEffect->getLightStage().getLight(lightID); |
| 591 | 626 | if (!light) { |
| 592 | 627 | continue; |
| 593 | 628 | } |
| 594 | − // IN DEBUG: light->setShowContour(true); | |
| 595 | 629 | 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 | + { | |
| 610 | 631 | Transform model; |
| 611 | 632 | 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 | + | |
| 615 | 637 | } |
| 616 | 638 | } |
| 617 | 639 | } |
| @@ -634,34 +656,12 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, · 16 unmodified lines | ||
| 634 | 656 | if (!light) { |
| 635 | 657 | continue; |
| 636 | 658 | } |
| 637 | − // IN DEBUG: | |
| 638 | − // light->setShowContour(true); | |
| 639 | 659 | 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 | + { | |
| 659 | 661 | |
| 660 | 662 | Transform model; |
| 661 | 663 | model.setTranslation(light->getPosition()); |
| 662 | 664 | model.postRotate(light->getOrientation()); |
| 663 | − // model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius)); | |
| 664 | − | |
| 665 | 665 | batch.setModelTransform(model); |
| 666 | 666 | |
| 667 | 667 | batch.drawIndexed(model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex); |