Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have found problem in my shader code, which I dont´t know how to solve.

I want to rewrite this code without "ifs"

tmp = evaluate and result is 0 or 1 (nothing else)
if (tmp == 1) val = X1;
if (tmp == 0) val = X2;

I rewite it this way, but this piece of code doesn ´t word correctly

tmp = evaluate and result is 0 or 1 (nothing else)
val = tmp * X1
val = !tmp * X2

However if I change it to:

tmp = evaluate and result is 0 or 1 (nothing else)
val = tmp * X1
if (!tmp) val = !tmp * X2

It works fine... but it is useless because of "if", which need to be eliminated

I honestly don´t understand it Posted Image . I tried compilation with NO and FULL optimalization, result is same

share|improve this question
1  
How about some screenshots? What exactly is the problem? This looks like over micro-optimization. –  ashes999 Apr 23 '12 at 9:37
    
I don't know what is operators precedence in HLSL, but can you try: val = (!tmp) * X2 ? –  zacharmarz Apr 23 '12 at 9:52

2 Answers 2

up vote 4 down vote accepted

Your problem is: !1 == -2, not !1 == 0.

Try this instead:

val = tmp * X1;
val += (1 - tmp) * X2;

This works because:

1 * x = x

(1 - 1) * x = 
   0    * x = 0

-----------

0 * x = 0

(1 - 0) * x = 
   1    * x = x

As suggested by Nathan, to make the code more compact you can use lerp. The equation for lerp is (a * (1 - c)) + (b * c) which is identical to the equation you see above. Thus the code would become:

val = lerp(X2, X1, tmp);
share|improve this answer
1  
Smells like premature optimization though. –  Jonathan Dickinson Apr 23 '12 at 10:36
1  
You could also write val = lerp(X2, X1, tmp), slightly more compact. –  Nathan Reed Jun 26 '12 at 21:40
    
@NathanReed I didn't even realise that it was effectively the same equation as a lerp. Many thanks. –  Jonathan Dickinson Jun 28 '12 at 10:11

I'd advise to just write it with regular branching in your shader code. The D3D shader compiler is extremely good at taking code like this and converting it to a non-branching equivalent in bytecode, and can also detect cases (they're rare but they do happen) where a branching solution is actually faster than a non-branching one. You definitely shouldn't assume that just because your HLSL code uses branching it means that the generated shader will also branch - have a look at the asm version of your shader in PIX and you may be in for an eye-opener - they can often be quite different.

It will also be much more maintainable going forward than if you do anything tricksy to avoid branches in HLSL code.

share|improve this answer
    
+1 on this. I was suprised when I looked at my shaders how few of my branches ended up as branches in the generated code. –  JohnB Jun 27 '12 at 10:56
    
This is actually the definition of why premature optimization is evil - not because it's premature and not because it's optimization, but because it's trying to second-guess what the compiler/environment will do and creating a mess (maybe a small mess, but still a mess) while doing so. –  Darth Satan Jun 27 '12 at 12:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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