Sign in to follow this  
theScore

[HLSL] how to use several texture in pixel shader ?

Recommended Posts

theScore    158
Hi !
I have this as global variables in my pixel shader (v. PS 3.0):

sampler2D texMap;
sampler2D g_buffer_norm;
sampler2D g_buffer_pos;
sampler2D g_random;


i want to render on a quad with this :

o.color = tex2D(g_random, i.uv);

and in my directx 9 program

pixelShaderParams2->SetInt(initD3D9.pd3dDevice, "texMap", 0);
pixelShaderParams2->SetInt(initD3D9.pd3dDevice, "g_buffer_norm", 1);
pixelShaderParams2->SetInt(initD3D9.pd3dDevice, "g_buffer_pos", 2);
pixelShaderParams2->SetInt(initD3D9.pd3dDevice, "g_random", 3);

pd3dDevice->SetTexture( 0, initD3D9.texture1 );//color map
pd3dDevice->SetTexture( 1, initD3D9.texture3 );//normals map
pd3dDevice->SetTexture( 2, initD3D9.texture2 );//positions map
pd3dDevice->SetTexture( 3, initD3D9.texture4 );//random normal map
pd3dDevice->SetStreamSource(0, verticesPlanBuffer, 0, sizeof(float)*3);
pd3dDevice->SetStreamSource(1, texCoordPlanBuffer, 0, sizeof(float)*2);



pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,/* 0, 6, 0,*/ 2);


It only works if the first parameter of SetTexture is 0 (i tried for each map separately), how can i do to access to all my maps in the same time, in my pixel shader ?

Share this post


Link to post
Share on other sites
Zosimas    122
I'm not sure what you are asking, but if I understood right,
you don't have to use SetTexture in your program at all
if you use an effect.

You just load your textures in your shader and then combine
them in your pixel shader.

Simple example:

sampler2D texMap;
sampler2D g_buffer_norm;
sampler2D g_buffer_pos;
sampler2D g_random;

float3 tex1 = tex2D(texMap, i.uv).xyz;
float3 tex2 = tex2D(g_buffer_norm, i.uv).xyz;
float3 tex3 = tex2D(g_buffer_pos, i.uv).xyz;
float3 tex4 = tex2D(g_random, i.uv).xyz;

float3 result = lerp(tex1, tex2, 0.5);
result = lerp(result , tex3, 0.5);
result = lerp(result , tex4, 0.5);

o.color = result;

Share this post


Link to post
Share on other sites
Buckeye    10747
As Zosimas mentions, if you're using an effect, you don't set the textures in the pipeline. You set the sampler in the shader to the desired texture pointer.

E.g.,

D3DXHANDLE hTex1, hTex2;
hTex1 = effect->GetParameterByName(NULL,"texMap");
hTex2 = effect->GetParameterByName(NULL,"g_buffer_norm");
// etc.
// To set a texture sampler to a particular texture
effect->SetTexture(hTex1,texture1);
effect->SetTexture(hTex2,texture2);
// etc.

Also, remember, if you change the texture (or any effect parameter) between effect->Begin and effect->End, call effect->CommitChanges() after the new parameters have been set.

Share this post


Link to post
Share on other sites
sirlemonhead    227
I only know very basic HLSL, but what you have written there doesn't seem right to me.

From what I can see, you're setting up 4 sampler2Ds in the pixel shader. What you also seem to be doing, which is what I dont understand, is passing Ints in using what looks like constant tables, using constant names exactly the same as your sampler2Ds

what's the purpose of passing in 0, 1, 2 and 3 using the SetInt function?

Share this post


Link to post
Share on other sites
sirlemonhead    227
I'd remove those SetInt lines completely.

sampler2D texMap;
sampler2D g_buffer_norm;
sampler2D g_buffer_pos;
sampler2D g_random;


If you have those lines in your pixel shader, you then do:

SetTexture(0, initD3D9.texture1)
SetTexture(1, initD3D9.texture2)
SetTexture(2, initD3D9.texture3)
SetTexture(3, initD3D9.texture4)

That'll set texMap to initD3D9.texture1, g_buffer_norm to initD3D9.texture2 etc

then, sample them as required

o.color = tex2D(g_random, i.uv);
o.position = tex2D(g_buffer_pos, i.uv);

try that out

Share this post


Link to post
Share on other sites
Dawoodoz    461
I am using DirectX 11 but it is quite close.

This is how I define the textures and samplers in a HLSL file.

Texture2D g_txDiffuse : register( t0 );
Texture2D g_txNormal : register( t1 );
Texture2D g_txSpecular : register( t2 );
Texture2D g_txIllumination : register( t3 );
Texture2D g_txShadow : register( t5 );
Texture2D g_txInputA : register( t6 );
Texture2D g_txInputB : register( t7 );
Texture2D g_txInputC : register( t8 );
Texture2D g_txInputD : register( t9 );

SamplerState m_pSamMipmap : register( s0 );
SamplerState m_pSamAnisotropicMipmap : register( s1 );
SamplerState m_pSamSharp : register( s2 );
SamplerState m_pSamEffect : register( s3 );
SamplerComparisonState g_samShadow : register( s5 );



DirectX11 in Cpp:
pd3dImmediateContext->PSSetShaderResources( n, 1, &MyShaderResourceView );
Will set texture n to the texture pointed to in MyShaderResourceView.
A shader resource view contains data about where a texture is and how to read it.

DirectX11 in Cpp:
pd3dImmediateContext->PSSetSamplers( n, 1, &MySampler );
Will set sampler n to MySampler.
A sampler is an interpolation method that may use mipmaps, anisotropic filtering...

HLSL with Shader 4.0:
vOriginalColor = g_txDiffuse.Sample( m_pSamMipmap, vMyUVCoordinate );
Will sample a point from the diffuse texture using the m_pSamMipmap sampler at coordinate vMyUVCoordinate and return the 4 channel color to vOriginalColor.
You can use any float2 value as the UV input for special effects.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this