2017-02-08 21 views
0

У меня есть средство визуализации WebGL, и я хочу преобразовать случайные координаты мира в координаты экрана в шейдерах фрагментов.Мировое положение для позиции экрана в фрагменте шейдера glsl

Это позволит мне сравнить «рассчитанные координаты экрана» с текущими координатами экрана фрагмента.

У меня есть вся информация, необходимая для этого, я верю, просто не уверен, что это правильный способ сделать это.

... 
    // available information: 

    // uCanvasWidth (float) 
    // uCanvasHeight (float) 
    // modelMatrix (mat4) 
    // modelViewMatrix (mat4) 
    // projectionMatrix (mat4) 
    vec4 someWorldCoordinates = vec4(1., 2., 3., 1.); 
    // map it to screen coordinates? 
    vec4 screenCoordinates = ??? 

    // compare to current fragment location 
    if(screenCoordinates.x > gl_FragCoord.x){ 
    // do stuff 
    } 
    ... 

ответ

1
vec4 worldSpace = vec4(1., 2., 3., 1.); 
// get homogeneous clip space coordinates 
vec4 clipSpace = projectionMatrix * (modelViewMatrix * worldCoords); 
// apply perspective divide to get normalized device coordinates 
vec3 ndc = clipSpace.xyz/clipSpace.w; 
// do viewport transform 
vec2 screenSpace = (ndc.xy * .5 + .5) * vec2(uCanvasWidth, uCanvasHeight); 
screenSpace.y = uCanvasHeight - screenSpace.y; 

Обратите внимание, что ваша modelView матрица, вероятно, содержит трансформирует модели вы рендеринга. Я бы предположил, что точки, указанные в шейдере, считаются уже «final» мир (как в отношении относительно модели, которую вы просматриваете), поэтому вы можете использовать здесь только матрицу view (предпочтительнее предварительно умноженный viewProjection).

+1

Я думаю, что это даст вам инвертированный 'screenSpace.y'. –

+0

Да, вы правы, забыли об этом, исправлено :) –

+1

должно быть 'screenSpace = (ndx.xy * .5 + .5) * vec2 (viewportWidth, viewportIHeight) + vec2 (viewportLeft, viewportRight);'? – gman