参考自:
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;
}