我试图添加方向阴影映射到我的地形项目,但我遇到了一些问题。作为参考,我正在学习RasterTek阴影教程。
本教程本质上遵循了以下过程:创建光线>创建基于灯光视图的深度纹理>渲染模型并应用阴影着色器。
我正在努力解决的主要问题是本教程如何处理光线。它本质上模拟了一个位置,并创建了一个正交和视图矩阵。从灯光的设置方式看,这个问题似乎正在升级。对于一个简单的测试,我创建了一个平面,并将光的方向直接向下设置,因此所有的东西都应该被点燃,然而,发生了以下情况:

当地形产生时:

下面是一些我认为有用的领域的代码:
光设置
mLight->SetPosition(XMFLOAT3(10.0f, 30.0f, -0.1f));
mLight->SetLookAt(XMFLOAT3(-10.0f, 0.0f, 0.0f));
mLight->GenerateOthoMatrix(40.0f, 1.0f, 50.0f);void GenerateOthoMatrix(float width, float nearClip, float farClip)
{
mOrthoMatrix = XMMatrixOrthographicLH(width, width, nearClip, farClip);
}XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMVECTOR pos = XMLoadFloat3(&mPosition);
XMVECTOR la = XMLoadFloat3(&mLookAt);
mViewMatrix = XMMatrixLookAtLH(pos, la, up);深度渲染传递
mRenderTexture->SetRenderTarget(mGraphicsDevice->GetContext());
mRenderTexture->ClearRenderTarget(mGraphicsDevice->GetContext());
mLight->GenerateViewMatrix();
mDepthShader.Info.worldMatrix = mTerrain->GetWorldMatrix();
mDepthShader.Info.viewMatrix = mLight->GetViewMatrix();
mDepthShader.Info.projMatrix = mLight->GetOrthoMatrix();
mTerrain->Render(mGraphicsDevice->GetContext());
mDepthShader.Render(mGraphicsDevice->GetContext(), mTerrain->GetIndexCount());
mGraphicsDevice->ResetBackBuffer();
mGraphicsDevice->ResetViewport();Shader呈现调用只需将“info”设置映射到常量缓冲区,然后调用它们的相对顶点/像素着色器。
地形渲染调用只是设置索引/顶点缓冲区和拓扑,为着色DrawIndexed做好准备。
RenderTexture本质上是第二个视图,用于呈现和获取深度纹理。
主渲染传递
mTerrain->Render(mGraphicsDevice->GetContext());
mLight->GenerateViewMatrix();
mShader.Info.lightProj = mLight->GetOrthoMatrix();
mShader.Info.lightView = mLight->GetViewMatrix();
mShader.Info.depthTex = mRenderTexture->GetSRV();
mShader.Render(mGraphicsDevice->GetContext(), mTerrain->GetIndexCount());深度顶点着色器
cbuffer SPerFrameCB : register(b0)
{
matrix worldMatrix;
matrix viewMatrix;
matrix projMatrix;
};
struct VertexIn
{
float4 Pos : POSITION;
};
struct VertexOut
{
float4 Pos : SV_POSITION;
float4 DPos : TEXTURE0;
};
VertexOut main(VertexIn vin)
{
VertexOut vout;
vin.Pos.w = 1.0f;
vout.Pos = mul(vin.Pos, worldMatrix);
vout.Pos = mul(vout.Pos, viewMatrix);
vout.Pos = mul(vout.Pos, projMatrix);
vout.DPos = vout.Pos;
return vout;
}深度象素着色器
struct PixelIn
{
float4 Pos : SV_POSITION;
float4 DPos : TEXTURE0;
};
float4 main(PixelIn pin) : SV_Target
{
float depthVal = pin.DPos.z / pin.DPos.w;
float4 colour = float4(depthVal, depthVal, depthVal, 1.0f);
return colour;
}阴影顶点着色器
cbuffer SPerFrameCB : register(b0)
{
matrix worldMatrix;
matrix viewMatrix;
matrix projMatrix;
matrix lightViewMatrix;
matrix lightProjMatrix;
};
struct VertexIn
{
float4 Pos : POSITION;
float2 Tex : TEXCOORD0;
float3 Normal : NORMAL;
};
struct VertexOut
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD0;
float3 Normal : NORMAL;
float4 LightV : TEXCOORD1;
};
VertexOut main(VertexIn vin)
{
VertexOut vout;
vin.Pos.w = 1.0f;
float4 worldPos = mul(vin.Pos, worldMatrix);
vout.Pos = worldPos;
vout.Pos = mul(vout.Pos, viewMatrix);
vout.Pos = mul(vout.Pos, projMatrix);
vout.LightV = worldPos;
vout.LightV = mul(vout.LightV, lightViewMatrix);
vout.LightV = mul(vout.LightV, lightProjMatrix);
vout.Tex = vin.Tex;
vout.Normal = mul(vin.Normal, (float3x3)worldMatrix);
vout.Normal = normalize(vout.Normal);
return vout;
}阴影象素阴影
Texture2D shaderTexture;
Texture2D lowerTex : register(t0);
Texture2D mediumTex : register(t1);
Texture2D higherTex : register(t2);
Texture2D depthTex : register(t3);
SamplerState SampleTypeClamp : register(s0);
SamplerState SampleTypeWrap : register(s1);
cbuffer SPerLightCB : register(b0)
{
float4 ambientColour;
float4 diffuseColour;
float3 lightDirection;
float padding;
};
struct PixelIn
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD0;
float3 Normal : NORMAL;
float4 LightV : TEXCOORD1;
};
float4 main(PixelIn pin) : SV_Target
{
float bias = 0.001f;
float3 lightDir = -lightDirection;
float4 colour = ambientColour;
float2 projTexCoord;
projTexCoord.x = pin.LightV.x / pin.LightV.w / 2.0f + 0.5f;
projTexCoord.y = -pin.LightV.y / pin.LightV.w / 2.0f + 0.5f;
if ((saturate(projTexCoord.x) == projTexCoord.x) && (saturate(projTexCoord.y) == projTexCoord.y))
{
float depthVal = depthTex.Sample(SampleTypeClamp, projTexCoord).r;
float lightDepthVal = pin.LightV.z / pin.LightV.w;
lightDepthVal -= bias;
if (lightDepthVal < depthVal)
{
float lightIntensity = saturate(dot(pin.Normal, lightDir));
if (lightIntensity > 0.0f)
{
colour += diffuseColour * lightIntensity;
colour = saturate(colour);
}
}
}
float4 lowerColour = lowerTex.Sample(SampleTypeWrap, pin.Tex);
float4 mediumColour = mediumTex.Sample(SampleTypeWrap, pin.Tex);
float4 higherColour = higherTex.Sample(SampleTypeWrap, pin.Tex);
float4 texColour;
float slope = 1.0f - pin.Normal.y, bVal;
if (slope < 0.4f)
{
bVal = slope / 0.4f;
texColour = lerp(lowerColour, mediumColour, bVal);
}
if (slope >= 0.4f && slope < 0.6f)
{
bVal = (slope - 0.4f) * (1.0f / (0.6f - 0.4f));
texColour = lerp(mediumColour, higherColour, bVal);
}
if (slope >= 0.6f)
{
texColour = higherColour;
}
colour *= texColour;
return colour;
}对于大量的代码,我感到非常抱歉--我不确定哪些部分最有助于识别问题。如果有人能帮忙,或者提供影子映射资源,我将非常感激。似乎没有多少影子映射资源,或者至少我找不到很多。
发布于 2015-12-10 02:56:30
看起来你的深度阴影看起来不错。我注意到了你的阴影着色器的不同之处。我已经通过和完全两个系列的DirectX 10和11通过光栅。我将向您展示我的阴影着色器是什么样子;但是,我不记得它们是否从一个教训改变到另一个教训。我会把它们贴在这里供你比较。
Shadow.vsh
/////////////////////////////////////////////////
// Filename: shadow.vsh
/////////////////////////////////////////////////
/////////////
// GLOBALS //
/////////////
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
matrix lightViewMatrix;
matrix lightProjectionMatrix;
};
//////////////////////
// CONSTANT BUFFERS //
//////////////////////
cbuffer LightBuffer2
{
float3 lightPosition;
float padding;
};
//////////////
// TYPEDFES //
struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
float4 lightViewPosition : TEXCOORD1;
float3 lightPos : TEXCOORD2;
};
/////////////////////////////////////////////////
// Vertex Shader
/////////////////////////////////////////////////
PixelInputType ShadowVertexShader( VertexInputType input )
{
PixelInputType output;
float4 worldPosition;
// Change The Position Vector To Be 4 Units For Proper Matrix Calculations
input.position.w = 1.0f;
// Calculate The Position Of The Vertex Against The World, View And Projection Matrices
output.position = mul( input.position, worldMatrix );
output.position = mul( output.position, viewMatrix );
output.position = mul( output.position, projectionMatrix );
// Calculate The Position Of The Vertex As Viewed By The Light Source
output.lightViewPosition = mul( input.position, worldMatrix );
output.lightViewPosition = mul( output.lightViewPosition, lightViewMatrix );
output.lightViewPosition = mul( output.lightViewPosition, lightProjectionMatrix );
// Store The Texture Coordinate For The Pixel Shader
output.tex = input.tex;
// Calculate The Normal Vector Against The World Matrix Only
output.normal = mul( input.normal, (float3x3)worldMatrix );
// Normalize The Normal Vector
output.normal = normalize( output.normal );
// Calculate The Position Of The Vertex In The World
worldPosition = mul( input.position, worldMatrix );
// Determine The Light Position Based On The Position Of The Light And The Position Of The Vertex In The World
output.lightPos = lightPosition.xyz - worldPosition.xyz;
// Normalize The Light Position Vector
output.lightPos = normalize( output.lightPos );
return output;
} // ShadowVertexShaderShadow.psh
/////////////////////////////////////////////////
// Filename: shadow.ps
/////////////////////////////////////////////////
//////////////
// TEXTURES //
Texture2D depthMapTexture : register(t0);
///////////////////
// SAMPLE STATES //
///////////////////
SamplerState SampleTypeClamp : register(s0);
//////////////
// TYPEDEFS //
//////////////
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
float4 lightViewPosition : TEXCOORD1;
float3 lightPos : TEXCOORD2;
};
/////////////////////////////////////////////////
// Pixel Shader
/////////////////////////////////////////////////
float4 ShadowPixelShader( PixelInputType input ) : SV_TARGET
{
float bias;
float4 color;
float2 projectTexCoord;
float depthValue;
float lightDepthValue;
float lightIntensity;
// Set The Bias Value For Fixing The Floating Point Precision Issues
bias = 0.001f;
// Set The Default Output Color To Be Black (Shadow)
color = float4( 0.0f, 0.0f, 0.0f, 1.0f );
// Calculate The Projected Texture Coordinates
projectTexCoord.x = input.lightViewPosition.x / input.lightViewPosition.w / 2.0f + 0.5f;
projectTexCoord.y = -input.lightViewPosition.y / input.lightViewPosition.w / 2.0f + 0.5f;
// Determine If The Projected Coordinates Are In The [0,1] Range. If So Then This Pixel Is In The View Of The Light
if ( (saturate( projectTexCoord.x) == projectTexCoord.x) && (saturate(projectTexCoord.y) == projectTexCoord.y) )
{
// Sample The Shadow Map Depth Value From The Depth Texture Using The Sampler At The Projected Texture Coordinate Location
depthValue = depthMapTexture.Sample( SampleTypeClamp, projectTexCoord).r;
// Calculate The Depth Of The Light
lightDepthValue = input.lightViewPosition.z / input.lightViewPosition.w;
// Subtract The Bias From The LightDepthValue
lightDepthValue = lightDepthValue - bias;
// Compare The Depth Of The Shadow Map Value And The Depth Of The Light To Determine Whether To Shadow Or To Light This Pixel
// If The Light Is In Front Of The Object Then Light The Pixel, If Not Then Shadow This Pixel Since An Object (Occluder) Is Casting A Shadow On It
if ( lightDepthValue < depthValue )
{
// Calculate The Amount Of Light On This Pixel
lightIntensity = saturate( dot( input.normal, input.lightPos ) );
// If This Pixel Is Illuminated Then Set It To Pure White (Non-Shadow)
if ( lightIntensity > 0.0f )
{
// Determine The Final Diffuse Color Based On The Diffuse Color And The Amount Of Light Intensity
color = float4( 1.0f, 1.0f, 1.0f, 1.0f );
}
}
}
return color;
} // ShadowPixelShader还要确保相应的.h & .cpp着色文件与您的着色器中正确的输入和输出结构相匹配。在计算象素着色器中的光强时,似乎使用的是光的方向,而不是光的位置。你确实有更多的纹理添加到你的版本的着色器比我,但我不认为这会造成不同的情况。我没有权限查看您的整个解决方案,因此很难知道错误可能来自何处。我只希望他能帮你当向导。
发布于 2015-12-15 12:46:59
我很清楚这个问题..。我只是看了看图片,没有看你的长文。
我认为光并不能看到整个场景,只看到被照亮的部分。
有一些解决办法,但没有一个是很好的。这是一个典型的问题。
试着增加光视角的效果。XMMatrixOrthographicLH需要更大的宽度。增加光的观察结果减少了你的影子地图的细节。
没有perfekt的解决方案。您需要尝试哪些值适合您的问题。
https://stackoverflow.com/questions/34192133
复制相似问题