微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用路径跟踪渲染体素时出现问题

如何解决使用路径跟踪渲染体素时出现问题

我目前正在使用 c 和 open cl 开发路径跟踪器。 我正在使用 this 算法进行渲染。第一次碰撞效果很好,但是,从第二次碰撞开始,体素的下侧有一个暗影。

这是初始光线击中的体素的颜色:

result

这是第二条射线击中的体素的颜色:

result

这是渲染到1000深度后的结果:

result

这是我使用的代码 (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 举报,一经查实,本站将立刻删除。