- Home /
Why is the negative texel size check necessary when flipping texture coordinates for D3D?
In the Unity docs here , the code for flipping texture coordinates during postprocessing based on whether texture coordinates start at the top (like D3D) is as follows
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
uv.y = 1-uv.y;
#endif
Why do we need the negative texel size check? The code seems to work fine in most cases without the 'if' clause using just the preprocessor check. When "chaining" multiple postprocessing effects though, it's found that the 'if' clause is necessary for the code to work. Could someone please explain why we need if this check for negative texel size and what it means?
Answer by teamLab_davis · Nov 11, 2021 at 12:11 PM
Hi @thallippoli "Writing shaders for different graphics APIs" section of Unity's documentation contains your answer.
https://docs.unity3d.com/Manual/SL-PlatformDifferences.html
I'll copy some text below in case the link changes in the future. (this Q&A form doesn't have such great text formatting options.)
-=-=-=-=-=-=-=-
Render Texture coordinates
Vertical Texture coordinate conventions differ between two types of platforms: Direct3D-like and OpenGL-like.
Direct3D-like: The coordinate is 0 at the top and increases downward. This applies to Direct3D, Metal and consoles.
OpenGL-like: The coordinate is 0 at the bottom and increases upward.
This applies to OpenGL and OpenGL ES.
This difference tends not to have any effect on your project, other than when rendering into a Render Texture . When rendering into a Texture on a Direct3D-like platform, Unity internally flips rendering upside down. This makes the conventions match between platforms, with the OpenGL-like platform convention the standard.
Image Effects and rendering in UV space are two common cases in the Shaders where you need to take action to ensure that the different coordinate conventions do not create problems in your project.
Image Effects
When you use Image Effects and anti-aliasing, the resulting source Texture for an Image Effect is not flipped to match the OpenGL-like platform convention. In this case, Unity renders to the screen to get anti-aliasing and then resolves rendering into a Render Texture for further processing with an Image Effect.
If your Image Effect is a simple one that processes one Render Texture at a time, Graphics.Blit deals with the inconsistent coordinates. However, if you’re processing more than one Render Texture together in your Image Effect, the Render Textures are likely to come out at different vertical orientations in Direct3D-like platforms and when you use anti-aliasing. To standardise the coordinates, you need to manually “flip” the screen Texture upside down in your Vertex Shader so that it matches the OpenGL-like coordinate standard.
The following code sample demonstrates how to do this:
Note: the sample code in the article matches the sample code mentioned in the question