Рендеринг только за один проход.
В этот проход вы делаете только обратные лица. Положение камеры должно быть переведено из мировых координат в систему координат, которая создается тремя осями с размерами выставляемого объема. Ваша цель - создать матрицу 4x4, где все векторы столбца представляют собой векторы vec4 (..., 0) и x, y, z этих векторов, определяются направлениями оси x, y, z с длиной окна объема. Если ящик параллелен оси х, этот вектор равен (1,0,0). Если он растянут до (2,0,0), то это его собственная ось X, и это будет вектор-столбец для столбца 0 в матрице. Сделайте это с осью y и z с их длиной. Последний вектор столбца в матрице - это положение поля как vec4 (tx, ty, tz, 1), так как эта матрица затем определяет систему координат, и вы используете ее для преобразования положения камеры в однородную (0,0,0) - (1,1,1) поле объема.
Создайте обратную матрицу томов и умножьте кулачок как vec4 (campos, 1) с правой стороны на invVolMatrix. Отправьте полученный vec3 как UNIFORM в шейдер.
Извлеките только обратные поверхности с (0,0,0) - (1,1,1) координатами на соответствующие углы volBox - как вы это делали. Теперь у вас есть в вашем шейдере
- равномерной Кампос
- задняя поверхность Voltex координаты
- вы знаете, что ваш volbox является единичным кубом в локальной системе координат с диагональю от (0,0,0) до (1 , 1,1)
В затенении сделать:
varying vec3 vLocalUnitTexCoord; // backface interpolated coordinate
uniform vec3 LOCAL_CAM_POS; // localised camPos
struct AABB {
vec3 min; // (0,0,0)
vec3 max; // (1,1,1)
};
struct Ray {
vec3 origin; vec3 dir;
};
float getUnitAABBEntry(in Ray r) {
AABB b;
b.min = vec3(0);
b.max = vec3(1);
// compute clipping for box.min and box.max corner
vec3 rInvDir = vec3(1.0)/r.dir;
vec3 tMinima = (b.min - r.origin) * rInvDir;
vec3 tMaxima = (b.max - r.origin) * rInvDir;
// sort for nearest corner
vec3 tEntries = min(tMinima, tMaxima);
// find first real entry value of 3 t-distance values in vec3 container
vec2 tMaxEntryCandidates = max(vec2(tEntries.st), vec2(tEntries.pp));
float tMaxEntry = max(tMaxEntryCandidates.s, tMaxEntryCandidates.t);
}
vec3 getCloserPos(in vec3 camera, in vec3 frontFaceIntersection, in float t) {
float useFrontCoord = 0.5 + 0.5 * sign(t);
vec3 startPos = mix(camera, frontFaceIntersection, useFrontCoord);
return startPos;
}
vec4 main(void)
{
Ray r;
r.origin = LOCAL_CAM_POS;
r.dir = normalize(vLocalUnitTexCoord - LOCAL_CAM_POS);
float t = getUnitAABBEntry(r);
vec3 frontFaceLocalUnitTexCoord = r.origin + r.dir * t;
vec3 startPos = getCloserPos(LOCAL_CAM_POS, frontFaceLocalUnitTexCoord, t);
// loop for integration follows here
vec3 start = startpos;
vec3 end = vLocalUnitTexCoord;
...for loop..etc...
}
Счастливый кодирования!