Reading a texture inside if statement

This topic is 1245 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hello. I have a theory question. I'm programming in flash stage3d and it's forbidden to read a texture inside conditionals. But why? I searched in goggle but what I could find is that behavior caused by derivatives (but how ddx/ddy relates to texture read?) - it's impossible to get them in if-statement. But, again, why? As far as I know pixel shader runs on 2x2 pixel grid. If there's a condition in a shader - both parts of it run anyway. So since it runs anyway we have final color in the end. So what's the problem to calculate derivatives?

Share on other sites

if(UV.x>=0)
color=Tex1D(texture,sqrt(UV.x));
what would the proper derivatives be in that case? you as a human might think of a work around or a better solution, but the shader compiler and the HW don't really know.
also, that error is just a desperate try to avoid bad results, you can of course do a
color=Tex1D(texture,sqrt(UV.x));
and skip the compile error, yet you've just hidden the problem, it's still there and the compiler just doesn't know and the hw will show you eventually bad results. Edited by Krypt0n

Share on other sites
Hi, Krypt0n. Thank you. But I still don't get it. Why derivative inside inside 'if' impossible if that 'if' computes anyway? And how derivative relates to texture fetch? It's just uv I need - interpolated value from vertex shader.

Share on other sites

No idea what either of you are talking about. You can sample a texture how ever you want whenever you want. Are you suggesting "stage3d" (no idea what this is), will not let you do it? If so then maybe that's a restriction on that language.

Share on other sites

dpadam450, stage3d is a wraper that uses directx (9 or 11) on windows, opengl on mac and opengl es on mobiles.

No idea what either of you are talking about.

There are certain cases where using the branch or flatten attributes may generate a compile error. The branch attribute may fail if either side of the if statement contains a gradient function, such as tex2D.

And I can't understand this - why sampling uses gradient functions? And what's the problem if both sides of the branch executes.

Share on other sites

If there's a condition in a shader - both parts of it run anyway.

That's not always true; for example, you can control this behavior as shown here in HLSL.  However, even when it is, you don't keep both parts just because you evaluated both parts.

MJP's reply in this thread does a good job of explaining why the problem exists and how to work around it.  Chapter 24.2 of this also explains how ddx/ddy are related to texture sampling if you're interested in the why.

Share on other sites

Thank you. I've read all your links. And I understood that I'm totally confused. Why ddx/ddy can't be calculated ith branch? The pixel have have it's output color, it have interpolated values from vertex shader. Even if shader calculate both sides of the branch, it applies a mask for choosing correct color for pixel. What keeps it to apply that mask to a ddx/ddy values?

Share on other sites

The if/branch has nothing specifically to do with texture sampling. I don't know much about the compile error DX doc says it may push, that could be if you are using a lot of samples/branch samples where it only allows you to say perform 8 samples and because of flattening you actually have 16.

I can tell you my experience with OpenGL an if() statement has sped up my pixel shader in various cases if not speeding up every case, so I don't know when it will actually flatten vs allow dynamic branching.

I was going to say the derivatives have nothing to do with branching, but the above posts suggests something otherwise. But what I dont get is those deriviates are based on the uv values relative to screen space pixels.......if I sample 2 textures 1024 and 512, and only sample one of them and they both use the same uv coords, or not, how does that matter? Mip map selection should still be fine for both those textures. What am I missing. They should be able to fetch properly.  I don't know I've used if's all over the place surrounding what textures to sample or not and never seen anything crazy, unless I just havent benchmarked them enough.

Share on other sites

MJP, thanks a lot. Your explanation is indeed very good. It seems that it's a problem with me . How does texture coordinates relates to your example:

if(x > 1.0f)
x = x * 10.0f;

Sorry, I can't understand it - if shader will execute both parts of a branch and mask out wrong result - it will have the correct data anyway.