0

我正在尝试实现一个 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;
}

提前感谢您的帮助。

4

1 回答 1

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代表纹理的高度和宽度......

修复问题。

于 2013-01-18T03:46:48.247 回答