public CameraController(Camera camera, Vector3 initialPosition, Vector2 initialOrientation) { _camera = camera; Speed = 0.5f; orientation = initialOrientation; position = initialPosition; }
public FollowLight(float radius, float intensity, Color color, Camera cam) : base(Vector3.Zero, Quaternion.Identity, Vector3.One) { _camera = cam; Light light; light = new Light(); light.Color = color; light.Radius = radius; light.Intensity = intensity; light.LocalTransform = Matrix.Identity; light.Shadow = false; Lights.Add(light); }
public virtual void DrawHighlight(Camera camera, GraphicsDevice graphicsDevice, RenderTarget2D edgemask) { foreach (ModelMesh mesh in _model.Meshes) { if (camera.Frustum.Intersects(Helpers.TransformSphere(mesh.BoundingSphere, m[mesh.ParentBone.Index]))) { foreach (EffectMaterial effect in mesh.Effects) { effect.CurrentTechnique = effect.Techniques["DrawHighlight"]; effect.Parameters["WorldViewProjection"].SetValue(m[mesh.ParentBone.Index] * camera.EyeProjectionTransform); effect.Parameters["edgemask"].SetValue(edgemask); mesh.Draw(); } } } }
public virtual void DrawOcclusion(Camera camera, GraphicsDevice graphicsDevice, Light light, bool front = true) { if (Draw) { Vector3 LightPos = light.Transform.Translation; BoundingBox bb; float val; if (front) { bb = new BoundingBox(LightPos - ((Vector3.UnitZ + Vector3.UnitX) * light.Radius), LightPos + (Vector3.One * light.Radius)); val = 1.0f; } else { bb = new BoundingBox(LightPos - (Vector3.One * light.Radius), LightPos + ((Vector3.UnitZ + Vector3.UnitX) * light.Radius)); val = -1.0f; } foreach (ModelMesh mesh in _model.Meshes) { if (bb.Intersects(Helpers.TransformSphere(mesh.BoundingSphere, m[mesh.ParentBone.Index])) || Game1.drawall) { foreach (EffectMaterial effect in mesh.Effects) { effect.CurrentTechnique = effect.Techniques["ShadowMap"]; effect.Parameters["Dir"].SetValue(val); effect.Parameters["LightWorldView"].SetValue(m[mesh.ParentBone.Index] * light.LightView); effect.Parameters["LightWorldViewProjection"].SetValue(m[mesh.ParentBone.Index] * light.LightViewProj); effect.Parameters["LightPosition"].SetValue(LightPos); effect.Parameters["LightClip"].SetValue(light.Radius); mesh.Draw(); Game1.occluders++; } } } } }
private void RenderToGBuffer(Camera cam, List<LPPMesh> meshes) { foreach (LPPMesh mesh in meshes) { meshCountGBuffer++; mesh.RenderToGBuffer(cam, GraphicsDevice); } }
private void RenderLights(Camera camera, List<Light> lights, List<LPPMesh> occludingMeshes) { Vector3[] camCorners = camera.Frustum.GetCorners(); Vector3 camCentre = Vector3.Zero; foreach (Vector3 vec in camCorners) { camCentre += vec; } camCentre /= camCorners.Length; Effect _lighting; foreach (Light light in lights) { if (light.LightType == "DynamicShadow") { light.LightView = Matrix.CreateLookAt(light.Transform.Translation, light.Transform.Translation - Vector3.UnitY, Vector3.UnitZ); light.LightViewProj = light.LightView * Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(90), 1.0f, 0.01f, light.Radius); GenerateDPSShadowMap(camera, light, occludingMeshes, _shadowBuffer); _lighting = _shadowLighting; _lighting.Parameters["InvViewLightViewProj"].SetValue(Matrix.Invert(camera.EyeTransform) * light.LightViewProj); _lighting.Parameters["InvView"].SetValue(Matrix.Invert(camera.EyeTransform)); _lighting.Parameters["LightView"].SetValue(light.LightView); _graphicsDevice.SetRenderTarget(_lightBuffer); _lighting.Parameters["ShadowMap"].SetValue(_shadowBuffer); _lighting.Parameters["texOffset"].SetValue(Game1.texOffset); } else if (light.LightType == "BakedShadow") { _lighting = _shadowLighting; if (light.shadowMap == null) { light.LightView = Matrix.CreateLookAt(light.Transform.Translation, light.Transform.Translation - Vector3.UnitY, Vector3.UnitZ); light.LightViewProj = light.LightView * Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(90), 1.0f, 0.01f, light.Radius); var tmpBuffer = new RenderTarget2D(GraphicsDevice, ShadowMapSize, ShadowMapSize * 2, false, SurfaceFormat.Rg32, DepthFormat.Depth16, 0, RenderTargetUsage.DiscardContents); GenerateDPSShadowMap(camera, light, occludingMeshes, tmpBuffer); light.shadowMap = tmpBuffer; } drawTex = light.shadowMap; _lighting.Parameters["InvViewLightViewProj"].SetValue(Matrix.Invert(camera.EyeTransform) * light.LightViewProj); _lighting.Parameters["InvView"].SetValue(Matrix.Invert(camera.EyeTransform)); _lighting.Parameters["LightView"].SetValue(light.LightView); _graphicsDevice.SetRenderTarget(_lightBuffer); _lighting.Parameters["ShadowMap"].SetValue(light.shadowMap); _lighting.Parameters["texOffset"].SetValue(Game1.texOffset); } else { _graphicsDevice.SetRenderTarget(_lightBuffer); _lighting = _basicLighting; } _graphicsDevice.BlendState = lightBlend; _graphicsDevice.DepthStencilState = DepthStencilState.None; _lighting.Parameters["texOffset"].SetValue(Game1.texOffset); _lighting.Parameters["GBufferPixelSize"].SetValue(new Vector2(0.5f / _width, 0.5f / _height)); _lighting.Parameters["DepthBuffer"].SetValue(_depthBuffer); _lighting.Parameters["NormalBuffer"].SetValue(_normalBuffer); _lighting.Parameters["fudge"].SetValue(Game1.mix); _lighting.Parameters["FarClip"].SetValue(camera.FarClip); _lighting.Parameters["Radius"].SetValue(light.Radius); _lighting.Parameters["LightViewRay"].SetValue(-light.Transform.Translation); //convert light position into viewspace Vector3 viewSpaceLPos = Vector3.Transform(light.Transform.Translation, camera.EyeTransform); _lighting.Parameters["LightPosition"].SetValue(viewSpaceLPos); Vector3 lightColor = light.Color.ToVector3() * light.Intensity; _lighting.Parameters["LightColor"].SetValue(lightColor); float invRadiusSqr = 1.0f / (light.Radius * light.Radius); _lighting.Parameters["InvLightRadiusSqr"].SetValue(invRadiusSqr); Vector2 bottomLeftCorner, topRightCorner, size; //compute a screen-space quad that fits the light's bounding sphere camera.ProjectBoundingSphereOnScreen(light.BoundingSphere, out bottomLeftCorner, out size); bottomLeftCorner.Y = -bottomLeftCorner.Y - size.Y; // topRightCorner = bottomLeftCorner + size; //clamp them bottomLeftCorner.X = Math.Max(bottomLeftCorner.X, -1); bottomLeftCorner.Y = Math.Max(bottomLeftCorner.Y, -1); topRightCorner.X = Math.Min(topRightCorner.X, 1); topRightCorner.Y = Math.Min(topRightCorner.Y, 1); //apply our frustum corners to this effect. Use the computed view-space rect ApplyFrustumCorners(_lighting, bottomLeftCorner, topRightCorner); _lighting.CurrentTechnique.Passes[0].Apply(); _quadRenderer.RenderQuad(_graphicsDevice, bottomLeftCorner, topRightCorner, pixelSize); } }
private void ReconstructShading(Camera cam, List<LPPMesh> meshes) { RenderTarget2D currentLightBuffer = Console.GetBool("glow") ? _glowBuffer : _lightBuffer; foreach (LPPMesh mesh in meshes) { meshCountReconstructed++; mesh.ReconstructShading(cam, GraphicsDevice, currentLightBuffer); } }
private void PostProcess(Camera camera) { if (_highlight) { _graphicsDevice.SetRenderTarget(_outputTexture); _graphicsDevice.BlendState = BlendState.AlphaBlend; _mesh.DrawHighlight(camera, GraphicsDevice, _edgeMask); } _highlight = false; if (Console.GetBool("blur")) { _graphicsDevice.SetRenderTarget(_preProcess); _postProcess.CurrentTechnique = _postProcess.Techniques["EdgeBlur"]; _postProcess.Parameters["inputtexture"].SetValue(_outputTexture); _postProcess.Parameters["edgemask"].SetValue(_edgeMask); _postProcess.Parameters["invScreenHeight"].SetValue(1.0f / _height); _postProcess.Parameters["invScreenWidth"].SetValue(1.0f / _width); _postProcess.CurrentTechnique.Passes[0].Apply(); _quadRenderer.RenderQuad(GraphicsDevice, -Vector2.One, Vector2.One, pixelSize); _graphicsDevice.SetRenderTarget(_outputTexture); _postProcess.Parameters["inputtexture"].SetValue(_preProcess); _postProcess.CurrentTechnique.Passes[1].Apply(); _quadRenderer.RenderQuad(GraphicsDevice, -Vector2.One, Vector2.One, pixelSize); } }
private void GenerateDPSShadowMap(Camera camera, Light light, List<LPPMesh> occludingMeshes, RenderTarget2D target) { _currentOccluders.Clear(); foreach (LPPMesh occluder in occludingMeshes) { if (occluder.BoundingSphere.Intersects(light.BoundingSphere)) _currentOccluders.Add(occluder); } _graphicsDevice.BlendState = BlendState.Opaque; _graphicsDevice.DepthStencilState = DepthStencilState.Default; _graphicsDevice.SetRenderTarget(target); _clearShadow.CurrentTechnique.Passes[0].Apply(); _quadRenderer.RenderQuad(GraphicsDevice, -Vector2.One, Vector2.One, pixelSize / 2); foreach (LPPMesh occluder in _currentOccluders) { occluder.DrawOcclusion(camera, GraphicsDevice, light); //Game1.occluders++; } _graphicsDevice.SetRenderTarget(target); _clearShadow.CurrentTechnique.Passes[0].Apply(); _quadRenderer.RenderQuad(GraphicsDevice, -Vector2.One, Vector2.One, pixelSize / 2); foreach (LPPMesh occluder in _currentOccluders) { occluder.DrawOcclusion(camera, GraphicsDevice, light, false); } Game1.shadowmaps++; _graphicsDevice.SetRenderTarget(null); }
private void ComputeFrustumCorners(Camera camera) { camera.Frustum.GetCorners(_cornersWorldSpace); Matrix matView = camera.EyeTransform; //this is the inverse of our camera transform Vector3.Transform(_cornersWorldSpace, ref matView, _cornersViewSpace); //put the frustum into view space for (int i = 0; i < 4; i++) //take only the 4 farthest points { _currentFrustumCorners[i] = _cornersViewSpace[i + 4]; } Vector3 temp = _currentFrustumCorners[3]; _currentFrustumCorners[3] = _currentFrustumCorners[2]; _currentFrustumCorners[2] = temp; }
public RenderTarget2D Render(Camera camera, List<Light> lights, List<LPPMesh> meshes, List<LPPMesh> occludingMeshes) { ComputeFrustumCorners(camera); meshCountGBuffer = 0; meshCountReconstructed = 0; //first of all, we must bind our GBuffer and reset all states _graphicsDevice.SetRenderTargets(_normalBuffer, _depthBuffer); _graphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Stencil, Color.Black, 1.0f, 0); _graphicsDevice.BlendState = BlendState.Opaque; _graphicsDevice.DepthStencilState = DepthStencilState.None; _graphicsDevice.RasterizerState = RasterizerState.CullNone; //bind the effect that outputs the default GBuffer values _clearGBuffer.CurrentTechnique.Passes[0].Apply(); //draw a full screen quad for clearing our GBuffer _quadRenderer.RenderQuad(_graphicsDevice, -Vector2.One, Vector2.One, pixelSize); _graphicsDevice.DepthStencilState = DepthStencilState.Default; _graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; //now, render all our objects RenderToGBuffer(camera, meshes); if (Console.GetBool("drawdepth")) return _depthBuffer; if (Console.GetBool("drawnormal")) return _normalBuffer; _graphicsDevice.SetRenderTarget(_edgeMask); _edgeDetect.Parameters["normal"].SetValue(_normalBuffer); _edgeDetect.Parameters["depth"].SetValue(_depthBuffer); _edgeDetect.Parameters["invScreenWidth"].SetValue(1.0f / _width); _edgeDetect.Parameters["invScreenHeight"].SetValue(1.0f / _height); _edgeDetect.CurrentTechnique.Passes[0].Apply(); _quadRenderer.RenderQuad(GraphicsDevice, -Vector2.One, Vector2.One, pixelSize); //resolve our GBuffer and render the lights //clear the light buffer with black _graphicsDevice.SetRenderTarget(_lightBuffer); //dont be fooled by Color.Black, as its alpha is 255 (or 1.0f) _graphicsDevice.Clear(new Color(0, 0, 0, 0)); //dont use depth/stencil test...we dont have a depth buffer, anyway _graphicsDevice.DepthStencilState = DepthStencilState.None; _graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; //draw using additive blending. //At first I was using BlendState.additive, but it seems to use alpha channel for modulation, //and as we use alpha channel as the specular intensity, we have to create our own blend state here RenderLights(camera, lights, occludingMeshes); AddGlow(); if (Console.GetBool("drawshadowmap")) return _shadowBuffer; if (Console.GetBool("drawedgemask")) return _edgeMask; if (Console.GetBool("drawlightbuffer")) { _graphicsDevice.SetRenderTarget(_outputTexture); _drawLights.CurrentTechnique.Passes[0].Apply(); _drawLights.Parameters["lightBuffer"].SetValue(_lightBuffer); _quadRenderer.RenderQuad(GraphicsDevice, -Vector2.One, Vector2.One, pixelSize); return _outputTexture; } //reconstruct each object shading, using the light texture as input (and another specific parameters too) _graphicsDevice.SetRenderTarget(_outputTexture); _graphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Stencil | ClearOptions.Target, Color.Black, 1.0f, 0); _graphicsDevice.DepthStencilState = DepthStencilState.Default; _graphicsDevice.BlendState = BlendState.Opaque; ReconstructShading(camera, meshes); PostProcess(camera); //unbind our final buffer and return it _graphicsDevice.SetRenderTarget(null); return _outputTexture; }
public virtual void ReconstructShading(Camera camera, GraphicsDevice graphicsDevice, Texture2D lightBuffer) { float glowval = (float)Math.Sin(Game1.time.TotalGameTime.TotalSeconds * 2.0d) * 0.3f; if (Draw) { foreach (ModelMesh mesh in _model.Meshes) { if (camera.Frustum.Intersects(Helpers.TransformSphere(mesh.BoundingSphere, m[mesh.ParentBone.Index]))) { foreach (EffectMaterial effect in mesh.Effects) { //this pass uses the light accumulation texture and reconstructs the mesh's shading effect.CurrentTechnique = effect.Techniques[1]; effect.Parameters["World"].SetValue(m[mesh.ParentBone.Index]); effect.Parameters["View"].SetValue(camera.EyeTransform); effect.Parameters["Projection"].SetValue(camera.ProjectionTransform); effect.Parameters["WorldView"].SetValue(m[mesh.ParentBone.Index] * camera.EyeTransform); effect.Parameters["WorldViewProjection"].SetValue(m[mesh.ParentBone.Index] * camera.EyeProjectionTransform); if (Highlight) { effect.Parameters["Highlight"].SetValue(1.5f + glowval); effect.Parameters["HighlightMin"].SetValue(0.4f); } else { effect.Parameters["Highlight"].SetValue(1.0f); effect.Parameters["HighlightMin"].SetValue(0.003f); } effect.Parameters["LightBuffer"].SetValue(lightBuffer); effect.Parameters["LightBufferPixelSize"].SetValue(new Vector2(0.5f / lightBuffer.Width, 0.5f / lightBuffer.Height)); //effect.CurrentTechnique.Passes[0].Apply(); mesh.Draw(); } } } } }
public virtual void RenderToGBuffer(Camera camera, GraphicsDevice graphicsDevice) { if (Draw) { _model.CopyAbsoluteBoneTransformsTo(m); foreach (ModelMesh mesh in _model.Meshes) { m[mesh.ParentBone.Index] *= Premult * Transform; if (camera.Frustum.Intersects(Helpers.TransformSphere(mesh.BoundingSphere, m[mesh.ParentBone.Index]))) { foreach (EffectMaterial effect in mesh.Effects) { effect.CurrentTechnique = effect.Techniques[0]; //our first pass is responsible for rendering into GBuffer effect.Parameters["SpecularPower"].SetValue(SpecularPower); effect.Parameters["Shininess"].SetValue(Shininess); effect.Parameters["World"].SetValue(m[mesh.ParentBone.Index]); effect.Parameters["View"].SetValue(camera.EyeTransform); effect.Parameters["Projection"].SetValue(camera.ProjectionTransform); effect.Parameters["WorldView"].SetValue(m[mesh.ParentBone.Index] * camera.EyeTransform); effect.Parameters["WorldViewProjection"].SetValue(m[mesh.ParentBone.Index] * camera.EyeProjectionTransform); effect.Parameters["FarClip"].SetValue(camera.FarClip); mesh.Draw(); } } } } }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); #region models boxmodel = Content.Load<Model>("primitives/box"); lppbox = Content.Load<Model>("primitives/lit/box"); lppsphere = Content.Load<Model>("primitives/lit/sphere"); lppcapsule = Content.Load<Model>("primitives/lit/capsule"); lppcylinder = Content.Load<Model>("primitives/lit/cylinder"); cylindermodel = Content.Load<Model>("primitives/cylinder"); spheremodel = Content.Load<Model>("primitives/sphere"); capsulemodel = Content.Load<Model>("primitives/capsule"); floormodel = Content.Load<Model>("floor/floor"); boxdata = Content.Load<PhysicsInfo>("walls/roomphys"); circleimg = Content.Load<Texture2D>("textures/circle"); Model blockman = Content.Load<Model>("floor/floor"); //Model skullmodel = Content.Load<Model>("skull/skull"); Model wallmodel = Content.Load<Model>("room/room"); PhysicsInfo skullphys = Content.Load<PhysicsInfo>("skull/skullphys"); ShadowEffect = Content.Load<Effect>("shaders/Shadow"); Model sceneModel = Content.Load<Model>("scene/scenetest"); PhysicsInfo scenePhys = Content.Load<PhysicsInfo>("scene/scenetestphys"); #endregion #region Effects NormalEffect = Content.Load<Effect>("shaders/LPPNormalEffect"); BasicEffect = Content.Load<Effect>("shaders/LPPBasicEffect"); TexturedEffect = Content.Load<Effect>("shaders/LPPTexturedEffect"); MainEffect = Content.Load<Effect>("shaders/LPPMainEffect"); #endregion Vector3 lowerButton = new Vector3(134.988f, 61.178f, 126.411f) * (2.54f / 64.0f); Vector3 upperButton = new Vector3(134.988f, 64.803f, 126.411f) * (2.54f / 64.0f); float convFactor = 2.54f / 64.0f; Console.Parse("physdebug false"); Console.Parse("drawconstraints false"); Console.Parse("drawedgemask false"); Console.Parse("drawdepth false"); Console.Parse("drawnormal false"); Console.Parse("drawall false"); Console.Parse("drawspheres false"); Console.Parse("blur true"); Console.Parse("drawshadowmap false"); Console.Parse("drawlightbuffer false"); Console.Parse("showPosition true"); Console.LoadContent(Content); /*boxdata = new PhysicsInfo(); boxdata.CreateBox(new Vector3(-1, -1, -1), Matrix.Identity, Vector3.One); boxdata.CreateBox(new Vector3(1, 1, 1), Matrix.Identity, Vector3.One); boxdata.CreateSphere(new Vector3(1, 3, 1), 1);*/ // TODO: use this.Content to load your game content here projmatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), (float)graphics.PreferredBackBufferWidth / (float)graphics.PreferredBackBufferHeight, 0.01f, 2500.0f); /* fallingBox = new Component(new Vector3(3.6f, 7.5f, -2.4f), Quaternion.Identity, Vector3.One / 2.0f); fallingBox.SetCollision(skullphys, false); fallingBox.Mesh = new LPPMesh(skullmodel); fallingBox.Mesh.Occlude = true; Actors.Add(new Actor(fallingBox));*/ /*immovableBox = new TriangleMeshActor(floormodel, Vector3.Zero, Vector3.One / 8.0f); immovableBox.Mesh = new LPPMesh(floormodel); immovableBox.Mesh.Occlude = true; Entities.Add(new Entity(immovableBox));*/ immovableBox = new TriangleMeshComponent(wallmodel, Vector3.Zero, Vector3.One / (64.0f / 2.54f)); var lppmesh = new LPPMesh(wallmodel); var scene = new Component(new LPPMesh(sceneModel), new Vector3(3.8f, 7.5f, -3.0f), Quaternion.Identity, Vector3.One / 64.0f); scene.SetCollision(scenePhys, true); Actors.Add(new Actor(scene)); Actors.Add(new LiftButton(upperButton, Vector3.One / 64.0f, "lift up")); Actors.Add(new LiftButton(lowerButton, Vector3.One / 64.0f, "lift down")); lppmesh.SpecularPower = 1.0f; lppmesh.Shininess = 1.0f; immovableBox.Mesh = lppmesh; Actors.Add(new Actor(immovableBox)); Actors.Add(new CeilingLamp(new Vector3(-1.5f, 11.9f, 1.68f), 0.75f)); Actors.Add(new Ladder(new Vector3(13.735f, 5.0f, -2.32f), 1.0f, 3.5f, 0.5f)); lift = new Lift(Vector3.Zero, 1 / 64.0f); Actors.Add(lift); Actors.Add(new PulsingLight(new Vector3(12.86f, 3.43f, 5.84f), Color.Red, 7.5f, 1.0f, 0.2f, 3.0d)); Actors.Add(new BareBulb(new Vector3(-14.5f, 11.4f, 3f), Vector3.One / 64.0f, Color.Wheat, 10.0f, 0.6f)); font = Content.Load<SpriteFont>("font"); RasterizerState rs = RasterizerState.CullCounterClockwise; GraphicsDevice.RasterizerState = rs; bs = GraphicsDevice.BlendState; cam = new Camera(); cam.Aspect = (float)scrwidth / (float)scrheight; cam.Viewport = new Viewport(0, 0, scrwidth, scrheight); cam.NearClip = 0.01f; cam.FarClip = 100.0f; cam.Transform = Matrix.Identity; characterController = new CharacterController(new Vector3(-1.0f, 2.0f, 7.311f), 3.0f, 0.75f, 0.1f, 0.2f); characterInput = new CharacterControllerInput(space, cam); characterInput.CharacterController = characterController; characterInput.Activate(); camcontrol = new CameraController(cam, Vector3.Zero, Vector2.Zero); Actors.Add(new Actor(new FollowLight(12.5f, 1.0f, Color.White, cam))); lppRenderer = new LPPRenderer(GraphicsDevice, Content, scrwidth, scrheight); for (int i = /*200*/0; i > 0; --i) { space.Update(0.0166f); } window = new Dialog(Manager); window.SetPosition(0, 0); window.SetSize(512, 512); window.Text = "Console"; textBox = new TextBox(Manager); textBox.SetPosition(32, 32); window.Add(textBox, false); Manager.Add(window); }
public void DrawSphere(SpriteBatch spriteBatch, Camera camera) { }
/// <summary> /// Constructs the character and internal physics character controller. /// </summary> /// <param name="owningSpace">Space to add the character to.</param> /// <param name="CameraToUse">Camera to attach to the character.</param> public CharacterControllerInput(Space owningSpace, Camera CameraToUse) { Space = owningSpace; Camera = CameraToUse; }