Nice results , 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.
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.
In my case using 128x128 blurred maps is enough, so I donāt have to worry about the resolution.
Hereās a nice comparison of these two written by Wolfgang Engel: http://diaryofagraphicsprogrammer.blogspot.com/2008/12/dual-paraboloid-shadow-maps.html
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 http://graphicsrunner.blogspot.de/2008/07/dual-paraboloid-shadow-maps.html
EDIT2: In case anyone reads this here is a link to an implementation of DPSM shadows in XNA http://www.kylehayward.com/Projects/paraboloid.htm this could surely help if you want to go this route
These few posts are more information than Iāve technically found myself. I find myself learning more and more every time I turn around.
Kosmo,
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);
[loop]
for (int i = 0; i < MaxLightsRendered; i++)
{
float3 PointLightDirection = input.WorldPos - PointLightPosition[i];
float DistanceSq = lengthSquared(PointLightDirection);
float radius = PointLightRadius[i];
[branch]
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 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!