How to get multiple textures on a model in DX11?

Started by
6 comments, last by michaelmk86 10 years, 11 months ago

Hi, how to get multiple textures on a model without the need to use separate draw calls for each texture that is on the model?


SamplerState SampleTypeWrap  : register(s0);

Texture2D mTexture0 : register(t0);
Texture2D mTexture1 : register(t1);
Texture2D mTexture2 : register(t2);


struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0; // contains texture coordinates for all 3 Textures that are on the model
    float3 normal : NORMAL;
};

float4 PPixelShader(PixelInputType input) : SV_TARGET
{

    //need to fine how to determine what Textures(mTexture0, mTexture1, mTexture2) corresponds to the input.tex (that contains all the texture coordinates)

    float4 output;

    //if(this pixel have Texture mTexture0)
    	output = mTexture0.Sample(SampleTypeWrap, input.tex);
    //if(this pixel have Texture mTexture1)
    	output = mTexture1.Sample(SampleTypeWrap, input.tex);
    //if(this pixel have Texture mTexture2)
    	output = mTexture2.Sample(SampleTypeWrap, input.tex);

    return output;
}

I hope i make myself clear.smile.png

Advertisement

If you aren't blending textures then the easiest way is to combine the textures into one. You would have to recompute your texture coordinates.

Otherwise you need an index per-vertex telling you which texture to use in the pixel shader. You can add a uint to the input and output of your vertex shader. Your vertex buffer will need to specify the integer index of the texture for each vertex. The vertex shader will just pass the integer through to the pixel shader. Then change your Texture2D to an array like Texture2D mTexture[3] : register(t0); and call mTexture[input.index].Sample().

If you are doing something like terrain where you want to blend multiple textures then you just need multiple texture coordinates.

You can just sample from two different texture and combine the two using additive or modulative blending in a single pass depending on how you want them to blend.

Create a different shader permutation for different versions of the shader (single texture, multi texture etc). Combine the textures inside the shader with a mathematical formula as desired (there is no one answer to this since two textures can be combined in numerous ways).

Here's few examples for combining 2 textures.


float4 PPixelShader(PixelInputType input) : SV_TARGET
{
    float4 Tex1 = mTexture0.Sample(SampleTypeWrap, input.tex);
    float4 Tex2 = mTexture1.Sample(SampleTypeWrap, input.tex);

   return Tex1 * Tex2;  //simple modulation, useful for detail maps
   return Tex1 + Tex2;  //additive
   return Tex1 * Tex2 * 2.0f; //simple modulation with multiplier
   return lerp(Tex1,Tex2, SomeValue); // interpolate between two texture based on some value.
   return Tex1 - Tex2; //subtractive

}

Cheers!

Otherwise you need an index per-vertex telling you which texture to use in the pixel shader. You can add a uint to the input and output of your vertex shader. Your vertex buffer will need to specify the integer index of the texture for each vertex. The vertex shader will just pass the integer through to the pixel shader. Then change your Texture2D to an array like Texture2D mTexture[3] : register(t0); and call mTexture[input.index].Sample().

that is exactly what I need, but can you give a bit more info on how to make this input to the shader?


//currently have this
struct VertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    uint material; // what i need to put here? 
    uint InstanceId : SV_InstanceID;
};
As an alternative: If your textures have the same dimension and format you could use texture arrays (in HLSL: Texture2DArray).

Also: I don't think you can index dynamically into several registers.

it works now.

with the "uint material : BLENDINDICES;" as input in the vertex shader

thanks

something weird that i notice


struct VertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    uint material : BLENDINDICES;
    uint InstanceId : SV_InstanceID;
};

in this line in the VertexShader

output.material = input.material;

have around 10% performance impact, I mean all it dose is to pass the an int to the Pixel Shader wacko.png

This topic is closed to new replies.

Advertisement