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?
Respuestas:
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.
fuente