Jump to content
  • Advertisement
Sign in to follow this  
ferr

[.net] XNA Per-Pixel Lighting - *MULTIPLE* Lights

This topic is 4084 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been messing with Riemer's PPL tutorial and have found great success with rendering ONE light. But what about multiple? I've been googling for hours now and all I can find are MDX/HLSL tutorials such as Riemer's which make use of methods that XNA has no equivalent for (i.e. Matrix.LookAtLH and a couple of others). I've tried modifying Riemer's PPL HLSL file by using similar concepts to the MDX tutorials with no success. Here is my most recent version of trying to get it to work properly:
struct VertexToPixel
{
    float4 Position     : POSITION;
    float2 TexCoords        : TEXCOORD0;


     float3 Normal        : TEXCOORD1;
     float3 Position3D        : TEXCOORD2;


};

struct PixelToFrame
{
    float4 Color        : COLOR0;
};

float4x4 xWorldViewProjection;


 float4x4 xWorld;
 float4 xLightPos[2];
 float xLightPower;


bool xUseBrownInsteadOfTextures;

Texture xColoredTexture;

sampler ColoredTextureSampler = sampler_state { texture = <xColoredTexture> ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};



 VertexToPixel SimplestVertexShader( float4 inPos : POSITION0, float3 inNormal: NORMAL0, float2 inTexCoords : TEXCOORD0, uniform int CurrentLight)


{
    VertexToPixel Output = (VertexToPixel)0;

    Output.Position = mul(inPos, xWorldViewProjection);


     Output.Normal = normalize(mul(inNormal, (float3x3)xWorld));
     Output.Position3D = mul(inPos, xWorld);


    Output.TexCoords = inTexCoords;

    if (xUseBrownInsteadOfTextures)
        Output.TexCoords = (0,0);

    return Output;
}



 float DotProduct(float3 LightPos, float3 Pos3D, float3 Normal)
 {
     float3 LightDir = normalize(LightPos - Pos3D);
     return dot(LightDir, Normal);
 }



PixelToFrame OurFirstPixelShader(VertexToPixel PSIn, uniform int CurrentLight)
{
    PixelToFrame Output = (PixelToFrame)0;

     float DiffuseLightingFactor = DotProduct(xLightPos[CurrentLight], PSIn.Position3D, PSIn.Normal);
     Output.Color = tex2D(ColoredTextureSampler, PSIn.TexCoords)*DiffuseLightingFactor*xLightPower;

    return Output;
}

technique Simplest
{
    pass Pass0
    {
         VertexShader = compile vs_2_0 SimplestVertexShader(0);
         PixelShader = compile ps_2_0 OurFirstPixelShader(0);
    }
    pass Pass1
    {    
         VertexShader = compile vs_2_0 SimplestVertexShader(1);
         PixelShader = compile ps_2_0 OurFirstPixelShader(1);
    }
}
All that seems to happen is the Pass1 PixelShader overwrites the Pass0 PixelShader (the second light is the only one rendered). The main difference in my code and Riemer's MDX version is in the Vertex Shader where he makes use of a xLightViewProjection array which is made up of the MDX exclusive Matrix methods. This is how he creates one of the LightViewProjections in MDX:
LightViewProjection[0] = Matrix.LookAtLH(LightPos[0], new Vector3(2, 10, -3), new Vector3(0, 0, 1)) * Matrix.PerspectiveFovLH((float)Math.PI / 2, this.Width / this.Height, 1f, 100f);

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by smitty1276
Why not do all of the lights in one pass?


Wow, that worked. I tried something very similar earlier but I must have formed the Output differently somehow. Here is the solution:


PixelToFrame OurFirstPixelShader(VertexToPixel PSIn, uniform int CurrentLight)
{
PixelToFrame Output = (PixelToFrame)0;

float DiffuseLightingFactor = DotProduct(xLightPos[0], PSIn.Position3D, PSIn.Normal);
float DiffuseLightingFactor2 = DotProduct(xLightPos[1], PSIn.Position3D, PSIn.Normal);

Output.Color = tex2D(ColoredTextureSampler, PSIn.TexCoords)
* (DiffuseLightingFactor + DiffuseLightingFactor2)
* xLightPower;

return Output;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!