Jump to content

  • Log In with Google      Sign In   
  • Create Account

How to get multiple textures on a model in DX11?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 michaelmk86   Members   -  Reputation: 189

Like
0Likes
Like

Posted 20 May 2013 - 12:47 PM

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


Edited by michaelmk86, 20 May 2013 - 12:48 PM.


Sponsor:

#2 menohack   Members   -  Reputation: 216

Like
2Likes
Like

Posted 20 May 2013 - 05:16 PM

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.



#3 BornToCode   Members   -  Reputation: 951

Like
0Likes
Like

Posted 20 May 2013 - 07:07 PM

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.


Edited by BornToCode, 20 May 2013 - 07:09 PM.


#4 kauna   Crossbones+   -  Reputation: 2864

Like
0Likes
Like

Posted 21 May 2013 - 07:35 AM

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!


Edited by kauna, 21 May 2013 - 07:45 AM.


#5 michaelmk86   Members   -  Reputation: 189

Like
0Likes
Like

Posted 21 May 2013 - 07:40 AM

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;
};

Edited by michaelmk86, 21 May 2013 - 07:42 AM.


#6 unbird   Crossbones+   -  Reputation: 6022

Like
0Likes
Like

Posted 21 May 2013 - 10:34 AM

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.

#7 michaelmk86   Members   -  Reputation: 189

Like
0Likes
Like

Posted 21 May 2013 - 02:32 PM

it works now.

 

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

 

thanks



#8 michaelmk86   Members   -  Reputation: 189

Like
0Likes
Like

Posted 21 May 2013 - 03:51 PM

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






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS