You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
* Generate surfels directly from the triangles instead of relying on ray tracing, to fix coverage issues on some meshes * Surfels which are inside meshes (surrounded by back faces) or are too close to geometry are discarded * New surfel clustering algorithm, which inserts one seed after another and tries to iteratively grow clusters in order to find the best set of seeds. Final step is to reset all clusters and grow all simultaneously from previously selected seeds. * Cluster growing is based on normal, distance and surfel visibility (don�t cluster surfels near geometry first, as it can cause algorithm to be stuck in a local minimum) * Runtime sampling has strict culling based on the angle and card AABB. Additionally, the tri-planar blending zone was tightened. This improves performance. 0.62-0.5 ms. * Added various visualizations and CVars for card generation debugging * Fixed card visibility bug, where card could influence outside of it�s range due to negative shadow map visibility [FYI] Daniel.Wright, Patrick.Kelly #ROBOMERGE-SOURCE: CL 16897632 #ROBOMERGE-BOT: (v836-16769935) [CL 16916104 by krzysztof narkowicz in ue5-main branch]
163 lines
3.5 KiB
C++
163 lines
3.5 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "MeshUtilities.h"
|
|
#include "kDOP.h"
|
|
|
|
#if USE_EMBREE
|
|
#include <embree3/rtcore.h>
|
|
#include <embree3/rtcore_ray.h>
|
|
#else
|
|
typedef void* RTCDevice;
|
|
typedef void* RTCScene;
|
|
typedef void* RTCGeometry;
|
|
#endif
|
|
|
|
class FSourceMeshDataForDerivedDataTask;
|
|
|
|
class FMeshBuildDataProvider
|
|
{
|
|
public:
|
|
|
|
/** Initialization constructor. */
|
|
FMeshBuildDataProvider(
|
|
const TkDOPTree<const FMeshBuildDataProvider, uint32>& InkDopTree) :
|
|
kDopTree(InkDopTree)
|
|
{}
|
|
|
|
// kDOP data provider interface.
|
|
|
|
FORCEINLINE const TkDOPTree<const FMeshBuildDataProvider, uint32>& GetkDOPTree(void) const
|
|
{
|
|
return kDopTree;
|
|
}
|
|
|
|
FORCEINLINE const FMatrix& GetLocalToWorld(void) const
|
|
{
|
|
return FMatrix::Identity;
|
|
}
|
|
|
|
FORCEINLINE const FMatrix& GetWorldToLocal(void) const
|
|
{
|
|
return FMatrix::Identity;
|
|
}
|
|
|
|
FORCEINLINE FMatrix GetLocalToWorldTransposeAdjoint(void) const
|
|
{
|
|
return FMatrix::Identity;
|
|
}
|
|
|
|
FORCEINLINE float GetDeterminant(void) const
|
|
{
|
|
return 1.0f;
|
|
}
|
|
|
|
private:
|
|
|
|
const TkDOPTree<const FMeshBuildDataProvider, uint32>& kDopTree;
|
|
};
|
|
|
|
struct FEmbreeTriangleDesc
|
|
{
|
|
int16 ElementIndex;
|
|
|
|
bool IsTwoSided() const
|
|
{
|
|
// MaterialIndex on the build triangles was set to 1 if two-sided, or 0 if one-sided
|
|
return ElementIndex == 1;
|
|
}
|
|
};
|
|
|
|
// Mapping between Embree Geometry Id and engine Mesh/LOD Id
|
|
struct FEmbreeGeometry
|
|
{
|
|
TArray<uint32> IndexArray;
|
|
TArray<FVector3f> VertexArray;
|
|
TArray<FEmbreeTriangleDesc> TriangleDescs; // The material ID of each triangle.
|
|
RTCGeometry InternalGeometry;
|
|
};
|
|
|
|
class FEmbreeScene
|
|
{
|
|
public:
|
|
bool bUseEmbree = false;
|
|
int32 NumIndices = 0;
|
|
|
|
// Embree
|
|
RTCDevice EmbreeDevice = nullptr;
|
|
RTCScene EmbreeScene = nullptr;
|
|
FEmbreeGeometry Geometry;
|
|
|
|
// DOP tree fallback
|
|
TkDOPTree<const FMeshBuildDataProvider, uint32> kDopTree;
|
|
};
|
|
|
|
#if USE_EMBREE
|
|
struct FEmbreeRay : public RTCRayHit
|
|
{
|
|
FEmbreeRay() :
|
|
ElementIndex(-1)
|
|
{
|
|
hit.u = hit.v = 0;
|
|
ray.time = 0;
|
|
ray.mask = 0xFFFFFFFF;
|
|
hit.geomID = RTC_INVALID_GEOMETRY_ID;
|
|
hit.instID[0] = RTC_INVALID_GEOMETRY_ID;
|
|
hit.primID = RTC_INVALID_GEOMETRY_ID;
|
|
}
|
|
|
|
FVector3f GetHitNormal() const
|
|
{
|
|
return FVector3f(-hit.Ng_x, -hit.Ng_y, -hit.Ng_z).GetSafeNormal();
|
|
}
|
|
|
|
bool IsHitTwoSided() const
|
|
{
|
|
// MaterialIndex on the build triangles was set to 1 if two-sided, or 0 if one-sided
|
|
return ElementIndex == 1;
|
|
}
|
|
|
|
// Additional Outputs.
|
|
int32 ElementIndex; // Material Index
|
|
};
|
|
|
|
struct FEmbreeIntersectionContext : public RTCIntersectContext
|
|
{
|
|
FEmbreeIntersectionContext() :
|
|
ElementIndex(-1)
|
|
{}
|
|
|
|
bool IsHitTwoSided() const
|
|
{
|
|
// MaterialIndex on the build triangles was set to 1 if two-sided, or 0 if one-sided
|
|
return ElementIndex == 1;
|
|
}
|
|
|
|
// Additional Outputs.
|
|
int32 ElementIndex; // Material Index
|
|
};
|
|
|
|
#endif
|
|
|
|
namespace MeshRepresentation
|
|
{
|
|
/**
|
|
* Generates unit length, stratified and uniformly distributed direction samples in a hemisphere.
|
|
*/
|
|
void GenerateStratifiedUniformHemisphereSamples(int32 NumSamples, FRandomStream& RandomStream, TArray<FVector4>& Samples);
|
|
|
|
/**
|
|
* [Frisvad 2012, "Building an Orthonormal Basis from a 3D Unit Vector Without Normalization"]
|
|
*/
|
|
FMatrix44f GetTangentBasisFrisvad(FVector3f TangentZ);
|
|
|
|
void SetupEmbreeScene(FString MeshName,
|
|
const FSourceMeshDataForDerivedDataTask& SourceMeshData,
|
|
const FStaticMeshLODResources& LODModel,
|
|
const TArray<FSignedDistanceFieldBuildMaterialData>& MaterialBlendModes,
|
|
bool bGenerateAsIfTwoSided,
|
|
FEmbreeScene& EmbreeScene);
|
|
|
|
void DeleteEmbreeScene(FEmbreeScene& EmbreeScene);
|
|
}; |