некоторые свойства частиц SPH не обновляются в Compute Shader - PullRequest
0 голосов
/ 11 мая 2019

В настоящее время я работаю над диссертацией о гидродинамике с использованием SPH в Unity3D, и у меня уже работает базовый алгоритм.

Сейчас я пытаюсь оптимизировать его с помощью Compute Shader.

Каждой частице нужны соседние частицы, чтобы обновить ее плотность и давление. Используя базовый однопоточный алгоритм, частицы движутся в порядке. Но когда я переместил код в вычислительный шейдер, я не столкнулся с каждой частицей.

Это мой рабочий однопоточный код

// Working Single Thread
for (int i = 0; i < particles.Length; i++)
{
    particles[i].density = 0.0f;

    for (int j = 0; j < particles.Length; j++)
    {
        Vector3 rij = particles[j].position - particles[i].position;
        float r2 = rij.sqrMagnitude;

        if (r2 < parameters.smoothingRadiusSq)
        {
            particles[i].density += parameters.particleMass * (315.0f / (64.0f * Mathf.PI * Mathf.Pow(parameters.smoothingRadius, 9.0f))) * Mathf.Pow(parameters.smoothingRadiusSq - r2, 3.0f);
        }
    }

    particles[i].pressure = GAS_CONST * (particles[i].density - parameters.restDensity);
}

Это моя попытка оптимизации с использованием вычислительного шейдера

// file.cs
void InitBuffer(){
    kernel = densityPressureComputation.FindKernel("ComputeDensityPressure");
    buffer = new ComputeBuffer(particles.Length, 56);

    buffer.SetData(particles);

    densityPressureComputation.SetBuffer(kernel, "Result", buffer);
    densityPressureComputation.SetFloat("GAS_CONST", GAS_CONST);
    densityPressureComputation.SetFloat("smoothingRadius", parameters.smoothingRadius);
    densityPressureComputation.SetFloat("smoothingRadiusSq", parameters.smoothingRadiusSq);
    densityPressureComputation.SetFloat("restDensity", parameters.restDensity);
    densityPressureComputation.SetFloat("particleMass", parameters.particleMass);
}

void Update(){
    buffer.SetData(particles);
    densityPressureComputation.Dispatch(kernel,16,16,1);        
    buffer.GetData(particles);
}
// file.compute
int currID = id.x + id.y * (16*16);
Result[currID].density = 0.0;
for (int j = 0; j < Result.Length; j++)
{
    float3 rij = Result[j].position - Result[currID].position;
    float r2 = rij * rij;

    if (r2 < smoothingRadiusSq)
    {
        Result[currID].density += particleMass * (315.0 / (64.0 * 3.14 * pow(smoothingRadius, 9))) * pow(smoothingRadiusSq - r2, 3);
    } 
}
Result[currID].pressure = GAS_CONST * (Result[currID].density - restDensity);

Используя работающий однопоточный код, моделирование работает так, как должно быть, столкновения работают, гравитация работает и т. Д.

Но, используя код Compute Shader, в то время как гравитация работает просто отлично, столкновение между частицами не работает, частицы просто проходили друг через друга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...