Exemplo n.º 1
0
        public void DrawLights(RenderObjects renderObjects, List<Light> lights, Matrix4 projectionMatrix, float zNear, Camera camera)
        {
            if (lights.Count == 0)
            {
                return;
            }

            Matrix4 invProjectionMatrix = Matrix4.Invert(projectionMatrix);
            Matrix4 invViewMatrix = Matrix4.Invert(camera.ViewMatrix);

            Matrix4 m =
                    new Matrix4(
                        new Vector4(2.0f, 0.0f, 0.0f, 0.0f),
                        new Vector4(0.0f, 2.0f, 0.0f, 0.0f),
                        new Vector4(0.0f, 0.0f, 2.0f, 0.0f),
                        new Vector4(-1.0f, -1.0f, -1.0f, 1.0f))
                  * invProjectionMatrix;

            int idx = 0;
            foreach (Light light in lights)
            {
                idx++;

                if (light is SpotLight)
                {
                    DrawLight(idx, renderObjects, (SpotLight)light, m, projectionMatrix, invViewMatrix, camera, zNear);
                }
                else // light is PointLight
                {
                    DrawLight(idx, renderObjects, (PointLight)light, m, projectionMatrix, invViewMatrix, camera, zNear);
                }
            }
        }
Exemplo n.º 2
0
        void DrawLight(int idx, RenderObjects renderObjects, SpotLight light, Matrix4 m, Matrix4 projectionMatrix, Matrix4 invViewMatrix, Camera camera, float zNear)
        {
            using (RenderStateBinder binder = device.ChangeRenderState())
            {
                device.RenderState.DepthWrite = true;
                device.RenderState.DepthTest = true;
                device.RenderState.ColorWrite = false;
                device.RenderState.FrontFace = FrontFaceDirection.CCW;
                device.RenderState.PolygonOffset = true;
                device.RenderState.PolygonOffsetFactor = 0.0f;
                device.RenderState.PolygonOffsetUnits = -1.0f;
                device.ApplyRenderState();

                shadow_fb.SetTexture2D(FramebufferAttachment.DepthAttachment, 0, shadow_texture);
                device.SetFramebuffer(shadow_fb);

                device.Clear(BufferMask.DepthBuffer);

                device.SetShader(generate_shadowmap);

                device.SetMatrix(MatrixModeEnum.Projection, light.ProjectionMatrix);
                renderObjects(light.ViewMatrix);
            }

            device.SetFramebuffer(lighting_fb);
            device.SetMatrix(MatrixModeEnum.Projection, projectionMatrix);

            using (RenderStateBinder binder = device.ChangeRenderState())
            {
                device.SetShader(deferred_spotlight);
                deferred_spotlight.GetSampler("color_texture").Set(color_texture);
                deferred_spotlight.GetSampler("normal_texture").Set(normal_texture);
                deferred_spotlight.GetSampler("depth_texture").Set(depth_texture);
                deferred_spotlight.GetSampler("shadow_texture").Set(shadow_texture);

                deferred_spotlight.GetUniform("buffer_range").Set(1.0f / device.Width, 1.0f / device.Height);
                deferred_spotlight.GetUniform("ndc_to_view").Set(m);

                deferred_spotlight.GetUniform("shadow_matrix").Set(invViewMatrix * light.ShadowMatrix);
                deferred_spotlight.GetUniform("light_params").Set(light.Ambient, light.Diffuse, light.Specular, light.Shininess);
                deferred_spotlight.GetUniform("light_params2").Set(light.Length2, light.AngleParam1, light.AngleParam2, light.Exponent);
                deferred_spotlight.GetUniform("light_position").Set(Vector3.TransformPosition(light.Position, camera.ViewMatrix));
                deferred_spotlight.GetUniform("light_direction").Set(Vector3.TransformVector(light.Direction, camera.ViewMatrix));
                deferred_spotlight.GetUniform("light_color").Set(light.Color);

                device.SetVertexBuffer(spot_light_VB, 0);
                device.SetIndexBuffer(spot_light_IB);

                device.SetMatrix(MatrixModeEnum.ModelView, light.WorldMatrix * camera.ViewMatrix);

                bool inside = false;
                Vector3 p = (camera.Position + camera.ZAxis * zNear) - light.Position;
                float dot = Vector3.Dot(p, light.Direction);
                if (dot > 0.0f || dot < light.Length)
                {
                    float cosBeta = dot / p.Length;
                    if (cosBeta > Degrees.Cos(light.Angle + 5))
                    {
                        inside = true;
                    }
                }

                device.RenderState.DepthWrite = false;
                device.RenderState.Blend = true;
                device.RenderState.BlendingFuncDst = BlendingFactorDest.One;
                device.RenderState.BlendingFuncSrc = BlendingFactorSrc.One;

                if (inside)
                {
                    device.RenderState.FrontFace = FrontFaceDirection.CCW;
                    device.RenderState.DepthFunction = DepthFunction.GEqual;
                    device.RenderState.StencilTest = false;
                    device.ApplyRenderState();

                    device.DrawElements(BeginMode.TriangleStrip, 0, spot_light_primitives);
                }
                else
                {
                    if (has_stencil)
                    {
                        device.RenderState.FrontFace = FrontFaceDirection.CW;
                        device.RenderState.ColorWrite = false;
                        device.RenderState.DepthFunction = DepthFunction.Less;
                        device.RenderState.StencilTest = true;
                        device.RenderState.StencilFunc = StencilFunction.Always;
                        device.RenderState.StencilFail = StencilOpEnum.Keep;
                        device.RenderState.StencilZFail = StencilOpEnum.Keep;
                        device.RenderState.StencilZPass = StencilOpEnum.Replace;
                        device.RenderState.StencilFuncReference = idx;
                        device.ApplyRenderState();

                        device.DrawElements(BeginMode.TriangleStrip, 0, spot_light_primitives);

                        device.RenderState.FrontFace = FrontFaceDirection.CCW;
                        device.RenderState.ColorWrite = true;
                        device.RenderState.DepthFunction = DepthFunction.GEqual;
                        device.RenderState.StencilFunc = StencilFunction.Equal;
                        device.RenderState.StencilZPass = StencilOpEnum.Keep;
                        device.RenderState.StencilFuncReference = idx;
                        device.ApplyRenderState();

                        device.DrawElements(BeginMode.TriangleStrip, 0, spot_light_primitives);
                    }
                    else
                    {
                        device.RenderState.FrontFace = FrontFaceDirection.CW;
                        device.RenderState.DepthFunction = DepthFunction.Less;
                        device.RenderState.StencilTest = false;
                        device.ApplyRenderState();

                        device.DrawElements(BeginMode.TriangleStrip, 0, spot_light_primitives);
                    }
                }
            }
        }
Exemplo n.º 3
0
        void DrawLight(int idx, RenderObjects renderObjects, PointLight light, Matrix4 m, Matrix4 projectionMatrix, Matrix4 invViewMatrix, Camera camera, float zNear)
        {
            using (RenderStateBinder binder = device.ChangeRenderState())
            {
                device.RenderState.DepthWrite = true;
                device.RenderState.DepthTest = true;
                device.RenderState.ColorWrite = false;
                device.RenderState.FrontFace = FrontFaceDirection.CCW;
                device.RenderState.PolygonOffset = true;
                device.RenderState.PolygonOffsetFactor = -1.0f;
                device.RenderState.PolygonOffsetUnits = -1.0f;
                device.ApplyRenderState();

                device.SetShader(generate_dp_shadowmap);

                Vector3[,] direction = new Vector3[6, 2]
                {
                    { -Vector3.UnitX, Vector3.UnitY },
                    { Vector3.UnitX, Vector3.UnitY },
                    { -Vector3.UnitY, -Vector3.UnitZ },
                    { Vector3.UnitY, Vector3.UnitZ },
                    { -Vector3.UnitZ, Vector3.UnitY },
                    { Vector3.UnitZ, Vector3.UnitY },
                };

                TextureTarget[] targets = new TextureTarget[6]
                {
                    TextureTarget.TextureCubeMapPositiveX,
                    TextureTarget.TextureCubeMapNegativeX,
                    TextureTarget.TextureCubeMapPositiveY,
                    TextureTarget.TextureCubeMapNegativeY,
                    TextureTarget.TextureCubeMapPositiveZ,
                    TextureTarget.TextureCubeMapNegativeZ,
                };

                device.SetMatrix(MatrixModeEnum.Projection, Matrix4.Perspective(90.0f, 1.0f, Light.zNear, light.Radius));
                device.SetFramebuffer(shadow_fb);

                for (int i = 0; i < 6; i++)
                {
                    shadow_fb.SetTextureCubeMap(FramebufferAttachment.DepthAttachment, targets[i], 0, shadow_texture_cube);
                    device.Clear(BufferMask.DepthBuffer);

                    Matrix4 lightViewMatrix = Matrix4.LookAt(light.Position, light.Position + direction[i, 0], direction[i, 1]);

                    renderObjects(lightViewMatrix);
                }

                //// front
                //shadow_fb.SetTexture2D(FramebufferAttachment.DepthAttachment, 0, shadow_texture[1]);
                //device.SetFramebuffer(shadow_fb);
                //device.Clear(BufferMask.DepthBuffer);

                //generate_dp_shadowmap.GetUniform("direction").Set(1.0f);

                //Vector3 pos = light.Position;// -new Vector3(0.0f, 0.0f, 0.02f);
                //Matrix4 lightViewMatrix = Matrix4.LookAt(pos, pos + Vector3.UnitZ, Vector3.UnitY);

                //renderObjects(lightViewMatrix);

                //// back
                //shadow_fb.SetTexture2D(FramebufferAttachment.DepthAttachment, 0, shadow_texture[2]);
                //device.Clear(BufferMask.DepthBuffer);

                //generate_dp_shadowmap.GetUniform("direction").Set(-1.0f);

                //pos = light.Position;// -new Vector3(0.0f, 0.0f, 0.02f);
                //lightViewMatrix = Matrix4.LookAt(pos, pos + Vector3.UnitZ, Vector3.UnitY);
                //renderObjects(lightViewMatrix);
            }

            device.SetFramebuffer(lighting_fb);
            device.SetMatrix(MatrixModeEnum.Projection, projectionMatrix);

            using (RenderStateBinder binder = device.ChangeRenderState())
            {
                device.SetShader(deferred_pointlight);
                deferred_pointlight.GetSampler("color_texture").Set(color_texture);
                deferred_pointlight.GetSampler("normal_texture").Set(normal_texture);
                deferred_pointlight.GetSampler("depth_texture").Set(depth_texture);
                //deferred_pointlight.GetSampler("shadowFront_texture").Set(shadow_texture[1]);
                //deferred_pointlight.GetSampler("shadowBack_texture").Set(shadow_texture[2]);
                deferred_pointlight.GetSampler("shadow_texture").Set(shadow_texture_cube);

                deferred_pointlight.GetUniform("buffer_range").Set(1.0f / device.Width, 1.0f / device.Height);

                deferred_pointlight.GetUniform("ndc_to_view").Set(m);

                device.SetVertexBuffer(point_light_VB, 0);
                device.SetIndexBuffer(point_light_IB);

                deferred_pointlight.GetUniform("shadow_matrix").Set(invViewMatrix);
                deferred_pointlight.GetUniform("light_params").Set(light.Ambient, light.Diffuse, light.Specular, light.Shininess);
                deferred_pointlight.GetUniform("light_position").Set(Vector3.TransformPosition(light.Position, camera.ViewMatrix));
                deferred_pointlight.GetUniform("light_positionW").Set(light.Position);
                deferred_pointlight.GetUniform("light_radius2").Set(light.Radius2);
                deferred_pointlight.GetUniform("light_color").Set(light.Color);
                deferred_pointlight.GetUniform("depth_param1").Set(light.DepthParam1);
                deferred_pointlight.GetUniform("depth_param2").Set(light.DepthParam2);

                device.SetMatrix(MatrixModeEnum.ModelView, light.WorldMatrix * camera.ViewMatrix);

                Vector3 p = camera.Position - light.Position;

                device.RenderState.DepthWrite = false;
                device.RenderState.Blend = true;
                device.RenderState.BlendingFuncDst = BlendingFactorDest.One;
                device.RenderState.BlendingFuncSrc = BlendingFactorSrc.One;

                if (p.Length < light.Radius + 2.0f * zNear)
                {
                    device.RenderState.FrontFace = FrontFaceDirection.CCW;
                    device.RenderState.DepthFunction = DepthFunction.GEqual;
                    device.RenderState.StencilTest = false;
                    device.ApplyRenderState();

                    device.DrawElements(BeginMode.TriangleStrip, 0, point_light_primitives);
                }
                else
                {
                    if (has_stencil)
                    {
                        device.RenderState.FrontFace = FrontFaceDirection.CW;
                        device.RenderState.ColorWrite = false;
                        device.RenderState.DepthFunction = DepthFunction.Less;
                        device.RenderState.StencilTest = true;
                        device.RenderState.StencilFunc = StencilFunction.Always;
                        device.RenderState.StencilFail = StencilOpEnum.Keep;
                        device.RenderState.StencilZFail = StencilOpEnum.Keep;
                        device.RenderState.StencilZPass = StencilOpEnum.Replace;
                        device.RenderState.StencilFuncReference = idx;
                        device.ApplyRenderState();

                        device.DrawElements(BeginMode.TriangleStrip, 0, point_light_primitives);

                        device.RenderState.FrontFace = FrontFaceDirection.CCW;
                        device.RenderState.ColorWrite = true;
                        device.RenderState.DepthFunction = DepthFunction.GEqual;
                        device.RenderState.StencilFunc = StencilFunction.Equal;
                        device.RenderState.StencilZPass = StencilOpEnum.Keep;
                        device.RenderState.StencilFuncReference = idx;
                        device.ApplyRenderState();

                        device.DrawElements(BeginMode.TriangleStrip, 0, point_light_primitives);
                    }
                    else
                    {
                        device.RenderState.FrontFace = FrontFaceDirection.CW;
                        device.RenderState.DepthFunction = DepthFunction.Less;
                        device.RenderState.StencilTest = false;
                        device.ApplyRenderState();

                        device.DrawElements(BeginMode.TriangleStrip, 0, point_light_primitives);
                    }
                }
            }
        }
Exemplo n.º 4
0
        public void Render(RenderObjects renderObjects, Matrix4 projectionMatrix, Matrix4 viewMatrix)
        {
            device.SetFramebuffer(deferred_fb);

            using (RenderStateBinder binder = device.ChangeRenderState())
            {
                device.RenderState.DepthWrite = true;
                device.RenderState.DepthTest = true;
                device.ApplyRenderState();
                device.Clear(BufferMask.ColorBuffer | BufferMask.DepthBuffer | BufferMask.StencilBuffer);
            }

            device.SetShader(deferred_geometry);

            device.SetMatrix(MatrixModeEnum.Projection, projectionMatrix);

            renderObjects(viewMatrix);

            // TODO: add this as last pass
            device.SetFramebuffer(lighting_fb);

            using (RenderStateBinder binder = device.ChangeRenderState())
            {
                device.RenderState.DepthTest = false;
                device.RenderState.DepthWrite = false;
                device.ApplyRenderState();

                device.SetShader(deferred_ambient);
                deferred_ambient.GetSampler("color_texture").Set(color_texture);
                deferred_ambient.GetUniform("ambient_light").Set(0.7f); // TODO: full diffuse color for directional light

                device.SetVertexBuffer(unit_quad_VB, 0);
                device.DrawArrays(BeginMode.TriangleStrip, 0, 4);
            }
        }