1
$\begingroup$

I am rendering an infinite plane as described in the following answers:

  1. https://stackoverflow.com/questions/12965161/rendering-infinitely-large-plane
  2. https://stackoverflow.com/questions/7380250/how-to-render-a-plane-of-seemingly-infinite-size

Specifically, I am rendering an "infinite" XZ plane using the following five 4D vertices: $$(0, 0, 0, 1)\quad(1, 0, 0, 0)\quad(0, 0, 1, 0)\quad(-1, 0, 0, 0)\quad(0, 0, -1, 0)$$

In my engine, this is displayed as a ground plane at origin.

What I would like to do is texture this plane. For now, it would be nice to just have a checkered grid. In my fragment shader, I am doing this via the varying $x$ and $z$ positions. This works fine for other "non-infinite" meshes, but for the infinite plane, it is incorrect. This is because the interpolated positions that are passed to the fragment shader don't really make sense in world space, as far as I can tell.

How can I compute the world-space position coordinates in my fragment shader? Is it possible to compute them from the vertex positions, since they represent points at infinity?

The next step would be UV coordinates, but as I understand that might not be possible. I am interested more in being able to easily procedurally texture the plane rather than apply an image to it.

$\endgroup$
2
$\begingroup$

$$ \def\mvec#1{\begin{pmatrix}#1\end{pmatrix}} \def\ivec#1{\left(\begin{smallmatrix}#1\end{smallmatrix}\right)} \def\mmat#1{\begin{bmatrix}#1\end{bmatrix}} \def\vec#1{\mathrm{\mathbf{#1}}} \def\mat#1{\mathrm{\mathbf{#1}}} $$ If you have the screen-space x and y coordinates as well as the depth of your fragment, you can directly compute the coordinates of the corresponding point in world-space. To do so, first compute the clip-space coordinates of your fragment \begin{equation} \vec p'' = \mvec{ 2\cdot\frac{x}{r_x} - 1 \\ 2\cdot\frac{y}{r_y} - 1 \\ 2 \cdot z - 1 \\ 1 } \end{equation} where $x$ and $y$ are the screen-space (pixel) coordinates of the fragment, $z$ is the fragment depth, and $r_x$ and $r_y$ are the width and height (resolution) of the viewport. The above computation is assuming that you're using OpenGL with the default depth range. If you're using Direct3D, use $z$ directly without applying a scaling and offset. If you're using a depth range different from the default, apply whatever is the the appropriate inverse transformation in your case to get from screen-space to clip-space $z$.

Once you have the clip-space coordinates of your fragment, you can simply unproject the fragment by transforming with the inverse view-projection matrix: \begin{equation} \vec p' = \mat M^{-1} \vec p'' \end{equation} where $\mat M$ would be your view-projection matrix. (Note: you will most likely want to pass the inverse view-projection matrix to the shader as a uniform as inverting the view-projection matrix in the shader for every fragment would most likely introduce quite some unnecessary overhead.)

The final step is then to homogenize to get the world-space coordinates of the point \begin{equation} \vec p = \frac{1}{p'_w} \cdot \mvec{ p'_x \\ p'_y \\ p'_z }. \end{equation}

By the way: It would seem to me that rendering this "infinite plane" should be possible using just a single triangle with all corners at infinity in different directions instead of four triangles. Since the boundary of your polygon is pushed to infinity, it shouldn't matter how many edges it has…

$\endgroup$
  • $\begingroup$ This makes sense, but is there any way to do this without computing the world-space position in the fragment shader? It seems kind of brute-force, but I understand if that's the only realistic solution here. Edit: I ask because I've been able to generate some symmetric patterns on the plane already without sending any additional data to the shaders. $\endgroup$ – softbodies Jan 6 at 4:23
  • $\begingroup$ I believe the reason there are four tris is because there are four "vanishing" points to contend with with regards to the infinite plane. If you only have one triangle, it would not be possible to cover the entire space? $\endgroup$ – softbodies Jan 6 at 4:26

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.