Aviso já que não tenho jeito para as palavras, mas espero que ajude a quem não está familiarizado com shaders.

Primeiramente a estrutura de um shader vazio será mais ou menos assim:
Código: Selecionar todos
Shader "Custom/ThatsEnough" {
Properties {
//variáveis de entrada ficam aqui (atribuídas no editor do unity)
}
SubShader {
Pass {
Tags { "RenderType"="Opaque" }
LOD 200
//funções de calculo ficam aqui
}
}
}
Para as variáveis de entrada podemos definir por exemplo:
Código: Selecionar todos
_DifuseColor ("Difuse Color", Color) = (0.5,0.5,0.5,0.5) //cor para sobrepor à textura
_DifuseTex ("Difuse Texture", 2D) = "white" {} //texture
Existem 3 tipos de funçoes que podemos usar em unity
-Surface shaders (não faço a mínima)
-Vertex e Fragment shaders (igual a GLSL / HLSL)
-Fixed Functions (funções não programáveis, ou seja, era da pedra )
Neste caso vamos usar Vertex e Fragment. Para isso precisamos de dizer quais as funções que dizem respeito ao fragment e vertex shader usando #pragma vertex/fragment nome_da_função.
Código: Selecionar todos
#pragma vertex vert
Precisamos também de dizer que buffers é que vamos receber, o vertex buffer será indispensável mas podemos receber também cordenadas de texturas, cor, normais etc..
Código: Selecionar todos
float4 vertex : POSITION;
Código: Selecionar todos
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
sampler2D _DifuseTex;
fixed4 _DifuseColor;
struct vertexIN {
float4 vertex : POSITION;
//fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct vertexOUT {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
vertexOUT vert (vertexIN v) {
//cálculos relativos aos vértices
}
float4 frag (vertexOUT f) : COLOR {
//cálculos relativos aos fragmentos(pixeis)
}
ENDCG
Um dos objectivos principais do vertex shader será aplicar as transformações necessárias aos vertices para que estes sejam movidos/rodados para a posição correcta de acordo com a camara. Para isto multiplica-se os vértices pela matriz MVP (Projection * View * Model). Model será respectivo à transform do objecto, Projection e View são relativos à camara.
Usando:
Código: Selecionar todos
vertex = mul(UNITY_MATRIX_MVP, v.vertex);
Obtemos o seguinte resultado:


Vamos atribuir à cor do vértice a cor escolhida no editor do unity para dar a possibilidade de acrescentar uma tonalidade à textura e vamos simplesmente passar as coordenadas de textura sem fazer nenhum cálculo.
Código: Selecionar todos
vertexOUT vert (vertexIN v){
vertexOUT o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.color = _DifuseColor;
o.texcoord = v.texcoord; // TRANSFORM_TEX(v.texcoord,_DifuseTex);
return o;
}
Depois do vertex shader vêm mais alguns processos como tesselation e por aí, mas não vou entrar em detalhes, se quiserem saber mais pesquisem "Graphic pipeline". A parte que nos interessa agora é o fragment shader, para já vamos apenas atribuir a cor ao pixel consoante a textura escolhida e as respectivas coordenadas UV.
Código: Selecionar todos
float4 frag (vertexOUT f) : COLOR {
float4 c = tex2D(_DifuseTex, f.texcoord);
return c;
}
Obtemos assim um simples shader com uma textura:

Código: Selecionar todos
Shader "Custom/ThatsEnough" {
Properties {
_DifuseColor ("Difuse Color", Color) = (1,1,1,1)
_DifuseTex ("Difuse Texture", 2D) = "white" {}
}
SubShader {
Pass {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
sampler2D _DifuseTex;
fixed4 _DifuseColor;
struct vertexIN {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct vertexOUT {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
vertexOUT vert (vertexIN v)
{
vertexOUT o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.color = _DifuseColor;
o.texcoord = v.texcoord; // TRANSFORM_TEX(v.texcoord,_DifuseTex);
return o;
}
float4 frag (vertexOUT f) : COLOR
{
float4 c = tex2D(_DifuseTex, f.texcoord);
return c;
}
ENDCG
}
}
}
(continua....)