0

I have a fragment shader that transforms the view into something resembling mode7. I want to know the Screen-Space x,y coordinates given a world position. As the transformation happens in the fragment shader, I can't simply inverse a matrix. This is the fragment shader code:

uniform float Fov; //1.4
uniform float Horizon; //0.6
uniform float Scaling; //0.8

void main() {
    vec2 pos = uv.xy - vec2(0.5, Horizon);
    vec3 p = vec3(pos.x, pos.y, pos.y + Fov);
    vec2 s = vec2(p.x/p.z, p.y/p.z) * Scaling;

    s.x += 0.5;
    s.y += screenRatio;

    gl_FragColor = texture2D(ColorTexture, s);
}

It transforms pixels in a pseudo 3d way:

Mode 7 Pic

- What I want to do is get a screen-space coordinate for a given world position (in normal code, not shaders). How do I reverse the order of operations above?

This is what I have right now: (GAME_WIDTH and GAME_HEIGHT are constants and hold pixel values, e.g. 320x240)

vec2 WorldToScreenspace(float x, float y) {
    // normalize coordinates 0..1, as x,y are in pixels
    x = x/GAME_WIDTH - 0.5;
    y = y/GAME_HEIGHT - Horizon;

    // as z depends on a y value I have yet to calculate, how can I calc it?
    float z = ??;

    // invert: vec2 s = vec2(p.x/p.z, p.y/p.z) * Scaling;
    float sx = x*z / Scaling;
    float sy = y*z / Scaling;

    // invert: pos = uv.xy - vec2(0.5, Horizon);
    sx += 0.5;
    sy += screenRatio;

    // convert back to screen space
    return new vec2(sx * GAME_WIDTH, sy * GAME_HEIGHT);
}
Spektre
  • 49,595
  • 11
  • 110
  • 380
mfl
  • 1
  • 1
  • "As the transformation happens in the fragment shader, I can't simply inverse a matrix.". Why not? the transformation you do in the FS is just representable as a uniform standard homogeneous transform matrix, and so is its inverse. Also, using `textureProj` familiy of functions would lead to the most efficient way to do the perspective divide in your scenario. – derhass Feb 11 '18 at 17:59
  • why not pass world coordinates (un-transformed) to fragment too ... also see [Understanding 4x4 homogenous transform matrices](https://stackoverflow.com/a/28084380/2521214) so (pseudo)inverse matrix is also an option – Spektre Feb 12 '18 at 07:59
  • @derhass I am not really sure how I would go about that. My framework doesnt allow access to the vertex shader, can I pass that into the fragment shader? – mfl Feb 12 '18 at 23:54
  • also, my game doesn't really use matrixes internally and i am not that familiar with them. i wouldn't know how to represent my shader as a transformation matrix. but thanks for the link. – mfl Feb 13 '18 at 00:02

0 Answers0