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

Started by
8 comments, last by theScore 13 years, 6 months ago
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 ?
Advertisement
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;

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 textureeffect->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.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

When you talk about effect, you mean .fx files ?
I'm not using .fx file, i shoulded say before sorry.
is there something that i have to set or call for other texture stage than 0 ?
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?
i believe that it is the texture stage numbers, but i am really not sure...
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
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.
Hi guys !
Well, thanks for your help, you're both right :
SetInt(...) is unuseful...
And the keyword "register(s[n]) //with n my texture stage
was missing in the shader.

Thanks !

This topic is closed to new replies.

Advertisement