显示模型纹理

时间:2011-06-08 19:13:45

标签: xna

我已经对App Hub提出了一个问题,但没有任何回复,所以我想我会问这里的大师。

是否可以让模型显示其纹理而不是此项目输出的灰度?

可在此site上找到代码。

Image render

修改

我上传了源代码here,因为我仍然无法使其正常工作。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:4)

我只是快速浏览了着色器代码,因为我怀疑像素着色器不使用任何纹理,

// Calculates the contribution for a single light source using phong lighting
 float3 CalcLighting (  float3 vDiffuseAlbedo, 
                    float3 vSpecularAlbedo, 
                    float fSpecularPower, 
                    float3 vLightColor, 
                    float3 vNormal, 
                    float3 vLightDir, 
                    float3 vViewDir )
{
    float3 R = normalize(reflect(-vLightDir, vNormal));

     // Calculate the raw lighting terms
     float fDiffuseReflectance = saturate(dot(vNormal, vLightDir));
     float fSpecularReflectance = saturate(dot(R, vViewDir));

     // Modulate the lighting terms based on the material colors, and the attenuation   factor
     float3 vSpecular = vSpecularAlbedo * vLightColor * pow(fSpecularReflectance,     fSpecularPower);
     float3 vDiffuse = vDiffuseAlbedo * vLightColor * fDiffuseReflectance;  

     // Lighting contribution is the sum of the diffuse and specular terms
     return vDiffuse + vSpecular;
}

正如您所看到的,纹理未被修复,漫反射被计算为各种其他变量的组合。

这几乎肯定是为了降低代码的复杂性,但是添加对纹理的支持应该是相当微不足道的。您应该查看this sample底部的像素和顶点着色器,以了解如何在着色器中使用纹理并将其与CalcLighting()函数集成。

您需要在代码中自己设置模型纹理,以便着色器查看它。我无法记住确切的语法,但是这样的话:

effect.SetTexture("texture_name", texture);

您正在寻找什么,其中“texture_name”是您在着色器文件中声明的类型纹理的名称。

你需要考虑的另一件事是重写CalcLighting接受的参数,你需要从顶点着色器传递纹理坐标,你可以可能删除vDiffuseAlbedo,因为它可以是取而代之的是纹理的颜色。

不幸的是,如果没有实际编写代码(我目前无法访问XNA安装),我无法更彻底地回答这个问题,请考虑这些指针并尝试找到使用着色器加载纹理模型的教程。由于您似乎对使用自定义着色器感兴趣,因此避免使用关于BasicEffect的教程,因为BasicEffect几乎隐藏了所有相关着色器代码,您将不会学到任何东西。

我很难建议你可以学习的教程,因为有很多在线教程,每个教程都有人喜欢。所以请记住我所说的随意找到一个你熟悉的教程,解释如何加载和正确渲染纹理模型,然后使用该知识将其应用于此示例。它真的不像最初看起来那么难!

刚刚对您的示例代码进行了快速修改,它应该可以很好地演示着色器中的纹理映射,

我在model.fx中添加了一个纹理变量,我通过代码设置它,以便绘制纹理而不是白色,并确保顶点着色器将顶点的纹理坐标传递给像素着色器。请记住,我故意打破了光照计算,以简化纹理采样器的属性。

//=========================================================================
//
//  DeferredShadowMaps
//
//      by MJP  (mpettineo@gmail.com)
//      12/14/08      
//
//=========================================================================
//
//  File:       Model.fx
//
//  Desc:       Outputs the lighting contribution for a single directional
//              light source. Also samples shadow occlusion from a texture.
//
//=========================================================================

float4x4 g_matWorld;
float4x4 g_matViewProj;
float4x4 g_matWorldIT;

float2 g_vRTDimensions;

float3 g_vDiffuseAlbedo = {0.5f, 0.5f, 0.5f};
float3 g_vSpecularAlbedo = {1.0f, 1.0f, 1.0f};
float g_fSpecularPower = 32.0f;

float3 g_vLightDirectionWS;
float3 g_vLightColor;

float3 g_vAmbientColor;

float3 g_vCameraPositionWS;

texture ShadowOcclusion;
sampler2D ShadowOcclusionSampler = sampler_state
{
    Texture = <ShadowOcclusion>;
    MinFilter = Point; 
    MagFilter = Point; 
    MipFilter = Point;
};


texture ModelTexture;
sampler2D ModelSampler = sampler_state
{
    Texture = <ModelTexture>;
    MinFilter = Linear; 
    MagFilter = Linear; 
    MipFilter = Linear;
};

void ModelVS(   in float4 in_vPositionOS    : POSITION,
                in float3 in_vNormalOS      : NORMAL,   
                in float2 in_vTexCoord      : TEXCOORD0,
                out float4 out_vPositionCS  : POSITION,
                out float3 out_vNormalWS    : TEXCOORD0,
                out float3 out_vPositionWS  : TEXCOORD1,
                out float4 out_vPositionCS2 : TEXCOORD2,
                out float2 out_vTexCoord    : TEXCOORD3 )                                       
{   
    // Figure out the position of the vertex in world space, and clip space
    out_vPositionWS = mul(in_vPositionOS, g_matWorld).xyz;  
    out_vPositionCS = mul(float4(out_vPositionWS, 1), g_matViewProj);    

    // Rotate the normal so it's in world space
    out_vNormalWS = mul(in_vNormalOS, g_matWorldIT);

    // Also store the clip-space position in a TEXCOORD, since we can't
    // read from the POSITION register in the pixel shader.
    out_vPositionCS2 = out_vPositionCS;

    // Pass out the texture coordinates to the pixel shader
    out_vTexCoord = in_vTexCoord;
}

// Calculates the contribution for a single light source using phong lighting
float3 CalcLighting (   float3 vDiffuseAlbedo, 
                        float3 vSpecularAlbedo, 
                        float fSpecularPower, 
                        float3 vLightColor, 
                        float3 vNormal, 
                        float3 vLightDir, 
                        float3 vViewDir )
{
    float3 R = normalize(reflect(-vLightDir, vNormal));

    // Calculate the raw lighting terms
    float fDiffuseReflectance = saturate(dot(vNormal, vLightDir));
    float fSpecularReflectance = saturate(dot(R, vViewDir));

    // Modulate the lighting terms based on the material colors, and the attenuation factor
    float3 vSpecular = vSpecularAlbedo * vLightColor * pow(fSpecularReflectance, fSpecularPower);
    float3 vDiffuse = vDiffuseAlbedo * vLightColor * fDiffuseReflectance;   

    // Lighting contribution is the sum of the diffuse and specular terms
    return vDiffuse + vSpecular;
}

// Gets the screen-space texel coord from clip-space position
float2 CalcSSTexCoord (float4 vPositionCS)
{
    float2 vSSTexCoord = vPositionCS.xy / vPositionCS.w;
    vSSTexCoord = vSSTexCoord * 0.5f + 0.5f;    
    vSSTexCoord.y = 1.0f - vSSTexCoord.y; 
    vSSTexCoord += 0.5f / g_vRTDimensions;    
    return vSSTexCoord;
}   

float4 ModelPS( in float3 in_vNormalWS      : TEXCOORD0,
                in float3 in_vPositionWS    : TEXCOORD1,
                in float4 in_vPositionCS    : TEXCOORD2,
                in float2 in_vTexCoord      : TEXCOORD3) : COLOR0
{    
    // Sample the shadow term based on screen position
    float2 vScreenCoord = CalcSSTexCoord(in_vPositionCS);    
    float fShadowTerm = tex2D(ShadowOcclusionSampler, vScreenCoord).r;  

    // Normalize after interpolation
    float3 vNormalWS = normalize(in_vNormalWS);
    float3 vLightDirWS = normalize(-g_vLightDirectionWS);
    float3 vViewDirWS = normalize(g_vCameraPositionWS - in_vPositionWS);

    // Calculate the lighting term for the directional light
    float3 vLightContribition = 0;
    vLightContribition = fShadowTerm * tex2D(ModelSampler, in_vTexCoord);

    // Add in ambient term  
    vLightContribition.xyz += g_vDiffuseAlbedo * g_vAmbientColor;       
    return float4(vLightContribition, 1.0f);
}

technique Model
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 ModelVS();
        PixelShader = compile ps_2_0 ModelPS();

        ZEnable = true;
        ZWriteEnable = true;
        CullMode = CCW;
        FillMode = Solid;
        AlphaBlendEnable = false;
        AlphaTestEnable = false;
    }
}

使用'DrawMainLightingPass'中'DefferedShadowMaps.cs'源文件中的一个样本我修改了一些绘图代码如下:

       // Loads the texture here (note this is put here for the skae of simplicity, the texture should generally be retrieved from the model)
       Texture texture = Content.Load<Texture>("Models/Beast_1");

        // Begin the Effect
        modelEffect.Begin();

        modelEffect.CurrentTechnique.Passes[0].Begin();

        // Draw the models
        foreach (ModelInstance modelInstance in modelList)
        {
           modelEffect.Parameters["ModelTexture"].SetValue(texture);
            modelInstance.Draw(GraphicsDevice, modelEffect);
        }

请注意,这不是您应该处理模型绘制和管理的方式,但它是我可以演示您纹理模型的最直接方式。这是有效的(我运行它很好),所以随意修改它,使其适合您自己的引擎设计:)