Skip to content

Commit

Permalink
linear acceleration
Browse files Browse the repository at this point in the history
  • Loading branch information
ChenxiZhou0619 committed Mar 10, 2023
1 parent cf43362 commit 3f1bf20
Show file tree
Hide file tree
Showing 14 changed files with 247 additions and 69 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ add_executable(Moer

src/CoreLayer/Math/Transform.cpp

src/FunctionLayer/Acceleration/EmbreeBVH.cpp
src/FunctionLayer/Acceleration/AABB.cpp
src/FunctionLayer/Acceleration/Acceleration.cpp
src/FunctionLayer/Acceleration/EmbreeBVH.cpp
src/FunctionLayer/Acceleration/Linear.cpp

src/FunctionLayer/Integrator/NormalIntegrator.cpp
src/FunctionLayer/Integrator/DirectIntegrator.cpp
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Moer-lite的框架基于Moer主干:https://github.com/NJUCG/Moer .
- 修改了Triangle.cpp中的bug(之前当mesh文件不存在法线和纹理信息时会发生段错误)
- 对AABB进行封装(见Shape::getAABB)
- Scene::rayIntersect、Shape::rayIntersectShape、Acceleration::rayIntersect、Integrator::li中const Ray& 修改为Ray&
- 修改了Acceleration求交的接口,现在每个加速结构需要实现bool Acceleration::rayIntersect(Ray &ray, int *geomID, int *primID, float *u, float *v) const函数

## TODO
- 对mesh和sphere实现表面采样(目前只有parallelogram可以配置为面光源)
27 changes: 27 additions & 0 deletions src/FunctionLayer/Acceleration/Acceleration.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "Acceleration.h"
#include "EmbreeBVH.h"
#include "Linear.h"

// Default acceleration type is embree
AccelerationType Acceleration::type = AccelerationType::Embree;

std::map<std::string, AccelerationType> accelerationTypeMap = {
{"embree", AccelerationType::Embree}, {"linear", AccelerationType::Linear}};

std::map<AccelerationType, std::function<std::shared_ptr<Acceleration>()>>
accelerationBuildMap = {
{AccelerationType::Embree, std::make_shared<EmbreeBVH>},
{AccelerationType::Linear, std::make_shared<LinearAcceleration>}};

void Acceleration::setAccelerationType(std::string type) {
if (accelerationTypeMap.count(type) == 0) {
std::cerr << "Unkown acceleration type " << type << "!\n";
exit(1);
}
std::cout << "Using acceleration type " << type << "\n";
Acceleration::type = accelerationTypeMap[type];
}

std::shared_ptr<Acceleration> Acceleration::createAcceleration() {
return accelerationBuildMap[Acceleration::type]();
}
31 changes: 25 additions & 6 deletions src/FunctionLayer/Acceleration/Acceleration.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,44 @@
#include <FunctionLayer/Shape/Shape.h>
#include <optional>
#include <vector>

enum class AccelerationType { Embree, Linear };

//* 所有空间加速结构的基类
class Acceleration {
public:
Acceleration() = default;

virtual ~Acceleration() = default;

static void setAccelerationType(std::string type);

static std::shared_ptr<Acceleration> createAcceleration();

std::optional<Intersection> rayIntersect(Ray &ray) const {
int primID, geomID = -1;
float u, v;
bool hit = rayIntersect(ray, &geomID, &primID, &u, &v);
if (!hit)
return std::nullopt;
Intersection its;
shapes[geomID]->fillIntersection(ray.tFar, primID, u, v, &its);
return std::make_optional(its);
}

//* 所有空间加速结构需要实现的接口
virtual std::optional<Intersection> rayIntersect(Ray &ray) const = 0;
virtual bool rayIntersect(Ray &ray, int *geomID, int *primID, float *u,
float *v) const = 0;

//* 根据场景中的所有几何体构建加速结构
virtual void build() = 0;

//* 向加速结构中增加一个几何体
void attachShape(std::shared_ptr<Shape> shape) {
shape->geometryID = shapes.size();
shapes.emplace_back(shape);
}
void attachShape(std::shared_ptr<Shape> shape) { shapes.emplace_back(shape); }

public:
static AccelerationType type;

protected:
std::vector<std::shared_ptr<Shape>> shapes; //* 场景中的所有几何体
};
};
15 changes: 8 additions & 7 deletions src/FunctionLayer/Acceleration/EmbreeBVH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ void EmbreeBVH::build() {
rtcCommitScene(scene);
}

std::optional<Intersection> EmbreeBVH::rayIntersect(Ray &ray) const {
bool EmbreeBVH::rayIntersect(Ray &ray, int *geomID, int *primID, float *u,
float *v) const {
RTCIntersectContext context;
RTCRayHit rtcRayHit;
rtcInitIntersectContext(&context);
Expand All @@ -40,13 +41,13 @@ std::optional<Intersection> EmbreeBVH::rayIntersect(Ray &ray) const {

//* 如果光线与加速结构没有交点
if (rtcRayHit.hit.geomID == RTC_INVALID_GEOMETRY_ID)
return std::nullopt;
return false;

//* 有交点,填充intersection数据结构
ray.tFar = rtcRayHit.ray.tfar;
auto shape = shapes[rtcRayHit.hit.geomID];
Intersection intersection;
shape->fillIntersection(rtcRayHit.ray.tfar, rtcRayHit.hit.primID,
rtcRayHit.hit.u, rtcRayHit.hit.v, &intersection);
return std::make_optional(intersection);
*geomID = rtcRayHit.hit.geomID;
*primID = rtcRayHit.hit.primID;
*u = rtcRayHit.hit.u;
*v = rtcRayHit.hit.v;
return true;
}
3 changes: 2 additions & 1 deletion src/FunctionLayer/Acceleration/EmbreeBVH.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ class EmbreeBVH : public Acceleration {

virtual void build() override;

virtual std::optional<Intersection> rayIntersect(Ray &ray) const override;
virtual bool rayIntersect(Ray &ray, int *geomID, int *primID, float *u,
float *v) const override;

private:
//* 通过RTCDevice和RTCScene调用embree
Expand Down
19 changes: 8 additions & 11 deletions src/FunctionLayer/Acceleration/Linear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,18 @@ LinearAcceleration::LinearAcceleration() {
}

void LinearAcceleration::build() {
// do nothing
for (auto shape : shapes)
shape->initInternalAcceleration();
}

std::optional<Intersection> LinearAcceleration::rayIntersect(Ray &ray) const {
bool LinearAcceleration::rayIntersect(Ray &ray, int *geomID, int *primID,
float *u, float *v) const {
// Just traverse all shapes in the scene
float u, v;
int primID, geomID = -1;

for (const auto shape : shapes) {
if (shape->rayIntersectShape(ray, &primID, &u, &v)) {
geomID = shape->geometryID;
if (shape->rayIntersectShape(ray, primID, u, v)) {
*geomID = shape->geometryID;
}
}
if (geomID == -1)
return std::nullopt;
Intersection its;
shapes[geomID]->fillIntersection(ray.tFar, primID, u, v, &its);
return std::make_optional(its);
return (*geomID != -1);
}
3 changes: 2 additions & 1 deletion src/FunctionLayer/Acceleration/Linear.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ class LinearAcceleration : public Acceleration {

virtual void build() override;

virtual std::optional<Intersection> rayIntersect(Ray &ray) const override;
virtual bool rayIntersect(Ray &ray, int *geomID, int *primID, float *u,
float *v) const override;
};
10 changes: 8 additions & 2 deletions src/FunctionLayer/Scene/Scene.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
#include "Scene.h"
#include <FunctionLayer/Acceleration/EmbreeBVH.h>
#include <FunctionLayer/Acceleration/Linear.h>
#include <FunctionLayer/Light/AreaLight.h>
#include <ResourceLayer/Factory.h>

Scene::Scene(const Json &json) {
//* 初始化加速结构
acceleration = std::make_shared<EmbreeBVH>();
//* 初始化加速结构,默认使用embree
std::string accelerationType =
fetchOptional<std::string>(json, "acceleration", "embree");
Acceleration::setAccelerationType(accelerationType);
acceleration = Acceleration::createAcceleration();

//* 添加几何体
auto shapes = json["shapes"];
for (int i = 0; i < shapes.size(); ++i) {
auto shape = Factory::construct_class<Shape>(shapes[i]);
shape->geometryID = i;
acceleration->attachShape(shape);
}
//* 添加光源
Expand Down
6 changes: 6 additions & 0 deletions src/FunctionLayer/Shape/Shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ class Shape : public Transformable {
virtual void uniformSampleOnSurface(Vector2f sample, Intersection *result,
float *pdf) const = 0;

//* 当不使用embree时,TriangleMesh需要实现内部加速结构,调用该方法
virtual void initInternalAcceleration() {
// Default do nothing
return;
}

public:
int geometryID;
std::shared_ptr<Light> light;
Expand Down
Loading

0 comments on commit 3f1bf20

Please sign in to comment.