好的,我移植了一个我一直在做的游戏到Monogame,但是现在我有一个着色器的问题,因为它被移植了。这是一个奇怪的bug,因为它适用于我的旧XNA项目,并且在我第一次在新的monogame项目中使用它时也有效,但在那之后就不会了,除非我重新启动游戏。
着色器是一个非常简单的着色器,它查看灰度图像,并基于灰度从查找纹理中拾取颜色。基本上,每次屏幕上有新的敌人时,我都会用它随机化一个敌人的精灵图像。它在敌人第一次产卵时起作用,但在那之后就不起作用了,只是提供了一个完全透明的纹理(而不是空纹理)。
此外,我现在只针对Windows桌面,但我计划在某个时候针对Mac和Linux。
这是着色器代码本身。
sampler input : register(s0);
Texture2D colorTable;
float seed; //calculate in program, pass to shader (between 0 and 1)
sampler colorTableSampler =
sampler_state
{
Texture = <colorTable>;
};
float4 PixelShaderFunction(float2 c: TEXCOORD0) : COLOR0
{
//get current pixel of the texture (greyscale)
float4 color = tex2D(input, c);
//set the values to compare to.
float hair = 139/255; float hairless = 140/255;
float shirt = 181/255; float shirtless = 182/255;
//var to hold new color
float4 swap;
//pixel coordinate for lookup
float2 i;
i.y = 1;
//compare and swap
if (color.r >= hair && color.r <= hairless)
{
i.x = ((0.5 + seed + 96)/128);
swap = tex2D(colorTableSampler,i);
}
if (color.r >= shirt && color.r <= shirtless)
{
i.x = ((0.5 + seed + 64)/128);
swap = tex2D(colorTableSampler,i);
}
if (color.r == 1)
{
i.x = ((0.5 + seed + 32)/128);
swap = tex2D(colorTableSampler,i);
}
if (color.r == 0)
{
i.x = ((0.5 + seed)/128);
swap = tex2D(colorTableSampler, i);
}
return swap;
}
technique ColorSwap
{
pass Pass1
{
// TODO: set renderstates here.
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}这是创建纹理的函数。我还应该注意到,纹理生成在没有着色器的情况下工作得很好,我只得到了灰度基础图像。
public static Texture2D createEnemyTexture(GraphicsDevice gd, SpriteBatch sb)
{
//get a random number to pass into the shader.
Random r = new Random();
float seed = (float)r.Next(0, 32);
//create the texture to copy color data into
Texture2D enemyTex = new Texture2D(gd, CHARACTER_SIDE, CHARACTER_SIDE);
//create a render target to draw a character to.
RenderTarget2D rendTarget = new RenderTarget2D(gd, CHARACTER_SIDE, CHARACTER_SIDE,
false, gd.PresentationParameters.BackBufferFormat, DepthFormat.None);
gd.SetRenderTarget(rendTarget);
//set background of new render target to transparent.
//gd.Clear(Microsoft.Xna.Framework.Color.Black);
//start drawing to the new render target
sb.Begin(SpriteSortMode.Immediate, BlendState.Opaque,
SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullNone);
//send the random value to the shader.
Graphics.GlobalGfx.colorSwapEffect.Parameters["seed"].SetValue(seed);
//send the palette texture to the shader.
Graphics.GlobalGfx.colorSwapEffect.Parameters["colorTable"].SetValue(Graphics.GlobalGfx.palette);
//apply the effect
Graphics.GlobalGfx.colorSwapEffect.CurrentTechnique.Passes[0].Apply();
//draw the texture (now with color!)
sb.Draw(enemyBase, new Microsoft.Xna.Framework.Vector2(0, 0), Microsoft.Xna.Framework.Color.White);
//end drawing
sb.End();
//reset rendertarget
gd.SetRenderTarget(null);
//copy the drawn and colored enemy to a non-volitile texture (instead of render target)
//create the color array the size of the texture.
Color[] cs = new Color[CHARACTER_SIDE * CHARACTER_SIDE];
//get all color data from the render target
rendTarget.GetData<Color>(cs);
//move the color data into the texture.
enemyTex.SetData<Color>(cs);
//return the finished texture.
return enemyTex;
}以防万一,在着色器中加载的代码:
BinaryReader Reader = new BinaryReader(File.Open(@"Content\\shaders\\test.mgfx", FileMode.Open));
colorSwapEffect = new Effect(gd, Reader.ReadBytes((int)Reader.BaseStream.Length));如果任何人有解决这个问题的想法,我将非常感谢,如果你需要关于这个问题的其他信息,请告诉我。
发布于 2013-11-23 00:13:16
我不知道为什么在字符串前面有"at“(@)符号,当你转义反斜杠时-除非你想在字符串中有\,但它在文件路径中看起来很奇怪。
你在你的代码中写道:
BinaryReader Reader = new BinaryReader(File.Open(@"Content\\shaders\\test.mgfx", FileMode.Open));除非您想在字符串中使用\
BinaryReader Reader = new BinaryReader(File.Open(@"Content\shaders\test.mgfx", FileMode.Open));或
BinaryReader Reader = new BinaryReader(File.Open("Content\\shaders\\test.mgfx", FileMode.Open));但不要两个都使用。
发布于 2015-01-10 10:58:25
我没有看到任何非常明显的东西,只是通读它,但实际上,这可能是棘手的人只看你的代码。
我建议做一个图形配置文件(通过visual studio),捕获正确渲染的帧,然后不正确地渲染帧,并比较两者的状态。
例如,输入纹理是否如您所期望的那样,像素是否正在输出但被剔除,渲染目标上的输出是否正确(在这种情况下,问题可能是Get/SetData),等等。
发布于 2016-09-28 13:53:25
将ps_2_0更改为ps_4__level_9_3。
Monogame不能使用构建在HLSL 2上的着色器。
此外,内建的精灵批处理着色器使用ps_4__level_9_3和vs_4__level_9_3,如果您尝试用不同级别的着色器替换着色器的像素部分,将会出现问题。
这是我在你的代码中看到的唯一问题。
https://stackoverflow.com/questions/18753473
复制相似问题