忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

かんたんXNA その21 深度バッファへの書き込みの無効化

このページは古いです
最新版はこちら

前回は深度バッファそのものを無効化しましたが、
深度バッファのチェックはそのままに、
書き込みだけを無効化することも出来ます。

書き込みを無効にすると、
深度バッファそのものを無効化したときのように
やはり奥の物が手前のものより前に描画されてしまいます。

深度が記録されなくなって、どの物体が手前に、
どの物体が奥にあるのかわからなくなるからです。

しかし使いようによっては変わったこともできます。
深度バッファそのものは有効なので
半透明のビームなどを描きたいときには
壁に隠れてかつ、ビーム同士では半透明で隠れない
といったことができます。

深度バッファへの書き込みを無効にするには
RenderState.DepthBufferWriteEnable
プロパティを使います。

public bool DepthBufferWriteEnable { get; set; }

このプロパティにfalseをセットすると書き込みが無効化されます。
もちろんデフォルトはtrueです。
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;


class Triangle
{
    VertexPositionColor[] vertices = new VertexPositionColor[3];

    public Triangle(Vector3 p1, Vector3 p2, Vector3 p3, Color color)
    {
        vertices[0] = new VertexPositionColor(p1, color);
        vertices[1] = new VertexPositionColor(p2, color);
        vertices[2] = new VertexPositionColor(p3, color);
    }

    public void Draw(GraphicsDevice graphicsDevice, BasicEffect effect)
    {
        graphicsDevice.VertexDeclaration = new VertexDeclaration(
            graphicsDevice,
            VertexPositionColor.VertexElements);
        effect.VertexColorEnabled = true;

        effect.Begin();

        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        {
            pass.Begin();

            graphicsDevice.DrawUserPrimitives<VertexPositionColor>(
                PrimitiveType.TriangleList,
                vertices,
                0,
                1
                );

            pass.End();
        }

        effect.End();
    }
}

class MyGame : Game
{
    GraphicsDeviceManager graphics;
    BasicEffect basicEffect;

    Triangle blueTriangle = new Triangle(
        new Vector3(0,1, 0),
        new Vector3(1, -0.5f, 0),
        new Vector3(-1, -0.5f, 0),
        Color.Blue
        );
    Triangle redTriangle = new Triangle(
        new Vector3(1, 0.5f, -1),
        new Vector3(0, -1, -1),
        new Vector3(-1, 0.5f, -1),
        Color.Red
        );


    public MyGame()
    {
        graphics = new GraphicsDeviceManager(this);
    }

    protected override void LoadGraphicsContent(bool loadAllContent)
    {
        if (loadAllContent)
        {
            basicEffect = new BasicEffect(graphics.GraphicsDevice, null);
            basicEffect.View = Matrix.CreateLookAt(
                new Vector3(0, 0, 3),
                new Vector3(0, 0, 0),
                new Vector3(0, 1, 0)
                );
            basicEffect.Projection = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.ToRadians(45),
                Window.ClientBounds.Width / (float)Window.ClientBounds.Height,
                1, 100
                );
        }
    }

    protected override void Draw(GameTime gameTime)
    {
        graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

        graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = false;

        blueTriangle.Draw(graphics.GraphicsDevice, basicEffect);
        redTriangle.Draw(graphics.GraphicsDevice, basicEffect);
    }
}

depthBufferWriteDisabled.jpg
ここでも、2つの三角形を描画しています。
手前に青い三角形、奥に赤い三角形があるのですが、
深度バッファへ書き込みがされていないので
ポリゴンが常に描画されてしまい、
赤い三角形が上に描画されてしまいます。

さて、これだけではRenderState.DepthBufferEnableプロパティ
との違いがわかりにくいですね。
そういうときには次のようにすると違いがわかります。
    protected override void Draw(GameTime gameTime)
    {
        graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

        blueTriangle.Draw(graphics.GraphicsDevice, basicEffect);
        graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = false;
        redTriangle.Draw(graphics.GraphicsDevice, basicEffect);
        graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;
    }

これは三角形を正常に描画します。
最後の赤い三角形の次にはもう描画するポリゴンがないので
深度バッファを書き込まなくても問題はないのです。



拍手[0回]

PR