Столкновение глубины частиц графического процессора не определяется должным образом.C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Столкновение глубины частиц графического процессора не определяется должным образом.

Сообщение Anonymous »

Я написал систему частиц на основе графического процессора (вычислительных шейдеров). Он работает нормально, я хотел добавить столкновение с буфером глубины.
Непрозрачные объекты визуализируются отложенным способом, а некоторые объекты используют трафаретный буфер, поэтому для прохода освещения я повторно использую этот трафарет глубины. текстура (маска глубины отключена, трафарет привязан к чтению). Поэтому для частиц я использую скопированную текстуру трафарета глубины.
Псевдоконвейер:

Код: Выделить всё

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
//...
};

Радиус намеренно установлен на 0
Могу заверить вас, что u_camera.view и u_camera.projection верны, потому что я использую u_camera.viewProjection для рендеринга, который представляет собой просто проекцию * view в c++.

Код: Выделить всё

resolution.xy
— размер области просмотра, это тоже правильно. Я перепроверил это в renderdoc и также использую в других эффектах, которые работают.
К сожалению, столкновение не работает, и частицы не становятся красными после столкновения с каким-либо объектом:< /p>
введите здесь описание изображения
Что я делаю не так? Что я могу проверить для отладки? Я также загрузил Wicked Engine, который имеет эту функцию, и подключил этот код (с небольшими исправлениями, поскольку Wicked Engine использует матрицу по столбцам), и все заработало.
Я установил цвет частиц на выведите значение LinearEyeDepth в красный канал частица.color = float4(linearEyeDepth, 0, 0, 1);
введите здесь описание изображения
Проверил viewPos.z таким же способом:
введите сюда описание изображения
Не знаю, как исправить это

Подробнее здесь: https://stackoverflow.com/questions/784 ... d-properly
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»