@SpectreSpect

Как оптимизировать запись в RWStructuredBuffer?

Я хочу перенести мой трассировщик путей с пиксильного шейдера на несколько вычислительных шейдеров, чтобы во первых было удобнее задавать сцену, а во вторых, чтобы избежать проблему с текстурами(количество слотов под текстуры ограничено. Я хочу при столкновении луча с объектом определять, с каким именно объектом он столкнулся, и в соответствии с текстурой, заданной в объекте, задавать цвет поверхности, с которой столкнулся луч). Но проблема в том, что моя идея получается очень не оптимизированной, фпс падает до 30 при рисовании 2 сфер(при высчитывании трассировки путей с двумя сферами в одном шейдере, фпс было около 700). Вот пример кода:
```
struct Ray
{
float3 direction;
float t;
float3 origin;
float padding1;
float3 energy;
float padding2;
float3 result;
float padding3;
};

RWTexture2D Result : register(u0);
RWStructuredBuffer tray : register(u1);

Ray InitRay0(float3 direction, float3 origin)
{
Ray ray;
ray.t = 0;
ray.direction = direction;
ray.origin = origin;
ray.energy = 1;
ray.result = 0;
ray.padding1 = 0;
ray.padding2 = 0;
ray.padding3 = 0;
return ray;
}

[numthreads(8, 8, 1)]
void main(uint3 threadID : SV_DispatchThreadID)
{
_seed = _randValue;
uint width, height;
Result.GetDimensions(width, height);
uint oneDID = threadID.x + threadID.y * width;
for (int i = 0; i < 8; i++)
{
tray[oneDID] = InitRay0(float3(0, 0, 0), float3(0, 0, 0));
Result[threadID.xy] = float4(tray[oneDID].result, 1);
}
}
```
Я хочу перенести мой трассировщик путей с пиксильного шейдера на несколько вычислительных шейдеров, чтобы во первых было удобнее задавать сцену, а во вторых, чтобы избежать проблему с текстурами(количество слотов под текстуры ограничено. Я хочу при столкновении луча с объектом определять, с каким именно объектом он столкнулся, и в соответствии с текстурой, заданной в объекте, задавать цвет поверхности, с которой столкнулся луч). Но проблема в том, что моя идея получается очень не оптимизированной, фпс падает до 30 при рисовании 2 сфер(при высчитывании трассировки путей с двумя сферами в одном шейдере, фпс было около 700). Вот пример кода:

struct Ray
{
float3 direction;
float t;
float3 origin;
float padding1;
float3 energy;
float padding2;
float3 result;
float padding3;
};

RWTexture2D Result : register(u0);
RWStructuredBuffer tray : register(u1);

Ray InitRay0(float3 direction, float3 origin)
{
Ray ray;
ray.t = 0;
ray.direction = direction;
ray.origin = origin;
ray.energy = 1;
ray.result = 0;
ray.padding1 = 0;
ray.padding2 = 0;
ray.padding3 = 0;
return ray;
}

[numthreads(8, 8, 1)]
void main(uint3 threadID : SV_DispatchThreadID)
{
_seed = _randValue;
uint width, height;
Result.GetDimensions(width, height);
uint oneDID = threadID.x + threadID.y * width;
for (int i = 0; i < 8; i++)
{
tray[oneDID] = InitRay0(float3(0, 0, 0), float3(0, 0, 0));
Result[threadID.xy] = float4(tray[oneDID].result, 1);
}
}
Да, это не трассировка путей, этим кодом я просто эмулирую нагрузку. При этом вместо цикла, должно быть несколько вызовов шейдера, с привязыванием разных данных. При этом фпс около 60(но в том примере с реальной трассировкой было 30, важно то, что перезаписывание данных в буфер очень нагружает по всей видимости). Может быть я как то не правильно распределяю потоки, или не правильно упаковал структуры? Ну или же моя идея очень не оптимизированная и нужно находить другой подход, но какой? В чём проблема?(да, возможно в фпс измерять не правильно, но это примерные данные, суть в том, что фпс явно становится очень мало, даже невооружённым глазом видно)
  • Вопрос задан
  • 36 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы