Casino online









Mercato forex






B12. HLSL: le tecniche Textured e MultiTextured


La tecnica Textured
Le parti di codice che riguardano questa tecnica sono le seguenti:
//...

texture ATexture;
sampler TextureSampler = sampler_state 
{
    Texture = <ATexture>;
    Magfilter = Linear;
    Minfilter = Linear;
    Mipfilter = Linear;
    AddressU = Mirror;
    AddressV = Mirror;
};

//...

//--------------------------------------------
//Tecnica 3 : Textured
//--------------------------------------------

VertexToPixel TexturedVertexShader(float4 inPos : POSITION, 
    float3 inNormal: NORMAL, float2 inTexCoords: TEXCOORD0)
{    
    VertexToPixel Output = (VertexToPixel)0;
	
    float4x4 ViewProjection = mul(View, Projection);
    float4x4 WorldViewProjection = mul(World, ViewProjection);
    
    Output.Position = mul(inPos, WorldViewProjection);    
    Output.TextureCoords = inTexCoords;
        
    Output.LightingFactor = 1;
    if (LightEnabled)
    {
        float3 Normal = normalize(mul(normalize(inNormal), World));	
        Output.LightingFactor = saturate(dot(Normal, -LightDirection));
    }
    
    return Output;    
}

PixelToFrame TexturedPixelShader(VertexToPixel inPixel)
{
    PixelToFrame Output = (PixelToFrame)0;        
    
    Output.Color = tex2D(TextureSampler, inPixel.TextureCoords);
    Output.Color.rgb *= saturate(inPixel.LightingFactor + AmbientFactor);

    return Output;
}

technique Textured
{
    pass Pass0
    {
        VertexShader = compile vs_1_1 TexturedVertexShader();
        PixelShader = compile ps_1_1 TexturedPixelShader();
    }
}
Cominciamo con l'introdurre un nuovo tipo di dato: texture. Molto semplicemente, esso rappresenta una texture, ed è l'equivalente di Texture2D in XNA. Strettamente legato a quest'ultimo c'è sampler (dall'inglese "sample" = "campione"). Questo oggetto permette di ottenere il colore di un determinato pixel di una texture. La sua inizializzazione è alquanto complessa e prevede che gli si assegni un valore creato da texture_sampler, con l'aggiunta di alcuni parametri tra le paretesi graffe. Ecco una descrizione dei parametri: Nel nostro caso, abbiamo dichiarato tutti i filtri come Linear, mentre le coordinate UV come mirror: in realtà, con le texture che stiamo usando, non si vede molto la differenza tra wrap e mirror.
Il vertex shader è praticamente uguale a quello della tecnica ColoredPlus, con un'unica eccezione: c'è un parametro in più (la coordinate texture).
Il pixel shader presenta anch'esso una sola differenza col precedente:
Output.Color = tex2D(TextureSampler, inPixel.TextureCoords);
Questa linea è molto semplice: la funzione tex2D non fa altro che prelevare il colore del pixel che si trova alle coordinate inPixel.TextureCoords della texture contenuta nel sampler TextureSampler.


La tecnica MultiTextured
Questa tecnica è abbastanza complessa, molto più delle precedenti. Ecco il suo codice:
struct MultiVertexToPixel
{
    float4 Position         : POSITION;    
    float4 Color            : COLOR0;
    float3 Normal           : TEXCOORD0;
    float2 TextureCoords    : TEXCOORD1;
    float4 LightDirection   : TEXCOORD2;
    float4 TextureWeights   : TEXCOORD3;
    float Depth             : TEXCOORD4;
};

struct MultiPixelToFrame
{
    float4 Color : COLOR0;
};

Texture Texture0;
Texture Texture1;
Texture Texture2;
Texture Texture3;

sampler TextureSampler0 = sampler_state 
{
	Texture = <Texture0>; 
	Magfilter = Linear; 
	Minfilter = Linear; 
	Mipfilter = Linear; 
	AddressU = Wrap; 
	AddressV = Wrap;
};

sampler TextureSampler1 = sampler_state 
{
	Texture = <Texture1>; 
	Magfilter = Linear; 
	Minfilter = Linear; 
	Mipfilter = Linear; 
	AddressU = Wrap; 
	AddressV = Wrap;
};

sampler TextureSampler2 = sampler_state 
{
	Texture = <Texture2>; 
	Magfilter = Linear; 
	Minfilter = Linear; 
	Mipfilter = Linear; 
	AddressU = Mirror; 
	AddressV = Mirror;
};

sampler TextureSampler3 = sampler_state 
{
	Texture = <Texture3>; 
	Magfilter = Linear; 
	Minfilter = Linear; 
	Mipfilter = Linear;
	AddressU = Mirror; 
	AddressV = Mirror;
};



MultiVertexToPixel MultiTexturedVertexShader(float4 inPos : POSITION, 
    float3 inNormal: NORMAL, float4 inTexCoords: TEXCOORD0, 
    float4 inTexWeights: TEXCOORD1)
{    
    MultiVertexToPixel Output = (MultiVertexToPixel)0;
	
    float4x4 ViewProjection = mul(View, Projection);
    float4x4 WorldViewProjection = mul(World, ViewProjection);
    
    Output.Position = mul(inPos, WorldViewProjection);
    Output.Normal = mul(normalize(inNormal), World);
    Output.TextureCoords = inTexCoords;
    Output.LightDirection.xyz = -LightDirection;
    Output.LightDirection.w = 1;    
    Output.TextureWeights = inTexWeights;
    Output.Depth = Output.Position.z / Output.Position.w;
    
    return Output;    
}

MultiPixelToFrame MultiTexturedPixelShader(MultiVertexToPixel inPixel)
{
    MultiPixelToFrame Output = (MultiPixelToFrame)0;        
    
    float lightingFactor = 1;
    if (LightEnabled)
        lightingFactor = saturate(saturate(dot(inPixel.Normal, 
            inPixel.LightDirection)) + AmbientFactor);
        
    float blendDistance = 0.99f;
    float blendWidth = 0.005f;
    float blendFactor = 
        clamp((inPixel.Depth - blendDistance) / blendWidth, 0, 1);
        
    float4 farColor;
    farColor = tex2D(TextureSampler0, inPixel.TextureCoords) * 
        inPixel.TextureWeights.x;
    farColor += tex2D(TextureSampler1, inPixel.TextureCoords) * 
        inPixel.TextureWeights.y;
    farColor += tex2D(TextureSampler2, inPixel.TextureCoords) * 
        inPixel.TextureWeights.z;
    farColor += tex2D(TextureSampler3, inPixel.TextureCoords) * 
        inPixel.TextureWeights.w;
    
    float4 nearColor;
    float2 nearTextureCoords = inPixel.TextureCoords * 3;
    nearColor = tex2D(TextureSampler0, nearTextureCoords) * 
        inPixel.TextureWeights.x;
    nearColor += tex2D(TextureSampler1, nearTextureCoords) * 
        inPixel.TextureWeights.y;
    nearColor += tex2D(TextureSampler2, nearTextureCoords) * 
        inPixel.TextureWeights.z;
    nearColor += tex2D(TextureSampler3, nearTextureCoords) * 
        inPixel.TextureWeights.w;

    Output.Color = lerp(nearColor, farColor, blendFactor);
    Output.Color *= lightingFactor;
    
    return Output;
}

technique MultiTextured
{
    pass Pass0
    {
        VertexShader = compile vs_2_0 MultiTexturedVertexShader();
        PixelShader = compile ps_2_0 MultiTexturedPixelShader();
    }
}
Analizziamo il codice un pezzo alla volta: Infine, bisogna notare che il vertex e il pixel shader risultano compilati non con la versione 1.1, ma con la 2.0, poiché la funzione lerp non è supportata dalla 1.1.





 

The Totem's Lair - Copyright (C) 2009
È vietata la riproduzione sia totale che parziale del sito.