Skip to content

Commit 687f028

Browse files
add ortho camera support
and fix cubemap issues
1 parent 2b7c40b commit 687f028

File tree

3 files changed

+130
-99
lines changed

3 files changed

+130
-99
lines changed

examples_tests/22.RaytracedAO/Renderer.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,7 +1629,7 @@ void Renderer::denoiseCubemapFaces(
16291629
// one day it will just work like that
16301630
//#include <nbl/builtin/glsl/sampling/box_muller_transform.glsl>
16311631

1632-
bool Renderer::render(nbl::ITimer* timer, const bool beauty)
1632+
bool Renderer::render(nbl::ITimer* timer, const bool transformNormals, const bool beauty)
16331633
{
16341634
if (m_cullPushConstants.maxGlobalInstanceCount==0u)
16351635
return true;
@@ -1794,7 +1794,13 @@ bool Renderer::render(nbl::ITimer* timer, const bool beauty)
17941794
{
17951795
m_driver->bindDescriptorSets(EPBP_COMPUTE,m_resolvePipeline->getLayout(),0u,1u,&m_resolveDS.get(),nullptr);
17961796
m_driver->bindComputePipeline(m_resolvePipeline.get());
1797-
m_driver->pushConstants(m_resolvePipeline->getLayout(),ICPUSpecializedShader::ESS_COMPUTE,0u,sizeof(m_prevView),&m_prevView);
1797+
if (transformNormals)
1798+
m_driver->pushConstants(m_resolvePipeline->getLayout(),ICPUSpecializedShader::ESS_COMPUTE,0u,sizeof(m_prevView),&m_prevView);
1799+
else
1800+
{
1801+
decltype(m_prevView) identity;
1802+
m_driver->pushConstants(m_resolvePipeline->getLayout(),ICPUSpecializedShader::ESS_COMPUTE,0u,sizeof(identity),&identity);
1803+
}
17981804
m_driver->dispatch(m_raygenWorkGroups[0],m_raygenWorkGroups[1],1);
17991805
COpenGLExtensionHandler::pGlMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT|GL_SHADER_IMAGE_ACCESS_BARRIER_BIT
18001806
// because of direct to screen resolve

examples_tests/22.RaytracedAO/Renderer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class Renderer : public nbl::core::IReferenceCounted, public nbl::core::Interfac
5454

5555
void denoiseCubemapFaces(std::filesystem::path filePaths[6], const std::string& mergedFileName, int borderPixels, const DenoiserArgs& denoiserArgs = {});
5656

57-
bool render(nbl::ITimer* timer, const bool beauty=true);
57+
bool render(nbl::ITimer* timer, const bool transformNormals, const bool beauty=true);
5858

5959
auto* getColorBuffer() { return m_colorBuffer; }
6060

examples_tests/22.RaytracedAO/main.cpp

Lines changed: 121 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ int main(int argc, char** argv)
311311
ext::MitsubaLoader::CElementFilm::FileFormat fileFormat;
312312
Renderer::DenoiserArgs denoiserInfo = {};
313313
int32_t highQualityEdges = 0u;
314+
bool envmap = false;
314315

315316
scene::CSceneNodeAnimatorCameraModifiedMaya* getInteractiveCameraAnimator()
316317
{
@@ -415,26 +416,46 @@ int main(int argc, char** argv)
415416
{
416417
std::cout << "[ERROR] film.outputFilePath's extension is not compatible with film.fileFormat" << std::endl;
417418
}
419+
// handle missing output path
420+
if (mainSensorData.outputFilePath.empty())
421+
{
422+
auto extensionStr = getFileExtensionFromFormat(mainSensorData.fileFormat);
423+
if(shouldHaveSensorIdxInFileName)
424+
mainSensorData.outputFilePath = std::filesystem::path("Render_" + mainFileName + "_Sensor_" + std::to_string(idx) + extensionStr);
425+
else
426+
mainSensorData.outputFilePath = std::filesystem::path("Render_" + mainFileName + extensionStr);
427+
}
418428

419429
mainSensorData.samplesNeeded = sensor.sampler.sampleCount;
420430
std::cout << "\t SamplesPerPixelNeeded = " << mainSensorData.samplesNeeded << std::endl;
421431

422432
const ext::MitsubaLoader::CElementSensor::PerspectivePinhole* persp = nullptr;
433+
const ext::MitsubaLoader::CElementSensor::Orthographic* ortho = nullptr;
423434
const ext::MitsubaLoader::CElementSensor::CameraBase* cameraBase = nullptr;
424435
switch (sensor.type)
425436
{
426437
case ext::MitsubaLoader::CElementSensor::Type::PERSPECTIVE:
427438
persp = &sensor.perspective;
428-
cameraBase = static_cast<const ext::MitsubaLoader::CElementSensor::CameraBase*>(&sensor.perspective);
439+
cameraBase = persp;
429440
std::cout << "\t Type = PERSPECTIVE" << std::endl;
430441
break;
431442
case ext::MitsubaLoader::CElementSensor::Type::THINLENS:
432443
persp = &sensor.thinlens;
433-
cameraBase = static_cast<const ext::MitsubaLoader::CElementSensor::CameraBase*>(&sensor.thinlens);
444+
cameraBase = persp;
434445
std::cout << "\t Type = THINLENS" << std::endl;
435446
break;
447+
case ext::MitsubaLoader::CElementSensor::Type::ORTHOGRAPHIC:
448+
ortho = &sensor.orthographic;
449+
cameraBase = ortho;
450+
std::cout << "\t Type = ORTHOGRAPHIC" << std::endl;
451+
break;
452+
case ext::MitsubaLoader::CElementSensor::Type::TELECENTRIC:
453+
ortho = &sensor.telecentric;
454+
cameraBase = ortho;
455+
std::cout << "\t Type = TELECENTRIC" << std::endl;
456+
break;
436457
case ext::MitsubaLoader::CElementSensor::Type::SPHERICAL:
437-
cameraBase = static_cast<const ext::MitsubaLoader::CElementSensor::CameraBase*>(&sensor.spherical);
458+
cameraBase = &sensor.spherical;
438459
std::cout << "\t Type = SPHERICAL" << std::endl;
439460
break;
440461
default:
@@ -508,72 +529,8 @@ int main(int argc, char** argv)
508529
float farClip = cameraBase->farClip;
509530
if(farClip > nearClip * 10'000.0f)
510531
std::cout << "[WARN] Depth Range is too big: nearClip = " << nearClip << ", farClip = " << farClip << std::endl;
511-
512-
if(mainSensorData.type == ext::MitsubaLoader::CElementSensor::Type::PERSPECTIVE || mainSensorData.type == ext::MitsubaLoader::CElementSensor::Type::THINLENS)
513-
{
514-
switch (persp->fovAxis)
515-
{
516-
case ext::MitsubaLoader::CElementSensor::PerspectivePinhole::FOVAxis::X:
517-
realFoVDegrees = convertFromXFoV(persp->fov);
518-
break;
519-
case ext::MitsubaLoader::CElementSensor::PerspectivePinhole::FOVAxis::Y:
520-
realFoVDegrees = persp->fov;
521-
break;
522-
case ext::MitsubaLoader::CElementSensor::PerspectivePinhole::FOVAxis::DIAGONAL:
523-
{
524-
float aspectDiag = tan(core::radians(persp->fov)*0.5f);
525-
float aspectY = aspectDiag/core::sqrt(1.f+aspectRatio*aspectRatio);
526-
realFoVDegrees = core::degrees(atan(aspectY)*2.f);
527-
}
528-
break;
529-
case ext::MitsubaLoader::CElementSensor::PerspectivePinhole::FOVAxis::SMALLER:
530-
if (width < height)
531-
realFoVDegrees = convertFromXFoV(persp->fov);
532-
else
533-
realFoVDegrees = persp->fov;
534-
break;
535-
case ext::MitsubaLoader::CElementSensor::PerspectivePinhole::FOVAxis::LARGER:
536-
if (width < height)
537-
realFoVDegrees = persp->fov;
538-
else
539-
realFoVDegrees = convertFromXFoV(persp->fov);
540-
break;
541-
default:
542-
realFoVDegrees = NAN;
543-
assert(false);
544-
break;
545-
}
546-
547-
if (mainSensorData.outputFilePath.empty())
548-
{
549-
auto extensionStr = getFileExtensionFromFormat(mainSensorData.fileFormat);
550-
if(shouldHaveSensorIdxInFileName)
551-
mainSensorData.outputFilePath = std::filesystem::path("Render_" + mainFileName + "_Sensor_" + std::to_string(idx) + extensionStr);
552-
else
553-
mainSensorData.outputFilePath = std::filesystem::path("Render_" + mainFileName + extensionStr);
554-
}
555532

556-
mainSensorData.staticCamera = smgr->addCameraSceneNode(nullptr);
557-
auto & staticCamera = mainSensorData.staticCamera;
558-
559-
staticCamera->setPosition(mainCamPos.getAsVector3df());
560-
561-
auto target = mainCamView+mainCamPos;
562-
std::cout << "\t Camera Target = <" << target.x << "," << target.y << "," << target.z << ">" << std::endl;
563-
staticCamera->setTarget(target.getAsVector3df());
564-
565-
if (core::dot(core::normalize(core::cross(staticCamera->getUpVector(),mainCamView)),core::cross(mainCamUp,mainCamView)).x<0.99f)
566-
staticCamera->setUpVector(mainCamUp);
567-
568-
if (mainSensorData.rightHandedCamera)
569-
staticCamera->setProjectionMatrix(core::matrix4SIMD::buildProjectionMatrixPerspectiveFovRH(core::radians(realFoVDegrees), aspectRatio, nearClip, farClip));
570-
else
571-
staticCamera->setProjectionMatrix(core::matrix4SIMD::buildProjectionMatrixPerspectiveFovLH(core::radians(realFoVDegrees), aspectRatio, nearClip, farClip));
572-
573-
mainSensorData.resetInteractiveCamera();
574-
sensors.push_back(mainSensorData);
575-
}
576-
else if (mainSensorData.type == ext::MitsubaLoader::CElementSensor::Type::SPHERICAL)
533+
if (mainSensorData.type == ext::MitsubaLoader::CElementSensor::Type::SPHERICAL)
577534
{
578535
nbl::core::vectorSIMDf camViews[6] =
579536
{
@@ -601,49 +558,42 @@ int main(int argc, char** argv)
601558
nbl::core::vectorSIMDf(0, +1, 0, 0), // +Y
602559
};
603560

604-
const std::string suffixes[6] =
605-
{
606-
std::string("_x+"),
607-
std::string("_x-"),
608-
std::string("_y+"),
609-
std::string("_y-"),
610-
std::string("_z+"),
611-
std::string("_z-"),
612-
};
613-
614561
CubemapRender cubemapRender = {};
615562
cubemapRender.sensorIdx = sensors.size();
616563
cubemapRenders.push_back(cubemapRender);
617564

618565
for(uint32_t i = 0; i < 6; ++i)
619566
{
620567
SensorData cubemapFaceSensorData = mainSensorData;
621-
cubemapFaceSensorData.width = mainSensorData.width + mainSensorData.highQualityEdges * 2;
622-
cubemapFaceSensorData.height = mainSensorData.height + mainSensorData.highQualityEdges * 2;
568+
cubemapFaceSensorData.envmap = true;
569+
623570
if(mainSensorData.width != mainSensorData.height)
624571
{
625572
std::cout << "[ERROR] Cannot generate cubemap faces where film.width and film.height are not equal. (Aspect Ration must be 1)" << std::endl;
626573
assert(false);
627574
}
575+
const auto baseResolution = core::max(mainSensorData.width,mainSensorData.height);
576+
cubemapFaceSensorData.width = baseResolution + mainSensorData.highQualityEdges * 2;
577+
cubemapFaceSensorData.height = baseResolution + mainSensorData.highQualityEdges * 2;
628578

629-
if (cubemapFaceSensorData.outputFilePath.empty())
630-
{
631-
if(shouldHaveSensorIdxInFileName)
632-
cubemapFaceSensorData.outputFilePath = std::filesystem::path("Render_" + mainFileName + "_Sensor_" + std::to_string(idx) + suffixes[i]);
633-
else
634-
cubemapFaceSensorData.outputFilePath = std::filesystem::path("Render_" + mainFileName + suffixes[i]);
635-
636-
}
637-
else
579+
// FIXME: suffix added after extension
580+
cubemapFaceSensorData.outputFilePath.replace_extension();
581+
constexpr const char* suffixes[6] =
638582
{
639-
cubemapFaceSensorData.outputFilePath += (suffixes[i]);
640-
}
583+
"_x+.exr",
584+
"_x-.exr",
585+
"_y+.exr",
586+
"_y-.exr",
587+
"_z+.exr",
588+
"_z-.exr",
589+
};
590+
cubemapFaceSensorData.outputFilePath += suffixes[i];
641591

642592
cubemapFaceSensorData.staticCamera = smgr->addCameraSceneNode(nullptr);
643-
auto & staticCamera = cubemapFaceSensorData.staticCamera;
593+
auto& staticCamera = cubemapFaceSensorData.staticCamera;
644594

645-
const auto & camView = camViews[i];
646-
const auto & upVector = upVectors[i];
595+
const auto& camView = camViews[i];
596+
const auto& upVector = upVectors[i];
647597

648598
staticCamera->setPosition(mainCamPos.getAsVector3df());
649599
staticCamera->setTarget((mainCamPos + camView).getAsVector3df());
@@ -663,6 +613,81 @@ int main(int argc, char** argv)
663613
sensors.push_back(cubemapFaceSensorData);
664614
}
665615
}
616+
else
617+
{
618+
mainSensorData.staticCamera = smgr->addCameraSceneNode(nullptr);
619+
auto& staticCamera = mainSensorData.staticCamera;
620+
621+
staticCamera->setPosition(mainCamPos.getAsVector3df());
622+
623+
{
624+
auto target = mainCamView+mainCamPos;
625+
std::cout << "\t Camera Target = <" << target.x << "," << target.y << "," << target.z << ">" << std::endl;
626+
staticCamera->setTarget(target.getAsVector3df());
627+
}
628+
629+
if (core::dot(core::normalize(core::cross(staticCamera->getUpVector(),mainCamView)),core::cross(mainCamUp,mainCamView)).x<0.99f)
630+
staticCamera->setUpVector(mainCamUp);
631+
632+
//
633+
if (ortho)
634+
{
635+
const auto scale = sensor.transform.matrix.extractSub3x4().getScale();
636+
const float volumeX = 2.f*scale.x;
637+
const float volumeY = (2.f/aspectRatio)*scale.y;
638+
if (mainSensorData.rightHandedCamera)
639+
staticCamera->setProjectionMatrix(core::matrix4SIMD::buildProjectionMatrixOrthoRH(volumeX, volumeY, nearClip, farClip));
640+
else
641+
staticCamera->setProjectionMatrix(core::matrix4SIMD::buildProjectionMatrixOrthoLH(volumeX, volumeY, nearClip, farClip));
642+
}
643+
else if (persp)
644+
{
645+
switch (persp->fovAxis)
646+
{
647+
case ext::MitsubaLoader::CElementSensor::PerspectivePinhole::FOVAxis::X:
648+
realFoVDegrees = convertFromXFoV(persp->fov);
649+
break;
650+
case ext::MitsubaLoader::CElementSensor::PerspectivePinhole::FOVAxis::Y:
651+
realFoVDegrees = persp->fov;
652+
break;
653+
case ext::MitsubaLoader::CElementSensor::PerspectivePinhole::FOVAxis::DIAGONAL:
654+
{
655+
float aspectDiag = tan(core::radians(persp->fov)*0.5f);
656+
float aspectY = aspectDiag/core::sqrt(1.f+aspectRatio*aspectRatio);
657+
realFoVDegrees = core::degrees(atan(aspectY)*2.f);
658+
}
659+
break;
660+
case ext::MitsubaLoader::CElementSensor::PerspectivePinhole::FOVAxis::SMALLER:
661+
if (width < height)
662+
realFoVDegrees = convertFromXFoV(persp->fov);
663+
else
664+
realFoVDegrees = persp->fov;
665+
break;
666+
case ext::MitsubaLoader::CElementSensor::PerspectivePinhole::FOVAxis::LARGER:
667+
if (width < height)
668+
realFoVDegrees = persp->fov;
669+
else
670+
realFoVDegrees = convertFromXFoV(persp->fov);
671+
break;
672+
default:
673+
realFoVDegrees = NAN;
674+
assert(false);
675+
break;
676+
}
677+
678+
if (mainSensorData.rightHandedCamera)
679+
staticCamera->setProjectionMatrix(core::matrix4SIMD::buildProjectionMatrixPerspectiveFovRH(core::radians(realFoVDegrees), aspectRatio, nearClip, farClip));
680+
else
681+
staticCamera->setProjectionMatrix(core::matrix4SIMD::buildProjectionMatrixPerspectiveFovLH(core::radians(realFoVDegrees), aspectRatio, nearClip, farClip));
682+
}
683+
else
684+
{
685+
assert(false);
686+
}
687+
688+
mainSensorData.resetInteractiveCamera();
689+
sensors.push_back(mainSensorData);
690+
}
666691

667692
return true;
668693
};
@@ -768,7 +793,7 @@ int main(int argc, char** argv)
768793

769794
driver->beginScene(false, false);
770795

771-
if(!renderer->render(device->getTimer()))
796+
if(!renderer->render(device->getTimer(),!sensorData.envmap))
772797
{
773798
renderFailed = true;
774799
driver->endScene();
@@ -909,7 +934,7 @@ int main(int argc, char** argv)
909934
}
910935

911936
driver->beginScene(false, false);
912-
if(!renderer->render(device->getTimer(),receiver.isRenderingBeauty()))
937+
if(!renderer->render(device->getTimer(),true,receiver.isRenderingBeauty()))
913938
{
914939
renderFailed = true;
915940
driver->endScene();

0 commit comments

Comments
 (0)