2017-08-05 4 views
0

J'ai un shader de calcul qui simule un fluide en tant que particule. Les particules sont lues à partir d'un tampon. Chaque particule est traitée dans un thread. Pendant l'exécution du thread, une particule déplace sa position uv et ajoute au pixel d'un UAV nommé Water. Par conséquent, chaque fil laisse une trace de son mouvement sur la texture Water.Existe-t-il un moyen d'écrire simultanément dans un UAV sans condition de compétition?

_watTx[texID] += watAddition * cellArea.x; 

Le problème est qu'il ya beaucoup de particules qui se déplacent et le plus souvent multiples sont présents en même texID. Il semble qu'il y ait une condition de compétition puisque chaque fois que je lance la simulation, les résultats sont légèrement différents. Existe-t-il un moyen d'imposer l'exclusion mutuelle afin que les écritures ne se produisent pas en même temps et que les résultats deviennent prévisibles?

Répondre

0

J'ai trouvé un moyen de résoudre ce problème. InterlockedAdd ajoute au pixel de manière atomique. Mais cela ne fonctionne que sur les UAV int et unit.

Dans mon cas, les valeurs sont en virgule flottante mais la plage est assez limitée (de 0 à 10). La solution consiste donc à utiliser un UAV int. On multiplie le résultat du calcul par un grand nombre (comme 10000), puis écrire sur le drone:

InterlockedAdd(_watTx[texID], (watAddition * cellArea.x * 10000)); 

Les résultats auront une précision 0,0001 qui est parfaitement bien dans mon cas. Après cela dans un autre pixel ou shader de calcul, nous pouvons multiplier les valeurs de l'UAV int par 0,0001 et écrire dans la cible de rendu à virgule flottante désirée.

Ce processus élimine le problème d'écriture simultanée et les résultats sont identiques à chaque exécution.