对于自动翻译,很抱歉。
现在卡住的部分是阴影贴图。
播放器的位置正好是2000,0,2000;有一个光源,它是天空正上方阴影贴图摄影机的原点(它是一个目录光)。
问题1
你需要一个阴影贴图来应用阴影贴图,不是吗?
阴影贴图现在不起作用,但让我们继续。
只要阴影贴图摄影机的视口位于覆盖空间本身,渲染就不会在阴影贴图上正常工作。
即使它被初始化为1.0f,它也应该都在阴影之外。
虽然当前的阴影贴图相机位置是2000,100,2000,并且焦点位置是0,0,0。
这不是一个红色的正方形区域,应该被确定为在阴影之外。
绿色正方形区域被确定为走出阴影。
仅供参考,视口中没有任何遮挡灯光的对象。你在屏幕截图中看到的阴影就在视口之外,所以它是一个来自阴影贴图上0.0f判断的阴影。
问题2
这是最根本的问题。在阴影过程中没有在阴影贴图上渲染。
一旦这个完成,我会找到第一个问题,但渲染本身不工作,所以没有阴影的对象->原因是未知的
Source表示ShadowShader类正在渲染阴影贴图(ShadowPassRender)
影响这一点的是在光源时创建的视图项目矩阵(阴影着色器类的更新ShaderVariables部分)。
我对这个最怀疑,但它的制作过程与示例没有什么不同,所以我不知道它错在哪里。
我正在使用灯光本身作为一个闪光乒乓球,我将以此为例,并为项目修复它。
生成阴影映射视图-投影矩阵的代码
void CShadowShader::UpdateShaderVariables(ID3D12GraphicsCommandList* pd3dCommandList, XMFLOAT3 xmf3TargetPos)
{
XMFLOAT3 TargetPos = {950, 0, 950};
XMMATRIX lightView = XMMatrixLookAtLH(XMLoadFloat3(&m_pLight->GetPosition()), XMLoadFloat3(&TargetPos), XMLoadFloat3(&m_pLight->GetUp()));
// Transform bounding sphere to light space.
XMFLOAT3 xmf3CenterLS;
XMStoreFloat3(&xmf3CenterLS, XMVector3TransformCoord(XMLoadFloat3(&TargetPos), lightView));
// Ortho frustum in light space encloses scene.
float l = xmf3CenterLS.x - 3000;
float b = xmf3CenterLS.y - 3000;
float n = xmf3CenterLS.z - 3000;
float r = xmf3CenterLS.x + 3000;
float t = xmf3CenterLS.y + 3000;
float f = xmf3CenterLS.z + 3000;
XMMATRIX lightProj = XMMatrixOrthographicOffCenterLH(l, r, b, t, n, f);
// Transform NDC space [-1,+1]^2 to texture space [0,1]^2
XMMATRIX T(
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f);
XMMATRIX S = lightView * lightProj * T;
XMFLOAT4X4 m_xmf4x4ShadowTransform;
XMStoreFloat4x4(&m_xmf4x4ShadowTransform, S);
CB_SHADOW cbShadow{ m_xmf4x4ShadowTransform, m_pLight->GetPosition() };
m_ubShadowCB->CopyData(0, cbShadow);
pd3dCommandList->SetGraphicsRootConstantBufferView(3, m_ubShadowCB->Resource()->GetGPUVirtualAddress());
}
使PSO用于阴影过程
void CShadowShader::CreateShader(ID3D12Device* pd3dDevice, ID3D12RootSignature* pd3dGraphicsRootSignature)
{
m_ubShadowCB = new UploadBuffer<CB_SHADOW>(pd3dDevice, 1, true);
ID3DBlob* pd3dVertexShaderBlob = NULL, * pd3dPixelShaderBlob = NULL;
D3D12_GRAPHICS_PIPELINE_STATE_DESC d3dPipelineStateDesc;
::ZeroMemory(&d3dPipelineStateDesc, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
d3dPipelineStateDesc.pRootSignature = pd3dGraphicsRootSignature;
d3dPipelineStateDesc.VS = CreateVertexShader(&pd3dVertexShaderBlob);
d3dPipelineStateDesc.PS = CreatePixelShader(&pd3dPixelShaderBlob);
d3dPipelineStateDesc.RasterizerState = CreateRasterizerState();
d3dPipelineStateDesc.RasterizerState.DepthBias = 10000.0f;
d3dPipelineStateDesc.RasterizerState.DepthBiasClamp = 0.0f;
d3dPipelineStateDesc.RasterizerState.SlopeScaledDepthBias = 1.0f;
d3dPipelineStateDesc.BlendState = CreateBlendState();
d3dPipelineStateDesc.DepthStencilState = CreateDepthStencilState();
d3dPipelineStateDesc.InputLayout = CreateInputLayout();
d3dPipelineStateDesc.SampleMask = UINT_MAX;
d3dPipelineStateDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
d3dPipelineStateDesc.NumRenderTargets = 0;
d3dPipelineStateDesc.RTVFormats[0] = DXGI_FORMAT_UNKNOWN;
d3dPipelineStateDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
d3dPipelineStateDesc.SampleDesc.Count = 1;
d3dPipelineStateDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
auto tmp = pd3dDevice->CreateGraphicsPipelineState(&d3dPipelineStateDesc, __uuidof(ID3D12PipelineState), (void**)&m_pd3dPipelineState);
if (pd3dVertexShaderBlob)
pd3dVertexShaderBlob->Release();
if (pd3dPixelShaderBlob)
pd3dPixelShaderBlob->Release();
if (d3dPipelineStateDesc.InputLayout.pInputElementDescs)
delete[] d3dPipelineStateDesc.InputLayout.pInputElementDescs;
}
阴影过程的着色器
#include "Common.hlsli"
struct VertexIn
{
float3 PosL : POSITION;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
};
VertexOut VS(VertexIn vin)
{
VertexOut vout = (VertexOut) 0.0f;
MATERIAL matData = material;
// Transform to world space.
float4 posW = mul(float4(vin.PosL, 1.0f), gmtxWorld);
// Transform to homogeneous clip space.
vout.PosH = mul(posW, gmtxShadowTransform);
return vout;
}
// This is only used for alpha cut out geometry, so that shadows
// show up correctly. Geometry that does not need to sample a
// texture can use a NULL pixel shader for depth pass.
void PS(VertexOut pin)
{
// Fetch the material data.
MATERIAL matData = material;
float4 diffuseAlbedo = matData.DiffuseAlbedo;
}
渲染过程的Default.hlsl (韩语评论很少。不重要)
#include "Common.hlsli"
//정점 셰이더의 입력을 위한 구조체를 선언한다.
struct VS_DEFAULT_INPUT
{
float3 position : POSITION;
float3 normal : NORMAL;
};
//정점 셰이더의 출력(픽셀 셰이더의 입력)을 위한 구조체를 선언한다.
struct VS_DEFAULT_OUTPUT
{
float4 position : SV_POSITION;
float4 position_shadow : POSITION0;
float3 position_w : POSITION1;
float3 normal : NORMAL;
};
VS_DEFAULT_OUTPUT VS_Default(VS_DEFAULT_INPUT input)
{
VS_DEFAULT_OUTPUT output;
output.position = mul(mul(float4(input.position, 1.0f), gmtxWorld), gmtxViewProj);
output.position_w = mul(float4(input.position, 1.0f), gmtxWorld).xyz;
output.normal = normalize(mul(float4(input.normal, 0.0f), gmtxWorld).xyz);
output.position_shadow = mul(float4(output.position_w, 1.0f), gmtxShadowTransform);
return (output);
}
float4 PS_Default(VS_DEFAULT_OUTPUT input) : SV_TARGET
{
float4 cColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
cColor += material.AmbientLight * material.DiffuseAlbedo;
float3 toEyeW = normalize(cameraPos - input.position_w);
float3 shadowFactor = float3(1.0f, 1.0f, 1.0f);
shadowFactor[0] = CalcShadowFactor(input.position_shadow);
for (int i = 0; i < nLights; i++)
{
cColor += ComputeLighting(light[i], input.position_w, input.normal, toEyeW, shadowFactor[0]);
}
// Add in specular reflections.
float3 r = reflect(-toEyeW, input.normal);
float4 reflectionColor = { 1.0f, 1.0f, 1.0f, 0.0f };
float3 fresnelFactor = SchlickFresnel(material.FresnelR0, input.normal, r);
cColor.rgb += material.Shininess * fresnelFactor * reflectionColor.rgb;
// Common convention to take alpha from diffuse albedo.
cColor.a = material.DiffuseAlbedo.a;
return (cColor);
}
GitHub链接:https://github.com/kcjsend2/3DGP-BulletPhysics
子弹头物理引擎包括在内,因此子弹头引擎将需要接收并连接到项目以建立。
有关示例,请参阅弗兰克·露娜的“使用DirectX12进行3d游戏编程简介”中的第20章“阴影映射”。
框架是独立的,所以它与示例有很大的不同。
子弹头物理引擎包括在内,因此子弹头引擎将需要接收并连接到项目以建立。
发布于 2021-08-28 14:09:41
我修好了。因为hlsl着色器和direct x使用了不同类型的矩阵。hlsl着色器使用主要列,而直接x使用主要行矩阵。我也用矩阵乘法的顺序来计算错误。
worng是问题的第一个密码
...and这是固定代码:
XMVECTOR lightPos = XMLoadFloat3(&m_pLight->GetPosition());
XMVECTOR TargetPos = XMLoadFloat3(&xmf3TargetPos);
XMVECTOR lightUp = XMLoadFloat3(&m_pLight->GetUp());
XMMATRIX lightView = XMMatrixLookAtLH(lightPos, TargetPos, lightUp);
/*XMVECTOR lightLook = Vector3::Normalize(lightPos - TargetPos);*/
// Transform bounding sphere to light space.
XMFLOAT3 xmf3CenterLS;
XMStoreFloat3(&xmf3CenterLS, XMVector3TransformCoord(XMLoadFloat3(&xmf3TargetPos), lightView));
// Ortho frustum in light space encloses scene.
float l = xmf3CenterLS.x - 800;
float b = xmf3CenterLS.y - 800;
float n = xmf3CenterLS.z - 800;
float r = xmf3CenterLS.x + 800;
float t = xmf3CenterLS.y + 800;
float f = xmf3CenterLS.z + 800;
XMMATRIX lightProj = XMMatrixOrthographicOffCenterLH(l, r, b, t, n, f);
// Transform NDC space [-1,+1]^2 to texture space [0,1]^2
XMMATRIX T(
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f);
XMMATRIX S = lightView * lightProj;
XMFLOAT4X4 xmf4x4LightViewProj;
XMStoreFloat4x4(&xmf4x4LightViewProj, XMMatrixTranspose(S));
S = S * T;
XMFLOAT4X4 xmf4x4ShadowTransform;
XMStoreFloat4x4(&xmf4x4ShadowTransform, XMMatrixTranspose(S));
CB_SHADOW cbShadow{ xmf4x4ShadowTransform, xmf4x4LightViewProj, m_pLight->GetPosition() };
m_ubShadowCB->CopyData(0, cbShadow);
pd3dCommandList->SetGraphicsRootConstantBufferView(3, m_ubShadowCB->Resource()->GetGPUVirtualAddress());
发布于 2021-09-28 11:34:25
当我没有转置发送到着色器的矩阵时,我遇到了完全相同的问题,然后我转置了它,它工作了。:)
https://stackoverflow.com/questions/68939246
复制相似问题