Лучшее решение, которое я мог придумать, состояло в том, чтобы использовать цилиндрический щит для расчета глубины и сферический для фактического положения квадроцикла. Это позволяет использовать сферический биллбординг, гарантируя постоянную глубину квадроцикла.
Для справки приведены чертежные модели ModelView Matrixes. [x]: означает, что значение остается как есть.
Cylindrical mvMatrix Spherical mvMatrix
[1][x][0][x] [1][0][0][x]
[0][x][0][x] [0][1][0][x]
[0][x][1][x] [0][0][1][x]
[x][x][x][x] [x][x][x][x]
Сначала модифицировать ModelViewMatrix для цилиндрического billboarding и генерировать глубины вершины как таковой:
depthV = projectionMatrix * (mvm * vertex);
Далее установите вторые значения столбцов для сферической billboarding и создать четверной как обычно:
mvm[1][0] = 0; mvm[1][2] = 0; mvm[1][1] = 1;
gl_Position = projectionMatrix * (mvm * vertex);
Наконец, отправьте depthV в шейдер фрагмента и используйте его для расчета глубины.
float ndcDepth = depthV.z/depthV.w;
gl_FragDepth = ((gl_DepthRange.diff * ndcDepth) + gl_DepthRange.near + gl_DepthRange.far)/2.0;
Масштабирование должно выполняться перед применением матриц ModelView.