Generando terreno en GPU

9

En mi motor, creo un terreno infinito con el uso del algoritmo de ruido Perlin calculado en la CPU.

La creación del terreno es así:

  • Si la cámara está cerca del parche descargado, créelo
  • Calcule la matriz de ruido 513x513 con límites dados
  • Calcular normales, tangentes, binormales, índices
  • Pasar datos a vbo

Pros:

  • Solo necesita ser renderizado cuando sea necesario
  • Fácil de hacer colisión

Estafa

  • Lento 64 parches 513x513 se crean en 3,1s (un hilo). Para cada mosaico ~ 20ms de creación de ruido, ~ 25ms de vértices, normales, tangentes, bitangentes, índices. Cuando la cámara se mueve rápido, el usuario puede notar la carga de mosaicos.
  • ¿Consumo de memoria?

Ahora me preguntaba cómo acelerar esto generando terreno completamente en la GPU. Pero hay algunas dudas:

  • Si los sombreadores ejecutan cada cuadro, ¿no es este desperdicio de energía de cálculo para calcular el ruido una y otra vez? Esto puede evitarse escribiendo el resultado en la textura RBGA y luego se usa en el sombreador de vértices para el desplazamiento, pero aumenta el uso de la memoria. Por otro lado, si la creación fuera súper rápida, solo los mosaicos visibles deberían permanecer en la memoria. Sin embargo, la desconexión del búfer provoca la sincronización de gpu-cpu que puede ralentizar la aplicación (¿estoy en lo cierto?)
  • Si el terreno es solo una cuadrícula plana desplazada por el sombreador de vértices, se debe hacer el mismo trabajo en la CPU para calcular la altura y la normalidad en el punto dado para la colisión.
  • Esto es solo un concepto, pero para acelerar todo estaba pensando en proyectar la cuadrícula en la ventana gráfica para que solo se use una cantidad mínima de vértices. ¿Crees que esto funcionaría?

Mi pregunta final es:

¿Cuál es la mejor técnica / más rápida / ampliamente utilizada para crear un terreno infinito en la GPU?

usuario1075940
fuente
8
Solo tenga en cuenta que la creación de terreno en la GPU dificultará la detección de colisiones, la detección de picking o casi cualquier tipo de interacción con el terreno.
MichaelHouse
1
Se puede usar un sombreador de cómputo (DX10 u 11) para generar el terreno en la GPU. Pero como dijo Byte56, deberá extraer los valores de la GPU para interactuar con ella. msdn.microsoft.com/en-us/library/windows/desktop/…
UnderscoreZero
crear terreno en una GPU me parece una mala idea. Puede funcionar, pero creo que probablemente funcionaría un poco mejor si solo genera el terreno en el lado de la CPU y envía el material de dibujo estándar a la GPU.
Benjamin Danger Johnson
Solo mi experiencia; Realmente hice esto con aparapi y conseguí que funcionara; pero en realidad terminó siendo más lento que simplemente hacer que la CPU haga el trabajo. Creo que debido a la sobrecarga de enviar datos a / desde la gpu. Si recuerdo correctamente, gpu realmente solo funciona si el cálculo es grande en comparación con el tamaño de los datos (y también grande en términos absolutos)
Richard Tingle
Este artículo puede darle algunas ideas http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html
Jeremiah Leslie

Respuestas:

2

Bueno, si tuviera que intentar usar la GPU para tal cosa, creo que iría por compute / opencl / cuda.

Sin embargo, independientemente de usar la GPU o la CPU (que es lo que realmente hago), lo haría de forma asincrónica, decidiendo que necesita algún terreno nuevo para el marco actual probablemente sea demasiado tarde (por ejemplo, considere 1000ms / 60 = 16.666ms, y todo el marco quiere encajar en eso).

Comience a generar (o cargar desde archivos comprimidos) terreno en un subproceso de trabajo, y ponerlo a disposición del resto del juego y renderizar una vez que el trabajador haya terminado, generalmente este será el siguiente fotograma, o tal vez el fotograma después de eso, por lo que el el usuario realmente no notará la diferencia allí, pero hace las cosas más suaves.

Será
fuente