top of page
Foto del escritorBraulio Madrid

Cómo hacer tus propios modelos de iluminación en shaders de superficie

Actualizado: 23 jul 2020



Introducción

Ya saben que últimamente he estado muy juicioso con este tema de los shaders, muchas veces tardo en publicar algo porque primero tengo que probarlo a fondo, al igual que ustedes también estoy aprendiendo.


Ahora la intención del Blog de hoy es explicar a fondo el cómo y el porqué de la función Lighting en shaders de superficie que nos permite hacer nuestros propios modelos de iluminación ya sea porque queremos darle un toque personalizado a como se comporta la luz en nuestros objetos o porque queremos simplificarlos o ampliarlos.


Para poder seguir será necesario entender como hacer su propio archivo CGINCLUDE y saber aplicar los Drawers de [Toggle(X)] y de [Enum(X, Y, Z)], dejaré relacionados los blogs necesarios para que repasen antes de continuar.


La intención es poder simplificar varios modelos en unos pocos y que podamos usar distintas variedades y hacer uso de otros modelos pocos conocidos.


Preparando la escena

En la ventana Jerarquía

  • Crea una escena nueva vacía;

  • Agrega  en ella una luz direccional blanca

  • Agrega 3 o 4 luces puntuales de distintos colores

  • Agrega al menos una esfera

En la ventana de proyecto

  • Crea un material nuevo y arrastralo a la esfera

  • Crea un shader de superficie y arrastralo al material

  • Crea un archivo cginc nuevo con el nombre CustomLighting.cginc en la misma carpeta donde esta el shader

Analizando el código por defecto.

Cuando abres el código generado en el shader de superficie por defecto de unity, ves un montón de cosas, pero entre ellas destaca estas líneas.

La primera es el preprocesador que le dice a unity que tipo de shader es.

surface surf: es el tipo de shader, si fuera otro seria vertex vert: fragment frag, esto le dice a unity que includes cargar, optimizaciones, compilaciones etc.


Standard: Esto le dice a unity que modelo de iluminación utilizar, Standard es la que actualmente se encuentra por defecto, es la versión mas moderna y la más utilizada en este momento por la industria.


Pero también existe Lambert (El diffuse de toda la vida) y BlinnPhong, también llamado especular. Por si te lo preguntas los nombres de esos modelos son apellidos de científicos, Johann Heinrich Lambert, Jim Blinn y Bui Tuong Phong.


SurfaceOutputStandard: Esta es una estructura de salida que usa el modelo Standard, también puedes crear tus propias estructuras. pero en mi caso yo prefiero reutilizar lo que ya hay. Estos son los que trae Unity.


Creando el primer modelo de iluminación.

He borrado todo lo innecesario en el shader a continuación y he cambiado un par de cosas.

La primera es que he incluido el archivo CustomLighting.cginc, nótese que lo he puesto antes del #pragma, en el fondo estos shaders son lenguaje C, no tiene la característica de leer funciones en cualquier orden, sino que tiene el orden de arriba hacia abajo. en este caso primero carga el archivo cginc, porque luego el #pragma buscará la función NoLighting dentro del cginc.



He cambiado surface surf Standard por surface surf NoLighting.

Por último he cambiado la entrada SurfaceOutputStandard por SurfaceOutput.

Si guardamos ahora, es obvio que no funcionará porque debemos hacer el modelo de iluminación dentro del archivo cginc.

Cómo ves el modelo de iluminación es una simple función que devuelve un color, el nombre de la función debe coincidir con el nombre del modelo #pragma surf X. precedido de la palabra LightingX., donde X es el nombre que quieras ponerle a tu modelo.


También puede ver que hay unos parámetros, el primero de ellos es la estructura ya sea una de las que unity usa como predeterminadas o ya sea una que usted construya, pero por lo general siempre usaremos SurfaceOutput.


Seguido vendría uno o 2 parámetros que son vectores, de manera obligatoria la dirección de la luz, opcionales puede ser la dirección de la vista o el vector medio entre la vista y la luz.

Por ultimo esta un valor de atenuación, que hace una corrección del color.

Los parámetros de la dirección de la luz, la vista, el vector medio y el valor de la atenuación son proporcionadas por unity.

Este modelo de iluminación simple corresponde al llamado Unlit, que no es afectado por la luz, simplemente regresa el color Albedo y Alpha proveniente de SurfaceOutput.

Proceda a guardar y ver el resultado.


Modelo Lambert personalizado

Como todo modelo de iluminación tiene el mismo retorno, he decidido hacer una pequeña función que nombré finalColor, que a largo plazo reduzca la cantidad de líneas y mejore la legibilidad del código, La función lo único que hace es hacer multiplicaciones y retornar el color final.

Vamos a agregarle la iluminación Lambert que es simplemente producto punto que se obtiene entre la dirección de la luz y el vector normal del objeto, llamado comúnmente NdotL casi como un estándar entre varios modelos de iluminación. de esta variable hay 2 variantes.


Unity tiene una función optimizada que elige la mejor opcion segun el dispositivo de destino. llamada DotClamped().


Caso aparte de la multiplicación hay otras variantes al modelo Lambert, como HalfLambert y WrapLambert.

Vamos a hacer una versión que permita elegir entre los 3 modelos, comencemos modificando el archivo .cginc.

Ahora vamos a habilitar en el shader esa posibilidad.


Conclusión

Ya el blog se ha hecho muy largo, en una próxima entrega agregaremos el modelo Blinn Phong y el modelo Toon, existen otros modelos como Minnaert y Oren Nayar, dejaré el link a estos últimos dos para que los implementen.


Cómo pudo observar la aplicación práctica de los Drawers del Blog pasado y el uso de archivos cginc y pudo entender que hay detrás de las funciones de iluminación, en el próximo blog se profundizará más en este tema.

Hasta la próxima.





16 visualizaciones0 comentarios

Comments


bottom of page