Esempio n. 1
0
        public void AddSpotlight(Vector3 position, Vector3 lookat, Vector3 up, float theta, Color color, float near, float far, float daRatioConstant, float daRatioLinear, float daRatioQuadratic, float edgeSpotlightAttenuationPercent = 1.0f / 256.0f)
        {
            var projCm = MatrixCM.PerspectiveFovRH(theta, 1.0f, near, far);

            var viewCm = MatrixCM.ViewLookAtRH(position, lookat, up);

            // solve distance attenuation constants: 1/256 = atten = 1 / (x * darc + far * x * darl + far * far * x * darq)
            // 256 = x * darc + far * x * darl + far * far * x * darq
            // 256 = x * (darc + far * darl + far * far * darq)
            var x = 256 / (daRatioConstant + far * daRatioLinear + far * far * daRatioQuadratic);
            //Console.WriteLine(x + " " + daRatioConstant + " " + daRatioLinear + " " + daRatioQuadratic);
            var direction = lookat - position;

            direction.Normalize();
            //Console.WriteLine("@8: " + (daRatioConstant * x + daRatioLinear * x * 8 + daRatioQuadratic * x * 8 * 8));
            //Console.WriteLine("@far: " + (daRatioConstant * x + daRatioLinear * x * far + daRatioQuadratic * x * far * far));

            // solve spotlight attenuation constant.
            // edge% = atten_spotlight = dot(spotlightDirectionUnit, objectDirectionUnit) ^ power
            // edge% = cos(theta) ^ power
            // Math.Log(edge%, cos(theta)) = power
            var power = Math.Log(edgeSpotlightAttenuationPercent, Math.Cos(theta));
            //Console.WriteLine("Power: " + power);
            //Console.WriteLine("@far: " + Math.Pow(Math.Cos(theta), power));

            var projViewCm = projCm * viewCm;

            AddSpotlight(new SpotlightInfo {
                Origin    = position,
                Direction = direction,

                Color = color,
                DistanceAttenuationConstant  = x * daRatioConstant,
                DistanceAttenuationLinear    = x * daRatioLinear,
                DistanceAttenuationQuadratic = x * daRatioQuadratic,
                SpotlightAttenuationPower    = (float)power,

                ProjViewCM = projViewCm,
            });
        }
Esempio n. 2
0
        public static void Main(string[] args)
        {
            var graphicsLoop = GraphicsLoop.CreateWithNewWindow(1280, 720, InitFlags.DisableVerticalSync | InitFlags.EnableDebugStats);

            graphicsLoop.Form.Resize += (s, e) => UpdateProjViewMatrix(graphicsLoop.Form.ClientSize);

            graphicsLoop.Form.MouseWheel += (s, e) => {
                var dir = cameraOffset;
                dir.Normalize();
                cameraOffset += dir * (-e.Delta / 100.0f);
                Console.WriteLine(e.Delta + " " + dir + " " + cameraOffset);
                view = MatrixCM.ViewLookAtRH(cameraTarget + cameraOffset, cameraTarget, new Vector3(0, 1, 0));
                UpdateProjViewMatrix(graphicsLoop.Form.ClientSize);
            };

            UpdateProjViewMatrix(graphicsLoop.Form.ClientSize);

            //var projViewInv = MatrixCM.Invert(projView);
            //projViewInv.Transpose();
            //var asdf = Vector4.Transform(new Vector4(0, 0, 1, 1), projViewInv);
            //Console.WriteLine(asdf / asdf.W);
            //asdf = Vector4.Transform(new Vector4(1, 0, 1, 1), projViewInv);
            //Console.WriteLine(asdf / asdf.W);
            //asdf = Vector4.Transform(new Vector4(0, 1, 1, 1), projViewInv);
            //Console.WriteLine(asdf / asdf.W);
            //return;

            var floatingCubesBatch = RenderJobBatch.Create(graphicsLoop.Presets.GetPresetMesh(MeshPreset.UnitCube));

            //floatingCubesBatch.Wireframe = true;
            foreach (var transform in cubeDefaultTransforms)
            {
                floatingCubesBatch.Jobs.Add(new RenderJobDescription {
                    WorldTransform         = transform,
                    MaterialProperties     = { Metallic = 0.0f, Roughness = 0.0f },
                    MaterialResourcesIndex = -1,
                    Color = Color.White
                });
            }

            var gizmos = new GizomisidfojdsTSOmethign(graphicsLoop.Input, graphicsLoop.Presets.UnitSphere, graphicsLoop.Presets.UnitCube);
            var scene  = new Scene();

            for (var frame = 0; graphicsLoop.IsRunning(out var renderer, out var input); frame++)
            {
                var t = (float)graphicsLoop.Statistics.FrameTime.TotalSeconds;
                //scene.SetTime((float)Math.Sin(t * 1));
                scene.SetTime((float)t);

                var right = Vector3.Cross(-cameraOffset, cameraUp);
                right.Normalize();

                var forward = -cameraOffset;
                forward.Normalize();

                var up = Vector3.Cross(right, forward);

                if (input.IsMouseDown(MouseButtons.Right))
                {
                    var rotation = Matrix.RotationY(-input.DeltaX * 0.005f) * Matrix.RotationAxis(right, -input.DeltaY * 0.005f);
                    cameraOffset = (Vector3)Vector3.Transform(cameraOffset, rotation);
                }

                var v = (input.IsKeyDown(Keys.ShiftKey) ? 7.0f : 1.0f) * 50;
                if (input.IsKeyDown(Keys.Left) || input.IsKeyDown(Keys.A))
                {
                    cameraTarget -= right * 0.005f * v;
                }
                if (input.IsKeyDown(Keys.Right) || input.IsKeyDown(Keys.D))
                {
                    cameraTarget += right * 0.005f * v;
                }
                if (input.IsKeyDown(Keys.Up) || input.IsKeyDown(Keys.W))
                {
                    cameraTarget += forward * 0.005f * v;
                }
                if (input.IsKeyDown(Keys.Down) || input.IsKeyDown(Keys.S))
                {
                    cameraTarget -= forward * 0.005f * v;
                }
                if (input.IsKeyDown(Keys.Space))
                {
                    cameraTarget += cameraUp * 0.005f * (input.IsKeyDown(Keys.ShiftKey) ? -1 : 1);
                }

                view = MatrixCM.ViewLookAtRH(cameraTarget + cameraOffset, cameraTarget, new Vector3(0, 1, 0));
                UpdateProjViewMatrix(graphicsLoop.Form.ClientSize);

                scene.Clear();
                scene.SetCamera(cameraTarget + cameraOffset, projView);

                gizmos.HandleFrameEnter(scene, projView);

                // draw pick ray
                var viewProj = projView;
                viewProj.Transpose();
                var ray = Ray.GetPickRay(input.X, input.Y, new ViewportF(0, 0, 1280, 720, 1.0f, 100.0f), viewProj);

                var nspheres       = 100;
                var raySphereBatch = RenderJobBatch.Create(graphicsLoop.Presets.UnitCube);
                raySphereBatch.Wireframe = true;
                for (var i = 0; i < nspheres; i++)
                {
                    raySphereBatch.Jobs.Add(new RenderJobDescription {
                        WorldTransform         = MatrixCM.Translation(ray.Position + ray.Direction * i / 10.0f) * MatrixCM.Scaling(0.01f),
                        MaterialProperties     = { Metallic = 0.0f, Roughness = 0.0f },
                        MaterialResourcesIndex = -1,
                        Color = Color.Black,
                    });
                }
                //scene.AddRenderJobBatch(raySphereBatch);

                // Draw floor
//            scene.AddRenderable(
//               graphicsLoop.Presets.UnitCube,
//               MatrixCM.Scaling(4f, 0.1f, 4f) * MatrixCM.Translation(0, -0.5f, 0) * MatrixCM.RotationX((float)Math.PI),
//               new MaterialDescription { Properties = { Metallic = 0.0f, Roughness = 0.04f } },
//               Color.White);

                // Draw sun
//            scene.AddRenderable(
//               graphicsLoop.Presets.UnitSphere,
//               MatrixCM.Translation(new Vector3(-10, 3, -3) * 3) * MatrixCM.Scaling(1 * 3),
//               new MaterialDescription { Properties = { Metallic = 0.0f, Roughness = 0.04f } },
//               Color.Yellow);


                // Draw center cube / sphere
                scene.AddRenderable(
                    false ? graphicsLoop.Presets.UnitCube : graphicsLoop.Presets.UnitSphere,
                    MatrixCM.Translation(1, 0.5f, 0),
                    new MaterialDescription {
                    Properties = { Metallic = 0.0f, Roughness = 0.04f }
                },
                    Color.Red);
                scene.AddRenderable(
                    false ? graphicsLoop.Presets.UnitCube : graphicsLoop.Presets.UnitSphere,
                    MatrixCM.Translation(0, 1.5f, 0),
                    new MaterialDescription {
                    Properties = { Metallic = 0.0f, Roughness = 0.04f }
                },
                    Color.Lime);
                scene.AddRenderable(
                    false ? graphicsLoop.Presets.UnitCube : graphicsLoop.Presets.UnitSphere,
                    MatrixCM.Translation(0, 0.5f, 1),
                    new MaterialDescription {
                    Properties = { Metallic = 0.0f, Roughness = 0.04f }
                },
                    Color.Blue);

                // Draw floating cubes circling around center cube
                floatingCubesBatch.BatchTransform = MatrixCM.RotationY(t * (float)Math.PI / 10.0f);
                floatingCubesBatch.MaterialResourcesIndexOverride = scene.AddMaterialResources(new MaterialResourcesDescription {
                    BaseTexture = graphicsLoop.Presets.SolidCubeTextures[Color.Red, Color.Cyan, Color.Lime, Color.Magenta, Color.Blue, Color.Yellow]
                });
                if (false)
                {
                    floatingCubesBatch.MaterialResourcesIndexOverride = -1;
                    for (var i = 0; i < floatingCubesBatch.Jobs.Count; i++)
                    {
                        floatingCubesBatch.Jobs.store[i].MaterialResourcesIndex = scene.AddMaterialResources(new MaterialResourcesDescription {
                            BaseTexture = graphicsLoop.Presets.SolidCubeTextures[new Color4(i / (float)(floatingCubesBatch.Jobs.Count - 1), 0, 0, 1)]
                        });
                    }
                }
//            scene.AddRenderJobBatch(floatingCubesBatch);

                // Add spotlights
                scene.AddSpotlight(
                    new Vector3(5, 4, 3), new Vector3(0, 0, 0), Vector3.Up, (float)Math.PI / 8.0f,
                    Color.White, 100.0f,
                    0.0f, 6.0f, 3.0f,
                    0.5f / 256.0f);
                scene.AddSpotlight(new Vector3(5, 4, -5), new Vector3(0, 0, 0), Vector3.Up, (float)Math.PI / 8.0f, Color.White, 0.1f, 100.0f, 3.0f, 6.0f, 1.0f);

                // Draw the scene
                var snapshot = scene.ExportSnapshot();
                renderer.RenderScene(snapshot);
                snapshot.ReleaseReference();
            }
        }