コード例 #1
0
ファイル: Renderer.cs プロジェクト: justshiv/LightSavers
        /// <summary>
        /// Do a frustum culling test on each sub mesh, adding the visible ones to our list
        /// </summary>
        /// <param name="camera"></param>
        /// <param name="meshes"></param>
        private void CullVisibleMeshes(Camera camera, BaseSceneGraph sceneGraph)
        {
            for (int index = 0; index < _visibleMeshes.Length; index++)
            {
                _visibleMeshes[index].Clear();
            }

            sceneGraph.GetVisibleMeshes(camera.Frustum, _visibleMeshes);
        }
コード例 #2
0
ファイル: Renderer.cs プロジェクト: justshiv/LightSavers
 /// <summary>
 /// Generate the shadow maps and matrixes for the visible lights. We should limit
 /// our shadow-casters based on number of available shadow maps (we could use some
 /// performance-related heuristic here too)
 /// </summary>
 /// <param name="camera"></param>
 /// <param name="meshes"></param>
 /// <param name="renderWorld"></param>
 private void GenerateShadows(Camera camera, BaseSceneGraph sceneGraph)
 {
     for (int index = 0; index < _lightShadowCasters.Count; index++)
     {
         LightEntry light = _lightShadowCasters[index];
         //only spot
         if (light.light.LightType == Light.Type.Spot)
         {
             _shadowRenderer.GenerateShadowTextureSpotLight(this, sceneGraph, light.light, light.spotShadowMap);
         }
     }
 }
コード例 #3
0
        /// <summary>
        /// Generate the shadow map for a given spot light
        /// </summary>
        /// <param name="renderer"></param>
        /// <param name="meshes"></param>
        /// <param name="light"></param>
        /// <param name="shadowMap"></param>
        public void GenerateShadowTextureSpotLight(Renderer renderer, BaseSceneGraph renderWorld, Light light, SpotShadowMapEntry shadowMap)
        {
            //bind the render target
            renderer.GraphicsDevice.SetRenderTarget(shadowMap.Texture);
            //clear it to white, ie, far far away
            renderer.GraphicsDevice.Clear(Color.White);
            renderer.GraphicsDevice.BlendState        = BlendState.Opaque;
            renderer.GraphicsDevice.DepthStencilState = DepthStencilState.Default;


            Matrix viewProj = light.ViewProjection;

            shadowMap.LightViewProjection = viewProj;

            BoundingFrustum frustum = light.Frustum;

            _visibleMeshes.Clear();
            //cull meshes outside the light volume
            renderWorld.GetShadowCasters(frustum, _visibleMeshes);

            renderer.InstancingGroupManager.Reset();
            for (int index = 0; index < _visibleMeshes.Count; index++)
            {
                Mesh.SubMesh subMesh = _visibleMeshes[index];
                //render it
                if (!subMesh.InstanceEnabled)
                {
                    subMesh.RenderShadowMap(ref viewProj, renderer.GraphicsDevice);
                }
                else
                {
                    renderer.InstancingGroupManager.AddInstancedSubMesh(subMesh);
                }
            }
            renderer.InstancingGroupManager.GenerateInstanceInfo(renderer.GraphicsDevice);
            renderer.InstancingGroupManager.RenderShadowMap(ref viewProj, renderer.GraphicsDevice);
        }
コード例 #4
0
ファイル: Renderer.cs プロジェクト: justshiv/LightSavers
        /// <summary>
        /// Render the current scene. The culling will be performed inside this method,
        /// because we need all meshes here to compute the shadow maps.
        /// </summary>
        /// <param name="camera">Current camera</param>
        /// <param name="visibleLights"></param>
        /// <param name="meshes">All meshes</param>
        /// <param name="sceneGraph"></param>
        /// <param name="particleSystems"></param>
        /// <param name="gameTime"></param>
        /// <param name="lights">Visible lights</param>
        /// <returns></returns>
        public RenderTarget2D RenderScene(Camera camera, BaseSceneGraph sceneGraph)
        {
            InstancingGroupManager.Reset();

            sceneGraph.DoPreFrameWork(camera.Frustum);


            _depthDownsampledThisFrame = false;
            _currentCamera             = camera;


            //compute the frustum corners for this camera
            ComputeFrustumCorners(camera);

            //this resets the free shadow maps
            _shadowRenderer.InitFrame();



            _visibleLights.Clear();
            sceneGraph.GetVisibleLights(camera.Frustum, _visibleLights);
            //sort lights, choose the shadow casters
            BuildLightEntries(camera);
            SelectShadowCasters();

            //generate all shadow maps
            GenerateShadows(camera, sceneGraph);


            //first of all, we must bind our GBuffer and reset all states
            GraphicsDevice.SetRenderTargets(_gBufferBinding);

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

            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GraphicsDevice.RasterizerState   = RasterizerState.CullCounterClockwise;

            //select the visible meshes
            CullVisibleMeshes(camera, sceneGraph);

            //now, render them to the G-Buffer
            RenderToGbuffer(camera);

            //resolve our GBuffer and render the lights
            //clear the light buffer with black
            GraphicsDevice.SetRenderTargets(_lightAccumBinding);
            //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

            GraphicsDevice.BlendState = _lightAddBlendState;

            RenderLights(camera);

            //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;
            GraphicsDevice.RasterizerState   = RasterizerState.CullCounterClockwise;

            //reconstruct the shading, using the already culled list
            ReconstructShading(camera);
            //render objects that doesn't need the lightbuffer information, such as skyboxes, pure reflective meshes, etc
            DrawOpaqueObjects(camera);
            //draw objects with transparency
            DrawBlendObjects(camera);

            //draw SSAO texture. It's not correct to do it here, because ideally the SSAO should affect only
            //the ambient light, but it looks good this way

            //unbind our final buffer and return it
            GraphicsDevice.SetRenderTarget(null);

            return(_outputTexture);
        }