Hello laugh ,

I need a really(really, really) good Spotlight
shader - it will be the most important part of
the game, so vertex lightning is much to bad.

I know that there is a Spotlight shader by Emre,
who already helped me once adding Dynamic Lights.
But I get more and more problems with that Shader...

It looks good, but I need some things to be
changed/a new one. Here is how it looks at
the moment(Its a bit racked... but just because i
got a new monitor today..):


I applied the object shader to the view...
Invisible Objects sometimes get Visible,
Translucent things aren't translucent and
no static lights...

EDIT: Here is the code for the shader (at the moment)
Code:
// By Joseph Duffey Jan 2008
// For the GameStudio Community
// 
// Projective Texturing Spotlight + Fog
//

const float4x4 matWorldViewProj;                                          // World*view*projection matrix.
const float4x4 matMtl;                                                    // custom matrix passed via the material
const float4x4 matWorld;                                                  // World matrix.
const float4 vecViewPos;                                                  // Current view position passed from application
const float4 vecFog;                                                      // Vector calculated from the current view's clip and fog parameters
const float4 vecAmbient;                                                  // Ambient color, passed by the engine.
const float4 vecSkill1;                                                   // spotlights pos (xyz) and range (w) from application
const float4 vecSkill5;                                                   // spotlights normalized direction vector from aplication
static const float SpecularIntensity = 0.5f;                              // The intensity of the specular light. 
static const float SpecularPower = 2.0f;                                  // The specular power, used as 'glossiness' factor. 

texture entSkin1;                                                         // bitmap of object material applied to
texture mtlSkin1;                                                         // projection bitmap defined in material

sampler BaseTex = sampler_state
{
    Texture = <entSkin1>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = wrap;
    AddressV = wrap;
};

sampler ProjTex = sampler_state
{
    Texture = <mtlSkin1>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = clamp;
    AddressV = clamp;
};

struct VS_INPUT
{
    float4 Pos    : POSITION;
    float3 Normal : NORMAL;
    float4 Tex    : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4 Pos       : POSITION;
    float4 Tex       : TEXCOORD0;
    float4 Tex1      : TEXCOORD1;
    float4 LightVec  : TEXCOORD2;
    float3 Normal    : TEXCOORD3;
    float3 ViewDir   : TEXCOORD4; 
    float Fog        : FOG;
};

struct PS_INPUT
{
    float4 Tex      : TEXCOORD0;
    float4 Tex1     : TEXCOORD1;
    float4 LightVec : TEXCOORD2;
    float3 Normal   : TEXCOORD3;
    float4 ViewDir  : TEXCOORD4;
};


VS_OUTPUT MAIN_VS( VS_INPUT In ) 
{
    VS_OUTPUT Out = (VS_OUTPUT) 0;

    Out.Pos = mul(In.Pos, matWorldViewProj);                                 // Transform vertex position to screen space:
    Out.Normal = normalize(mul(In.Normal, matWorld));                        // Transform the normal from object space to world space:
    Out.Tex = In.Tex;                                                        // Copy color texture coordinates through
    Out.Tex1 = mul( mul(In.Pos,matWorld), matMtl);                      // Calc the projected texture coordinates
    Out.LightVec.xyz = mul(In.Pos, matWorld) - vecSkill1;                    // light to position vector
    Out.LightVec.w = length(Out.LightVec.xyz)/vecSkill1.w;                   // light range
    Out.ViewDir = vecViewPos - mul(In.Pos, matWorld);                        // Calculate a vector from the vertex to the view, for specular  
  
    float3 worldPos = mul(In.Pos, matWorld);                                 // Transform the vertex to world space
    Out.Fog = 1 - (distance(worldPos, vecViewPos) - vecFog.x) * (vecFog.z);  // Calculate Fog
    return Out;
}

float4 MAIN_PS( PS_INPUT In ) : COLOR 
{
    In.LightVec.xyz = normalize(In.LightVec.xyz);                            // normalize light pos xyz, but not w (range) 
    In.Normal = normalize(In.Normal);
    In.ViewDir = normalize(In.ViewDir);

    float4 LightDir = normalize(vecSkill5);                                  // Normalize spotlight direction

    float4 Attn = 1 - saturate(dot(In.LightVec.w, In.LightVec.w));           // Calculate attenuation
    float4 Color = tex2D( BaseTex, In.Tex );                                 // Base texture lookup
 
    float projIntensity = saturate(dot(-In.LightVec, In.Normal));            // The more perpendicular the polygon to the light, the more light PPL
    float4 projColor = In.Tex1.w < 0.0 ? 0.0 : tex2Dproj( ProjTex, In.Tex1 ); // look up projection texture only in facing dir (avoid back proj)
    float4 proj = projColor * projIntensity;                                 // multiply the proj color with the amount of intensity

    float3 R = normalize(2 * dot(In.Normal, -LightDir) * In.Normal + LightDir); // Calculate the reflection vector:
    float Specular = 0;//(pow(saturate(dot(R, In.ViewDir)), SpecularPower) * SpecularIntensity);    // Calculate the speculate component only in spotlight

    Specular *= saturate(proj);                                              // only allow specular in projection area

    return (Color * vecAmbient) +  Color * ((proj + Specular)* Attn);        // final color
}

//////////////////////////////
// ADD POINTLIGHT
//////////////////////////////
float4 vecLightPos[8];
float4 vecLightColor[8];
float4x4 matWorldInv;	
struct PointOut
{
	float4 Position     : POSITION;
	float2 Tex0    : TEXCOORD0; 
	float4 Color		: COLOR0; 
	float  Fog     : FOG;

};
PointOut PointVS(float4 inPos : POSITION, float2 inTex0 : TEXCOORD0,float3 inNormal: NORMAL0)
{
	PointOut Out;
	Out.Position = mul(inPos, matWorldViewProj);
	Out.Tex0 = inTex0;
	Out.Color        = float4(0,0,0,0);
	//Add point lights
	for(int i = 0; i <= 5; i++)
	{
		// Diffuse lighting
		float4 objLightPos  = mul(float4(vecLightPos[i].xyz, 1), matWorldInv);
		float4 objLightDir  = objLightPos - inPos;
		float4 objLightDirN = normalize(objLightDir);
		float  diffLight    = max(dot(objLightDirN, inNormal), 0);
		
		// Calculate attenuation factor
		float falloffFactor = 0;
		if(vecLightPos[i].w > 0)
		{
			float linearDistance = length(objLightDir)/vecLightPos[i].w;
			if(linearDistance < 1) falloffFactor = 1 - linearDistance;
		}
		diffLight *= falloffFactor;
		
		// Add to final result
		Out.Color.rgb  += vecLightColor[i].rgb * diffLight;
	}
	float3 worldPos =  mul(inPos, matWorld);
	Out.Fog = 1 - (distance(worldPos, vecViewPos) - vecFog.x) * (vecFog.z);
	return Out;
}
float4 PointPS(PointOut In) : COLOR0
{
	float4 FinalColor;
	FinalColor = tex2D(BaseTex,In.Tex0);
	FinalColor *=(In.Color)*3;
	return FinalColor;
}
technique PP_Spot
{
	pass p0 
	{
		VertexShader = compile vs_1_1 MAIN_VS();
		PixelShader  = compile ps_2_0 MAIN_PS();
	}
	pass P1
	{
		alphablendenable=true;
		srcblend=one;
		destblend=one;
		VertexShader = compile vs_2_0 PointVS();
		PixelShader = compile ps_2_0 PointPS();
	}
}



So, but the shader I need, needs:
  • Pointlights
  • Use Models Ambient Value to make Object brighter
  • Static Lights (pre-compiled with wed)
  • Let Translucent Objects Translucent
  • Let Invisible Objects Invisible
  • Should apply to all objects
  • Not be tooo slow...not so important, A8 Pro will make with BSP faster laugh
  • Size should be adjustable
  • Lightrange should be adjustable
  • Make use of FOG


Thanks for any input laugh

I know it is really, really, really much
what I want, but I am such a noob at
programming shaders...


Thanks for advance and best regards,
Rei

Last edited by Rei_Ayanami; 06/10/10 13:27.