public void RenderShadowMap() { // clear some basics for GL.Disable(EnableCap.Lighting); GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.Texture2D); GL.Disable(EnableCap.Lighting); GL.ShadeModel(ShadingModel.Flat); GL.Disable(EnableCap.ColorMaterial); var frustumMatrix = m_renderConfig.invCameraViewMat * m_renderConfig.projectionMatrix; var cameraFrustum = new Util3d.FrustumCuller(ref frustumMatrix); // Shadow Map Pass(es) foreach (var light in m_lights) { if (light.ShadowMap != null) { light.ShadowMap.PrepareForRender(m_renderConfig, m_objects, cameraFrustum, this.ActiveCamera); var lightFrustum = m_renderConfig.invCameraViewMat * m_renderConfig.projectionMatrix; renderPass(false, new Util3d.FrustumCuller(ref lightFrustum)); light.ShadowMap.FinishRender(m_renderConfig); } } // update mvps shadowmaps in the main shader if (m_renderConfig.BaseShader != null) { m_renderConfig.BaseShader.Activate(); m_renderConfig.BaseShader.UpdateShadowMapMVPs(m_lights); } }
private void renderPass(bool notifyBeforeRender, Util3d.FrustumCuller fc = null) { // reset stats renderConfig.renderStats = new SSRenderStats(); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref renderConfig.projectionMatrix); bool needObjectDelete = false; foreach (var obj in objects) { if (obj.renderState.toBeDeleted) { needObjectDelete = true; continue; } if (!obj.renderState.visible) { continue; // skip invisible objects } if (renderConfig.drawingShadowMap && !obj.renderState.castsShadow) { continue; // skip non-shadow casters } // frustum test... #if true if (renderConfig.frustumCulling && obj.localBoundingSphereRadius >= 0f && obj.renderState.frustumCulling && fc != null && !fc.isSphereInsideFrustum(obj.worldBoundingSphere)) { renderConfig.renderStats.objectsCulled++; continue; // skip the object } #endif // finally, render object if (notifyBeforeRender && BeforeRenderObject != null) { BeforeRenderObject(obj, renderConfig); } renderConfig.renderStats.objectsDrawn++; obj.Render(renderConfig); } if (needObjectDelete) { objects.RemoveAll(o => o.renderState.toBeDeleted); } }
public void PrepareForRender(SSRenderConfig renderConfig, List <SSObject> objects, Util3d.FrustumCuller frustum, SSCamera camera) { GL.Ext.BindFramebuffer(FramebufferTarget.Framebuffer, m_frameBufferID); GL.Viewport(0, 0, c_texWidth, c_texHeight); float width, height, nearZ, farZ; Vector3 viewEye, viewTarget, viewUp; if (true) { // dynamically compute light frustum Util3d.Projections.SimpleShadowmapProjection( objects, m_light, frustum, camera, out width, out height, out nearZ, out farZ, out viewEye, out viewTarget, out viewUp); } else { // hard-coded "whole scene"... width = 2500; height = 1500; nearZ = 1; farZ = 15000; viewEye = new Vector3(0, 0, -1500f); viewTarget = new Vector3(0, 0, 1f); viewUp = new Vector3(0, 1f, 0); } m_projMatrix = Matrix4.CreateOrthographic(width, height, nearZ, farZ); m_viewMatrix = Matrix4.LookAt(viewEye, viewTarget, viewUp); renderConfig.projectionMatrix = m_projMatrix; renderConfig.invCameraViewMat = m_viewMatrix; renderConfig.drawingShadowMap = true; SSShaderProgram.DeactivateAll(); GL.DrawBuffer(DrawBufferMode.None); GL.Clear(ClearBufferMask.DepthBufferBit); assertFramebufferOK(); }