2013-07-21 28 views
1

我剛開始使用着色器使用XNA,並且遇到了幾乎不能立即理解的行爲。是否有需要在着色器之間重置的狀態

我創建了一個簡單的場景帶有紋理箱和一些地面爲它坐,使用重複的紋理單一紋理四組成(所以我的紋理座標,其中來自0,0 10,10,使其重複10倍)。最初這兩個都使用BasicEffect類。

然後我按照教程創建了我的第一個着色器,並將其用於多維數據集 - 沒有什麼比使用着色器能夠在座標座標處返回紋理的顏色,併爲我提供與之前相同的紋理多維數據集。

然而奇怪的事情發生 - 突然地面幾乎全是純色2個模糊的邊緣和角落裏的適當紋理的一個實例。紋理不再重複。我改變了我繪製立方體和地面的順序,只是對立方體解決問題發表評論。

然後我看着在我的shader代碼,大多隻是從教程複製,並認爲這指明線夾AddressU和AddressV。改變這種包裝固定了一切,但仍然給我一個問題 - 爲什麼一個着色器的紋理環繞邏輯會影響基本着色器?這是一個正常的行爲,是否有某種我需要做的狀態保存,或者這是否表明我的代碼中可能有另一個錯誤?

groundEffect.View = camera1.View; // BasicEffect 
groundEffect.Projection = projection; 
groundEffect.World = Matrix.CreateTranslation(0, -1.5f, 0); 
groundEffect.TextureEnabled = true; 
groundEffect.Texture = groundTexture; 
GraphicsDevice.Indices = groundIndexBuffer; 
GraphicsDevice.SetVertexBuffer(groundVertexBuffer); 
foreach (EffectPass pass in groundEffect.CurrentTechnique.Passes) 
{ 
    pass.Apply(); 
    GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, groundVertexBuffer.VertexCount, 0, groundIndexBuffer.IndexCount/3); 
} 


shaderEffect.Parameters["View"].SetValue(camera1.View); 
shaderEffect.Parameters["Projection"].SetValue(projection); 
shaderEffect.Parameters["World"].SetValue(modelPosition); 
shaderEffect.Parameters["ModelTexture"].SetValue(boxTexture); 
GraphicsDevice.Indices = model.IndexBuffer; 
GraphicsDevice.SetVertexBuffer(model.VertexBuffer); 
foreach (EffectPass pass in shaderEffect.CurrentTechnique.Passes) 
{ 
    pass.Apply(); 
    GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, model.VertexBuffer.VertexCount, 0, model.IndexBuffer.IndexCount/3);  
} 

回答

1

渲染狀態由四個狀態的對象來控制:

GraphicsDevice.BlendState 
GraphicsDevice.DepthStencilState 
GraphicsDevice.RasterizerState 
GraphicsDevice.SamplerStates[] // one for each sampler 

及其在XNA 4介紹在this blog post進行說明。

所有狀態變化去通過這些變量或可在.fx文件中設置。

IIRC,XNA的內置Effect對象不使用任何一種方法設置狀態 - 儘管SpriteBatch的確如此。

我無法確定從您提供的代碼中設置狀態。通常我會猜想SpriteBatch是罪魁禍首(see this blog post) - 因爲這會出現很多。但也許這是你的shaderEffect

無論如何,在渲染之前簡單設置你想要的狀態是完全合理的。下面是3D渲染的典型狀態:

GraphicsDevice.BlendState = BlendState.Opaque; 
GraphicsDevice.DepthStencilState = DepthStencilState.Default; 
GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; 
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap; 
相關問題