Skip to content

Commit

Permalink
allow camera to enter a medium
Browse files Browse the repository at this point in the history
  • Loading branch information
cuteday committed Nov 11, 2023
1 parent 22a1ef6 commit 6ede06b
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 71 deletions.
15 changes: 12 additions & 3 deletions src/core/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
104 changes: 54 additions & 50 deletions src/core/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Camera>;

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();
Expand All @@ -66,25 +68,27 @@ 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> scene) { mScene = scene; }

Matrix4f getViewMatrix() const;
Matrix4f getProjectionMatrix() const;
Matrix4f getViewProjectionMatrix() const;

protected:
KRR_CLASS_DEFINE(Camera, mData);
CameraData mData, mDataPrev;
std::weak_ptr<Scene> mScene;
rt::CameraData mData, mDataPrev;
bool mHasChanges = false;
bool mPreserveHeight = true; // preserve sensor height on aspect ratio changes.
};
Expand Down
13 changes: 11 additions & 2 deletions src/core/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
6 changes: 2 additions & 4 deletions src/core/scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,8 @@ class Scene : public std::enable_shared_from_this<Scene> {
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);
Expand Down
2 changes: 1 addition & 1 deletion src/core/scenegraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class SceneGraphLeaf {

SceneGraphNode *getNode() const { return mNode.lock().get(); }
std::shared_ptr<SceneGraphNode> getNodeSharedPtr() const { return mNode.lock(); }
virtual AABB getLocalBoundingBox() const { return AABB(); }
virtual AABB getLocalBoundingBox() const { return AABB(0, 0); }
virtual std::shared_ptr<SceneGraphLeaf> clone() = 0;
virtual void renderUI() {}

Expand Down
2 changes: 1 addition & 1 deletion src/render/passes/gbuffer/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct LaunchParameters<GBufferPass> {
size_t frameIndex;

rt::SceneData sceneData;
Camera::CameraData cameraData;
rt::CameraData cameraData;
OptixTraversableHandle traversable;
};

Expand Down
2 changes: 1 addition & 1 deletion src/render/path/device.cu
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/render/path/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct LaunchParameters<MegakernelPathTracer> {
int spp = 1;
int lightSamples = 1;
// scene
Camera::CameraData camera;
rt::CameraData camera;
LightSampler lightSampler;
rt::SceneData sceneData;
const RGBColorSpace *colorSpace;
Expand Down
2 changes: 1 addition & 1 deletion src/render/spectrum.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/render/wavefront/integrator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void WavefrontPathTracer::initialize() {
else mediumScatterQueue = alloc.new_object<MediumScatterQueue>(maxQueueSize, alloc);
}
cudaDeviceSynchronize();
if (!camera) camera = alloc.new_object<Camera::CameraData>();
if (!camera) camera = alloc.new_object<rt::CameraData>();
CUDA_SYNC_CHECK();
}

Expand Down Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion src/render/wavefront/integrator.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class WavefrontPathTracer : public RenderPass {


OptixBackend *backend{ };
Camera::CameraData* camera{ };
rt::CameraData* camera{ };
LightSampler lightSampler;

// work queues
Expand Down
8 changes: 4 additions & 4 deletions src/scene/krrscene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ bool SceneImporter::import(const json &j, Scene::SharedPtr scene, SceneGraphNode
}

if (j.contains("camera")) {
scene->mCamera = std::make_shared<Camera>(j.at("camera"));
scene->mCameraController =
std::make_shared<OrbitCameraController>(j.at("cameraController"));
scene->mCameraController->setCamera(scene->mCamera);
scene->setCamera(std::make_shared<Camera>(j.at("camera")));
scene->setCameraController(
std::make_shared<OrbitCameraController>(j.at("cameraController")));
scene->getCameraController()->setCamera(scene->mCamera);
}

if (j.contains("model")) {
Expand Down

0 comments on commit 6ede06b

Please sign in to comment.