(Monogame / HLSL)与阴影贴图问题 - 暗影依赖于相机位置

问题描述 投票:1回答:1

现在我敲我的头,在这个问题相当长的一段时间,终于意识到,我需要认真的帮助......

所以基本上我想要实现正确的阴影到Monogame我的项目我写。为此,我使用多个教程,主要为老XNA写了递延dhader在HLSL。问题是,尽管对我的聚光灯照明和阴影的工作,在我的场景的地板上的光线非常依赖我的相机,因为你可以在图像中看到:https://imgur.com/a/TU7y0bs

我尝试了很多不同的东西来解决这个问题:

  1. 一个更大的DepthBias将拓宽那就是“无阴影”进行大规模的彼得平移和所描述的问题是不固定的,在所有的半径。
  2. 使用指数阴影贴图一纸建议,但我不喜欢,结果所有的,因为光出血难忍小阴影(如在墙上的火炬背后的一个)将不会被渲染。
  3. 我打开我的GBuffer深度图1-Z / W,以获得更多的精度,但它还是不解决问题。

我使用的是

new RenderTarget2D(device,
                Width, Height, false, SurfaceFormat.Vector2, DepthFormat.Depth24Stencil8)

以存储从灯立体深度。

我计算使用此功能PixelShader暗影:请注意,我想这个shader适应在将来点光 - 这就是为什么IM简单地使用长度(LightPos - PixelPos)。 SpotLight.fx - PixelShader

float4 PS(VSO input) : SV_TARGET0
{

    // Fancy Lighting equations

input.ScreenPosition.xy /= input.ScreenPosition.w;
float2 UV = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1) - float2(1.0f / GBufferTextureSize.xy);

// Sample Depth from DepthMap
float Depth = DepthMap.Sample(SampleTypeClamp, UV).x;

// Getting the PixelPosition in WorldSpace
float4 Position = 1.0f;
Position.xy = input.ScreenPosition.xy;
Position.z = Depth;

// Transform Position to WorldSpace
Position = mul(Position, InverseViewProjection);
Position /= Position.w;

float4 LightScreenPos = mul(Position, LightViewProjection);
LightScreenPos /= LightScreenPos.w;


// Calculate Projected UV from Light POV -> ScreenPos is in [-1;1] Space
float2 LightUV = 0.5f * (float2(LightScreenPos.x, -LightScreenPos.y) + 1.0f);
float lightDepth = ShadowMap.Sample(SampleDot, LightUV).r;

// Linear depth model
float closestDepth = lightDepth * LightFarplane; // Depth is stored in [0, 1]; bring it to [0, farplane]
float currentDepth = length(LightPosition.xyz - Position.xyz) - DepthBias;
ShadowFactor = step(currentDepth, closestDepth); // closestDepth > currentDepth -> Occluded, Shadow.

float4 phong = Phong(...); 
return ShadowFactor * phong;
}

LightViewProjection只是light.View * light.Projection InverseViewProjection是Matrix.Invert(camera.View * Camera.Projection)蓬()是一个函数调用我以完成灯光的lightDepthMap简单地存储length(lightPos - Position)

我想在去能够适应代码点光源,以及图片显示,神器。

难道这是与我检索屏幕空间世界上的地位和我的深度得到了一个低分辨率的方式有问题?

帮助深表感谢!

---更新---

我改变了我的灯光着色器来显示存储在阴影贴图的距离和在Pixelshader当场计算出的距离之间的差异:

float4 PixelShaderFct(...) : SV_TARGET0
{
    // Get Depth from Texture

    float4 Position = 1.0f;
    Position.xy = input.ScreenPosition.xy;
    Position.z = Depth;
    Position = mul(Position, InverseViewProjection);
    Position /= Position.w; 

    float4 LightScreenPos = mul(Position, LightViewProjection);
    LightScreenPos /= LightScreenPos.w; 

    // Calculate Projected UV from Light POV -> ScreenPos is in [-1;1] Space
    float2 LUV = 0.5f * (float2(LightScreenPos.x, -LightScreenPos.y) + 1.0f);
    float lightZ = ShadowMap.Sample(SampleDot, LUV).r;

    float Attenuation = AttenuationMap.Sample(SampleType, LUV).r;

    float ShadowFactor = 1;
    // Linear depth model; lightZ stores (LightPos - Pos)/LightFarPlane
    float closestDepth = lightZ * LightFarPlane;
    float currentDepth = length(LightPosition.xyz - Position.xyz) -DepthBias;
    return (closestDepth - currentDepth);
}

正如我基本上输出长度 - (长度 - 偏差)人会期望有一个图像的“DepthBias”作为自己的颜色。但是,这并不是我在这里得到的结果:

https://imgur.com/a/4PXLH7s

在此基础上,我假设,要么我有精密的问题(我觉得这不可思议,因为IM与近和farplanes [0.1,50]工作),或什么是错与IM的方式恢复从我的深度图给定像素的worldPosition。

c# shadow monogame hlsl deferred
1个回答
0
投票

我终于找到了解决办法,如果有人在同样的问题绊倒我在这里张贴:

我使用的教程是为XNA / DX9。但是,作为即时通讯打靶DX10 +一个微小的变化需要做的事情:

在XNA / DX9的UV坐标与实际像素对齐,需要对齐。这就是- float2(1.0f / GBufferTextureSize.xy);float2 UV = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1) - float2(1.0f / GBufferTextureSize.xy);用的。这是没有必要的DX10及以上,并会导致问题,我有。

解:

UV坐标全屏四: 对于XNA / DX9:

input.ScreenPosition.xy /= input.ScreenPosition.w;
float2 UV = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1) - float2(1.0f / GBufferTextureSize.xy);

对于单配制/ DX10 +

input.ScreenPosition.xy /= input.ScreenPosition.w;
float2 UV = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1)
© www.soinside.com 2019 - 2024. All rights reserved.