Unity Cómo crear un sombreador

Shader es un pequeño script que contiene cálculos matemáticos y algoritmos para calcular el color de cada píxel renderizado, según la entrada de iluminación y la configuración del material.

Unity usa Shaders que están escritos en los siguientes idiomas:

  • Se utiliza un lenguaje de programación llamado HLSL para escribir los propios programas de sombreado.
  • Se utiliza un lenguaje específico de Unity llamado ShaderLab para definir un objeto Shader, que actúa como un contenedor para los programas de sombreado.

Para crear un shader en Unity sigue los pasos a continuación:

Crear un sombreador

  • Haga clic derecho en la vista Proyecto -> 'Create' -> 'Shader'

Dependiendo de la versión Unity que esté usando, las opciones de Shader pueden diferir, pero esto es lo que significa cada una de las opciones:

  1. 'Standard Surface Shader': Este sombreador está diseñado para funcionar con el sistema de renderizado basado en la física (PBR) Unity's. Permite a los desarrolladores crear materiales que respondan a las condiciones de iluminación de manera realista. Admite varias funciones de representación, como mapeo normal, reflejos especulares y reflejos. Es un shader versátil que proporciona un buen equilibrio entre realismo y rendimiento.
  2. 'Unlit Shader': Como sugiere el nombre, un shader sin iluminación no considera las condiciones de iluminación. A menudo se usa para renderizar efectos que no necesitan una iluminación realista, como elementos de interfaz de usuario, sistemas de partículas o efectos especiales. Los sombreadores no iluminados suelen ser más eficientes y pueden ser útiles en situaciones en las que se requiere un control total sobre la apariencia de un objeto sin ningún cálculo de iluminación.
  3. 'Image Effect Shader': Los sombreadores efecto de imagen se utilizan para aplicar efectos post-procesamiento al pantalla completa o objetivos de renderización específicos. Permiten a los desarrolladores modificar la imagen renderizada final una vez que se completa la renderización principal. Los ejemplos de efectos de imagen incluyen desenfoque, gradación de color, distorsión o filtros estilizados. Se pueden utilizar para mejorar la calidad visual o crear efectos artísticos específicos.
  4. 'Compute Shader': Un sombreador de cómputo es un tipo de sombreador que se ejecuta en la GPU pero no opera en los píxeles directamente. Se utiliza para cálculos de propósito general en datos paralelos, lo que permite a los desarrolladores realizar cálculos o simulaciones complejos de manera eficiente. Los sombreadores de computación se usan comúnmente para tareas como simulaciones físicas, generación de procedimientos o procesamiento de datos.
  5. 'Ray Tracing Shader': Los sombreadores de trazado de rayos utilizan la tecnología de trazado de rayos, que simula el comportamiento de la luz con mayor precisión en comparación con las técnicas de rasterización tradicionales. Los sombreadores de trazado de rayos se utilizan normalmente para lograr iluminación, reflejos y sombras muy realistas en aplicaciones en tiempo real. Requieren un hardware potente y, a menudo, se utilizan en campos con uso intensivo de gráficos, como los juegos o la visualización arquitectónica.
  • Después de seleccionar el sombreador, escriba cualquier nombre y presione Entrar

El nuevo Shader se crea y se puede abrir en cualquier editor de scripts y modificar para que se ajuste a sus necesidades.

Predeterminado 'Standard Surface Shader':

Shader "Custom/NewSurfaceShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

Predeterminado 'Unlit Shader':

Shader "Unlit/NewUnlitShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

Predeterminado 'Image Effect Shader':

Shader "Hidden/NewImageEffectShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D _MainTex;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                // just invert the colors
                col.rgb = 1 - col.rgb;
                return col;
            }
            ENDCG
        }
    }
}

Predeterminado 'Compute Shader':

// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain

// Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture
RWTexture2D<float4> Result;

[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    // TODO: insert actual code here!

    Result[id.xy] = float4(id.x & id.y, (id.x & 15)/15.0, (id.y & 15)/15.0, 0.0);
}

Predeterminado 'Ray Tracing Shader':

RWTexture2D<float4> RenderTarget;

#pragma max_recursion_depth 1

[shader("raygeneration")]
void MyRaygenShader()
{
    uint2 dispatchIdx = DispatchRaysIndex().xy;
   
    RenderTarget[dispatchIdx] = float4(dispatchIdx.x & dispatchIdx.y, (dispatchIdx.x & 15)/15.0, (dispatchIdx.y & 15)/15.0, 0.0);
}

Conclusión

Cada tipo de shader tiene sus propias ventajas y usos. Es importante elegir el sombreador adecuado según sus requisitos específicos y los efectos visuales que desea lograr en su proyecto.

Artículos sugeridos
Cómo reproducir archivos de vídeo en Unity
Cómo hacer que un objeto siga el cursor del mouse en Unity
Crear juegos por turnos en Unity
Crear efecto de movimiento de cámara en Unity
Cómo agregar el efecto de mira de francotirador en Unity
Cómo pausar el juego en Unity
Cómo activar una escena en Unity