Непрозрачные объекты визуализируются отложенным способом, а некоторые объекты используют трафаретный буфер, поэтому для прохода освещения я повторно использую этот трафарет глубины. текстура (маска глубины отключена, трафарет привязан к чтению). Поэтому для частиц я использую скопированную текстуру трафарета глубины.
Псевдоконвейер:
Код: Выделить всё
Texture2D lightingColorMap;
Texture2D gColorMap;
Texture2D gNormalMap;
Texture2D gRoughnessMetalnessMap;
Texture2D gDepthStencilMap;
Texture2D copiedDepthStencilMap;
void CreateResources()
{
gColorMap = CreateRenderTarget();
gNormalMap = CreateRenderTarget();
gRoughnessMetalnessMap = CreateRenderTarget();
gDepthStencilMap = CreateDepthStencilTarget(DXGI_FORMAT_R24G8_TYPELESS, D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE);
lightingColorMap = CreateRenderTarget();
}
void CopyPass()
{
dx11Context->CopyResource(copiedDepthMap.Get(), gDepthStencilMap.Get());
}
void Draw()
{
CreateResources();
CopyPass();
//deferred pass
{
//this does
// ClearRenderTargetView
// ClearDepthStencilView only if clearDepthStencil is true
// OMSetRenderTargets
//uses g*Map textures
BindRenderTargets(.clearDepthStencil = true);
DrawOpaque();
UnbindRenderTargets();
}
//lighting pass + transparent (particles)
{
//this one binds lightingColorMap as render target and reuses gDepthStencilMap (read only)
//
BindRenderTargets(.clearDepthStencil = false);
gColorMap->BindSRV(0);
gNormalMap->BindSRV(1);
gRoughnessMetalnessMap->BindSRV(2);
gDepthStencilMap->BindSRV(3);
DrawFullscreen();
//runs compute shaders that emit, update and kickoff particles
//also executes the draw call
copiedDepthStencilMap->bindSRV(4);
DrawParticles();
}
}
в вычислительном шейдере обновления частиц я добавил функцию, которая должна проверять столкновение с буфером глубины:
Код: Выделить всё
float LinearizeDepth(const float z, const float near, const float far)
{
return near * far / (far + z * (near - far));
}
float LinearizeDepth(const float z)
{
const float near = nearFar.y;
const float far = nearFar.x;
return near * far / (far + z * (near - far));
}
Texture2D t_depthMap : register(t4);
void DepthCollision(inout Particle particle, float dt)
{
float3 nextPos = particle.position + particle.speed * dt;
float3 viewPos = mul(float4(nextPos, 1.0f), u_camera.view).xyz;
float4 projPos = mul(float4(viewPos, 1.0f), u_camera.projection);
projPos.xyz /= projPos.w;
float2 aProjPos = abs(projPos.xy);
if (aProjPos.x < 1.0f && aProjPos.y < 1.0f) // visible on screen
{
float2 uv = projPos.xy * float2(0.5f, -0.5f) + 0.5f;
float depth = t_depthMap[uv * resolution.xy].r;
float linearEyeDepth = LinearizeDepth(depth);
float radius = 0.0f;
float surfaceThickness = 1.0f;
if (viewPos.z > linearEyeDepth - radius && viewPos.z < linearEyeDepth + radius + surfaceThickness)
{
particle.color = float4(1, 0, 0, 1);
}
}
}
Код: Выделить всё
u_cameraКод: Выделить всё
struct Camera
{
row_major float4x4 model; //inverseView
row_major float4x4 view;
row_major float4x4 projection;
row_major float4x4 viewProjection;
row_major float4x4 inverseProjection;
row_major float4x4 inverseViewProjection;
};
cbuffer PerFrame : register(b0)
{
Camera u_camera;
float4 resolution; //.xy -> w, h; .zw -> 1/w, 1/h
float4 nearFar; //.xy -> near, far; .zw -> 1/near, 1/far
//...
};
Могу заверить вас, что u_camera.view и u_camera.projection верны, потому что я использую u_camera.viewProjection для рендеринга, который представляет собой просто проекцию * view в c++.
Код: Выделить всё
resolution.xyК сожалению, столкновение не работает, и частицы не становятся красными после столкновения с каким-либо объектом:< /p>
введите здесь описание изображения
Что я делаю не так? Что я могу проверить для отладки? Я также загрузил Wicked Engine, который имеет эту функцию, и подключил этот код (с небольшими исправлениями, поскольку Wicked Engine использует матрицу по столбцам), и все заработало.
Я установил цвет частиц на выведите значение LinearEyeDepth в красный канал частица.color = float4(linearEyeDepth, 0, 0, 1);
введите здесь описание изображения
Проверил viewPos.z таким же способом:
введите сюда описание изображения
Не знаю, как исправить это
Подробнее здесь: https://stackoverflow.com/questions/784 ... d-properly
Мобильная версия