Skip to content

Commit

Permalink
fixes made based on the review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
parbenc committed Aug 21, 2024
1 parent c22c401 commit 31d4194
Showing 1 changed file with 41 additions and 29 deletions.
70 changes: 41 additions & 29 deletions docs/understand/texture_fetching.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@
:keywords: AMD, ROCm, HIP, Texture, Texture Fetching

*******************************************************************************
Texture Fetching
Texture fetching
*******************************************************************************

`Textures <../doxygen/html/group___texture.html>`_ are more than just a buffer, that is interpreted as 1D, 2D or 3D array. Because of their legacy as a graphics functionality, textures are indexed with floating-point values. This can happen two different ways, either the index will be in the range of [0..size-1] or in [0..1]. The difference is mathematically just a division, so for the explanations on this page, we'll use the [0..size-1] indices.
`Textures <../doxygen/html/group___texture.html>`_ are more than just a buffer interpreted as a 1D, 2D, or 3D array.

Using floating-point indices isn't trivial. The two issues that come up are sampling and addressing.
As textures are associated with graphics, they are indexed using floating-point values. The index can be in the range of [0 to size-1] or in [0 to 1].

When a texture is indexed with a fraction, the queried value is often between two or more texels (texture elements). The sampling method defines what value to return in these cases.
Depending on the index, texture sampling or texture addressing is performed, which decides the return value.

Sometimes the index is outside the bounds of the texture. This might seem unintuitive, but is useful in computer graphics for putting a texture on a surface multiple times, or just creating a visible sign of out of bounds indexing. The addressing mode defines what value to return when indexing a texture out of bounds.
**Texture sampling**: When a texture is indexed with a fraction, the queried value is often between two or more texels (texture elements). The sampling method defines what value to return in such cases.

There are several different sampling and addressing modes, the differences between which are described in the following.
**Texture addressing**: Sometimes, the index is outside the bounds of the texture. This condition might look like a problem but helps to put a texture on a surface multiple times or to create a visible sign of out-of-bounds indexing, in computer graphics. The addressing mode defines what value to return when indexing a texture out of bounds.

This image is the texture, that will be used as for the examples below. It is 2x2 texels and is indexed in the [0..1] range.
The different sampling and addressing modes are described in the following sections.

Here is the sample texture used in this document for demonstration purposes. It is 2x2 texels and indexed in the [0 to 1] range.

.. figure:: ../data/understand/textures/original.png
:width: 150
Expand All @@ -29,15 +31,23 @@ This image is the texture, that will be used as for the examples below. It is 2x
Texture sampling
===============================================================================

Texture sampling handles the usage of fractional indices. It is the method that describes, which near by values will be used, and how they are combined into the resulting value.
Texture sampling handles the usage of fractional indices. It is the method that describes, which nearby values will be used, and how they are combined into the resulting value.

The various texture sampling methods are discussed in the following sections.

.. _texture_fetching_nearest:
Nearest point sampling
-------------------------------------------------------------------------------

In this mode the ``tex(x) = T[floor(x+0.5)]`` and similarly for 2D and 3D variants. This doesn't interpolate between neighboring values, which results in a pixelated look.
In this method:

``tex(x) = T[floor(x+0.5)]``

This image is the example texture stretched out to a 4x4 pixel quad, but still indexed in the [0..1] range. The in between values are the same as the values of the nearest texel.
This is also applicable for 2D and 3D variants.

This doesn't interpolate between neighboring values, which results in a pixelated look.

The following image shows a texture stretched to a 4x4 pixel quad but still indexed in the [0 to 1] range. The in-between values are the same as the values of the nearest texel.

.. figure:: ../data/understand/textures/nearest.png
:width: 300
Expand All @@ -50,17 +60,17 @@ This image is the example texture stretched out to a 4x4 pixel quad, but still i
Linear filtering
-------------------------------------------------------------------------------

The linear filtering method simply does a linear interpolation between values. Linear interpolation is used to create a linear transition between two values. The formula used is ``(1-t)P1 + tP2`` where ``P1`` and ``P2`` are the values and ``t`` is within the [0..1] range.
The linear filtering method does a linear interpolation between values. Linear interpolation is used to create a linear transition between two values. The formula used is ``(1-t)P1 + tP2`` where ``P1`` and ``P2`` are the values and ``t`` is within the [0 to 1] range.

In the case of texture sampling the following formulas are used:

* For one dimensional textures it is ``tex(x) = (1-α)T[i] + αT[i+1]``
* For two dimensional textures it is ``tex(x,y) = (1-α)(1-β)T[i,j] + α(1-β)T[i+1,j] + (1-α)βT[i,j+1] + αβT[i+1,j+1]``
* For three dimensional textures it is ``tex(x,y,z) = (1-α)(1-β)(1-γ)T[i,j,k] + α(1-β)(1-γ)T[i+1,j,k] + (1-α)β(1-γ)T[i,j+1,k] + αβ(1-γ)T[i+1,j+1,k] + (1-α)(1-β)γT[i,j,k+1] + α(1-β)γT[i+1,j,k+1] + (1-α)βγT[i,j+1,k+1] + αβγT[i+1,j+1,k+1]``
* For one dimensional textures: ``tex(x) = (1-α)T[i] + αT[i+1]``
* For two dimensional textures: ``tex(x,y) = (1-α)(1-β)T[i,j] + α(1-β)T[i+1,j] + (1-α)βT[i,j+1] + αβT[i+1,j+1]``
* For three dimensional textures: ``tex(x,y,z) = (1-α)(1-β)(1-γ)T[i,j,k] + α(1-β)(1-γ)T[i+1,j,k] + (1-α)β(1-γ)T[i,j+1,k] + αβ(1-γ)T[i+1,j+1,k] + (1-α)(1-β)γT[i,j,k+1] + α(1-β)γT[i+1,j,k+1] + (1-α)βγT[i,j+1,k+1] + αβγT[i+1,j+1,k+1]``

Where ``x, y, z`` are the floating-point indices, ``i, j, k`` are the integer indices and ``α, β, γ`` values represent how far along the sampled point is on the three axes. These values are calculated by these formulas: ``i = floor(x')``, ``α = frac(x')``, ``x' = x - 0.5``, ``j = floor(y')``, ``β = frac(y')``, ``y' = y - 0.5``, ``k = floor(z')``, ``γ = frac(z')`` and ``z' = z - 0.5``
Where x, y, and, z are the floating-point indices. i, j, and, k are the integer indices and, α, β, and, γ values represent how far along the sampled point is on the three axes. These values are calculated by these formulas: ``i = floor(x')``, ``α = frac(x')``, ``x' = x - 0.5``, ``j = floor(y')``, ``β = frac(y')``, ``y' = y - 0.5``, ``k = floor(z')``, ``γ = frac(z')`` and ``z' = z - 0.5``

This image is the example texture stretched out to a 4x4 pixel quad, but still indexed in the [0..1] range. The in between values are interpolated between the neighboring texels.
This following image shows a texture stretched out to a 4x4 pixel quad, but still indexed in the [0 to 1] range. The in-between values are interpolated between the neighboring texels.

.. figure:: ../data/understand/textures/linear.png
:width: 300
Expand All @@ -72,68 +82,70 @@ This image is the example texture stretched out to a 4x4 pixel quad, but still i
Texture addressing
===============================================================================

Texture addressing mode handles, when the index is out of bounds of the texture. It describes which values of the texture (or a preset value) to use, when the index is out of bounds.
Texture addressing mode handles the index that is out of bounds of the texture. This mode describes which values of the texture or a preset value to use when the index is out of bounds.

The following sections describe the various texture addressing methods.

.. _texture_fetching_border:
Address mode border
-------------------------------------------------------------------------------

This is probably the simplest address mode. When indexing out of bounds, the texture fetching returns a border value. This has to be set before texture fetching.
In this method, the texture fetching returns a border value when indexing out of bounds. This must be set before texture fetching.

This image is the example texture on a 4x4 pixel quad indexed in the [0..3] range. The out of bounds values are the border color, which is yellow.
The following image shows the texture on a 4x4 pixel quad, indexed in the [0 to 3] range. The out-of-bounds values are the border color, which is yellow.

.. figure:: ../data/understand/textures/border.png
:width: 300
:alt: Texture with yellow border color
:align: center

Texture with yellow border color. The purple lines are not part of the texture, only denote the edge, where the addressing begins.
The purple lines are not part of the texture, only denote the edge, where the addressing begins.

.. _texture_fetching_wrap:
Address mode wrap
-------------------------------------------------------------------------------

This addressing mode is very simple. Mathematically it uses modulo of the index.
In this addressing mode, the modulo of the index is calculated:

``tex(x) = T[x mod (size-1)]``

This creates a repeating image effect.

This image is the example texture on a 4x4 pixel quad indexed in the [0..3] range. The out of bounds values are repeating the original texture.
The following image shows the texture on a 4x4 pixel quad, indexed in the [0 to 3] range. The out-of-bounds values are repeating the original texture.

.. figure:: ../data/understand/textures/wrap.png
:width: 300
:alt: Texture with wrap addressing
:align: center

Texture with wrap addressing. The purple lines are not part of the texture, only denote the edge, where the addressing begins.
The purple lines are not part of the texture, only denote the edge, where the addressing begins.

.. _texture_fetching_mirror:
Address mode mirror
-------------------------------------------------------------------------------

Similar to wrapping mirror mode also creates a repeating image, but this time neighboring instances are mirrored.
Similar to the wrap mode, this mode also creates a repeating image, but by mirroring the neighboring instances.

This image is the example texture on a 4x4 pixel quad indexed in the [0..3] range. The out of bounds values are repeating the original texture, but mirrored.
The following image shows the texture on a 4x4 pixel quad, indexed in the [0 to 3] range. The out-of-bounds values are repeating the original texture, but mirrored.

.. figure:: ../data/understand/textures/mirror.png
:width: 300
:alt: Texture with mirror addressing
:align: center

Texture with mirror addressing. The purple lines are not part of the texture, only denote the edge, where the addressing begins.
The purple lines are not part of the texture, only denote the edge, where the addressing begins.

.. _texture_fetching_clamp:
Address mode clamp
-------------------------------------------------------------------------------

This mode simply clamps the index to be between [0..size-1]. This means that when indexing out of bounds, the values on the edge of the texture will repeat.
This mode clamps the index between [0 to size-1]. Due to this, when indexing out-of-bounds, the values on the edge of the texture repeat.

This image is the example texture on a 4x4 pixel quad indexed in the [0..3] range. The out of bounds values are repeating the values at the edge of the texture.
The following image shows the texture on a 4x4 pixel quad, indexed in the [0 to 3] range. The out-of-bounds values are repeating the values at the edge of the texture.

.. figure:: ../data/understand/textures/clamp.png
:width: 300
:alt: Texture with clamp addressing
:align: center

Texture with clamp addressing. The purple lines are not part of the texture, only denote the edge, where the addressing begins.
The purple lines are not part of the texture, only denote the edge, where the addressing begins.

0 comments on commit 31d4194

Please sign in to comment.