diff --git a/src/core/camera.cpp b/src/core/camera.cpp index 26145508..0b991d75 100644 --- a/src/core/camera.cpp +++ b/src/core/camera.cpp @@ -4,15 +4,24 @@ KRR_NAMESPACE_BEGIN bool Camera::update(){ - if (mPreserveHeight) - mData.filmSize[0] = mData.aspectRatio * mData.filmSize[1]; + if (mScene.lock()->getSceneRT()) { + /* Ray-tracing enabled, update medium info */ + for (auto medium : mScene.lock()->getMedia()) { + if (medium->getNode()->getGlobalBoundingBox().contains(getPosition())) { + mData.medium = + mScene.lock()->getSceneRT()->getMediumData()[medium->getMediumId()]; + } + } + } + /* Update parameters in data. */ + if (mPreserveHeight) mData.filmSize[0] = mData.aspectRatio * mData.filmSize[1]; else mData.filmSize[1] = mData.filmSize[0] / mData.aspectRatio; float fovY = atan2(mData.filmSize[1] * 0.5, mData.focalLength); mData.w = normalize(mData.target - mData.pos) * mData.focalDistance; mData.u = normalize(cross(mData.w, mData.up)) * tan(fovY) * mData.focalDistance * mData.aspectRatio; mData.v = normalize(cross(mData.u, mData.w)) * tan(fovY) * mData.focalDistance; - bool hasChanges = (bool)memcmp(&mData, &mDataPrev, sizeof(CameraData));; + bool hasChanges = (bool)memcmp(&mData, &mDataPrev, sizeof(rt::CameraData));; mDataPrev = mData; return hasChanges; } diff --git a/src/core/camera.h b/src/core/camera.h index f5ceed46..e707ec14 100644 --- a/src/core/camera.h +++ b/src/core/camera.h @@ -6,54 +6,56 @@ KRR_NAMESPACE_BEGIN using namespace io; +class Scene; + +namespace rt { +struct CameraData { + Vector2f filmSize{42.666667f, 24.0f}; // sensor size in mm [width, height] + float focalLength{21}; // distance from sensor to lens, in mm + float focalDistance{10}; // distance from lens to focal point, in scene units (m) + float lensRadius{0}; // aperture radius, in mm + float aspectRatio{1.777777f}; // width divides height + + Vector3f pos{0, 0, 0}; + Vector3f target{0, 0, -1}; + Vector3f up{0, 1, 0}; + + Vector3f u{1, 0, 0}; // camera right [dependent to aspect ratio] + Vector3f v{0, 1, 0}; // camera up [dependent to aspect ratio] + Vector3f w{0, 0, -1}; // camera forward + + Medium medium{nullptr}; // the ray is inside the medium + + KRR_CALLABLE Ray getRay(Vector2i pixel, Vector2i frameSize, Sampler &sampler) { + Ray ray; + /* 1. Statified sample on the film plane (within the fragment) */ + Vector2f p = + (Vector2f) pixel + Vector2f(0.5f) + sampler.get2D(); // uniform sample + box filter + Vector2f ndc = Vector2f(2 * p) / Vector2f(frameSize) + Vector2f(-1.f); // ndc in [-1, 1]^2 + if (lensRadius > 0) { /*Thin lens*/ + /* 2. Sample the lens (uniform) */ + Vector3f focalPoint = pos + ndc[0] * u + ndc[1] * v + w; + Vector2f apertureSample = + lensRadius > M_EPSILON ? uniformSampleDisk(sampler.get2D()) : Vector2f::Zero(); + ray.origin = pos + lensRadius * (apertureSample[0] * normalize(u) + + apertureSample[1] * normalize(v)); + ray.dir = normalize(focalPoint - ray.origin); + } else { /*Pin hole*/ + ray.origin = pos; + ray.dir = normalize(ndc[0] * u + ndc[1] * v + w); + } + ray.medium = medium; + return ray; + } + + KRR_CLASS_DEFINE(CameraData, pos, target, up, focalLength, focalDistance, lensRadius, + aspectRatio); +}; +} // namespace rt class Camera { public: using SharedPtr = std::shared_ptr; - - struct CameraData { - Vector2f filmSize{ 42.666667f, 24.0f }; // sensor size in mm [width, height] - float focalLength{ 21 }; // distance from sensor to lens, in mm - float focalDistance{ 10 }; // distance from lens to focal point, in scene units (m) - float lensRadius{ 0 }; // aperture radius, in mm - float aspectRatio{ 1.777777f }; // width divides height - - Vector3f pos{ 0, 0, 0 }; - Vector3f target{ 0, 0, -1 }; - Vector3f up{ 0, 1, 0 }; - - Vector3f u{ 1, 0, 0 }; // camera right [dependent to aspect ratio] - Vector3f v{ 0, 1, 0 }; // camera up [dependent to aspect ratio] - Vector3f w{ 0, 0, -1 }; // camera forward - - Medium medium{nullptr}; // the ray is inside the medium - - KRR_CALLABLE Ray getRay(Vector2i pixel, Vector2i frameSize, Sampler& sampler) { - Ray ray; - /* 1. Statified sample on the film plane (within the fragment) */ - Vector2f p = - (Vector2f) pixel + Vector2f(0.5f) + sampler.get2D(); // uniform sample + box filter - Vector2f ndc = - Vector2f(2 * p) / Vector2f(frameSize) + Vector2f(-1.f); // ndc in [-1, 1]^2 - if (lensRadius > 0) { /*Thin lens*/ - /* 2. Sample the lens (uniform) */ - Vector3f focalPoint = pos + ndc[0] * u + ndc[1] * v + w; - Vector2f apertureSample = - lensRadius > M_EPSILON ? uniformSampleDisk(sampler.get2D()) : Vector2f::Zero(); - ray.origin = pos + lensRadius * (apertureSample[0] * normalize(u) + - apertureSample[1] * normalize(v)); - ray.dir = normalize(focalPoint - ray.origin); - } else { /*Pin hole*/ - ray.origin = pos; - ray.dir = normalize(ndc[0] * u + ndc[1] * v + w); - } - ray.medium = medium; - return ray; - } - - KRR_CLASS_DEFINE(CameraData, pos, target, up, focalLength, focalDistance, lensRadius, aspectRatio); - }; - Camera() = default; bool update(); @@ -66,17 +68,18 @@ class Camera { KRR_CALLABLE Vector3f getUp() const { return normalize(mData.v); } KRR_CALLABLE Vector3f getRight() const { return normalize(mData.u); } KRR_CALLABLE Vector2f getFilmSize() const { return mData.filmSize; } - KRR_CALLABLE float getfocalDistance() const { return mData.focalDistance; } - KRR_CALLABLE float getfocalLength() const { return mData.focalLength; } - KRR_CALLABLE const CameraData& getCameraData() const { return mData; } + KRR_CALLABLE float getFocalDistance() const { return mData.focalDistance; } + KRR_CALLABLE float getFocalLength() const { return mData.focalLength; } + KRR_CALLABLE const rt::CameraData& getCameraData() const { return mData; } KRR_CALLABLE void setAspectRatio(float aspectRatio) { mData.aspectRatio = aspectRatio; } KRR_CALLABLE void setFilmSize(Vector2f& size) { mData.filmSize = size; } - KRR_CALLABLE void setfocalDistance(float focalDistance) { mData.focalDistance = focalDistance; } - KRR_CALLABLE void setfocalLength(float focalLength) { mData.focalLength = focalLength; } + KRR_CALLABLE void setFocalDistance(float focalDistance) { mData.focalDistance = focalDistance; } + KRR_CALLABLE void setFocalLength(float focalLength) { mData.focalLength = focalLength; } KRR_CALLABLE void setPosition(Vector3f& pos) { mData.pos = pos; } KRR_CALLABLE void setTarget(Vector3f& target) { mData.target = target; } KRR_CALLABLE void setUp(Vector3f& up) { mData.up = up; } + KRR_CALLABLE void setScene(std::weak_ptr scene) { mScene = scene; } Matrix4f getViewMatrix() const; Matrix4f getProjectionMatrix() const; @@ -84,7 +87,8 @@ class Camera { protected: KRR_CLASS_DEFINE(Camera, mData); - CameraData mData, mDataPrev; + std::weak_ptr mScene; + rt::CameraData mData, mDataPrev; bool mHasChanges = false; bool mPreserveHeight = true; // preserve sensor height on aspect ratio changes. }; diff --git a/src/core/scene.cpp b/src/core/scene.cpp index 51000765..120f0a4d 100644 --- a/src/core/scene.cpp +++ b/src/core/scene.cpp @@ -16,15 +16,24 @@ Scene::Scene() { bool Scene::update(size_t frameIndex, double currentTime) { bool hasChanges = false; - if (mCameraController) hasChanges |= mCameraController->update(); - if (mCamera) hasChanges |= mCamera->update(); if (mEnableAnimation) mGraph->animate(currentTime); mGraph->update(frameIndex); + if (mCameraController) hasChanges |= mCameraController->update(); + if (mCamera) hasChanges |= mCamera->update(); if (mSceneRT) mSceneRT->update(); if (mSceneVK) mSceneVK->update(); return mHasChanges = hasChanges; } +void Scene::setCamera(Camera::SharedPtr camera) { + mCamera = camera; + camera->setScene(shared_from_this()); +} + +void Scene::setCameraController(OrbitCameraController::SharedPtr cameraController) { + mCameraController = cameraController; +} + void Scene::renderUI() { if (ui::TreeNode("Statistics")) { ui::Text("Meshes: %d", getMeshes().size()); diff --git a/src/core/scene.h b/src/core/scene.h index 8bb9e74d..99d3407e 100644 --- a/src/core/scene.h +++ b/src/core/scene.h @@ -50,10 +50,8 @@ class Scene : public std::enable_shared_from_this { void addMesh(Mesh::SharedPtr mesh) { mGraph->addMesh(mesh); } void addMaterial(Material::SharedPtr material) { mGraph->addMaterial(material); } - void setCamera(Camera::SharedPtr camera) { mCamera = camera; } - void setCameraController(OrbitCameraController::SharedPtr cameraController) { - mCameraController = cameraController; - } + void setCamera(Camera::SharedPtr camera); + void setCameraController(OrbitCameraController::SharedPtr cameraController); json getConfig() const { return mConfig; } void setConfig(const json &config, bool update = true); diff --git a/src/core/scenegraph.h b/src/core/scenegraph.h index 3dabdb67..f497300b 100644 --- a/src/core/scenegraph.h +++ b/src/core/scenegraph.h @@ -22,7 +22,7 @@ class SceneGraphLeaf { SceneGraphNode *getNode() const { return mNode.lock().get(); } std::shared_ptr getNodeSharedPtr() const { return mNode.lock(); } - virtual AABB getLocalBoundingBox() const { return AABB(); } + virtual AABB getLocalBoundingBox() const { return AABB(0, 0); } virtual std::shared_ptr clone() = 0; virtual void renderUI() {} diff --git a/src/render/passes/gbuffer/device.h b/src/render/passes/gbuffer/device.h index 22f43cc6..3bc3e492 100644 --- a/src/render/passes/gbuffer/device.h +++ b/src/render/passes/gbuffer/device.h @@ -14,7 +14,7 @@ struct LaunchParameters { size_t frameIndex; rt::SceneData sceneData; - Camera::CameraData cameraData; + rt::CameraData cameraData; OptixTraversableHandle traversable; }; diff --git a/src/render/path/device.cu b/src/render/path/device.cu index 9e2b229c..9da68c4a 100644 --- a/src/render/path/device.cu +++ b/src/render/path/device.cu @@ -185,7 +185,7 @@ extern "C" __global__ void KRR_RT_RG(Pathtracer)(){ const uint frameID = launchParams.frameID; const uint32_t fbIndex = pixel[0] + pixel[1] * launchParams.fbSize[0]; - Camera::CameraData camera = launchParams.camera; + rt::CameraData camera = launchParams.camera; PCGSampler sampler; sampler.setPixelSample(pixel, frameID); sampler.advance(fbIndex * 256); diff --git a/src/render/path/path.h b/src/render/path/path.h index cfdeb89a..4693d1fb 100644 --- a/src/render/path/path.h +++ b/src/render/path/path.h @@ -40,7 +40,7 @@ struct LaunchParameters { int spp = 1; int lightSamples = 1; // scene - Camera::CameraData camera; + rt::CameraData camera; LightSampler lightSampler; rt::SceneData sceneData; const RGBColorSpace *colorSpace; diff --git a/src/render/spectrum.h b/src/render/spectrum.h index 42024626..d95a56e9 100644 --- a/src/render/spectrum.h +++ b/src/render/spectrum.h @@ -151,7 +151,7 @@ class RGBUnboundedSpectrum { KRR_CALLABLE float maxValue() const { return scale * rsp.maxValue(); } KRR_CALLABLE RGBUnboundedSpectrum(): rsp(0, 0, 0), scale(0) {} - KRR_CALLABLE RGBUnboundedSpectrum::RGBUnboundedSpectrum(RGB rgb, const RGBColorSpace &cs); + KRR_CALLABLE RGBUnboundedSpectrum(RGB rgb, const RGBColorSpace &cs); KRR_CALLABLE SampledSpectrum sample(const SampledWavelengths &lambda) const { SampledSpectrum result; diff --git a/src/render/wavefront/integrator.cpp b/src/render/wavefront/integrator.cpp index 66523746..11d75887 100644 --- a/src/render/wavefront/integrator.cpp +++ b/src/render/wavefront/integrator.cpp @@ -36,7 +36,7 @@ void WavefrontPathTracer::initialize() { else mediumScatterQueue = alloc.new_object(maxQueueSize, alloc); } cudaDeviceSynchronize(); - if (!camera) camera = alloc.new_object(); + if (!camera) camera = alloc.new_object(); CUDA_SYNC_CHECK(); } @@ -199,7 +199,7 @@ void WavefrontPathTracer::setScene(Scene::SharedPtr scene) { void WavefrontPathTracer::beginFrame(RenderContext* context) { if (!mScene || !maxQueueSize) return; PROFILE("Begin frame"); - cudaMemcpyAsync(camera, &mScene->getCamera()->getCameraData(), sizeof(Camera::CameraData), + cudaMemcpyAsync(camera, &mScene->getCamera()->getCameraData(), sizeof(rt::CameraData), cudaMemcpyHostToDevice, 0); size_t frameIndex = getFrameIndex(); auto frameSize = getFrameSize(); diff --git a/src/render/wavefront/integrator.h b/src/render/wavefront/integrator.h index 1f289249..baf3e6e0 100644 --- a/src/render/wavefront/integrator.h +++ b/src/render/wavefront/integrator.h @@ -58,7 +58,7 @@ class WavefrontPathTracer : public RenderPass { OptixBackend *backend{ }; - Camera::CameraData* camera{ }; + rt::CameraData* camera{ }; LightSampler lightSampler; // work queues diff --git a/src/scene/krrscene.cpp b/src/scene/krrscene.cpp index 0c5bbcc4..354afbf5 100644 --- a/src/scene/krrscene.cpp +++ b/src/scene/krrscene.cpp @@ -59,10 +59,10 @@ bool SceneImporter::import(const json &j, Scene::SharedPtr scene, SceneGraphNode } if (j.contains("camera")) { - scene->mCamera = std::make_shared(j.at("camera")); - scene->mCameraController = - std::make_shared(j.at("cameraController")); - scene->mCameraController->setCamera(scene->mCamera); + scene->setCamera(std::make_shared(j.at("camera"))); + scene->setCameraController( + std::make_shared(j.at("cameraController"))); + scene->getCameraController()->setCamera(scene->mCamera); } if (j.contains("model")) {