Вы путаете мел и сыр. PositionCS
является позицией пространства клипа и может быть преобразована в нормализованную позицию пространства устройства с помощью Перспективного деления :
vec2 ndcPos = PositionCS.xyz / PositionCS.w;
sampledDepth
является значением глубины (которое по умолчанию в диапазоне [0, 1]) и может быть получен путем считывания "красного" цветового канала (.r
, .x
) из текстуры буфера глубины. Глубина может быть преобразована в нормализованную координату Z пространства устройства с помощью depth*2.0-1.0
:
vec2 texCoord = ndcPos.xy * 0.5 + 0.5;
// (+ 0.5/resolution.xy;) is not necessary if texture filter is GL_NEAREST
float sampledDepth = texture(gDepth, texCoord).x;
float sampleNdcZ = sampledDepth * 2.0 - 1.0;
. В перспективной проекции и в нормализованном пространстве устройства все точки с одинаковыми координатами x и y находятся на одном луче, который начинается с позиции просмотра.
Это означает, что буфер глубины gDepth
был создан с той же матрицей вида и матрицей проекции, что и ndcPos
(PositionCS
), Вы можете заменить ndcPos.z
соответствующей z-координатой NDC из буфера глубины (sampleNdcZ
), и точка все еще находится на том же луче обзора. ndcPos.z
и sampleNdcZ
являются сравниваемыми значениями в одной и той же системе отсчета.
vec3 ndcSample = vec3(ndcPos.xy, sampleNdcZ);
Эта координата может быть преобразована в координату пространства обзора с помощью матрицы обратной проекции и деления перспективы.
Если точки NDC на одном луче обзора преобразуются в пространство обзора, то координаты XY будут другими. Обратите внимание, что преобразование не является линейным из-за (* 1/.w
). См. Также OpenGL - координаты мыши для координат пространства .
uniform mat4 invProj; // = inverse(projection)
vec4 hViewPos = invProj * vec4(ndcSample, 1.0);
vec3 viewPosition = hViewPos.xyz / hViewPos.w;
Это может быть дополнительно преобразовано с помощью матрицы обратного обзора в мировое пространство и матрицы обратной модели в пространство объектов:
vec3 WorldPos = (invView * vec4(viewPosition, 1.0)).xyz;
vec3 objectPosition = (invModel * vec4(WorldPos, 1.0)).xyz;
Как Вы уже указали, urlencode () не нужно в этом случае, и ни один не для обрезки (). Если я понимаю правильно, шаг 4 должен избежать нескольких тире подряд, но он не предотвратит больше чем двух тире. С другой стороны, тире, соединяющие два слова (как в "крупномасштабном"), будут удалены Вашим решением, в то время как они, кажется, сохраняются на ТАК.
Я не уверен, что это - действительно лучший способ сделать это, но здесь является моим предложением:
$str = strtolower(
preg_replace( array('/[^a-z0-9\- ]/i', '/[ \-]+/'), array('', '-'),
$urlPart ) );
Так: