Este tutorial también introduce la técnica principal para depurar shaders en Unity: imágenes de color falso, es decir, se visualiza un valor estableciendo uno de los componentes del color del fragmento. Entonces, la intensidad de ese componente de color en la imagen resultante le permite sacar conclusiones sobre el valor en el shader.
Esto puede parecer una técnica de depuración muy primitiva porque es una técnica de depuración muy primitiva. Desafortunadamente, no hay alternativa en Unity.
Este tutorial describe los parámetros de entrada de vértices. Asume que usted está familiarizado con la sección "Minimal Shader" y la sección "RGB Cube" .
¿De dónde vienen los datos del vértice?
En la sección "Cubo RGB"usted ha visto cómo el fragmento shader obtiene sus datos del vertex shader por medio de una estructura de salida de parámetros, en salida del vertex shader. La pregunta aquí es: ¿de dónde saca el vertex shader? Dentro de Unity, la respuesta es que el componente Mesh Renderer de un gameobject envía todos los datos de la malla a la GPU en cada frame.
Tenga en cuenta que cada draw call tiene una sobrecarga de rendimiento, por lo tanto, es mucho más eficiente para enviar una gran malla con una llamada a la GPU que enviar varias mallas más pequeñas con múltiples llamadas.
Estos datos generalmente consta de una larga lista de triángulos, donde cada triángulo está definido por tres vértices y cada vértice tiene ciertos atributos, incluyendo la posición.
Estos atributos se ponen a disposición en el vertex shader por medio de parámetros de entrada de vértices. POSITION, NORMAL, TEXCOORD0, TEXCOORD1, TANGENT, COLOR, Etc.
(En las versiones anteriores de Unity, el incorporado en los parámetros de entrada vértice también tenía que tener nombres específicos, a saber, los nombres que se utilizan en este ejemplo.)
Parámetros de entrada de vértice incorporados y cómo visualizarlos.
A menudo es conveniente incluir todos los parámetros de los vértices de entrada en una sola estructura, por ejemplo:
Esta estructura podría utilizarse de esta manera:
En la sección "RGB Cube" ya hemos visto, cómo visualizar las coordenadas del vértice estableciendo el color del fragmento a esos valores. En este ejemplo, el color del fragmento se establece en las coordenadas de textura de tal manera que podemos ver qué tipo de coordenadas de textura proporciona Unity.
Observe que sólo los tres primeros componentes de tangent representan la dirección tangente. La escala y el cuarto componente se establecen de una manera específica, que es principalmente útil para el mapeado de paralaje.
Estructuras de entrada predefinidas.
Por lo general, puede lograr un rendimiento más alto especificando sólo los parámetros de entrada de vértices que realmente necesita, por ejemplo, posición, normal y un conjunto de coordenadas de textura; a veces también el vector tangente. Unity proporciona las estructuras de entrada predefinidos appdata_base, appdata_tan, appdata_full, y appdata_img para los casos más comunes.
Éstos se definen en el archivo UnityCG.cginc(en el directorio Unity> Editor> Data> CGIncludes):
El archivo UnityCG.cginc se incluye con la línea #include "UnityCG.cginc". Así, el shader anterior podría reescribirse de esta manera:
Cómo interpretar imágenes de color falso.
Al intentar entender la información en una imagen de color falso, es importante centrarse en un solo componente de color.
Por ejemplo, si el parámetro del vértice de entrada texcoord con semántica TEXCOORD0 para una esfera se escribe en el color del fragmento entonces el componente rojo del fragmento visualiza la coordenada X del texcoord, es decir, no importa si el color de salida es máximo rojo puro o amarillo máximo o magenta máximo, en todos los casos el componente rojo es 1.
Por otro lado, tampoco importa para el componente rojo si el color es azul o verde o cían de cualquier intensidad porque el componente rojo es 0 en todos los casos.
Si nunca ha aprendido a centrarse únicamente en un componente de color, esto probablemente sea bastante desafiante; por lo tanto, podría considerar mirar sólo un componente de color a la vez.
Por ejemplo, utilizando esta línea para establecer el parámetro de salida en el vertex shader:
output.col = float4(input.texcoord.x, 0.0, 0.0, 1.0);
Esto establece el componente rojo del parámetro de salida en el componente X del texcoord, pero establece los componentes verde y azul en 0 (y el componente alfa o de opacidad en 1, pero eso no importa en este shader).
Si usted se centra en el componente rojo o sólo visualiza el componente rojo, verá que aumenta de 0 a 1 cuando gira alrededor de la esfera y después de 360 ° vuelve a caer a 0. En realidad se comporta como una coordenada de longitud en la superficie de un planeta. (En términos de coordenadas esféricas, corresponde al azimut.)
Si el componente X del texcoord corresponde a la longitud, se podría esperar que el componente Y corresponda a la latitud (o la inclinación en coordenadas esféricas).
Sin embargo, tenga en cuenta que las coordenadas de textura siempre están entre 0 y 1; por lo tanto, el valor es 0 en la parte inferior (polo sur) y 1 en la parte superior (polo norte). Puede visualizar el componente Y como verde por sí solo con:
output.col = float4(0.0, input.texcoord.y, 0.0, 1.0);
Las coordenadas de textura son particularmente agradables de visualizar porque están entre 0 y 1 al igual que los componentes de color. Casi tan bonitas son las coordenadas de los vectores normalizados (es decir, los vectores de longitud 1, por ejemplo, el parámetro normal de entrada normalmente se normaliza), ya que siempre están entre -1 y +1. Para asignar este rango al rango de 0 a 1, agregue 1 a cada componente y divida todos los componentes por 2, por ejemplo:
output.col = float4((input.normal + float3(1.0, 1.0, 1.0)) / 2.0, 1.0);
Tenga en cuenta que normales un vector tridimensional, el negro corresponde entonces a la coordenada -1 ya la intensidad total de un componente a la coordenada +1.
Si el valor que desea visualizar está en otro rango que 0 a 1 o -1 a +1, tiene que asignarlo al rango de 0 a 1, que es el rango de componentes de color. Si no sabes qué valores esperar, sólo tienes que experimentar.
Lo que ayuda aquí es que si especifica componentes de color fuera del rango de 0 a 1, se sujetan automáticamente a este rango. Es decir, cuando el componente de color es 0 o 1, usted sabe por lo menos que el valor es menor o mayor que lo que asumió y luego puede adaptarse la asignación iterativamente hasta que el componente de color esté entre 0 y 1.
Práctica de depuración.
Para practicar la depuración de shaders, esta sección incluye algunas líneas que producen colores negros cuando la asignación a colen el vertex shader es reemplazada por cada uno de ellos. Su tarea es averiguar por cada línea, por qué el resultado es negro. Para ello, debe intentar visualizar cualquier valor que no esté absolutamente seguro y asignar los valores inferiores a 0 o mayores que 1 a otros rangos de modo que los valores sean visibles y tenga por lo menos una idea en qué rango se encuentran .
output.col = input.texcoord - float4(1.5, 2.3, 1.1, 0.0);
output.col = input.texcoord.zzzz;
output.col = input.texcoord / tan(0.0);
Las líneas siguientes requieren algún conocimiento sobre el producto punto y producto cruz:
output.col = dot(input.normal, input.tangent.xyz) * input.texcoord;
output.col = dot(cross(input.normal, input.tangent.xyz),input.normal) * input.texcoord;
output.col = float4(cross(input.normal, input.normal), 1.0);
output.col = float4(cross(input.normal, input.vertex.xyz),1.0);
// only for a sphere!
¿La función radians()siempre vuelve negra? ¿Para qué sirve eso?
Conclusión.
¡Enhorabuena, has llegado al final de este tutorial! Hemos visto:
La lista de parámetros de entrada de vértices incorporados en Unity.
Cómo visualizar estos parámetros (o cualquier otro valor) estableciendo componentes del color de salida del fragmento.
Comments