shader if else performance
Asked Answered
E

3

0

How expensive are if statements inside a fragment shader? How do they compare performance wise against a lerp?

Euonymus answered 6/6, 2023 at 1:53 Comment(0)
C
0

I think it depends on the hardware but in general they are really bad. That’s because the GPU is a pipeline processor. It works best with a fix set of instructions on a large amount of data which is called SIMD(single instruction multiple data). See the Advantages / Disadvantages sections. Any kind of branching is inefficient because the pipeline has to be rebuild. Modern GPUs have a great branch prediction and can hold multiple pipeline versions but in most cases a lerp instruction is better :wink:

Ceylon answered 6/6, 2023 at 2:24 Comment(5)

Ok This is going to be tricky then. I have: if(distance > _Value){ SomethingAwesomeHappens; }

Euonymus

What is "SomethingAwesomeHappens"? You can construct a value that is 1 if your condition is "true" and 0 if it's false. Something like that: // hlsl v = max(0,sign(distance - _Value)) However it depends on what SomethingAwesomeHappens does and if you can control it's result with a float value of 0 / 1. The compiler also might optimise a simple if else block into something like the above mentioned. It can also "unroll" for-loops if they are short and predictable.

Ceylon

I'm assigning one of two textures depending on their distance from a point. If it's within a specified range of the median point, it lerps between the two, otherwise it picks one depending on distance. if((distance < _ColorDecay + _FadeDistance) && (distance > _ColorDecay - _FadeDistance) ) { fixed mixFactor = saturate(1 - (((distance - _ColorDecay) + _FadeDistance) / (_FadeDistance * 2))); cfinal = lerp(c, c2, mixFactor); } else if(distance > _ColorDecay) { cfinal = c; } else { cfinal = c2; }

Euonymus

Uhm, what's actually the point of your if else statement? Your lerp already does everything at once since saturate clamps your mixFactor between 0 and 1. So just use this fixed mixFactor = saturate(1 - ((distance - _ColorDecay) / _FadeDistance + 1) * 0.5); cfinal = lerp(c, c2, mixFactor);

Ceylon

That works perfectly. I have no idea why I was trying to do this the hard way. Thanks!

Euonymus
S
0

Hey I have a question to this Topic.

I have something in my head like a pixelbased multimaterial.
I want to seperate phongshader and labertshader by an pixelbased if calculation to save math operations.
for example one part of the model use Nomalmaps and specular and an otherpart dont use it.
i think to use vertex/fracment with an lerp Funktion.
in the end it isnt specular normal some more expensive per Pixel math.

is it better to lerp between this or make some per Pixel if calculation to save not visible math or just use a different lighting model?

thanks… my english isnt the best but i hope u get the Point.

Thanks Robin

Selfaggrandizement answered 6/6, 2023 at 2:10 Comment(1)

Ask a new question. Don't post a question as an answer.

Dziggetai
J
0

Hi - In your opinion how evil is a fragment program like this that has 2 returns based on a conditional? Will the GPU have to process both outputs?

float4 frag (vertex_output IN): COLOR {
if ( sunColor.z < 0.15){
		float4 stars = tex2D( starTexture,IN.uv.xy );
		stars *= 1 - saturate(sunColor.z * 4);
		return stars + IN.color * float4(Saturate(sunColor,0,1.5,1,0,0),1);
	}
return IN.color * float4(Saturate(sunColor,0,1.5,1,0,0),1);
}
Jordan answered 6/6, 2023 at 1:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.