欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

【UE4】GAMES101 图形学作业6:通过BVH划分算法加速求交

最编程 2024-08-14 11:46:10
...
  • 文件目录
    /GAMES101/Source/GAMES101/Assignment6 ├─ Hw6_Main.cpp ├─ Hw6_Main.h ├─ BVHAccel.cpp - ├─ BVHAccel.h ├─ Hw6_MeshTriangle.cpp ├─ Hw6_MeshTriangle.h ├─ Bounds3.h ├─ Hw6_Global.h └─ ObjectInterface.h
  • class AHw6_Main : public AActor 入口和渲染
    void InitialScene(); //初始化场景组件 void buildBVHTree(); //构建 BVH 树 Intersection intersect(const Ray& ray) const; //求交 void Render(); //渲染入口,计算光线属性,更新贴图 FVector castRay(const Ray &ray, int depth); //光照计算 FVector reflect(const FVector& I, const FVector& N); //反射 FVector refract(const FVector& I, const FVector& N, const float& ior); //折射 float fresnel(const FVector& I, const FVector& N, const float& ior); //菲涅尔 void CreateTexture(); //贴图相关
  • class UBVHBuildNode : public UObjectBVH 节点
    Bounds3 bounds; //区域范围 UBVHBuildNode* left; //左节点 UBVHBuildNode* right; //右节点 TScriptInterface<IObjectInterface> object; //区域内的物体
  • class UBVHAccel : public UObject BVH 加速树
    //初始化 void Init(TArray<TScriptInterface<IObjectInterface>> p, int maxPrimsInNode = 1, SplitMethod splitMethod = SplitMethod::NAIVE, bool _bDraw = false); Intersection Intersect(const Ray& ray) const; //求交,本质还是调用 getIntersection Intersection getIntersection(UBVHBuildNode* node, const Ray& ray)const; //二叉树搜索求交 UBVHBuildNode* recursiveBuild(TArray<TScriptInterface<IObjectInterface>> objects); 构建节点,可递归 UPROPERTY() UBVHBuildNode* root; UPROPERTY() TArray<TScriptInterface<IObjectInterface>> primitives; bool IntersectP(const Ray& ray) const; //无用
  • class Bounds3 表示包围盒空间范围的类
    FVector pMin, pMax; // two points to specify the bounding box Bounds3() //三种构造方法 Bounds3(const FVector p) : pMin(p), pMax(p) {} Bounds3(const FVector p1, const FVector p2) FVector Diagonal() const { return pMax - pMin; } //对角线向量 int maxExtent() const // 最大轴分量,0、1、2分别代表 X、Y、Z 轴,便于按最长划分空间 double SurfaceArea() const // 表面积,暂时无用 FVector Centroid() { return 0.5 * pMin + 0.5 * pMax; } // 中心点位置 bool Overlaps(const Bounds3& b1, const Bounds3& b2) // 两空间是否重叠,暂时无用 bool Inside(const FVector& p, const Bounds3& b) // 点是否在空间内 inline const FVector& operator[](int i) const // 取pMin pMax void Union(const Bounds3& b2) //求空间并集 void Union(const FVector& p) bool IntersectP(const Ray& ray, const FVector& invDir, const FVector& dirisNeg) const //判断光线是否通过空间包围盒 void Draw(const UObject* worldContex, FLinearColor color, float time = 0.02f, float thickness = 1.5f)
  • IObjectInterface 接口
    UINTERFACE(MinimalAPI) class UObjectInterface : public UInterface class GAMES101_API IObjectInterface { GENERATED_BODY() public: virtual bool intersect(const Ray& ray) = 0; virtual bool intersect(const Ray& ray, float&, uint32_t&) const = 0; virtual Intersection getIntersection(Ray _ray) = 0; virtual void getSurfaceProperties(const FVector&, const FVector&, const uint32_t&, const FVector2D&, FVector&, FVector2D&) const = 0; virtual FVector evalDiffuseColor(const FVector2D&) const = 0; virtual Bounds3 getBounds() const = 0; };
  • class UHw6_Triangle : public UObject, public IObjectInterface 三角面
    FVector v0, v1, v2; // vertices A, B ,C , counter-clockwise order FVector e1, e2; // 2 edges v1-v0, v2-v0; FVector t0, t1, t2; // texture coords FVector normal; Material* m; Bounds3 bounding_box; UHw6_Triangle() {} void Init(FVector _v0, FVector _v1, FVector _v2, Material* _m = nullptr) //初始化顶点位置,计算法线(ue4坐标轴需要换下位置)、包围盒 Intersection getIntersection(Ray ray) override; // 求交,重点 void getSurfaceProperties( const FVector& P, const FVector& I, const uint32_t& index, const FVector2D& uv, FVector& N, FVector2D& st) const override { N = normal; }; FVector evalDiffuseColor(const FVector2D&) const override {return FVector(0.5, 0.5, 0.5);} Bounds3 getBounds() const override { return bounding_box; } bool intersect(const Ray& ray) override{ return true; } bool intersect(const Ray& ray, float& tnear, uint32_t& index) const override { return true; }
  • class AHw6_MeshTriangle : public AActor, public IObjectInterface 网格物体
    Bounds3 bounding_box; Material* m; UPROPERTY() TArray<FVector> vertices; UPROPERTY() TArray<uint32> vertexIndex; UPROPERTY() TArray<FVector2D> stCoordinates; UPROPERTY() TArray<TScriptInterface<IObjectInterface>> triangles; UPROPERTY() UBVHAccel* bvhTree; UPROPERTY(VisibleAnywhere) UStaticMeshComponent* meshComp; void getStaticMeshData(); //将 mesh 拆分成三角面构造 BVH Tree void buildBVHTree(); // 判断光线是否和三角面相交 bool rayTriangleIntersect(const FVector& v0, const FVector& v1, const FVector& v2, const FVector& orig, const FVector& dir, float& tnear, float& u, float& v) const; // 判断是否相交 bool intersect(const Ray& ray, float& tnear, uint32_t& index) const override; bool intersect(const Ray& ray) override { return true; } // 获取空间区域 Bounds3 getBounds() const override { return bounding_box; } // 获取表面信息 void getSurfaceProperties( const FVector& P, const FVector& I, const uint32_t& index, const FVector2D& uv, FVector& N, FVector2D& st) const override; // 获取点对应的颜色 FVector evalDiffuseColor(const FVector2D& st) const override; // 获取相交信息 Intersection getIntersection(Ray ray) override;
  • Hw6_Global.h 全局设置