   Is this (simple) HLSL shader correct?
  Hey Guys,I'm trying to make a shader that supports up to 8 lights with or without a texture on the model, and with or without a bump map.I had heard that if you use uniform bools like i am that the fx framework will automatically create a seperate shader for each permutation instead of doing branching at run time.Anyhow, does this look correct to you guys?  I know the bump mapping isn't correct but am i doing anything retarded otherwise, anything that might be hurting preformance or that could be done in a better way etc?Thank you!////////////////////////////////////////////////////////////////////////STRUCTURES//////////////////////////////////////////////////////////////////////struct VS_OUTPUT{  float4 hposition : POSITION;  float2 texture0  : TEXCOORD0;  float4 color: COLOR0;  float3 Norm : TEXCOORD2;};////////////////////////////////////////////////////////////////////////GLOBALS//////////////////////////////////////////////////////////////////////float4x4 WorldViewProj : WorldViewProjection; // This matrix will be loaded by the applicationfloat4x4 World;float4 Diffuse;texture Texture; // This texture will be loaded by the applicationsampler Sampler = sampler_state{  Texture   = (Texture);  MipFilter = NONE;  MinFilter = NONE;  MagFilter = NONE;};texture BumpMapTexture; // This texture will be loaded by the applicationsampler BumpMapSampler = sampler_state{  Texture   = (BumpMapTexture);  MipFilter = NONE;  MinFilter = NONE;  MagFilter = NONE;};//whether we should use textures or notuniform bool UseTextures;//whether we should use bump maps or notuniform bool UseBumpMap;//which lights are turned onuniform bool UseLight1;uniform bool UseLight2;uniform bool UseLight3;uniform bool UseLight4;uniform bool UseLight5;uniform bool UseLight6;uniform bool UseLight7;uniform bool UseLight8;//light position or direction informationuniform float4 LightPosDir1;uniform float4 LightPosDir2;uniform float4 LightPosDir3;uniform float4 LightPosDir4;uniform float4 LightPosDir5;uniform float4 LightPosDir6;uniform float4 LightPosDir7;uniform float4 LightPosDir8;//light coloruniform float4 LightColor1;uniform float4 LightColor2;uniform float4 LightColor3;uniform float4 LightColor4;uniform float4 LightColor5;uniform float4 LightColor6;uniform float4 LightColor7;uniform float4 LightColor8;//ambient lightuniform float4 AmbientLight;////////////////////////////////////////////////////////////////////////VERTEX//////////////////////////////////////////////////////////////////////VS_OUTPUT vs_main( float4 Position : POSITION, float2 Texture : TEXCOORD0, float3 Normal : NORMAL ){  VS_OUTPUT OUT;  OUT.hposition = mul( Position , WorldViewProj);  OUT.texture0 = Texture;  OUT.color = Diffuse;  OUT.Norm= -normalize(mul(Normal,World));  return OUT;}////////////////////////////////////////////////////////////////////////PIXEL//////////////////////////////////////////////////////////////////////float4 ps_main( VS_OUTPUT IN, uniform bool ShouldUseTextures, uniform bool ShouldUseBumpMap   , uniform bool ShouldUseLight1, uniform bool ShouldUseLight2    , uniform bool ShouldUseLight3, uniform bool ShouldUseLight4   , uniform bool ShouldUseLight5, uniform bool ShouldUseLight6   , uniform bool ShouldUseLight7, uniform bool ShouldUseLight8 ) : COLOR{  float4 Out;  float4 SourceColor;  float3 Bump;  float3 Norm;  //get the color of the object  if(ShouldUseTextures)  {    SourceColor = tex2D( Sampler, IN.texture0 ) * IN.color;  }  else  {    SourceColor = IN.color;  }  //handle ambient lighting  Out = SourceColor * AmbientLight;  //handle bump mapping  if(ShouldUseBumpMap)  {    IN.Norm += normalize(tex2D( BumpMapSampler, IN.texture0 ) * 2 - 1);  }  //handle light 1  if(ShouldUseLight1)  { Out += saturate(dot(LightPosDir1,IN.Norm)) * SourceColor * LightColor1;  }  //handle light 2  if(ShouldUseLight2)  { Out += saturate(dot(LightPosDir2,IN.Norm)) * SourceColor * LightColor2;  }  //handle light 3  if(ShouldUseLight3)  { Out += saturate(dot(LightPosDir3,IN.Norm)) * SourceColor * LightColor3;  }  //handle light 4  if(ShouldUseLight4)  { Out += saturate(dot(LightPosDir4,IN.Norm)) * SourceColor * LightColor4;  }  //handle light 5  if(ShouldUseLight5)  { Out += saturate(dot(LightPosDir5,IN.Norm)) * SourceColor * LightColor5;  }  //handle light 6  if(ShouldUseLight6)  { Out += saturate(dot(LightPosDir6,IN.Norm)) * SourceColor * LightColor6;  }  //handle light 7  if(ShouldUseLight7)  { Out += saturate(dot(LightPosDir7,IN.Norm)) * SourceColor * LightColor7;  }  //handle light 8  if(ShouldUseLight8)  { Out += saturate(dot(LightPosDir8,IN.Norm)) * SourceColor * LightColor8;  }  Out = saturate(Out);  return Out;}////////////////////////////////////////////////////////////////////////TECHNIQUE//////////////////////////////////////////////////////////////////////technique Technique0{  pass Pass0  {    Sampler[0] = (Sampler); // Needed by pixel shader    Sampler[1] = (BumpMapSampler);    VertexShader = compile vs_2_0 vs_main();    PixelShader  = compile ps_2_0 ps_main(UseTextures,UseBumpMap,UseLight1,UseLight2,UseLight3,UseLight4,UseLight5,UseLight6,UseLight7,UseLight8);  }}
  Why not pass the number of lights to the shader, put the relative data in an array, then use a loop to deal with the lights in turn?   ;  Would the looping be slower?Right now (to my understanding at least!!), it will create a shader for each permutation needed so if i have an area that only needs 3 lights, it will make a shader that processes 3 lights without branching or looping.Is that right?(btw wow... gd.net forums were down for at least 6 hours what happened i wonder??)   ;  I think it should create permutations for you...you can just use fxc and check the resulting assembly if you'd like to be sure.   ;  I have this working pretty well now but am trying to convert it to using arrays in the shader instead of having LightColor1, LightColor2, etc.Problem is, how do i set the value of an array in a shader?For setting a regular variable i do it like this:anEffect->SetBool("UseLight1",true);but if UseLight was a uniform bool array in the shader, how would i set UseLight[1] to true?   ;  Couldn't you set the array just before you send the data into the array?for all lights    light = true/falseanEffect->SetBoolArray(handle, boolArray, 8)I think that should work.;  Use an array instead. :-)Have you eventually heard of Deferred Rendering?It may be a bit simpler for many light sources.   ;  Here is some code showing how I do itin the shadershared float4 lightpos[10];then in c++ code, MAXLIGHTS defined as 10D3DXHANDLE lightposarray;shared_lightpos_fx = new D3DXHANDLE[MAXLIGHTS];lightposarray = Shaderfx->GetParameterByName( NULL, "lightpos" );for ( a = 0 ; a < MAXLIGHTS ; a++ ) {  shared_lightpos_fx[a] = Shaderfx->GetParameterElement(lightposarray,a);};  Thanks for that!I got this working a little bit ago and with arrays it's much nicer, thanks for the input guys (:In the example code above this post, it does this:shared_lightpos_fx = new D3DXHANDLE[MAXLIGHTS];Since MAXLIGHTS is a compile time constant, I'd say the better way would be to declare shared_lightpos_fx with a size of [MAXLIGHTS] instead of using new, since dynamic allocation is slow, can cause memory fragmentation, is easily leaked, etc!   