Unity Como criar um sombreador

Shader é um pequeno script que contém cálculos matemáticos e algoritmos para calcular a cor de cada pixel renderizado, com base na entrada de iluminação e na configuração do material.

Unity usa Shaders que são escritos nos seguintes idiomas:

  • Uma linguagem de programação chamada HLSL é usada para escrever os próprios programas de sombreamento.
  • Uma linguagem específica de Unity chamada ShaderLab é usada para definir um objeto Shader, que atua como um contêiner para os programas de sombreamento.

Para criar um sombreador em Unity siga os passos abaixo:

Criar um sombreador

  • Clique com o botão direito na visualização Projeto -> 'Create' -> 'Shader'

Dependendo da versão Unity que você está usando, as opções do Shader podem diferir, mas aqui está o que cada uma das opções significa:

  1. 'Standard Surface Shader': Este sombreador foi projetado para funcionar com o sistema Unity's de renderização com base física (PBR) . Ele permite que os desenvolvedores criem materiais que respondam às condições de iluminação de forma realista. Ele oferece suporte a vários recursos de renderização, como mapeamento normal, destaques especulares e reflexões. É um shader versátil que oferece um bom equilíbrio entre realismo e desempenho.
  2. 'Unlit Shader': Como o nome sugere, um shader apagado não considera as condições de iluminação. Geralmente é usado para renderizar efeitos que não precisam de iluminação realista, como elementos de interface do usuário, sistemas de partículas ou efeitos especiais. Shaders apagados são normalmente mais eficientes e podem ser úteis em situações onde requer controle total sobre a aparência de um objeto sem nenhum cálculo de iluminação.
  3. 'Image Effect Shader': Os sombreadores efeito de imagem são usados ​​para aplique efeitos de pós-processamento a toda a tela ou destinos de renderização específicos. Eles permitem que os desenvolvedores modifiquem a imagem renderizada final após a conclusão da renderização principal. Exemplos de efeitos de imagem incluem desfoque, gradação de cores, distorção ou filtros estilizados. Eles podem ser usados ​​para melhorar a qualidade visual ou criar efeitos artísticos específicos.
  4. 'Compute Shader': Um sombreador de computação é um tipo de sombreador que é executado na GPU, mas não opera diretamente nos pixels . Ele é usado para cálculos de uso geral em dados paralelos, permitindo que os desenvolvedores executem cálculos complexos ou simulações com eficiência. Compute shaders são comumente usados ​​para tarefas como simulações físicas, geração de procedimentos ou processamento de dados.
  5. 'Ray Tracing Shader': Os sombreadores de rastreamento de raio utilizam a tecnologia de rastreamento de raio, que simula o comportamento da luz com mais precisão em comparação com as técnicas tradicionais de rasterização . Os sombreadores de rastreamento de raio são normalmente usados ​​para obter iluminação, reflexos e sombras altamente realistas em aplicativos em tempo real. Eles exigem hardware poderoso e são frequentemente utilizados em campos com uso intensivo de gráficos, como jogos ou visualização arquitetônica.
  • Depois de selecionar o shader, digite qualquer nome e pressione Enter

O novo Shader foi criado e pode ser aberto em qualquer editor de script e modificado para atender às suas necessidades.

Padrão '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"
}

Padrão '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
        }
    }
}

Padrão '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
        }
    }
}

Padrão '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);
}

Padrão '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);
}

Conclusão

Cada tipo de sombreador tem seus próprios pontos fortes e usos. É importante escolher o sombreador apropriado com base em seus requisitos específicos e nos efeitos visuais que deseja alcançar em seu projeto.

Artigos sugeridos
Como fazer um objeto seguir o cursor do mouse no Unity
Como reproduzir arquivos de vídeo no Unity
Como adicionar o efeito Sniper Scope no Unity
Criar ScriptableObjects no Unity
Uma introdução ao GUILayout no Unity
Implementando temporizadores no Unity
Criando um GrabPack no Unity inspirado em Poppy Playtime