Что может быть источником этого псевдонима?

Я вручную трассирую 3D-изображение. Я заметил, что чем дальше от трехмерного изображения, тем больше алиасинг.

Это трехмерное изображение представляет собой вокселизированное изображение Стэнфордского дракона. Я поместил объем по центру в начале координат (крест диагонали в (0,0,0)), что означает, что один из углов находится в (-cube_dim, -cube_dim, -cube_dim), а другой в (cube_dim, cube_dim, cube_dim).

На близком расстоянии изображение в порядке:

введите описание изображения здесь

(Незначительный «псевдоним», который вы видите здесь, связан с тем, что я выполняю алгоритм марширования лучей, это не тот псевдоним, о котором я беспокоюсь, это было ожидаемо и приемлемо)

Однако, если мы уйдем достаточно далеко, начнем появляться псевдонимы:введите описание изображения здесь
(Это совершенно другой вид псевдонимов)

Фрагмент шейдера используется для генерации изображения это:

#version 430

in vec2 f_coord;

out vec4 fragment_color;

uniform layout(binding=0, rgba8) image3D volume_data;

uniform vec3 camera_pos;
uniform float aspect_ratio;
uniform float cube_dim;
uniform int voxel_resolution;

#define EPSILON 0.01
// Check whether the position is inside of the specified box
bool inBoxBounds(vec3 corner, float size, vec3 position)
{
bool inside = true;
//Put the position in the coordinate frame of the box
position-=corner;
//The point is inside only if all of it's components are inside
for(int i=0; i<3; i++)
{
inside = inside && (position[i] > -EPSILON);
inside = inside && (position[i] < size+EPSILON);
}

return inside;
}
//Calculate the distance to the intersection to a box, or inifnity if the bos cannot be hit
float boxIntersection(vec3 origin, vec3 dir, vec3 corner0, float size)
{
//dir = normalize(dir);
//calculate opposite corner
vec3 corner1 = corner0 + vec3(size,size,size);

//Set the ray plane intersections
float coeffs[6];
coeffs[0] = (corner0.x - origin.x)/(dir.x);
coeffs[1] = (corner0.y - origin.y)/(dir.y);
coeffs[2] = (corner0.z - origin.z)/(dir.z);
coeffs[3] = (corner1.x - origin.x)/(dir.x);
coeffs[4] = (corner1.y - origin.y)/(dir.y);
coeffs[5] = (corner1.z - origin.z)/(dir.z);

float t = 1.f/0.f;
//Check for the smallest valid intersection distance
//We allow negative values up to -size to create correct sorting if the origin is
//inside the box
for(uint i=0; i<6; i++)
t = (coeffs[i]>=0) && inBoxBounds(corner0,size,origin+dir*coeffs[i])?
min(coeffs[i],t) : t;

return t;
}

void main()
{
float v_size = cube_dim/voxel_resolution;
vec3 r = (vec3(f_coord.xy,1.f/tan(radians(40))));
r.y /= aspect_ratio;
vec3 dir = normalize(r);//;*v_size*0.5;
r+= camera_pos;

float t = boxIntersection(r, dir, -vec3(cube_dim), cube_dim*2);

if(isinf(t))
discard;

if(!((r.x>=-cube_dim) && (r.x<=cube_dim) && (r.y>=-cube_dim) &&
(r.y<=cube_dim) && (r.z>=-cube_dim) && (r.z<=cube_dim)))
r += dir*t;

vec4 color = vec4(0);
int c=0;
while((r.x>=-cube_dim) && (r.x<=cube_dim) && (r.y>=-cube_dim) &&
(r.y<=cube_dim) && (r.z>=-cube_dim) && (r.z<=cube_dim))
{
r += dir*v_size*0.5;
vec4 val = imageLoad(volume_data, ivec3(((r)*0.5/cube_dim+vec3(0.5))*(voxel_resolution-1)));

if(val.w > 0)
{
color = val;
break;
}
c++;
}
fragment_color = color;
}

Сначала мы создаем луч на основе координат экрана (мы используем стандартную технику трассировки лучей, где фокусное расстояние равно 1 / tan (угол)).

Затем мы запускаем луч в текущем положении камеры

Мы проверяем пересечение луча с прямоугольником, содержащим наш объект (мы в основном предполагаем, что наша 3D текстура — это большой куб в сцене, и мы проверяем, попали ли мы в него).

Если мы не нажмем его, мы отбросим фрагмент. Если мы ударим по нему и окажемся снаружи, мы будем двигаться вдоль луча, пока не окажемся на поверхности коробки. Если мы попали в него и оказались внутри, мы остаемся на месте.

На данный момент мы гарантируем, что позиция нашего луча находится внутри коробки.

Теперь мы движемся маленькими отрезками вдоль луча, пока не найдем ненулевое значение или не достигнем конца поля.

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]