我试图在片段着色器中编写一个简单的光线跟踪器。
我有应该创建如下的扩散球体的此功能:
这是函数:
vec3 GetRayColor(Ray ray)
{
Ray new_ray = ray;
vec3 FinalColor = vec3(1.0f);
bool IntersectionFound = false;
int hit_times = 0;
for (int i = 0; i < RAY_BOUNCE_LIMIT; i++)
{
RayHitRecord ClosestSphere = IntersectSceneSpheres(new_ray, 0.001f, MAX_RAY_HIT_DISTANCE);
if (ClosestSphere.Hit == true)
{
// Get the final ray direction
vec3 R;
R.x = nextFloat(RNG_SEED, -1.0f, 1.0f);
R.y = nextFloat(RNG_SEED, -1.0f, 1.0f);
R.z = nextFloat(RNG_SEED, -1.0f, 1.0f);
vec3 S = normalize(ClosestSphere.Normal) + normalize(R);
S = normalize(S);
new_ray.Origin = ClosestSphere.Point;
new_ray.Direction = S;
hit_times += 1;
IntersectionFound = true;
}
else
{
FinalColor = GetGradientColorAtRay(new_ray);
break;
}
}
if (IntersectionFound)
{
FinalColor /= 2.0f; // Lambertian diffuse only absorbs half the light
FinalColor = FinalColor / float(hit_times);
}
return FinalColor;
}
由于某种原因,hit_times
似乎是恒定的。此完全相同的代码在CPU上工作并生成了随附的屏幕截图。
我不确定这是否与GPU有关。但是我已经测试了所有其他功能,它们按预期工作。
这是可视化的
Normal + RandomVec
或S
:在 CPU 上完成时,它是完全相同的。
这是在 CPU上可视化的
hit_times
但是在GPU上,所有三个球都是白色的。
这是完整的片段着色器:https://pastebin.com/3xeA6LtT
以下是可在CPU上运行的代码:https://pastebin.com/eyLnHYzr
最佳答案
所有球都是白色的,因为ClosestSphere.Hit
函数中的GetRayColor
始终为true。
我认为问题出在您的IntersectSceneSpheres
函数中。
在CPU代码中,您返回HitAnything
,默认为false。同时,在片段着色器中,如果未命中任何内容,则返回未初始化的struct ClosestRecord
。
在ClosestRecord.Hit = HitAnything;
函数的末尾显式添加IntersectSceneSpheres
应该可以修复它
关于c++ - 在GPU上运行的此光线跟踪功能是否安全?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/65598017/