Recommendations for shading billboard sprites?


I’m currently implementing simple billboard sprites just to create a cheap effect for things like grass, moss, and probably particle effects. Right now, I am using BasicEffect to get them on the screen in 3d world space. As you can see below, my very dark scene has my billboard sprites lit very brightly. I’ve got a nice Ambient + Point Light shader thanks to Kosmo, and I suspect I can somehow feed my billboard sprites to that shader somehow.

Is there a recommended approach for shading billboard sprites within a scene that contains existing lighting shaders? My google results have returned me questionable results at best, with most recommend all sorts of tricks that feel like hacks. I have a feeling that this very simple, but I’m having trouble envisioning how you would shade raw textures without a model.

Thanks as always for any advice.

well you can always use the same shader you used for the other stuff. One problem with that would be that the billboard rotates with the camera and so it will be shaded differently depending on its rotation.

However, there is hope!

You would want to have diffuse lighting depending on the distance to each light source, but it should not change based on orientation.

So ideally you sample only the distance from the middle of your billboard to the light.

However, you can’t really do that in the pixel shader, since you only get the position of the current pixel, which rotates around with the billboard.

I think the most simple solution is to have a single float3 “position” variable that you pass before drawing for each billboard.

Then you can calculate the lighting in the vertex shader based on this position alone and pass it to the pixelshader for final output.

I think that should work.

That’s brilliant, I think that should work, I can’t believe I didn’t think of that. One thought, because I have multiple light sources, should I average the darkness based on nearby light sources? Or perhaps just sample the distance and colors from the nearby lights and then perform a combine?

WorldPosition being the variable passed

float3 diffuseLight = float3(0,0,0);

    for (int i = 0; i < MaxLightsRendered; i++)
        float3 PointLightDirection = WorldPosition - PointLightPosition[i];
        float DistanceSq = lengthSquared(PointLightDirection);

        float radius = PointLightRadius[i];
        if (DistanceSq < abs(radius * radius))
            float Distance = sqrt(DistanceSq);

            PointLightDirection /= Distance;

            float du = Distance / (1 - DistanceSq / (radius * radius - 1));

            float denom = du / abs(radius) + 1;

            //The attenuation is the falloff of the light depending on distance basically
            float attenuation = 1 / (denom * denom);

            diffuseLight += PointLightColor[i] *  PointLightIntensity[i] *attenuation;

return diffuseLight * textureColor;

Somehow I missed the notification of your reply! I will work with this. I’ve played with a very hacky way of simulating light. Thank you as always!