问题描述
我想弄清楚如何正确构建 TLAS。 使用 OptiX 7.1 和 Ingo Wald's Optix 7 samples 附带的示例,从一个三角形(仅包含几何图形的 BLAS)开始,它工作正常(将 SDK 的三角形示例移至 Wald 的示例框架)。 接下来,我引入了一个带有一个实例的 TLAS(即之前的 BLAS)并在着色器中使用了该 TLAS,但我没有得到任何命中。 我做错了什么?
OptixTraversableHandle SampleRenderer::buildAccelerator() {
OptixTraversableHandle geometryAcceleratorHandle{ 0 };
CUdeviceptr dAcceleratorBuffer;
OptixAccelBuildOptions acceleratorOptions{};
acceleratorOptions.buildFlags = OPTIX_BUILD_FLAG_NONE | OPTIX_BUILD_FLAG_ALLOW_COMPACTION;
acceleratorOptions.operation = OPTIX_BUILD_OPERATION_BUILD;
//Triangle build input: simple list of three vertices
const std::array<float3,3> vertices{ { { 0.33f,0.33f,0.0f },{ 0.33f,-0.33f,{ 0.66f,0.0f }} };
const size_t verticesSize = sizeof(float3) * vertices.size();
CUdeviceptr dVertices{ 0ull };
CUDA_CHECK(Malloc(reinterpret_cast<void**>(&dVertices),verticesSize));
CUDA_CHECK(Memcpy(reinterpret_cast<void*>(dVertices),vertices.data(),verticesSize,cudaMemcpyHostToDevice));
//Build input is a simple list of non-indexed triangle vertices
const uint32_t triangleInputFlags{ OPTIX_GEOMETRY_FLAG_NONE };
OptixBuildInput triangleInput{};
triangleInput.type = OPTIX_BUILD_INPUT_TYPE_TRIANGLES;
triangleInput.triangleArray.vertexFormat = OPTIX_VERTEX_FORMAT_FLOAT3;
triangleInput.triangleArray.numVertices = static_cast<uint32_t>(vertices.size());
triangleInput.triangleArray.vertexBuffers = &dVertices;
triangleInput.triangleArray.flags = &triangleInputFlags;
triangleInput.triangleArray.numSbtRecords = 1u;
OptixAccelBufferSizes blasBufferSizes;
OPTIX_CHECK(optixAccelComputeMemoryUsage(optixContext,&acceleratorOptions,&triangleInput,1,&blasBufferSizes));
CUdeviceptr dTempBuffer;
CUDA_CHECK(Malloc(reinterpret_cast<void**>(&dTempBuffer),blasBufferSizes.tempSizeInBytes));
CUDA_CHECK(Malloc(reinterpret_cast<void**>(&dAcceleratorBuffer),blasBufferSizes.outputSizeInBytes));
OPTIX_CHECK(
optixAccelBuild(
optixContext,dTempBuffer,blasBufferSizes.tempSizeInBytes,dAcceleratorBuffer,blasBufferSizes.outputSizeInBytes,&geometryAcceleratorHandle,nullptr,0)
);
CUDA_CHECK(Free((void*)dTempBuffer));
CUDA_CHECK(Free((void*)dVertices));
return geometryAcceleratorHandle;
}
我没有使用上面函数的返回值,而是将它提供给下面的 TLAS 创建函数,并在着色器中使用它的输出句柄:
OptixTraversableHandle SampleRenderer::buildInstanceAccelerator(const OptixTraversableHandle& geoHandle){
OptixInstance optixInstance = { { 1.0f,0.0f,1.0f,0.0f } };
optixInstance.flags = OPTIX_INSTANCE_FLAG_NONE;
optixInstance.instanceId = 0u;
optixInstance.sbtOffset = 0u;
optixInstance.visibilityMask = 1u;
optixInstance.traversableHandle = geoHandle;
CUdeviceptr dOptixInstance;
CUDA_CHECK(Malloc(reinterpret_cast<void**>(&dOptixInstance),sizeof(OptixInstance)));
CUDA_CHECK(Memcpy(reinterpret_cast<void*>(dOptixInstance),&optixInstance,sizeof(OptixInstance),cudaMemcpyHostToDevice));
OptixAabb optixAabb[2]{
{ -1.5f,-1.0f,-0.5f,0.5f,0.5f },{ 0.5f,-0.01f,1.5f,0.01f } };
CUdeviceptr dAabb;
CUDA_CHECK(Malloc(reinterpret_cast<void**>(&dAabb),2 * sizeof(OptixAabb)));
CUDA_CHECK(Memcpy(reinterpret_cast<void*>(dAabb),optixAabb,2 * sizeof(OptixAabb),cudaMemcpyHostToDevice));
OptixBuildInput instanceBuildInput{};
instanceBuildInput.type = OPTIX_BUILD_INPUT_TYPE_INSTANCES;
instanceBuildInput.instanceArray.instances = dOptixInstance;
instanceBuildInput.instanceArray.numInstances = 1u;
instanceBuildInput.instanceArray.aabbs = dAabb;
instanceBuildInput.instanceArray.numAabbs =1u;
OptixAccelBuildOptions acceleratorBuildOptions{};
acceleratorBuildOptions.buildFlags = OPTIX_BUILD_FLAG_NONE;
acceleratorBuildOptions.operation = OPTIX_BUILD_OPERATION_BUILD;
OptixAccelBufferSizes acceleratorBufferSizes;
OPTIX_CHECK(optixAccelComputeMemoryUsage(
optixContext,&acceleratorBuildOptions,&instanceBuildInput,1u,&acceleratorBufferSizes));
CUdeviceptr dTempBuffer;
CUDA_CHECK(Malloc(reinterpret_cast<void**>(&dTempBuffer),acceleratorBufferSizes.tempSizeInBytes));
CUdeviceptr dInstanceAcceleratorBuffer;
CUDA_CHECK(Malloc(reinterpret_cast<void**>(&dInstanceAcceleratorBuffer),acceleratorBufferSizes.outputSizeInBytes));
OptixTraversableHandle instanceAcceleratorHandle{ 0 };
OPTIX_CHECK(optixAccelBuild(
optixContext,acceleratorBufferSizes.tempSizeInBytes,dInstanceAcceleratorBuffer,acceleratorBufferSizes.outputSizeInBytes,&instanceAcceleratorHandle,0));
return instanceAcceleratorHandle;
}
参考着色器代码(当 OptixTraversableHandle 来自上面的第一个函数时它工作得很好:
namespace osc {
extern "C" __constant__ LaunchParams optixLaunchParams;
//Single ray type
enum { SURFACE_RAY_TYPE = 0,RAY_TYPE_COUNT };
static __forceinline__ __device__ void* unpackPointer(uint32_t i0,uint32_t i1) {
const uint64_t uptr = static_cast<uint64_t>(i0) << 32 | i1;
void* ptr = reinterpret_cast<void*>(uptr);
return ptr;
}
static __forceinline__ __device__ void packPointer(void* ptr,uint32_t& i0,uint32_t& i1) {
const uint64_t uptr = reinterpret_cast<uint64_t>(ptr);
i0 = uptr >> 32;
i1 = uptr & 0x00000000ffffffff;
}
template<typename T> static __forceinline__ __device__ T* getPRD() {
const uint32_t u0 = optixGetPayload_0();
const uint32_t u1 = optixGetPayload_1();
return reinterpret_cast<T*>(unpackPointer(u0,u1));
}
static __forceinline__ __device__ void trace(
OptixTraversableHandle handle,vec3f ray_origin,vec3f ray_direction,float tmin,float tmax,float3* prd) {
unsigned int p0,p1,p2;
p0 = float_as_int(prd->x);
p1 = float_as_int(prd->y);
p2 = float_as_int(prd->z);
optixTrace(
handle,ray_origin,ray_direction,tmin,tmax,// rayTime
OptixVisibilityMask(1),OPTIX_RAY_FLAG_DISABLE_ANYHIT,//OPTIX_RAY_FLAG_NONE,// SBT offset
0,// SBT stride
0,// missSBTIndex
p0,p2);
prd->x = int_as_float(p0);
prd->y = int_as_float(p1);
prd->z = int_as_float(p2);
}
static __forceinline__ __device__ void setPayload(float3 p) {
optixSetPayload_0(float_as_int(p.x));
optixSetPayload_1(float_as_int(p.y));
optixSetPayload_2(float_as_int(p.z));
}
static __forceinline__ __device__ float3 getPayload() {
return make_float3(int_as_float(optixGetPayload_0()),int_as_float(optixGetPayload_1()),int_as_float(optixGetPayload_2()));
}
extern "C" __global__ void __closesthit__radiance() {
//When built-in triangle intersection is used,a number of fundamental
//attributes are provided by the OptiX API,including barycentric coordinates
const float2 barycentricCoordinates = optixGetTriangleBarycentrics();
setPayload(make_float3(barycentricCoordinates.x,barycentricCoordinates.y,1.f - barycentricCoordinates.x - barycentricCoordinates.y));
}
extern "C" __global__ void __anyhit__radiance() { }
extern "C" __global__ void __intersection__radiance() { }
extern "C" __global__ void __miss__radiance() {
MissData* missData = reinterpret_cast<MissData*>(optixGetSbtDataPointer());
float3 payload = getPayload();//Why???
setPayload(missData->backgroundColor);
}
extern "C" __global__ void __raygen__renderFrame() {
// compute a test pattern based on pixel ID
const int ix = optixGetLaunchIndex().x;
const int iy = optixGetLaunchIndex().y;
const auto& camera = optixLaunchParams.camera;
// our per-ray data for this example. what we initialize it to
// won't matter,since this value will be overwritten by either
// the miss or hit program,anyway
float3 pixelColorPRD = { 0.5f,0.5f };
// normalized screen plane position,in [0,1]^2
const vec2f screen(vec2f(ix + .5f,iy + .5f) / vec2f(optixLaunchParams.frame.size));
// generate ray direction
vec3f rayDir = normalize(camera.direction + (screen.x - 0.5f) * camera.horizontal + (screen.y - 0.5f) * camera.vertical);
trace(optixLaunchParams.traversable,camera.position,rayDir,0.f,// tmin
1e16f,// tmax
&pixelColorPRD);
const int r = int(255.99f * pixelColorPRD.x);
const int g = int(255.99f * pixelColorPRD.y);
const int b = int(255.99f * pixelColorPRD.z);
const uint32_t rgba = 0xff000000 | (r << 0) | (g << 8) | (b << 16);
const uint32_t fbIndex = ix + iy * optixLaunchParams.frame.size.x;
optixLaunchParams.frame.colorBuffer[fbIndex] = rgba;
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)