Alright i seem to have something off, im getting a entirely shadowed scene but the depth visualization clearly shows that it sees these cubes this has me confused.
Im not sure either if the light position is truely at the cubes center or what is going on.
Heres my game1 and heres my shader currently.
game1
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
namespace TestTextureCube
{
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
RenderTargetCube renderTargetCube;
Effect effect;
//
float near = .1f;
float far = 1000f;
//
Matrix world, view, projection;
Matrix worldGrid, worldCamera, worldLight, worldCube;
// well draw a bunch.
Matrix[] worldCubes;
int numberOfCubes = 30;
Vector3 theLightsViewPosition;
// something to draw
Grid3dOrientation grid = new Grid3dOrientation(30, 30, .001f);
CubePNTT cube = new CubePNTT(true);
Quad quad = new Quad(1.7f); // 2.0 is screen scale with a wvp identity matrix.
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");
renderTargetCube = new RenderTargetCube(GraphicsDevice, 256, false, SurfaceFormat.Single, DepthFormat.Depth24);
//effect.Parameters["farPlane"].SetValue(far);
world = Matrix.Identity;
SetCreateView(world);
SetProjection(Matrix.CreatePerspectiveFieldOfView((float)MathHelper.Pi * .5f, GraphicsDevice.Viewport.Width / GraphicsDevice.Viewport.Height, near, far));
worldLight = CreateWorldToTarget(new Vector3(3f, 2f, -2f), Vector3.Zero, Vector3.Up);
worldGrid = Matrix.CreateScale(30f) * Matrix.CreateWorld(Vector3.Zero, Vector3.Forward, Vector3.Up);
worldCube = Matrix.CreateScale(1f) * CreateWorldToTarget(new Vector3(3f, .1f, -.5f), Vector3.Zero, Vector3.Up);
worldCamera = CreateWorldToTarget(new Vector3(.5f, -.5f, 4f), Vector3.Zero, Vector3.Up);
MakeBunchesOfCubes();
BasicStuff.camera.CameraType(BasicCamera.MOVEMENT_CAMERA);
BasicStuff.camera.SetPosition(worldCamera.Translation);
}
void MakeBunchesOfCubes()
{
// spiral
var pi2 = MathHelper.Pi *2f;
int len = numberOfCubes;
worldCubes = new Matrix[len];
for(int i = 0; i < len; i++)
{
float r = (float)(i) / (float)(len);
var t = (r) * pi2 * 2f; // 12 radians 2 circles
var x = (float)Math.Sin(t);
var y = 0f;
var z = (float)Math.Cos(t);
Vector3 p = new Vector3(x,y,z) * (2f + r * 4f ) + worldLight.Translation; // spirals instead
worldCubes[i] = Matrix.CreateScale(.4f + r) * Matrix.CreateWorld(p, Vector3.Forward, 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 };
//
// Render to each face of the cube this will need a spacial partition of some type later on.
//
GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.NegativeX);
SetCreateView(worldLight.Translation, Vector3.Left, Vector3.Up);
RenderSceneDepth();
GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.NegativeY);
SetCreateView(worldLight.Translation, Vector3.Down, Vector3.Forward);
RenderSceneDepth();
GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.NegativeZ);
SetCreateView(worldLight.Translation, Vector3.Forward, Vector3.Up);
RenderSceneDepth();
GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.PositiveX);
SetCreateView(worldLight.Translation, Vector3.Right, Vector3.Up);
RenderSceneDepth();
GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.PositiveY);
SetCreateView(worldLight.Translation, Vector3.Up, Vector3.Backward);
RenderSceneDepth();
GraphicsDevice.SetRenderTarget(renderTargetCube, CubeMapFace.PositiveZ);
SetCreateView(worldLight.Translation, Vector3.Backward, Vector3.Up);
RenderSceneDepth();
//
// Draw the scene with shadow from our depth cube.
//
GraphicsDevice.SetRenderTarget(null); // Switch back to the buffer.
SetCreateView(BasicStuff.camera.World); // We switch our view to the scene camera.
// Draw the scene with shadow.
DrawSceneWithShadowing();
// Draw the visualization enviromental cube. , note don't bother rotating it into place
DrawVisualizationCube();
base.Draw(gameTime);
}
public void RenderSceneDepth()
{
effect.CurrentTechnique = effect.Techniques["RenderShadowDepth"];
effect.Parameters["worldLightPosition"].SetValue(worldLight.Translation);
//// render grids depth // Dont render this depth for the moment.
//SetWorld(worldGrid);
//grid.Draw(GraphicsDevice, effect, 0);
//grid.Draw(GraphicsDevice, effect, 1);
//grid.Draw(GraphicsDevice, effect, 2);
// render cubes depth
effect.Parameters["TextureA"].SetValue(BasicTextures.checkerBoard);
effect.Parameters["TextureB"].SetValue(renderTargetCube);
for (int i = 0; i < worldCubes.Length;i++)
{
SetWorld(worldCubes[i]);
cube.Draw(GraphicsDevice, effect);
}
}
public void DrawSceneWithShadowing()
{
effect.CurrentTechnique = effect.Techniques["LightShadowCubeBasicShader"];
effect.Parameters["worldLightPosition"].SetValue(worldLight.Translation);
SetCreateView(BasicStuff.camera.World); // We switch our view to camera.
// draw grid
SetWorld(worldGrid);
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);
// draw cubes
effect.Parameters["TextureA"].SetValue(BasicTextures.checkerBoard);
effect.Parameters["TextureB"].SetValue(renderTargetCube);
for (int i = 0; i < worldCubes.Length; i++)
{
SetWorld(worldCubes[i]);
cube.Draw(GraphicsDevice, effect);
}
}
public void DrawVisualizationCube()
{
// draw a cube at the light with the depth visualization
effect.CurrentTechnique = effect.Techniques["DepthVisualization"];
SetWorld(worldLight);
effect.Parameters["TextureA"].SetValue(BasicTextures.checkerBoard);
effect.Parameters["TextureB"].SetValue(renderTargetCube);
cube.Draw(GraphicsDevice, effect);
}
//____________________
// some extra helper stuff
// ___________________
Matrix CreateWorldToTarget(Vector3 position, Vector3 targetPosition, Vector3 up)
{
return Matrix.CreateWorld(position, targetPosition - position, up);
}
void SetWorld(Matrix World)
{
world = World;
effect.Parameters["World"].SetValue(world);
}
void SetCreateView(Matrix worldForCamera)
{
view = Matrix.CreateLookAt(worldForCamera.Translation, worldForCamera.Forward + worldForCamera.Translation, worldForCamera.Up);
effect.Parameters["View"].SetValue(view);
}
void SetCreateView(Vector3 position, Vector3 direction, Vector3 up)
{
view = Matrix.CreateLookAt(position, position + direction, up);
effect.Parameters["View"].SetValue(view);
}
Vector3 GetViewPosition()
{
return view.Translation;
}
// humm should i be using the lights view position because of the targetcube.
Vector3 GetLightPosition(Matrix theLightsWorldMatrix)
{
var temp = Matrix.CreateLookAt(theLightsWorldMatrix.Translation, theLightsWorldMatrix.Forward + theLightsWorldMatrix.Translation, theLightsWorldMatrix.Up);
return temp.Translation;
}
void SetProjection(Matrix Projection)
{
projection = Projection;
effect.Parameters["Projection"].SetValue(projection);
}
void SetCreatePerspectiveProjection(float near, float far, float fovInDegrees)
{
projection= Matrix.CreatePerspectiveFieldOfView((float)MathHelper.Pi * MathHelper.ToRadians(fovInDegrees), GraphicsDevice.Viewport.Width / GraphicsDevice.Viewport.Height, near, far);
effect.Parameters["Projection"].SetValue(projection);
}
}
}
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
//_______________________
// _______________________
// Texture samplers.
//_______________________
Texture TextureA; // primary texture.
Texture TextureB; // render texture or secondary multi texture.
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;
};
//_______________________
// Shader globals
//_______________________
matrix World;
matrix View;
matrix Projection;
float3 worldLightPosition;
//_______________________________________________________________
// technique
// Render shadow depth
//_______________________________________________________________/
struct VsInputCalcSceneDepth
{
float4 Position : POSITION0;
float2 TexCoords : TEXCOORD0;
};
struct VsOutputCalcSceneDepth
{
float4 Position : SV_Position;
float4 Position3D : TEXCOORD0;
};
// Shader.
VsOutputCalcSceneDepth CreateDepthMapVertexShader(VsInputCalcSceneDepth input)//(float4 inPos : POSITION)
{
VsOutputCalcSceneDepth output;
output.Position3D = mul(input.Position, World);
float4x4 wvp = mul(World, mul(View, Projection));
output.Position = mul(input.Position, wvp);
return output;
}
float4 CreateDepthMapPixelShader(VsOutputCalcSceneDepth input) : COLOR
{
float lightDepth = input.Position3D.z;
return lightDepth;
}
//_________
// techniques
technique RenderShadowDepth
{
pass Pass0
{
VertexShader = compile VS_SHADERMODEL CreateDepthMapVertexShader();
PixelShader = compile PS_SHADERMODEL CreateDepthMapPixelShader();
}
}
//_______________________________________________________________
// technique
// DrawLightOrShadow
//_______________________________________________________________
struct VsInLightShadow
{
float4 Position : POSITION0;
float3 Normal : NORMAL0;
float2 TexureCoordinateA : TEXCOORD0;
};
struct VsOutLightShadow
{
float4 Position : SV_Position;
float2 TexureCoordinateA : TEXCOORD0;
float4 Position3D : TEXCOORD1;
};
struct PsOutLightShadow
{
float4 Color : COLOR0;
};
// shaders
VsOutLightShadow VsLightShadow(VsInLightShadow input)
{
VsOutLightShadow output;
output.Position3D = mul(input.Position, World);
float4x4 wvp = mul(World, mul(View, Projection));
output.Position = mul(input.Position, wvp);
output.TexureCoordinateA = input.TexureCoordinateA;
return output;
}
PsOutLightShadow PsLightShadow(VsOutLightShadow input)
{
PsOutLightShadow output;
float3 pixelpos = input.Position3D;
float3 lightpos = worldLightPosition;
float3 lightToPixelDir = pixelpos - lightpos;
float pixelDistance = distance(pixelpos, lightpos);
float4 texelcolor = tex2D(TextureSamplerA, input.TexureCoordinateA); // *input.Color;
float shadowDepth = texCUBE(TextureSamplerB, float4(lightToPixelDir, 0)).x;
if (shadowDepth < pixelDistance)
texelcolor = float4(0.7f, 0.7f, 0.7f, 1.0f); // light gray
output.Color = texelcolor;
return output;
}
//_________
// techniques
technique LightShadowCubeBasicShader
{
pass
{
VertexShader = compile VS_SHADERMODEL VsLightShadow();
PixelShader = compile PS_SHADERMODEL PsLightShadow();
}
}
//_______________________________________________________________
// technique
// Depth Visualization
//_______________________________________________________________
// shaders
VsOutLightShadow VsDepthVisualization(VsInLightShadow input)
{
VsOutLightShadow output;
output.Position3D = mul(input.Position, World);
float4x4 wvp = mul(World, mul(View, Projection));
output.Position = mul(input.Position, wvp);
output.TexureCoordinateA = input.TexureCoordinateA;
return output;
}
PsOutLightShadow PsDepthVisualization(VsOutLightShadow input)
{
PsOutLightShadow output;
float3 pixelpos = input.Position3D.xyz; // / input.Position3D.w;
float3 lightpos = worldLightPosition;
float3 lightToPixelDir = pixelpos - lightpos;
float4 texelcolor = tex2D(TextureSamplerA, input.TexureCoordinateA);
float shadowDepth = texCUBE(TextureSamplerB, float4(lightToPixelDir, 0)).x;
texelcolor = (texelcolor + shadowDepth) * 0.5f;
output.Color = texelcolor;
return output;
}
technique DepthVisualization
{
pass
{
VertexShader = compile VS_SHADERMODEL VsDepthVisualization();
PixelShader = compile PS_SHADERMODEL PsDepthVisualization();
}
}
Now if i change this.
pixelposition despite the name and all of the comparison variables should be in world space.
/*if (shadowDepth < pixelDistance)*/
if (shadowDepth < pixelpos.z)
i get this below…
What is even happening here i have no idea.
As the grid lines are not being depth rendered.
I can zip up the project, if you want to take a look at the whole thing.
Newer bug test is below.