Olá pessoal, tudo certo?!
Este é o primeiro post sobre XNA que escrevo desde o TechEd. Fiquei realmente feliz e satisfeito ao perceber tantas pessoas presentes nas minhas palestras.
No post de hoje, mostro a aplicação de uma técnica simples de multitexturing no “game” que estamos desenvolvendo. Veja o resultado:
O post de hoje pode ser percebido como uma “continuação” da parte 13. Se está chegando agora, recomendo a leitura dos outros posts dessa série.
Todo o código fonte está disponível em https://github.com/ElemarJR/VamosAprenderXNA.
IMPORTANTE: O post de hoje é inspirado nas idéias presentes no livro . Realmente achei interessante a proposta do autor e por isso reproduzo o conceito aqui.
Multitexturing, muitas texturas
Multitexturing faz sentindo quando desejamos aplicar mais de uma textura em um mesmo modelo. No “terreno” acima foram utilizadas quatro texturas: Rocha, Areia, Grama e Neve.
Para decidir que textura aplicar, utilizei um mapa de cores.
Basicamente, aplico:
- grama no preto;
- areia no vermelho;
- rocha no verde;
- neve no azul.
O bacana dessa técnica é que podemos modificar a “posição das texturas” simplesmente alterando esse bitmap.
Construindo o Effect
O effect proposto no livro é extramemente simples. Começa pelas texturas e samplers. Observe:
texture RTexture;
sampler RTextureSampler = sampler_state
{
texture = ;
AddressU = Wrap;
AddressV = Wrap;
MinFilter = Anisotropic;
MagFilter = Anisotropic;
};
texture GTexture;
sampler GTextureSampler = sampler_state
{
texture = ;
AddressU = Wrap;
AddressV = Wrap;
MinFilter = Anisotropic;
MagFilter = Anisotropic;
};
texture BTexture;
sampler BTextureSampler = sampler_state
{
texture = ;
AddressU = Wrap;
AddressV = Wrap;
MinFilter = Anisotropic;
MagFilter = Anisotropic;
};
texture BaseTexture;
sampler BaseTextureSampler = sampler_state
{
texture = ;
AddressU = Wrap;
AddressV = Wrap;
MinFilter = Anisotropic;
MagFilter = Anisotropic;
};
texture WeightMap;
sampler WeightMapSampler = sampler_state
{
texture = ;
AddressU = Wrap;
AddressV = Wrap;
MinFilter = Anisotropic;
MagFilter = Anisotropic;
};
Depois, parâmetros básicos e estrutura de dados:
float4x4 World;
float4x4 View;
float4x4 Projection;
float3 LightDirection = float3(1, -1, 0);
float TextureTiling = 6;
struct VertexShaderInput
{
float4 Position : POSITION0;
float2 UV : TEXCOORD0;
float3 Normal : NORMAL0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 UV : TEXCOORD0;
float3 Normal : TEXCOORD1;
};
Por fim, os shaders:
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.Normal = input.Normal;
output.UV = input.UV;
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float light = dot(
normalize(input.Normal),
normalize(LightDirection)
);
light = clamp(light + 0.4f, 0, 1);
float3 rtex = tex2D(RTextureSampler, input.UV * TextureTiling);
float3 gtex = tex2D(GTextureSampler, input.UV * TextureTiling);
float3 btex = tex2D(BTextureSampler, input.UV * TextureTiling);
float3 base = tex2D(BaseTextureSampler, input.UV * TextureTiling);
float3 weightMap = tex2D(WeightMapSampler, input.UV);
float3 output = clamp(1.0f - weightMap.r - weightMap.g - weightMap.b, 0, 1);
output *= base;
output += weightMap.r * rtex + weightMap.g * gtex + weightMap.b * btex;
return float4(output * light, 1);
}
technique Technique1
{
pass Pass1
{
VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
Repare como a combinação entre as texturas é feita de forma extremamente simples. Basicamente, utilizamos a “intensidade” de cada elemento no WeightMap para aplicar a textura que desejamos.
A configuração no Game também é bastante simples:
var effect = Content.Load("MultitextureTerrainEffect"); effect.Parameters["WeightMap"].SetValue(Content.Load ("WeightMap")); effect.Parameters["BaseTexture"].SetValue(Content.Load ("grass")); effect.Parameters["RTexture"].SetValue(Content.Load ("sand")); effect.Parameters["GTexture"].SetValue(Content.Load ("rock")); effect.Parameters["BTexture"].SetValue(Content.Load ("snow"));
Bacana!
Era isso!
![]()



Publicado em 11/10/2011
0