我正在尝试实施2D照明系统来学习如何使用着色器。我今晚刚刚开始运行第一台着色器。
目前,游戏非常简单,我只是使用此代码在后台渲染80x80px图块。
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
Texture2D tile = this.Content.Load<Texture2D>("tile");
Effect effect = this.Content.Load<Effect>("test");
MouseState ms = Mouse.GetState();
effect.Parameters["LightPosition"].SetValue(new Vector2(ms.X, ms.Y));
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone, effect);
for (int row = 0; row < 10; row++)
{
for (int col = 0; col < 6; col++)
{
Vector2 tilePos = new Vector2(row * 80, col * 80);
effect.Parameters["TilePosition"].SetValue(tilePos);
spriteBatch.Draw(tile, tilePos, Color.White);
}
}
spriteBatch.End();
// TODO: Add your drawing code here
base.Draw(gameTime);
}
我想要做的是让鼠标指针作为光源,然后计算鼠标位置和每个图块上每个像素位置之间的差异(毕达哥拉斯),并使用它逐渐变暗瓷砖每个像素离鼠标指针越远。
然而,正在发生的是,任何给定图块上的所有像素一次“亮起”或“变暗”,这取决于鼠标指针离图块左上角的距离。
这是我的着色器代码。
texture TileTexture;
float2 LightPosition : VPOS;
float2 TilePosition : VPOS;
sampler TextureSampler = sampler_state
{
Texture = <TileTexture>;
};
float4 PixelShaderFunction(float2 TextureCoordinate : TEXCOORD0) : COLOR0
{
float4 color = tex2D(TextureSampler, TextureCoordinate);
float x_dist;
float y_dist;
float distance;
// Calculate distance formula (pythagorean - a2 = b2 + c2)
x_dist = abs(LightPosition.x - (TextureCoordinate.x + TilePosition.x));
y_dist = abs(LightPosition.y - (TextureCoordinate.y + TilePosition.y));
distance = pow(x_dist, 2) + pow(y_dist, 2);
distance = sqrt(distance);
color.r = color.r - distance * 0.01;
color.g = color.g - distance * 0.01;
color.b = color.b - distance * 0.01;
return color;
}
technique Lighting
{
pass Pass1
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
奇怪的是,这段代码实际上确实影响了每个瓷砖的每个像素,而我真的没有看到我改变了什么阻止了它的工作。
float4 PixelShaderFunction(float2 TextureCoordinate : TEXCOORD0) : COLOR0
{
float4 color = tex2D(TextureSampler, TextureCoordinate);
//float value = (color.r + color.g + color.b) / 3;
color.r = color.r + TextureCoordinate.x + TextureCoordinate.y - 0.75;
color.g = color.g + TextureCoordinate.x + TextureCoordinate.y - 0.75;
color.b = color.b + TextureCoordinate.x + TextureCoordinate.y - 0.75;
return color;
}
提前感谢您的帮助。
答案 0 :(得分:0)
TEXCOORD语义不是用整数表示纹理的像素,而是用0.0到1.0的浮点值表示它们。改变这些行:
x_dist = abs(LightPosition.x - (TextureCoordinate.x + TilePosition.x));
y_dist = abs(LightPosition.y - (TextureCoordinate.y + TilePosition.y));
对此:
x_dist = abs(LightPosition.x - ((TextureCoordinate.x * 80) + TilePosition.x));
y_dist = abs(LightPosition.y - ((TextureCoordinate.y * 80) + TilePosition.y));
其中80表示纹理的高度和宽度......
解决了这个问题。