如何解决使用路径跟踪渲染体素时出现问题
我目前正在使用 c 和 open cl 开发路径跟踪器。 我正在使用 this 算法进行渲染。第一次碰撞效果很好,但是,从第二次碰撞开始,体素的下侧有一个暗影。
这是初始光线击中的体素的颜色:
这是第二条射线击中的体素的颜色:
这是渲染到1000深度后的结果:
这是我使用的代码 (openCL
):
int cast_ray(Renderer *r,Ray ray,float3 *hitPos,int3 *normal,Material *material) {
int3 voxel = convert_int3(ray.origin);
int3 step = {
(ray.direction.x >= 0) ? 1 : -1,(ray.direction.y >= 0) ? 1 : -1,(ray.direction.z >= 0) ? 1 : -1
};
float3 tMax = {
(ray.direction.x != 0) ? (voxel.x + step.x - ray.origin.x) / ray.direction.x : MAXFLOAT,(ray.direction.y != 0) ? (voxel.y + step.y - ray.origin.y) / ray.direction.y : MAXFLOAT,(ray.direction.z != 0) ? (voxel.z + step.z - ray.origin.z) / ray.direction.z : MAXFLOAT
};
float3 tDelta = {
(ray.direction.x != 0) ? 1 / ray.direction.x * step.x : MAXFLOAT,(ray.direction.y != 0) ? 1 / ray.direction.y * step.y : MAXFLOAT,(ray.direction.z != 0) ? 1 / ray.direction.z * step.z : MAXFLOAT
};
int side;
while(1) {
if(tMax.x < tMax.y) {
if(tMax.x < tMax.z) {
voxel.x += step.x;
tMax.x += tDelta.x;
side = 0;
} else {
voxel.z += step.z;
tMax.z += tDelta.z;
side = 2;
}
} else {
if(tMax.y < tMax.z) {
voxel.y += step.y;
tMax.y += tDelta.y;
side = 1;
} else {
voxel.z += step.z;
tMax.z += tDelta.z;
side = 2;
}
}
if(out_of_scene(r,voxel))
return 0;
MaterialID id = get_material_ID(r,voxel);
if(id == 0)
continue;
*material = get_material(r,id);
switch(side) {
case 0:
hitPos->x = (float)voxel.x;
hitPos->y = ray.origin.y + (hitPos->x - ray.origin.x) * ray.direction.y / ray.direction.x;
hitPos->z = ray.origin.z + (hitPos->x - ray.origin.x) * ray.direction.z / ray.direction.x;
*normal = (int3){-step.x,0};
break;
case 1:
hitPos->y = (float)voxel.y;
hitPos->x = ray.origin.x + (hitPos->y - ray.origin.y) * ray.direction.x / ray.direction.y;
hitPos->z = ray.origin.z + (hitPos->y - ray.origin.y) * ray.direction.z / ray.direction.y;
*normal = (int3){0,-step.y,0};
break;
case 2:
hitPos->z = (float)voxel.z;
hitPos->y = ray.origin.y + (hitPos->z - ray.origin.z) * ray.direction.y / ray.direction.z;
hitPos->x = ray.origin.x + (hitPos->z - ray.origin.z) * ray.direction.x / ray.direction.z;
*normal = (int3){0,-step.z};
break;
}
return 1;
}
}
float3 get_color(Renderer *r,Ray ray) {
float3 mask = 1;
float3 color = 0;
int maxDepth = 1000;
for(int i = 0; i < maxDepth; i++) {
float3 hitPos;
int3 inormal;
Material material;
if(cast_ray(r,ray,&hitPos,&inormal,&material)) {
float3 fnormal = convert_float3(inormal);
if(material.type == 1) {
color = mask * material.color;
break;
} else if(material.type == 2) {
float3 direction = fnormal + random_unit_vector(r->rng);
ray = (Ray){hitPos,direction};
mask *= material.color;
} else if(material.type == 3) {
float3 direction = reflection_dir(ray.direction,fnormal) + random_unit_vector(r->rng) * material.fuzzyness;
ray = (Ray){hitPos,direction};
mask = mask * (1 - material.tint) + mask * material.color * material.tint;
}
} else {
color = mask * r->bgColor;
break;
}
// if(i == 1)
// return material.color;
}
return color;
}
我认为问题在于光线的新起源不知何故不正确,但我找不到修复它的方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。