TexelFetch and Unity
I recently came across the texelFetch()
function in GLSL. I wanted to dig in to learn a little more about it. I did some research and compiled my findings in this document. As a developer using Unity to write shaders, I found texelFetch() to be surprisingly familiar. If you’re interested in learning more, continue reading.
texelFetch() is a GLSL function. You would use this function to address a specific integer texel from the source texture. It is easiest to understand texelFetch() in contrast to texture().
Key Takeaways
- texelFetch() addresses a 0-based integer coordinate from a texture.
- texelFetch() does not apply filtering to this coordinate.
- Load() is the HLSL version of texelFetch().
- These functions are good to use when the texture represents unique data elements.
Integer Coordinates
You use texture()
to address a specific 0.0-1.0 UV coordinate. For any texture, you would address your coordinates in a range of [0.0, 1.0].
In contrast, texelFetch()
addresses a specific 0-based integer coordinate. For example, in a texture with dimensions 512 x 512, your texelFetch would address a range of [0, 511].
Filtering
texture()
uses bilinear filtering by default. You can opt for point or trilinear instead. For example, suppose you have a 2x2 texture. Assume that the texture has a value of 0 (black) in the left column. Assume that the texture has a value of 1 (white) in the right column.
Now imagine that you sample this texture at point [0.5, 0,5]. The result would be a bilinear blend of 0 and 1. Your result is 0.5.
texelFetch()
does not use filtering. For that same texture, you can sample either coordinate [0,0], [0,1], [1,1], or [1,0]. If you sample coordinate [0,0], your result is 0. If you sample coordinate [1,0], your result is 1.
HLSL equivalent of texelFetch
HLSL has a method that is like texelFetch()
. This method is Load().
Load() also uses a 0-based integer coordinate and does not apply filtering.
How to use texelFetch
texelFetch and Load are both good at sampling unique elements from a texture. For example, you could use a 512x512 texture as a two-dimensional array. In this array, you can encode data about 262,144 elements (e.g., GPU Particles). Then, you can sample this data using texelFetch or Load. This ensures that you only get data about that specific particle.
In practice, I would recommend that you use a Compute Shader with a Structured Buffer or Unordered Access View.
Further Reading
- texelFetch documentation: https://registry.khronos.org/OpenGL-Refpages/gl4/html/texelFetch.xhtml
- Load documentation: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-load
- Mapping from GLSL to HLSL: https://anteru.net/blog/2016/mapping-between-HLSL-and-GLSL/
Hi! I’m Michael.
Thanks for reading my article. I hope you found it useful.
Do you use Unity to build games? Boy-oh-boy, I got some good news for you. I build graphics packages, tools, and assets for Unity. These game assets help you build your game faster. And, they make your game look better and run faster.
Making games with Unity takes a ton of work. I want to make it easier for you. Save yourself some time and make your game look great. I’m 100% confident that at least one of my assets will make your project better. Get started now.