2011-06-08 108 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