参考自:
https://github.com/Ubpa/ToyRTX
使用三种Texture 记录场景数据
1.SceneData
2.MatData
3.PackData
数据:
https://docs.qq.com/sheet/DQ2FqdE1jYWZpTldC?tab=BB08J2
SceneData:
0 |
1 |
2 |
3 |
4 |
type |
mat_id |
has material |
child |
end |
OT_Group |
-1 |
0 |
5 |
0 |
5 |
6 |
7 |
8 |
9 |
10 |
|
mat_id |
has material |
packData/4 |
child |
end |
OT_Transform |
0 |
1 |
0 |
11 |
-5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
|
mat_id |
has material |
packData/4 |
child |
end |
|
OT_BVHNode |
-1 |
0 |
11 |
18 |
-11 |
|
18 |
19 |
20 |
21 |
|
|
|
packData/4 |
OT_Triangle |
-1 |
0 |
|
MatData:
0 |
1 |
type |
|
2(RTX_DIELECTRIC) |
1.5( refract_idx) |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
|
mat_id |
has material |
packData/4 |
child |
end |
|
OT_BVHNode |
-1 |
0 |
11 |
18 |
-11 |
|
RayTrace Code:
struct HitRst TraceScene(inout struct Ray ray,inout struct HitRst finalHitRst){
finalHitRst = Hitrst_InVaild;
Stack_Push(3.0);
while(!Stack_Empty()){
float pIdx = Stack_Pop();
float idx = At(SceneData, pIdx);
if(idx <= 0.0){
idx = -idx;
float type = At(SceneData,idx);
if(type == HitableType_Group || type == HitableType_BVH || type == HitableType_TriMesh){
float matIdx = At(SceneData,idx+1.0);
if(matIdx == -1.0)
continue;
float in_tMax = Stack_Pop();
if (ray.tMax < in_tMax && finalHitRst.isMatCoverable == 1.0){
finalHitRst.matIdx = matIdx;
finalHitRst.isMatCoverable = At(SceneData, idx+2.0);
}
}
else if (type == HitableType_Transform) {
float in_tMax = Stack_Pop();// 进入节点时的tMax
mat4 tfmMat4;
GetPackData(At(SceneData,idx+3), tfmMat4);
Ray_Transform(ray, tfmMat4);
if(ray.tMax <= in_tMax){
mat3 normTfmMat3;
GetPackData((At(SceneData,idx+3.0)+8.0), normTfmMat3);
Vertex_Transform(finalHitRst.vertex, tfmMat4, normTfmMat3);
//if(finalHitRst.isMatCoverable == 1.0){
float matIdx = At(SceneData, idx+1);
if(matIdx != -1.0){
finalHitRst.matIdx = matIdx;
finalHitRst.isMatCoverable = At(SceneData, idx+2);
}
//}
}
}
continue;
}
Stack_Push(pIdx+1.0);
float type = At(SceneData,idx);
if(type == HitableType_Sphere){
RayIn_Sphere(idx, ray, finalHitRst);
}
else if(type == HitableType_Group){
float matIdx = At(SceneData,idx+1.0);
if(matIdx != -1.0)
Stack_Push(ray.tMax);
Stack_Push(idx+3.0);
}
else if(type == HitableType_BVH || type == HitableType_TriMesh){
if(AABB_Hit(ray,idx+3.0)){
float matIdx = At(SceneData,idx+1.0);
if(matIdx != -1.0)
Stack_Push(ray.tMax);
Stack_Push(idx+4.0);
}
}
else if(type == HitableType_Transform){
mat4 invMat;
GetPackData((At(SceneData,idx+3.0)+4.0),invMat);
Ray_Transform(ray,invMat);
Stack_Push(ray.tMax);
Stack_Push(idx+4.0);
}
else if(type == HitableType_Triangle){
RayIn_Triangle(idx, ray, finalHitRst);
}
else if(type == HitableType_Volume){
//RayIn_Volume(idx, ray, finalHitRst);
}
}
return finalHitRst;
}