-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathoptix_kernels.cu
More file actions
130 lines (102 loc) · 4.44 KB
/
optix_kernels.cu
File metadata and controls
130 lines (102 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "sphere_primitive_shared.h"
using namespace Shared;
RT_PIPELINE_LAUNCH_PARAMETERS PipelineLaunchParameters plp;
struct HitPointParameter {
union {
float b1;
float secondDistance;
};
float b2;
int32_t primIndex;
CUDA_DEVICE_FUNCTION CUDA_INLINE static HitPointParameter get() {
HitPointParameter ret;
OptixPrimitiveType primType = optixGetPrimitiveType();
if (primType == OPTIX_PRIMITIVE_TYPE_TRIANGLE) {
float2 bc = optixGetTriangleBarycentrics();
ret.b1 = bc.x;
ret.b2 = bc.y;
}
else if (primType == OPTIX_PRIMITIVE_TYPE_SPHERE) {
// When a ray hits a sphere twice, the attribute 0 contains the second distance.
uint32_t attr0 = optixGetAttribute_0();
ret.secondDistance = __uint_as_float(attr0);
}
ret.primIndex = optixGetPrimitiveIndex();
return ret;
}
};
struct HitGroupSBTRecordData {
GeometryData geomData;
CUDA_DEVICE_FUNCTION CUDA_INLINE static const HitGroupSBTRecordData &get() {
return *reinterpret_cast<HitGroupSBTRecordData*>(optixGetSbtDataPointer());
}
};
CUDA_DEVICE_FUNCTION CUDA_INLINE float3 calcSphereSurfaceNormal(
const GeometryData &geom, uint32_t primIndex, const float3 &hp) {
float3 center;
if constexpr (useEmbeddedVertexData) {
// OptiX Programming Guide
// > Similar to curves, if only the vertex data of a currently intersected sphere is used,
// > it is recommended to use the function without 'FromHandle'.
// > This does not require build flag OPTIX_BUILD_FLAG_ALLOW_RANDOM_VERTEX_ACCESS.
// JP: 直近に交差した球のパラメター取得だけであればGASビルド時に
// OPTIX_BUILD_FLAG_ALLOW_RANDOM_VERTEX_ACCESSを指定する必要はない。
// EN: It is not necessary to specify OPTIX_BUILD_FLAG_ALLOW_RANDOM_VERTEX_ACCESS
// when only retrieving the parameters of the most recently intersected sphere.
float4 centerAndRadius;
optixGetSphereData(¢erAndRadius);
center = make_float3(centerAndRadius);
}
else {
const SphereParameter ¶m = geom.sphereParamBuffer[primIndex];
center = param.center;
}
float3 sn = normalize(hp - center);
return sn;
}
CUDA_DEVICE_KERNEL void RT_RG_NAME(raygen)() {
uint2 launchIndex = make_uint2(optixGetLaunchIndex().x, optixGetLaunchIndex().y);
float x = static_cast<float>(launchIndex.x + 0.5f) / plp.imageSize.x;
float y = static_cast<float>(launchIndex.y + 0.5f) / plp.imageSize.y;
float vh = 2 * std::tan(plp.camera.fovY * 0.5f);
float vw = plp.camera.aspect * vh;
float3 origin = plp.camera.position;
float3 direction = normalize(plp.camera.orientation * make_float3(vw * (0.5f - x), vh * (0.5f - y), 1));
float3 color;
MyPayloadSignature::trace(
plp.travHandle, origin, direction,
0.0f, FLT_MAX, 0.0f, 0xFF, OPTIX_RAY_FLAG_NONE,
RayType_Primary, NumRayTypes, RayType_Primary,
color);
plp.resultBuffer[launchIndex] = make_float4(color, 1.0f);
}
CUDA_DEVICE_KERNEL void RT_MS_NAME(miss)() {
float3 color = make_float3(0, 0, 0.1f);
MyPayloadSignature::set(&color);
}
CUDA_DEVICE_KERNEL void RT_CH_NAME(closesthit)() {
auto sbtr = HitGroupSBTRecordData::get();
const GeometryData &geom = sbtr.geomData;
auto hpParam = HitPointParameter::get();
float3 sn;
OptixPrimitiveType primType = optixGetPrimitiveType();
if (primType == OPTIX_PRIMITIVE_TYPE_TRIANGLE) {
const Triangle &triangle = geom.triangleBuffer[hpParam.primIndex];
const Vertex &v0 = geom.vertexBuffer[triangle.index0];
const Vertex &v1 = geom.vertexBuffer[triangle.index1];
const Vertex &v2 = geom.vertexBuffer[triangle.index2];
float b0 = 1 - (hpParam.b1 + hpParam.b2);
sn = b0 * v0.normal + hpParam.b1 * v1.normal + hpParam.b2 * v2.normal;
}
else {
uint32_t primIndex = optixGetPrimitiveIndex();
float3 hp = optixGetWorldRayOrigin() + optixGetRayTmax() * optixGetWorldRayDirection();
hp = optixTransformPointFromWorldToObjectSpace(hp);
sn = calcSphereSurfaceNormal(geom, primIndex, hp);
}
sn = normalize(optixTransformNormalFromObjectToWorldSpace(sn));
// JP: 法線を可視化。
// EN: Visualize the normal.
float3 color = 0.5f * sn + make_float3(0.5f);
MyPayloadSignature::set(&color);
}