Struggling to find point light resources

Nice results :slight_smile: , are you using CubeMap Shadows or Dual-Paraboloid Shadows?

cubemap. Huge pain. Very unefficient so far. I do not cull at all and all maps are VSM shadows

Yeah, that’s why I implemented Dual-Paraboloid Shadow Maps. This technique uses only two textures instead of six cube map faces. It’s actually possible to render both paraboloids into one texture by writing depth to different color channels. :slight_smile:
Here is a shot of this technique (using Dual-Paraboloid Variance Shadow Maps) used in my engine:

Oh nice. How is artifacting toward the edges? Why do all big engines go the 6 projections way instead?

Well, there are actually two problems with this technique and they are tricky to hide.
First one is the seam between two shadow halves (paraboloids) after you blur the shadow map, but you can solve this by adjusting the blur on the edges of the map, or by offseting the depth by near plane distance (yeah, that’s weird but it works in my case).
The second one is the wrong vertex displacement due to low scene tessellation, but I haven’t encountered this yet.

This technique is great if you want to save on memory, 2 textures instead of 6.

Actually worse for memory, you need ~1.64 times the resolution for the same pixels covered since you have so much blank space. Plus the texel density is not as uniform obviously.

Much cheaper to render though, with cubemaps you have 3 times the drawcalls in the worst case.

It’s not worse for memory, although with Dual-Paraboloids you loose some of the texture space because of the spherical displacement, but it’s still two textures instead of six. Even if you want to have the resolution 1.64 times bigger you use less memory than when using cubemaps. :slight_smile:
In my case using 128x128 blurred maps is enough, so I don’t have to worry about the resolution. :wink:

Here’s a nice comparison of these two written by Wolfgang Engel:

worse for memory for the same quality i mean, if you have a 128x128x6 cubemap you would need to go at least 512x512x2 to match / exceed the quality, 256x256x2 is not sufficient in that case. But i guess that’s obvious.

EDIT nvm I thougth you linked this

EDIT2: In case anyone reads this here is a link to an implementation of DPSM shadows in XNA this could surely help if you want to go this route :slight_smile:

These few posts are more information than I’ve technically found myself. I find myself learning more and more every time I turn around.


Would you mind sharing your whole point light shader in its current state? No matter what I try with the specular, it just looks inverted and messed up. I think I’ve screwed it up along the way. I’m hoping to use yours to compare for mistakes so that I can learn what I did wrong. Somehow, even back to the specularLight question I asked some time ago, I can’t seem to get that working. I actually removed all of the specular code until I saw your screenshot. Sorry for being a pest, just not sure what to try next.

float4 CalcDiffuseLight(float3 normal, float3 lightDirection, float4 lightColor, float lightIntensity)
    return saturate(dot(normal, -lightDirection)) * lightIntensity * lightColor;

float4 CalcSpecularLight(float3 normal, float3 lightDirection, float3 cameraDirection, float4 lightColor, float lightIntensity)
    float3 halfVector = normalize(-lightDirection + -cameraDirection);
    float specular = saturate(dot(halfVector, normal));

    //I have all models be the same reflectance
    float specularPower = 20;

    return lightIntensity * lightColor * pow(abs(specular), specularPower);

// The squared length of a vector
float lengthSquared(float3 v1)
    return v1.x * v1.x + v1.y * v1.y + v1.z * v1.z;

//  Our pixel Shader

float4 BasePixelShader(VertexShaderOutput input) : SV_TARGET
    float4 baseColor = float4(0.7f, 0.7f, 0.7f, 1); //DiffuseTexture.Sample(textureSampler, input.TexCoord);

    float4 diffuseLight = float4(0, 0, 0, 0);
    float4 specularLight = float4(0, 0, 0, 0);

    //calculate our viewDirection
    float3 cameraDirection = normalize(input.WorldPos - CameraPosition);

    //calculate our sunlight
    diffuseLight += CalcDiffuseLight(input.Normal, SunLightDirection, SunLightColor, SunLightIntensity);
    specularLight += CalcSpecularLight(input.Normal, SunLightDirection, cameraDirection, SunLightColor, SunLightIntensity);

    for (int i = 0; i < MaxLightsRendered; i++)
        float3 PointLightDirection = input.WorldPos - 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 += CalcDiffuseLight(input.Normal, PointLightDirection, PointLightColor[i], PointLightIntensity[i]) * attenuation;
            specularLight += CalcSpecularLight(input.Normal, PointLightDirection, cameraDirection, PointLightColor[i], PointLightIntensity[i]) * attenuation;

    //calculate our pointLights

    return diffuseLight * baseColor + specularLight;

technique BasicLightShader
    pass Pass1
        VertexShader = compile vs_5_0 BaseVertexShader();
        PixelShader = compile ps_5_0 BasePixelShader();

Well Kosmo,

I deeply thank you for all your help. I’m running into the below now when standing at the corner of a block. I’m sure that this is something I’m doing, but I don’t have enough knowledge to continue right now. I’m going to keep playing with it, but I won’t keep bugging you with the issues I have. Thank you for your guidance, I’m sure I can conquer these shaders if I continue learning.

EDIT: I finally solved it! I’m going to get some sleep now and I’ll post more tomorrow. In the past few hours I’ve learned that I’ve been confusing what I’ve been trying to achieve with the technique I was using. I realized that the ellipses on my models were the specular reflection :blush: What I’ve really been after is a default illumination for the whole scene, which I’ve achieved with my own, from scratch, ambient shader! I’m so f#%$&@ happy right now. Thanks again for everything buddy!