View Full Version : Strange shader performance
O-san
12-04-2007, 04:04 AM
Hello! I'm trying to do a lighting shader and determine which lights are enabled. I made a simple IF to see what lights should be used but it slowed things down instead of speeding things up.
Following code is slower:
for(int i=0;i<5;i++){
if(gl_LightSource[i].diffuse != vec4(0.0,0.0,0.0,0.0))
pointLight(i, n, v, shininess, amb, dif, spe);
}
Follwing code is faster (IF is commented out):
for(int i=0;i<5;i++){
//if(gl_LightSource[i].diffuse != vec4(0.0,0.0,0.0,0.0))
pointLight(i, n, v, shininess, amb, dif, spe);
}
If using IF is a bad thing, how should I determine which lights are turned on? Any help appreciated.
ZbuffeR
12-04-2007, 04:46 AM
How much faster ?
What is your video card ?
Is "pointLight" a costly function ?
Hardware support for conditionals is not always very fast.
Depending on the hardware, both branches are executed, and one discarded. Sometimes there is a fixed cost for IF.
O-san
12-04-2007, 06:06 AM
In a simple scene which fills the entire screen I gain around 10-20 frames per second.
The pointLight function looks as follows:
void pointLight(in int i, in vec3 N, in vec3 V,
in float shininess,
inout vec4 ambient,
inout vec4 diffuse,
inout vec4 specular){
vec3 halfVector;
vec3 D = gl_LightSource[i].position.xyz - V;
vec3 L = normalize(D);
float pf=0.5;
float nDotL=0.5;
float dist = 1.0;
float att = 0.5;
dist = length(D);
att = (1.0/(gl_LightSource[i].constantAttenuation +
gl_LightSource[i].linearAttenuation * dist +
gl_LightSource[i].quadraticAttenuation *
dist * dist));
nDotL = dot(N,L);
pf = pow(max(0.0,dot(N,L)),shininess);
ambient += gl_LightSource[i].ambient * att;
diffuse += gl_LightSource[i].diffuse * nDotL * att;
specular += gl_LightSource[i].specular * pf * att;
}
My video card is an GeForce 7800 GT.
V-man
12-04-2007, 07:05 AM
It's normal. Heard it many times now.
Conditionals are costly. They are worth it if there is a large number of instructions that can be skipped.
If a light is off, either set its properties to zero or write multiple shader versions, one for 1 light, another for 2 lights, etc.
Ysaneya
12-04-2007, 07:28 AM
You should try to use a boolean "lightEnabled" instead of testing if the diffuse color isn't pure black. I think it'll allow the driver to do some optimizations, since the state of a light is a constant for all pixels.
O-san
12-04-2007, 11:20 AM
Is it really faster to have multiple versions of the same shader with different number of lights, even if I need to switch active shader a few times (3-8) per pass? That sounds like a strange work around.
Brolingstanz
12-07-2007, 04:00 AM
That sounds like a strange work around.
It's not as strange as it sounds.
Try it, you might like it.
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.