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);
    }

私がやりたいのは、マウスポインターを光源として機能させ、マウスの位置と各タイルの各ピクセルの位置との差(pythagorean)を計算し、それを使用してタイルを徐々に暗くすることです。各ピクセルはマウスポインタからのものです。

ただし、何が起こっているのかというと、マウスポインターがタイルの左上隅からどれだけ離れているかに基づいて、特定のタイルのすべてのピクセルが一度に「明るく」または「暗く」なります。

これが私のシェーダーコードです。

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までのfloat値で表します。これらの行の変更:

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 に答える