Dibujar con objetivos de renderizado en Unreal Engine


El objetivo de representación es esencialmente una textura en la que puede escribir en tiempo de ejecución. Desde el punto de vista del motor, almacenan información como el color base, las normales y la oclusión ambiental.

Desde el punto de vista del usuario, los objetivos de renderizado se utilizan principalmente como una especie de cámara adicional. Puede configurar la captura de escena en algún momento y guardar la imagen en el objetivo de renderizado. Luego puede mostrar el objetivo de renderizado en la malla, por ejemplo, para simular una cámara de vigilancia.

Después del lanzamiento de la versión del motor 4.13, Epic agregó la capacidad de dibujar materiales directamente en el objetivo de renderizado mediante romos. Esta característica le permite crear efectos complejos, como la simulación de fluidos y la deformación de la nieve. Suena increíble verdad? Pero antes de pasar a efectos tan complejos, es mejor sentirse cómodo con algo simple. ¿Qué podría ser más simple que dibujar en un objetivo de renderizado?

En este tutorial aprenderá lo siguiente:

  • Crea objetivos de renderizado dinámicamente con romos
  • Visualizar objetivo de renderizado en malla
  • Dibujar textura en el objetivo de renderizado
  • Cambiar el tamaño y la textura del pincel durante el juego

Nota: este tutorial asume que ya está familiarizado con los conceptos básicos del trabajo con Unreal Engine. Si eres nuevo en Unreal Engine, echa un vistazo a nuestra serie de diez partes de tutoriales de Unreal Engine para principiantes .

Llegar al trabajo


Comencemos descargando materiales para este tutorial (puede obtenerlos aquí ). Descomprímalos, vaya a CanvasPainterStarter y abra CanvasPainter.uproject . Si hace clic en Reproducir , verá lo siguiente:


El cuadrado en el medio (lienzo) es en lo que dibujaremos. Los elementos de la interfaz de usuario de la izquierda serán la textura que vamos a dibujar y su tamaño.

Primero, veamos el método utilizado para dibujar.

Método de dibujo


Lo primero que necesitamos es un objetivo de renderizado, utilizado como lienzo. Para determinar dónde dibujar en el objetivo de renderizado, trazaremos la línea recta que sale de la cámara hacia adelante. Si la línea se cruza con el lienzo, entonces podemos obtener la intersección en el espacio UV.

Por ejemplo, si el lienzo tiene una unión perfecta de coordenadas UV, la intersección en el centro devolverá el valor (0.5, 0.5) . Si la línea cruza el lienzo en la esquina inferior derecha, obtendremos el valor (1, 1) . Luego puede usar cálculos simples para calcular el lugar de dibujo.


Pero, ¿por qué obtener las coordenadas en el espacio UV? ¿Por qué no usar las coordenadas del espacio real del mundo? Al usar el espacio del mundo, primero tenemos que calcular la intersección relativa al plano. También deberá tener en cuenta la rotación y la escala del avión.

Cuando se utiliza el espacio UV, no se requieren todos estos cálculos. En un plano con una unión perfecta de coordenadas UV, la intersección con el medio siempre regresa (0.5, 0.5) , independientemente de la ubicación y rotación del plano.

Nota: el método considerado en este tutorial generalmente funciona solo con planos o superficies similares a los planos. Otros tipos de geometría requieren un método más complejo, que trataré en otro tutorial.

Primero, crearemos material que representará el objetivo de renderizado.

Crear material de lienzo


Vaya a la carpeta Materiales y abra M_Canvas .

En este tutorial, crearemos objetivos de renderizado dinámicamente usando romos. Esto significa que tenemos que configurar la textura como un parámetro para poder pasarla al objetivo. Para hacer esto, cree un TextureSampleParameter2D y llámelo RenderTarget . Luego conéctelo a BaseColor .


Por ahora, no se preocupe por elegir una textura; lo haremos más adelante en planos. Haga clic en Aplicar y luego cierre M_Canvas .

El siguiente paso es crear un objetivo de renderizado, después de lo cual lo usamos como material de lienzo.

Crear un objetivo de renderizado


Hay dos formas de crear un objetivo de renderizado. Primero: crear en el editor haciendo clic en Agregar nuevo \ Materiales y texturas \ Renderizar destino . Este método le permite hacer referencia convenientemente al mismo objetivo de renderizado a múltiples actores. Sin embargo, si necesitamos varios lienzos, tendremos que crear un objetivo de renderizado manualmente para cada lienzo.

Por lo tanto, es mejor crear objetivos de renderizado con romos. La ventaja de este enfoque es que creamos objetivos de renderizado solo cuando es necesario y no inflan el tamaño de los archivos del proyecto.

Primero necesitamos crear un objetivo de renderizado y guardarlo como una variable para uso futuro. Vaya a la carpeta Blueprints y abra BP_Canvas . Localice el evento BeginPlay y agregue los nodos seleccionados.


Establezca Ancho y Altura en 1024 . Entonces cambiamos la resolución del objetivo de renderizado a 1024 × 1024 . Cuanto mayor sea el valor, mayor será la calidad de la imagen, pero también mayor será el costo de la memoria de video.


Luego viene el nodo Clear Render Target 2D . Podemos usar este nodo para establecer el color del objetivo de renderizado. Establezca Color claro en (0.07, 0.13, 0.06) . En este caso, todo el objetivo de renderizado se llenará de color verdoso.


Ahora necesitamos mostrar el objetivo de renderizado en la malla del lienzo.

Renderizar pantalla de destino


En este punto, la malla del lienzo utiliza el material predeterminado. Para mostrar el objetivo de representación, debe crear una instancia dinámica de M_Canvas y pasarle el objetivo de representación. Luego, debe aplicar una instancia dinámica del material a la malla del lienzo. Para hacer esto, agregaremos los nodos seleccionados:


Primero, pasemos al nodo Crear instancia de material dinámico y establezcamos el valor primario en M_Canvas . Entonces crearemos una instancia dinámica de M_Canvas .


A continuación, vaya al nodo Establecer el valor del parámetro de textura y establezca el Nombre del parámetro en RenderTarget . Por lo tanto, pasaremos el objetivo de representación al parámetro de textura creado anteriormente.


Ahora el objetivo de renderizado se mostrará en la malla del lienzo. Haga clic en Compilar y vuelva al editor principal. Haga clic en Reproducir para ver cómo el lienzo cambia de color.


Ahora que tenemos el lienzo, necesitamos crear material que pueda usarse como pincel.

Crear material de pincel


Vaya a la carpeta Materiales . Cree el material M_Brush y ábralo. Primero configure el Modo de fusión en Translúcido . Esto nos permitirá usar texturas con transparencia.


Al igual que con el material de lienzo, establecemos la textura del pincel en romos. Cree un TextureSampleParameter2D y asígnele el nombre BrushTexture . Conéctelo de la siguiente manera:


Haga clic en Aplicar y luego cierre M_Brush .

Lo siguiente que debe hacer es crear una instancia dinámica del material del pincel para que pueda cambiar la textura del pincel. Abra BP_Canvas y agregue los nodos seleccionados.


A continuación, vaya al nodo Crear instancia de material dinámico y establezca el elemento primario en M_Canvas .


Creamos el material del pincel, y ahora necesitamos una función para pintar con el pincel en el objetivo de renderizado.

Pincel de pintura en el objetivo de renderizado


Cree una nueva función y asígnele el nombre DrawBrush . Primero necesitamos los parámetros: textura utilizada, tamaño del pincel y lugar para dibujar. Cree la siguiente entrada:

  • BrushTexture: seleccione el tipo Texture 2D
  • BrushSize: seleccione el tipo de flotador
  • DrawLocation: seleccione el tipo Vector 2D


Antes de dibujar un pincel, necesitamos establecer su textura. Para hacer esto, cree el circuito que se muestra a continuación. Asegúrese de que BrushTexture esté seleccionado como el Nombre del parámetro .


Ahora tenemos que hacer la representación en el destino de representación. Para hacer esto, cree los nodos seleccionados:


Iniciar Draw Canvas to Render Target le permitirá al motor saber que queremos comenzar a renderizar a un objetivo de renderizado específico. Dibujar material le permite dibujar material en una ubicación específica con el tamaño y la rotación seleccionados.

Calcular la posición de renderizado es un proceso de dos pasos. Primero necesitamos escalar DrawLocation para que se ajuste a la resolución del objetivo de renderizado. Para hacer esto, multiplique DrawLocation por Size .


Por defecto, el motor renderizará materiales utilizando la esquina superior izquierda como punto de partida. Por lo tanto, la textura del pincel no se centrará en nosotros donde queremos renderizar. Para solucionar esto, debemos dividir BrushSize entre 2 y luego restar el resultado del paso anterior.


Luego conectamos todo de la siguiente manera:


Finalmente, debemos decirle al motor que queremos detener el renderizado en el destino de renderizado. Agregue el lienzo de dibujo final para representar el nodo de destino y conéctelo de la siguiente manera:


Ahora, cada vez que se ejecuta DrawBrush, primero establecerá la textura transmitida como una textura para BrushMaterial . Luego renderizará el BrushMaterial en RenderTarget , utilizando la posición y el tamaño pasados.

Y en esto la función de renderizado está lista. Haga clic en Compilar y cierre BP_Canvas . El siguiente paso es trazar la línea desde la cámara y dibujar en el lugar del lienzo donde ocurrió la intersección.

Seguimiento directo de la cámara


Antes de dibujar en el lienzo, debemos especificar la textura y el tamaño del pincel. Vaya a la carpeta Blueprints y abra BP_Player . Luego establezca la variable BrushTexture en T_Brush_01 , y la variable BrushSize en 500 . Entonces asignamos una imagen de pincel de un mono con un tamaño de 500 × 500 píxeles.


A continuación, debe trazar la línea. Localice InputAxis Paint y cree el siguiente diagrama:


Así que trazaremos la línea dirigida directamente desde la cámara mientras el jugador mantiene presionada la tecla asignada a Paint (en nuestro caso, este es el botón izquierdo del mouse ).

Ahora tenemos que verificar si el lienzo recto se cruzó. Añadir nodos seleccionados:


Ahora, cuando la línea y el lienzo se cruzan , se ejecutará la función DrawBrush , utilizando las variables de pincel y las coordenadas UV que se le pasen.

Para que el nodo UV Find Collision funcione, necesitamos cambiar dos parámetros. Primero, vaya al nodo LineTraceByChannel y active Trace Complex .


En segundo lugar, vaya a Editar \ Configuración del proyecto y luego a Motor \ Física . Active Support UV From Hit Results y reinicie el proyecto.


Después de reiniciar, para dibujar en el lienzo, haga clic en Reproducir y haga clic con el botón izquierdo .


Incluso puede crear varios lienzos y dibujar en cada uno de ellos por separado. Esto es posible porque cada lienzo crea dinámicamente su propio objetivo de renderizado.


En la siguiente sección, implementamos la función de cambiar el tamaño del pincel de un jugador.

Cambiar el tamaño del pincel


Abra BP_Player y busque el nodo InputAxis ChangeBrushSize . Esta unión de eje está configurada para usar la rueda del mouse . Para cambiar el tamaño del pincel, es suficiente que cambiemos el valor de BrushSize según el valor del eje . Para hacer esto, cree el siguiente esquema:


Realizará la suma o resta de BrushSize cuando el jugador use la rueda del mouse. La primera multiplicación determina la tasa de suma o resta. Se ha agregado una abrazadera (flotador) como medida de seguridad. Asegura que el tamaño del pincel no sea inferior a 0 o superior a 1000 .

Haga clic en Compilar y vuelva al editor principal. Gire la rueda del mouse para cambiar el tamaño del pincel mientras dibuja.


En la última sección, crearemos una función que permita al jugador cambiar la textura del pincel.

Cambiar la textura del pincel


Primero, necesitamos una matriz para almacenar las texturas que el jugador puede usar. Abra BP_Player y cree una variable de matriz . Seleccione el tipo de textura 2D y asígnele el nombre Texturas .


Luego crea tres elementos en Texturas . Asigne los siguientes valores:

  • T_Brush_01
  • T_Brush_02
  • T_Brush_03


Estas serán las texturas que el jugador puede dibujar. Para agregar nuevas texturas, solo agréguelas a esta matriz.

A continuación, necesitamos una variable para almacenar el índice actual de la matriz. Cree una variable entera y asígnele el nombre CurrentTextureIndex .


A continuación, necesitamos una forma de atravesar todas las texturas en un bucle. Para este tutorial, configuré una asignación de acción llamada NextTexture y la vinculé al botón derecho del mouse . Cuando el jugador presiona esta tecla, se debe realizar la transición a la siguiente textura. Para hacer esto, busque el nodo InputAction NextTexture y cree el siguiente diagrama:


Este esquema incrementará CurrentTextureIndex cada vez que haga clic derecho . Si el índice llega al final de la matriz, se restablece nuevamente a 0 . Finalmente, BrushTexture establece la textura apropiada.

Haga clic en Compilar y cierre BP_Player . Haga clic en Reproducir y haga clic con el botón derecho para cambiar entre texturas.


¿A dónde ir después?


El proyecto terminado se puede descargar desde aquí .

Renderizar objetivo es una herramienta extremadamente poderosa y en este tutorial hemos cubierto solo los conceptos básicos. Si desea saber de qué son capaces los objetivos de renderizado, consulte Representación multipass basada en contenido en UE4 . Este video contiene ejemplos de mapas de flujo de dibujo, dibujo volumétrico, simulaciones de fluidos y más.

Consulte también nuestro video tutorial Blueprint Drawing to Render Targets para aprender a crear un mapa de altura con el objetivo de renderizado.

Source: https://habr.com/ru/post/es420031/


All Articles