2011-06-08 104 views
2

我问了一个关于App Hub的问题,但没有任何回应,所以我想我会问这位大师。显示模型纹理

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

该代码可以在site找到。

Image render

编辑

我已经上传的源代码here,因为我还不能得到这个正常工作。有人可以帮忙吗?

+0

你有模型的纹理添加到'内容'文件夹? – keyboardP 2011-06-08 19:30:57

+0

@Neil Knight - 你自己创造了另一个模型吗?该模型可能会将纹理位置存储在相对路径中,所以当您的模型加载时,它正在寻找(但无法找到)该路径中的纹理。如果可能的话,模型是否可以在线提供? – keyboardP 2011-06-08 19:45:31

+0

@Neil Knight - 尝试下载一个纹理样式的演示(http://create.msdn.com/en-US/education/catalog/?contenttype=0&devarea=4&platform=20&sort=1),并将模型替换为您的模型。 – keyboardP 2011-06-08 20:26:06

回答

4

我只花了快看看shader代码,并为我所怀疑的像素着色器不使用任何类型的质地,

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

正如你所看到的纹理没有被refrenced,漫正在计算为各种其他变量的组合。

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

您需要自己设置模型纹理以供着色器查看。我不记得确切的语法,但这样的事情:

effect.SetTexture("texture_name", texture); 

是你要找的内容,其中“texture_name”是你在着色器文件中声明的类型纹理的名称。

你需要考虑的是重新编写CalcLighting需要在参数另一件事,你将需要通过纹理从顶点着色器坐标,你可以可能删除vDiffuseAlbedo为可以通过颜色来代替的纹理。

不幸的是,我不能在没有真正编写代码的情况下做出更加彻底的回答(并且我目前无法访问XNA安装),请考虑这些指针并尝试找到使用着色器加载纹理模型的教程。由于您似乎对使用自定义着色器感兴趣,因此避免将BasicEffect的教程作为BasicEffect讨论,因为它隐藏了几乎所有与您相关的着色器代码,您将无法学习任何内容。

我很难建议你可以学习的教程,因为网上有这么多的教程,每个教程都会引起别人的幻想。因此,请记住我所说的话,随时可以找到您喜欢的教程,其中解释了如何加载并正确渲染纹理模型,然后使用该知识将其应用于此示例。它起初并不像看起来那么难!

只是做了quick'n'dirty修改示例代码对你来说,它应该工作以及足以证明在着色器纹理贴图,

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

//========================================================================= 
// 
// DeferredShadowMaps 
// 
//  by MJP ([email protected]) 
//  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); 
     } 

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

+0

@meds:这是很好的信息,请看我修改后的问题。 – 2011-06-09 12:18:31

+0

@Neil Knight在你的示例代码中似乎有一吨z战斗,你是在相同的框架中渲染同一模型两次(一次纹理,一次没有)? – tweetypi 2011-06-09 13:20:37

+0

@meds:是的。我想我不需要那样做,但是我如何才能应用纹理而不是灰度? – 2011-06-09 16:18:53