如何将纹理传递给 DirectX 9 像素着色器?

2024-06-18

我有像素着色器

// fxc.exe tiles.fs /T ps_3_0 /Fotiles.fsc /Fctiles.fsl

struct PSInput
{   
    float4 Pos : TEXCOORD0;
    float3 Normal : TEXCOORD1;
    float2 TexcoordUV : TEXCOORD2;
    float2 TexcoordST : TEXCOORD3;
};

sampler2D sampler0; //uniform 
sampler2D sampler1; //uniform 
sampler2D sampler2; //uniform 
sampler2D sampler3; //uniform 
sampler2D alphamap1;//uniform 
sampler2D alphamap2;//uniform 
sampler2D alphamap3;//uniform 
uniform int tex_count = 0;

uniform float4 color_ambient = float4(0.75, 0.75, 0.75, 1.0);
uniform float4 color_diffuse = float4(0.25, 0.25, 0.25, 1.0);
uniform float4 color_specular = float4(1.0, 1.0, 1.0, 1.0);
uniform float shininess = 77.0f;
uniform float3 light_position = float3(12.0f, 32.0f, 560.0f);

float4 main(PSInput In) : COLOR
{
    float3 light_direction = normalize(light_position - (float3)In.Pos);
    float3 normal = normalize(In.Normal);
    float3 half_vector = normalize(light_direction + normalize((float3)In.Pos));
    float diffuse = max(0.0, dot(normal, light_direction));
    float specular = pow(max(0.0, dot(In.Normal, half_vector)), shininess);
    float4 color = tex2D(sampler0, In.TexcoordUV);

    if (tex_count > 0){
        float4 temp = tex2D(sampler1, In.TexcoordUV);
        float4 amap = tex2D(alphamap1, In.TexcoordST);
        color = lerp(color, temp, amap.a);
    }
    if (tex_count > 1){
        float4 temp = tex2D(sampler2, In.TexcoordUV);
        float4 amap = tex2D(alphamap2, In.TexcoordST);
        color = lerp(color, temp, amap.a);
    }
    if (tex_count > 2){
        float4 temp = tex2D(sampler3, In.TexcoordUV);
        float4 amap = tex2D(alphamap3, In.TexcoordST);
        color = lerp(color, temp, amap.a);
    }
    color = color * color_ambient + diffuse * color_diffuse + specular * color_specular;

    return color;
}

顶点着色器

// fxc.exe tiles.vs /T vs_3_0 /Fotiles.vsc /Fctiles.vsl

struct VSInput
{
    float3 Pos : POSITION;
    float3 Normal : NORMAL;
    float2 TexcoordUV : TEXCOORD0;
    float2 TexcoordST : TEXCOORD1;
};

struct PSInput
{   
    float4 Pos : POSITION;
    float3 Normal : TEXCOORD0;
    float2 TexcoordUV : TEXCOORD1;
    float2 TexcoordST : TEXCOORD2;
};

uniform matrix modelMatrix;
uniform matrix projectionMatrix;
uniform matrix lookAtMatrix;

PSInput main(VSInput In)
{
    PSInput Out = (PSInput) 0;

    //projectionMatrix * lookAtMatrix * modelMatrix;
    matrix MVP = mul(modelMatrix, lookAtMatrix); 
    MVP = mul(MVP, projectionMatrix); 

    Out.Normal = mul(In.Normal, (float3x3)modelMatrix);
    Out.Pos = mul(float4(In.Pos, 1.0), MVP);    
    Out.TexcoordUV = In.TexcoordUV;
    Out.TexcoordST = In.TexcoordST;

    return Out;
}

在 OpenGL + GLSL 下同样有效,除了mix取而代之lerp(我希望它是正确的)。 举例来说来自http://www.two-kings.de/tutorials/dxgraphics/dxgraphics18.html http://www.two-kings.de/tutorials/dxgraphics/dxgraphics18.html我传递纹理:

ps_pConstantTable.SetInt(m_pD3DDevice, texCountHandle, 0);
for i := 0 to texCount - 1 do begin
  tBlp := texture_buf[cx, cy][i];
  if tBlp = nil then
      break;

  m_pD3DDevice.SetTexture(i, tBlp.itex);
  ps_pConstantTable.SetInt(m_pD3DDevice, texCountHandle, i);

  if i > 0 then begin
    // this time, use blending:
    m_pD3DDevice.SetTexture(i + 3, AlphaMaps[cx, cy][i]);
  end;
end;

因此序数纹理的索引为 0-3 和 alpha 4-6(最大 texCount 4)。 问题是:我可以看到网格(地形),但它是纯黑色的。我是否需要其他东西来设置(没有着色器,它也是黑色的,直到我分配材质和灯光)?我可以传递这样的纹理吗?我可以这样做吗sampler2D as uniform (how)?

编辑:示例包含源、着色器、多个使用的纹理和 alphamap、filebeam 处带有法线的顶点数据http://fbe.am/nm4 http://fbe.am/nm4添加。尽可能小。还包含 DXErr9ab.dll 用于记录错误。


要在像素着色器中使用纹理,您可以按照以下步骤操作

通过 D3DXCreateTextureFromFile 或其他函数在 C/C++ 文件中创建纹理。

if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "FaceTexture.jpg",
    &g_pTexture ) ) )
return E_FAIL;

声明一个 D3DXHANDLE 并将其与着色器文件中的纹理关联。(您应该在这一步之前编译效果文件,effects_ 这里是指向 ID3DXEffect 的指针)

texture_handle = effects->GetParameterByName(0, "FaceTexture");

在渲染函数中设置纹理

effects_->SetTexture(texture_handle, g_pTexture);

在着色器文件中声明纹理

纹理FaceTexture;

在着色器文件中声明一个采样器

// Face texture sampler
sampler FaceTextureSampler = sampler_state
{
    Texture   = <FaceTexture>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

在像素着色器函数中进行采样

float4 BasicPS(OutputVS outputVS) : COLOR
{
    float4 Output;
    Output = FaceTexture.Sample(FaceTextureSampler, outputVS.texUV);
    return Output;
}

如果您安装了 DirectX SDK,我建议您看一下示例“BasicHLSL”,其中对顶点着色器和像素着色器(包括纹理)进行了非常基本的介绍。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将纹理传递给 DirectX 9 像素着色器? 的相关文章

随机推荐