public void Draw(GraphicsDevice graphicsDevice, Camera camera, VolumeTextureEntity volumeTextureEntity, FullScreenTriangle fullScreenTriangle) { CameraPosition = camera.Position; VolumeTex = volumeTextureEntity.Texture; VolumeTexPosition = volumeTextureEntity.Position; VolumeTexResolution = volumeTextureEntity.Resolution; VolumeTexSize = volumeTextureEntity.Size; _basicPass.Apply(); fullScreenTriangle.Draw(graphicsDevice); //quadRenderer.RenderFullscreenQuad(graphicsDevice); }
//Load our default setup! private void SetUpEditorScene(GraphicsDevice graphics) { //////////////////////////////////////////////////////////////////////// // Camera //Set up our starting camera position // NOTE: Coordinate system depends on Camera.up, // Right now z is going up, it's not depth! Camera = new Camera(position: new Vector3(-88, -11f, 4), lookat: new Vector3(38, 8, 32)); EnvironmentSample = new EnvironmentSample(new Vector3(-45, -5, 5)); VolumeTexture = new VolumeTextureEntity("Content/Sponza/sponza_sdf.sdff", graphics, new Vector3(-7, 0, 63), new Vector3(200, 100, 100)) { NeedsUpdate = true }; _sdfGenerator = new SDFGenerator(); //////////////////////////////////////////////////////////////////////// // GUI //////////////////////////////////////////////////////////////////////// // Static geometry // NOTE: If you don't pass a materialEffect it will use the default material from the object BasicEntity testEntity = AddEntity(model: _assets.SponzaModel, position: Vector3.Zero, angleX: Math.PI / 2, angleY: 0, angleZ: 0, scale: 0.1f, hasStaticPhysics: false);//CHANGE BACK //AddEntity(model: _assets.CloneTrooper, // position: new Vector3(20, 0, 10), // angleX: Math.PI / 2, // angleY: 0, // angleZ: 0, // scale: 10.4f); for (int x = -5; x <= 5; x++) { for (int y = -5; y <= 5; y++) { AddEntity(model: _assets.Plane, materialEffect: ((x + 5 + y + 5) % 2 == 1) ? _assets.MirrorMaterial : _assets.MetalRough03Material, position: new Vector3(30 + x * 4, y * 4 + 4, 0), angleX: 0, angleY: 0, angleZ: 0, scale: 2); } } AddEntity(model: _assets.StanfordDragon, materialEffect: _assets.BaseMaterial, position: new Vector3(40, -10, 0), angleX: Math.PI / 2, angleY: 0, angleZ: 0, scale: 10); //////////////////////////////////////////////////////////////////////// // Dynamic geometry // NOTE: We first have to create a physics object and then apply said object to a rendered model // BEPU could use non-default meshes, but that is much much more expensive so I am using just default ones right now // ... so -> spheres, boxes etc. // For dynamic meshes I could use the same way i have static meshes, but use - MobileMesh - instead // NOTE: Our physics entity's position will be overwritten, so it doesn't matter // NOTE: If a physics object has mass it will move, otherwise it is static Entity physicsEntity; //Just a ground box where nothing should fall through //_physicsSpace.Add(new Box(new BEPUutilities.Vector3(0, 0, -0.5f), 1000, 1000, 1)); _physicsSpace.Add(physicsEntity = new Sphere(position: BEPUutilities.Vector3.Zero, radius: 5, mass: 50)); AddEntity(model: _assets.IsoSphere, materialEffect: _assets.AlphaBlendRim, position: new Vector3(20, 0, 10), angleX: Math.PI / 2, angleY: 0, angleZ: 0, scale: 5, PhysicsEntity: physicsEntity); testEntity.ApplyTransformation(); _sdfGenerator.Generate(testEntity); for (int i = 0; i < 10; i++) { MaterialEffect test = _assets.SilverMaterial.Clone(); test.Roughness = i / 9.0f + 0.1f; test.Metallic = 1; _physicsSpace.Add(physicsEntity = new Sphere(position: BEPUutilities.Vector3.Zero, radius: 5, mass: 50)); AddEntity(model: _assets.IsoSphere, materialEffect: test, position: new Vector3(30 + i * 10, 0, 10), angleX: Math.PI / 2, angleY: 0, angleZ: 0, scale: 5, PhysicsEntity: physicsEntity); } //////////////////////////////////////////////////////////////////////// // Decals Decals.Add(new Decal(_assets.IconDecal, new Vector3(-6, 22, 15), 0, -Math.PI / 2, 0, Vector3.One * 10)); //////////////////////////////////////////////////////////////////////// // Dynamic lights AddPointLight(position: new Vector3(-61, 0, 107), radius: 150, color: new Color(104, 163, 223), intensity: 20, castShadows: false, shadowResolution: 1024, staticShadow: false, isVolumetric: true); AddPointLight(position: new Vector3(15, 0, 107), radius: 150, color: new Color(104, 163, 223), intensity: 30, castShadows: false, shadowResolution: 1024, staticShadow: false, isVolumetric: true); AddPointLight(position: new Vector3(66, 0, 40), radius: 120, color: new Color(255, 248, 232), intensity: 120, castShadows: true, shadowResolution: 1024, softShadowBlurAmount: 0, staticShadow: false, isVolumetric: false); //volumetric light! //AddPointLight(position: new Vector3(-4, 40, 66), // radius: 80, // color: Color.White, // intensity: 50, // castShadows: true, // shadowResolution: 1024, // staticShadow: false, // isVolumetric: true, // volumetricDensity: 3); // Spawn a lot of lights to test performance //int sides = 4; //float distance = 20; //Vector3 startPosition = new Vector3(-30, 30, 1); ////amount of lights is sides*sides* sides*2 //for (int x = 0; x < sides * 2; x++) // for (int y = 0; y < sides; y++) // for (int z = 0; z < sides; z++) // { // Vector3 position = new Vector3(x, -y, z) * distance + startPosition; // AddPointLight(position, distance, FastRand.NextColor(), 50, false, false, 0.9f); // } //AddDirectionalLight(direction: new Vector3(0.2f, 0.2f, -1), // intensity: 100, // color: Color.White, // position: Vector3.UnitZ * 2, // drawShadows: true, // shadowWorldSize: 450, // shadowDepth: 180, // shadowResolution: 1024, // shadowFilteringFiltering: DirectionalLightSource.ShadowFilteringTypes.SoftPCF3x, // screenspaceShadowBlur: false); }
public void Draw(MeshMaterialLibrary meshMat, List <Decal> decals, List <PointLight> pointLights, List <DirectionalLight> dirLights, EnvironmentSample envSample, VolumeTextureEntity volumeTexture, Matrix viewProjection, Matrix view, EditorLogic.EditorSendData editorData, bool mouseMoved) { if (editorData.GizmoTransformationMode) { _graphicsDevice.SetRenderTarget(_idRenderTarget2D); _graphicsDevice.Clear(Color.Black); return; } if (mouseMoved) { DrawIds(meshMat, decals, pointLights, dirLights, envSample, volumeTexture, viewProjection, view, editorData); } if (GameSettings.e_drawoutlines) { DrawOutlines(meshMat, viewProjection, mouseMoved, HoveredId, editorData, mouseMoved); } }
public void DrawIds(MeshMaterialLibrary meshMat, List <Decal> decals, List <PointLight> pointLights, List <DirectionalLight> dirLights, EnvironmentSample envSample, VolumeTextureEntity volumeTexture, Matrix viewProjection, Matrix view, EditorLogic.EditorSendData editorData) { _graphicsDevice.SetRenderTarget(_idRenderTarget2D); _graphicsDevice.BlendState = BlendState.Opaque; _graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; _graphicsDevice.DepthStencilState = DepthStencilState.Default; meshMat.Draw(MeshMaterialLibrary.RenderType.IdRender, viewProjection); //Now onto the billboards DrawBillboards(decals, pointLights, dirLights, envSample, volumeTexture, viewProjection, view); //Now onto the gizmos DrawGizmos(viewProjection, editorData, _assets); Rectangle sourceRectangle = new Rectangle(Mouse.GetState().X, Mouse.GetState().Y, 1, 1); Color[] retrievedColor = new Color[1]; try { if (sourceRectangle.X >= 0 && sourceRectangle.Y >= 0 && sourceRectangle.X < _idRenderTarget2D.Width - 2 && sourceRectangle.Y < _idRenderTarget2D.Height - 2) { _idRenderTarget2D.GetData(0, sourceRectangle, retrievedColor, 0, 1); } } catch { //nothing } HoveredId = IdGenerator.GetIdFromColor(retrievedColor[0]); }
private void GenerateData(int xsteps, int ysteps, int zsteps, float stepssize, VolumeTextureEntity volumeTex, ref float[] data, int threadindex, int numberOfThreads) { float x, y, z; int xi, yi, zi; float volumeTexSizeX = volumeTex.SizeX; float volumeTexSizeY = volumeTex.SizeY; float volumeTexSizeZ = volumeTex.SizeZ; int i = 0; for (x = (int)-volumeTexSizeX, xi = 0; x <= volumeTexSizeX; x += stepssize, xi++) { for (y = (int)-volumeTexSizeY, yi = 0; y <= volumeTexSizeY; y += stepssize, yi++) { for (z = (int)-volumeTexSizeZ, zi = 0; z <= volumeTexSizeZ; z += stepssize, zi++) { //Only do it for the current thread! if (i++ % numberOfThreads != threadindex) { continue; } Vector3 position = volumeTex.Position + new Vector3(x, y, z); float color = ComputeSDF(position); //float color = 0;// //if (zi % 2 == 1 && xi%2 != yi%2) color = .25f; //points.Add(new SamplePoint(position, color)); data[toTexCoords(xi, yi, zi, xsteps, zsteps)] = color; if (threadindex == 0) { GameStats.sdf_load = (xi + (yi + zi / (float)zsteps) / (float)ysteps) / (float)xsteps; } } } } }
public void DrawBillboards(List <Decal> decals, List <PointLight> lights, List <DirectionalLight> dirLights, EnvironmentSample envSample, VolumeTextureEntity volumeTexture, Matrix staticViewProjection, Matrix view) { _graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; _graphicsDevice.SetVertexBuffer(_billboardBuffer.VBuffer); _graphicsDevice.Indices = (_billboardBuffer.IBuffer); Shaders.BillboardEffectParameter_Texture.SetValue(_assets.IconLight); Shaders.BillboardEffect.CurrentTechnique = Shaders.BillboardEffectTechnique_Id; for (int index = 0; index < decals.Count; index++) { var decal = decals[index]; Matrix world = Matrix.CreateTranslation(decal.Position); DrawBillboard(world, view, staticViewProjection, decal.Id); } for (int index = 0; index < lights.Count; index++) { var light = lights[index]; Matrix world = Matrix.CreateTranslation(light.Position); DrawBillboard(world, view, staticViewProjection, light.Id); } for (int index = 0; index < dirLights.Count; index++) { var light = dirLights[index]; Matrix world = Matrix.CreateTranslation(light.Position); DrawBillboard(world, view, staticViewProjection, light.Id); } Shaders.BillboardEffectParameter_Texture.SetValue(_assets.IconEnvmap); { Matrix world = Matrix.CreateTranslation(envSample.Position); DrawBillboard(world, view, staticViewProjection, envSample.Id); } { Matrix world = Matrix.CreateTranslation(volumeTexture.Position); DrawBillboard(world, view, staticViewProjection, volumeTexture.Id); } }
public void Update(VolumeTextureEntity volumeTex, GraphicsDevice graphics) { HelperGeometryManager manager = HelperGeometryManager.GetInstance(); //foreach (var point in points) //{ // manager.AddOctahedron(point, Vector4.One); //} //Show normals //foreach (var tri in triangles) //{ // manager.AddLineStartDir(tri.a, tri.n, 1, Color.Red, Color.Blue); //} if (!DebugScreen.ConsoleOpen && Input.WasKeyPressed(Keys.J) && generateTris != null && generateTris.IsCompleted) { setup = true; generateTask = Task.Factory.StartNew(() => { volumeTex.NeedsUpdate = false; const float stepssize = 2.5f; int xsteps = (int)(volumeTex.SizeX * 2 / stepssize) + 1; int ysteps = (int)(volumeTex.SizeY * 2 / stepssize) + 1; int zsteps = (int)(volumeTex.SizeZ * 2 / stepssize) + 1; texture?.Dispose(); texture = new Texture2D(graphics, xsteps * zsteps, ysteps, false, SurfaceFormat.Single); float[] data = new float[xsteps * ysteps * zsteps]; Stopwatch stopwatch = Stopwatch.StartNew(); int numberOfThreads = GameSettings.sdf_threads; if (numberOfThreads > 1) { Task[] threads = new Task[numberOfThreads - 1]; //Make local datas float[][] dataArray = new float[numberOfThreads][]; for (int index = 0; index < threads.Length; index++) { int i = index; dataArray[index + 1] = new float[xsteps * ysteps * zsteps]; threads[i] = Task.Factory.StartNew(() => { GenerateData(xsteps, ysteps, zsteps, stepssize, volumeTex, ref dataArray[i + 1], i + 1, numberOfThreads); }); } dataArray[0] = data; GenerateData(xsteps, ysteps, zsteps, stepssize, volumeTex, ref dataArray[0], 0, numberOfThreads); Task.WaitAll(threads); for (var index2 = 0; index2 < threads.Length; index2++) { threads[index2].Dispose(); } for (int i = 0; i < data.Length; i++) { data[i] = dataArray[i % numberOfThreads][i]; } } else { GenerateData(xsteps, ysteps, zsteps, stepssize, volumeTex, ref data, 0, numberOfThreads); } stopwatch.Stop(); Debug.Write("\nSDF generated in " + stopwatch.ElapsedMilliseconds + "ms with " + GameSettings.sdf_threads + " thread(s)"); string path = "sponza_sdf.sdff"; //Store DataStream.SaveImageData(data, xsteps, ysteps, zsteps, path); texture.SetData(data); volumeTex.Resolution = new Vector3(xsteps, ysteps, zsteps); //Stream stream = File.Create("volumetex"); //texture.SaveAsPng(stream, texture.Width, texture.Height); //stream.Dispose(); GameStats.sdf_load = 0; }); } if (setup && generateTask != null && generateTask.IsCompleted) { setup = false; volumeTex.Texture = texture; generateTask.Dispose(); } //foreach (var sample in points) //{ // manager.AddOctahedron(sample.p, Vector4.One * sample.sdf); //} }
public void DrawBillboards(List <Decal> decals, List <PointLight> lights, List <DirectionalLight> dirLights, EnvironmentSample envSample, VolumeTextureEntity volumeTexture, Matrix staticViewProjection, Matrix view, EditorLogic.EditorSendData sendData) { _graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; _graphicsDevice.SetVertexBuffer(_billboardBuffer.VBuffer); _graphicsDevice.Indices = (_billboardBuffer.IBuffer); Shaders.BillboardEffect.CurrentTechnique = Shaders.BillboardEffectTechnique_Billboard; Shaders.BillboardEffectParameter_IdColor.SetValue(Color.Gray.ToVector3()); //Decals Shaders.BillboardEffectParameter_Texture.SetValue(_assets.IconDecal); for (int index = 0; index < decals.Count; index++) { var decal = decals[index]; DrawBillboard(decal, staticViewProjection, view, sendData); } //Lights Shaders.BillboardEffectParameter_Texture.SetValue(_assets.IconLight); for (int index = 0; index < lights.Count; index++) { var light = lights[index]; DrawBillboard(light, staticViewProjection, view, sendData); } //DirectionalLights for (var index = 0; index < dirLights.Count; index++) { DirectionalLight light = dirLights[index]; DrawBillboard(light, staticViewProjection, view, sendData); HelperGeometryManager.GetInstance() .AddLineStartDir(light.Position, light.Direction * 10, 1, Color.Black, light.Color); HelperGeometryManager.GetInstance() .AddLineStartDir(light.Position + Vector3.UnitX * 10, light.Direction * 10, 1, Color.Black, light.Color); HelperGeometryManager.GetInstance() .AddLineStartDir(light.Position - Vector3.UnitX * 10, light.Direction * 10, 1, Color.Black, light.Color); HelperGeometryManager.GetInstance() .AddLineStartDir(light.Position + Vector3.UnitY * 10, light.Direction * 10, 1, Color.Black, light.Color); HelperGeometryManager.GetInstance() .AddLineStartDir(light.Position - Vector3.UnitY * 10, light.Direction * 10, 1, Color.Black, light.Color); HelperGeometryManager.GetInstance() .AddLineStartDir(light.Position + Vector3.UnitZ * 10, light.Direction * 10, 1, Color.Black, light.Color); HelperGeometryManager.GetInstance() .AddLineStartDir(light.Position - Vector3.UnitZ * 10, light.Direction * 10, 1, Color.Black, light.Color); if (light.CastShadows) { BoundingFrustum boundingFrustumShadow = new BoundingFrustum(light.LightViewProjection); HelperGeometryManager.GetInstance().CreateBoundingBoxLines(boundingFrustumShadow); } } //EnvMap Shaders.BillboardEffectParameter_Texture.SetValue(_assets.IconEnvmap); DrawBillboard(envSample, staticViewProjection, view, sendData); //Volume Texture DrawBillboard(volumeTexture, staticViewProjection, view, sendData); }
public void DrawEditorElements(MeshMaterialLibrary meshMaterialLibrary, List <Decal> decals, List <PointLight> lights, List <DirectionalLight> dirLights, EnvironmentSample envSample, VolumeTextureEntity volumeTexture, Matrix staticViewProjection, Matrix view, EditorLogic.EditorSendData editorData) { _graphicsDevice.SetRenderTarget(null); _graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; _graphicsDevice.DepthStencilState = DepthStencilState.Default; _graphicsDevice.BlendState = BlendState.Opaque; DrawGizmo(staticViewProjection, editorData); DrawBillboards(decals, lights, dirLights, envSample, volumeTexture, staticViewProjection, view, editorData); }
public void DrawIds(MeshMaterialLibrary meshMaterialLibrary, List <Decal> decals, List <PointLight> lights, List <DirectionalLight> dirLights, EnvironmentSample envSample, VolumeTextureEntity volumeTexture, Matrix staticViewProjection, Matrix view, EditorLogic.EditorSendData editorData) { _idAndOutlineRenderer.Draw(meshMaterialLibrary, decals, lights, dirLights, envSample, volumeTexture, staticViewProjection, view, editorData, _mouseMovement); }
/// <summary> /// Main Logic for the editor part /// </summary> /// <param name="gameTime"></param> /// <param name="entities"></param> /// <param name="data"></param> public void Update(GameTime gameTime, List <BasicEntity> entities, List <Decal> decals, List <PointLight> pointLights, List <DirectionalLight> dirLights, EnvironmentSample envSample, VolumeTextureEntity volumeTexture, EditorReceivedData data, MeshMaterialLibrary meshMaterialLibrary) { if (!GameSettings.e_enableeditor) { return; } if (Input.WasKeyPressed(Keys.R)) { GameStats.e_gizmoMode = GizmoModes.Rotation; } if (Input.WasKeyPressed(Keys.T)) { GameStats.e_gizmoMode = GizmoModes.Translation; } if (Input.WasKeyPressed(Keys.Z)) { GameStats.e_gizmoMode = GizmoModes.Scale; } _gizmoMode = GameStats.e_gizmoMode; int hoveredId = data.HoveredId; if (_gizmoTransformationMode) { if (Input.mouseState.LeftButton == ButtonState.Pressed) { GizmoControl(_gizmoId, data); } else { _gizmoTransformationMode = false; } } else if (Input.WasLMBClicked() && !GUIControl.UIWasUsed) { previousMouseX = Input.mouseState.X; previousMouseY = Input.mouseState.Y; //Gizmos if (hoveredId >= 1 && hoveredId <= 3) { _gizmoId = hoveredId; GizmoControl(_gizmoId, data); return; } if (hoveredId <= 0) { SelectedObject = null; return; } bool foundnew = false; //Get the selected entity! for (int index = 0; index < entities.Count; index++) { var VARIABLE = entities[index]; if (VARIABLE.Id == hoveredId) { SelectedObject = VARIABLE; foundnew = true; break; } } if (foundnew == false) { for (int index = 0; index < decals.Count; index++) { Decal decal = decals[index]; if (decal.Id == hoveredId) { SelectedObject = decal; break; } } for (int index = 0; index < pointLights.Count; index++) { PointLight pointLight = pointLights[index]; if (pointLight.Id == hoveredId) { SelectedObject = pointLight; break; } } for (int index = 0; index < dirLights.Count; index++) { DirectionalLight directionalLight = dirLights[index]; if (directionalLight.Id == hoveredId) { SelectedObject = directionalLight; break; } } { if (envSample.Id == hoveredId) { SelectedObject = envSample; } } { if (volumeTexture.Id == hoveredId) { SelectedObject = volumeTexture; } } } } //Controls if (Input.WasKeyPressed(Keys.Delete)) { //Find object if (SelectedObject is BasicEntity) { entities.Remove((BasicEntity)SelectedObject); meshMaterialLibrary.DeleteFromRegistry((BasicEntity)SelectedObject); SelectedObject = null; } else if (SelectedObject is Decal) { decals.Remove((Decal)SelectedObject); SelectedObject = null; } else if (SelectedObject is PointLight) { pointLights.Remove((PointLight)SelectedObject); SelectedObject = null; } else if (SelectedObject is DirectionalLight) { dirLights.Remove((DirectionalLight)SelectedObject); SelectedObject = null; } } if (Input.WasKeyPressed(Keys.Insert) || (Input.keyboardState.IsKeyDown(Keys.LeftControl) && Input.WasKeyPressed(Keys.C))) { if (SelectedObject is BasicEntity) { BasicEntity copy = (BasicEntity)SelectedObject.Clone; copy.RegisterInLibrary(meshMaterialLibrary); entities.Add(copy); } else if (SelectedObject is Decal) { Decal copy = (Decal)SelectedObject.Clone; decals.Add(copy); } else if (SelectedObject is PointLight) { PointLight copy = (PointLight)SelectedObject.Clone; pointLights.Add(copy); } else if (SelectedObject is DirectionalLight) { DirectionalLight copy = (DirectionalLight)SelectedObject.Clone; dirLights.Add(copy); } } }