Quantcast
Channel: Community | MonoGame - Latest topics
Viewing all articles
Browse latest Browse all 6821

Render Target Cube Texture Cube How to questions.

$
0
0

@willmotil wrote:

This is a continuation of a solved post here http://community.monogame.net/t/solved-how-would-one-render-the-screen-to-just-a-portion-of-a-rendertarget/10614/11
It was sort of off topic in the other thread.

I still have some questions on how to render this rendercube to a actual quad cube.
Do i set the light position to be the center of a quad cube and then get the rendered scene texels to do reflection mapping onto a cube ? Id like to also be able to colorize the depth and display it in that way onto a cube for visualization and to make sure it looks proper.

Anyways i got it running i have no idea how bugged up this really is till i get a better scene in there im tired so itll have to wait. But it appears to be doing some shadowing.

Gray is the shadow color in the below picture. So it's at least partialy working.

Here's my code so far minus the helper class with the grid.

Game1 and Shader

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace TestTextureCube
{

    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        // whats the difference here what does the textureCube do exactly
        TextureCube textureCube;
        // i get the rendertargetCube
        RenderTargetCube renderTargetCube;
        //
        Effect effect;
        //
        float near = 1.0f;
        float far = 1000f;
        Matrix world, view, projection;
        Matrix worldGrid, worldCamera, worldLight, worldObj1, worldObj2;
        Vector3 worldGridPosition, worldCameraPosition, worldLightPosition, worldObj1Position, worldObj2Position;

        // something to draw
        Grid3dOrientation grid = new Grid3dOrientation(30, 30, .001f);
        // 2.0 is screen scale with a wvp identity matrix.
        Quad quad = new Quad(1.7f);

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = this.LoadBasics("Shadow Cube test");
            effect = Content.Load<Effect>("EffectCubeMap");
            textureCube = new TextureCube(GraphicsDevice, 6, false, SurfaceFormat.Single);
            renderTargetCube = new RenderTargetCube(GraphicsDevice, 256, false, SurfaceFormat.Single, DepthFormat.Depth24);
            effect.Parameters["farPlane"].SetValue(far);

            world = Matrix.Identity;
            SetView(world);
            projection = Matrix.CreatePerspectiveFieldOfView((float)MathHelper.Pi * .5f, GraphicsDevice.Viewport.Width / GraphicsDevice.Viewport.Height, near, far);

            worldLightPosition = new Vector3(3f, .1f, -.5f);
            worldLight = CreateWorldToTarget(worldLightPosition, Vector3.Zero, Vector3.Up);
            worldGridPosition = Vector3.Zero;
            worldGrid = Matrix.CreateScale(30f) * Matrix.CreateWorld(Vector3.Zero, Vector3.Forward, Vector3.Up);
            worldCameraPosition = new Vector3(.5f, -.5f, 2f);
            worldCamera = CreateWorldToTarget(worldCameraPosition, Vector3.Zero, Vector3.Up);

        }

        protected override void UnloadContent()
        {
            this.UnloadBasics();
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            //BasicStuff.Update(gameTime);
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Black, 1, 0);
            GraphicsDevice.RasterizerState = new RasterizerState() { FillMode = FillMode.Solid, CullMode = CullMode.None };
            GraphicsDevice.DepthStencilState = new DepthStencilState() { DepthBufferEnable = true, DepthBufferFunction = CompareFunction.LessEqual };

            // ok so lets take a look
            effect.CurrentTechnique = effect.Techniques["CreateLightShadowCubeDepth"];

            // well set a rendertarget to prepare for drawing
            // we set our own view matrix to match at the light shadow location.
            // we draw some stuff to a depth buffer.
            GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.NegativeX);
            SetViewToLight(worldLightPosition, Vector3.Left);
            DrawGridToDepth();

            GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.NegativeY);
            SetViewToLight(worldLightPosition, Vector3.Down);
            DrawGridToDepth();

            GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.NegativeZ);
            SetViewToLight(worldLightPosition, Vector3.Forward);
            DrawGridToDepth();

            GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.PositiveX);
            SetViewToLight(worldLightPosition, Vector3.Right);
            DrawGridToDepth();

            GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.PositiveY);
            SetViewToLight(worldLightPosition, Vector3.Up);
            DrawGridToDepth();

            GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.PositiveZ);
            SetViewToLight(worldLightPosition, Vector3.Backward);
            DrawGridToDepth();

            // definately going to need a octree too.

            // Ok so we have our depths in this rendertarget cube.
            // I want to draw with the shadowing.
            // So on this calculation side, im guessing it just does the math and thats the attraction.
            // i suppose i can get data on this thing if i want to see it flattened out.

            // switch to backbuffer
            GraphicsDevice.SetRenderTarget(null);

            // we switch our view now to our actual camera and draw our scene with shadow.... but...
            effect.CurrentTechnique = effect.Techniques["LightShadowCubeBasicShader"];
            effect.Parameters["worldLightPosition"].SetValue(worldLightPosition);
            SetView(worldCamera);
            effect.Parameters["WorldViewProjection"].SetValue(GetWvp());

            DrawGridWithShadow();


            BasicStuff.Draw();
            base.Draw(gameTime);
        }

        // yes its wasteful i just want a working test for now.
        void DrawGridToDepth()
        {
            SetWorld(worldGrid);
            effect.Parameters["lightsPovWorldViewProjection"].SetValue(GetWvp());
            grid.Draw(GraphicsDevice, effect, 0);
            grid.Draw(GraphicsDevice, effect, 1);
            grid.Draw(GraphicsDevice, effect, 2);
        }
        void DrawGridWithShadow()
        {
            SetWorld(worldGrid);
            effect.Parameters["lightsPovWorldViewProjection"].SetValue(GetWvp());
            effect.Parameters["TextureB"].SetValue(renderTargetCube);

            effect.Parameters["TextureA"].SetValue(BasicTextures.red);
            grid.Draw(GraphicsDevice, effect, 0);
            effect.Parameters["TextureA"].SetValue(BasicTextures.green);
            grid.Draw(GraphicsDevice, effect, 1);
            effect.Parameters["TextureA"].SetValue(BasicTextures.blue);
            grid.Draw(GraphicsDevice, effect, 2);
        }

        void SetWorld(Matrix world)
        {
            this.world = world;
        }
        void SetView(Matrix worldForCamera)
        {
            var m = worldForCamera;
            view = Matrix.CreateLookAt(m.Translation, m.Forward + m.Translation, m.Up);
        }
        Matrix GetWvp()
        {
            return world * view * projection;
        }
        void SetViewToLight(Vector3 shadowCubePosition, Vector3 direction)
        {
            Matrix m = Matrix.CreateWorld(shadowCubePosition, direction, Vector3.Up);
            view = Matrix.CreateLookAt(m.Translation, 10f * m.Forward + m.Translation, m.Up);
        }
        Matrix CreateWorldToTarget(Vector3 position, Vector3 targetPosition, Vector3 up)
        {
            return Matrix.CreateWorld(position, targetPosition - position, up);
        }
        

    }
}

Shader.

//
//EffectCubeMap.fx
//
#if OPENGL
    #define SV_POSITION POSITION
    #define VS_SHADERMODEL vs_3_0
    #define PS_SHADERMODEL ps_3_0
#else
    #define VS_SHADERMODEL vs_4_0_level_9_1
    #define PS_SHADERMODEL ps_4_0_level_9_1
#endif

//_______________________
// Common Functions

// Calculate depth
float CalculateLightDepth(float pz, float farPlaneValue)
{
    float result = farPlaneValue - pz;
    return result;
}
// encode 3
float3 EncodeFloatRGB(float f)
{
    float3 color;
    f *= 256;
    color.x = floor(f);
    f = (f - color.x) * 256;
    color.y = floor(f);
    color.z = f - color.y;
    color.xy *= 0.00390625; // *= 1.0/256
    return color;
}
// decode 3
float DecodeFloatRGB(float3 color)
{
    const float3 byte_to_float = float3(1.0, 1.0 / 256, 1.0 / (256 * 256));
    return dot(color, byte_to_float);
}

// _______________________
// texture samplers.

Texture TextureA;
Texture TextureB;
sampler TextureSamplerA = sampler_state
{
    texture = <TextureA>;
    //magfilter = LINEAR; //minfilter = LINEAR; //mipfilter = LINEAR; //AddressU = mirror; //AddressV = mirror; 
};
sampler TextureSamplerB = sampler_state
{
    texture = <TextureB>;
    //magfilter = LINEAR; //minfilter = LINEAR; //mipfilter = LINEAR; //AddressU = mirror; //AddressV = mirror; 
};

//_______________________
// specifics

matrix World;
matrix View;
matrix Projection;
matrix WorldViewProjection;
matrix lightsPovWorldViewProjection;

float3  worldLightPosition;
float    farPlane;

//__________________
// Shaders begin now _
// _________________


//
//_______________________________________________________________
// techniques Create depth texture
//_______________________________________________________________
//

struct VsInputCalcSceneDepth
{
    float4 Position : POSITION0;
    float2 TexCoords    : TEXCOORD0;
};
struct VsOutputCalcSceneDepth
{
    float4 Position     : SV_Position;
    float4 Position2D    : TEXCOORD0;
};
struct PsOutputCalcSceneDepth
{
    float4 Color : COLOR0;
};

// ______
// Shader.
//
VsOutputCalcSceneDepth CreateDepthMapVertexShader(VsInputCalcSceneDepth input)//(float4 inPos : POSITION)
{
    VsOutputCalcSceneDepth Output;
    Output.Position = mul(input.Position, lightsPovWorldViewProjection);
    // might need to get changed
    Output.Position2D = Output.Position;
    return Output;
}
//
// I guess we set the render cube side in code so.
// Ok so were going to use the old calculation i guess.
// How does the perspective matrix align with this.
//
PsOutputCalcSceneDepth CreateDepthMapPixelShader(VsOutputCalcSceneDepth input)
{
    PsOutputCalcSceneDepth Output;
    // ABS ?
    float lightDepth = CalculateLightDepth(input.Position2D.z, farPlane);
    float3 temp = EncodeFloatRGB(lightDepth); // 24 bit depth
    float4 result = float4(temp.r, temp.g, temp.b, 1.0f);
    Output.Color = result;
    return Output;
}
//_________
// techniques
technique CreateLightShadowCubeDepth
{
    pass Pass0
    {
        VertexShader = compile VS_SHADERMODEL CreateDepthMapVertexShader();
        PixelShader = compile PS_SHADERMODEL CreateDepthMapPixelShader();
    }
}


//_______________________________________________________________
// techniques DrawLightOrShadow
//_______________________________________________________________
struct VsInLightShadow
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
    float2 TexureCoordinateA : TEXCOORD0;
};
struct VsOutLightShadow
{
    float4 Position : SV_Position;
    float2 TexureCoordinateA : TEXCOORD0;
    float4 Position2D    : TEXCOORD1;
};
struct PsOutLightShadow
{
    float4 Color : COLOR0;
};
//_______
// shaders
//
VsOutLightShadow VsLightShadow(VsInLightShadow input)
{
    VsOutLightShadow output;
    output.Position = mul(input.Position, WorldViewProjection); // basically matrix identity
    output.TexureCoordinateA = input.TexureCoordinateA;
    output.Position2D = output.Position;
    return output;
}
PsOutLightShadow PsLightShadow(VsOutLightShadow input)
{
    PsOutLightShadow output;
    output.Color = tex2D(TextureSamplerA, input.TexureCoordinateA); // *input.Color;
    // ok i think i need to mult the worldLightPosition its really in world space atm.
    float3 lightpos = mul(worldLightPosition, WorldViewProjection);
    float3 dir = input.Position2D - lightpos; //worldLightPosition
    // promlem is i dunno what texcobe does under the hood.
    float shadowDepth = DecodeFloatRGB(texCUBE(TextureSamplerB, dir).xyz);
    // texCUBE(TextureSamplerB, float4(dir, 0)).x;
    if (shadowDepth > input.Position2D.z)
        output.Color = float4(0.7f, 0.7f, 0.7f, 1.0f); // light gray
    return output;
}
//_________
// techniques
technique LightShadowCubeBasicShader
{
    pass
    {
        VertexShader = compile VS_SHADERMODEL VsLightShadow();
        PixelShader = compile PS_SHADERMODEL PsLightShadow();
    }
}

Posts: 3

Participants: 2

Read full topic


Viewing all articles
Browse latest Browse all 6821

Trending Articles