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 | globalLight->setAmbientMap(light->getAmbientMap()); | 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 | model::MeshPointer DeferredLightingEffect::getSpotLightMesh() { | 287 | model::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 base | 588 | // The view frustum is the mono frustum base |
| 550 | auto viewFrustum = args->getViewFrustum(); | 589 | auto viewFrustum = args->getViewFrustum(); |
| 551 | 590 | ||
| 552 | // Eval the mono projection | 591 | // 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 viewport | 602 | // 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 tesselation | 606 | 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 lights | 611 | // 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); |