What you need to do is check out the source code and specifically look at the test-cases. In the latter you’ll find examples on how to achieve what you’ve listed.
I had similar ambitions - basically I want to use the editor only as an asset manager and do all the scene and pipeline construction programmatically. To that end below is one experiment I did (started with the forward lighting sample and incrementally modified it to be entirely procedural); note this was some time ago so it’s 1.2 and I don’t recall what state I left it in (it worked, but was playing around and might have broken something before I left it). Posting it anyway fwiw.
using SiliconStudio.Core;
using SiliconStudio.Core.Diagnostics;
using SiliconStudio.Core.Mathematics;
using SiliconStudio.Core.Serialization.Assets;
using SiliconStudio.Paradox.Engine;
using SiliconStudio.Paradox.Extensions;
using SiliconStudio.Paradox.Games;
using SiliconStudio.Paradox.Graphics;
using SiliconStudio.Paradox.Graphics.Data;
using SiliconStudio.Paradox.Graphics.GeometricPrimitives;
using SiliconStudio.Paradox.Input;
using SiliconStudio.Paradox.Rendering;
using SiliconStudio.Paradox.Rendering.Composers;
using SiliconStudio.Paradox.Rendering.Lights;
using SiliconStudio.Paradox.Rendering.ProceduralModels;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ForwardLighting
{
public class MyGame : Game
{
public static readonly Logger TestGameLogger = GlobalLogger.GetLogger("TestGameLogger");
public int StopOnFrameCount { get; set; }
private Texture[] textures;
private int renderTargetToDisplayIndex = 0;
private Entity teapot;
private Scene scene;
private Entity mainCamera;
private RasterizerState wireframeState;
private SpriteBatch spriteBatch;
private SpriteFont font;
//private bool rotateModel;
public MyGame()
{
// Enable profiling
//Profiler.EnableAll();
GraphicsDeviceManager.PreferredBackBufferWidth = 800;
GraphicsDeviceManager.PreferredBackBufferHeight = 480;
GraphicsDeviceManager.PreferredDepthStencilFormat = PixelFormat.D24_UNorm_S8_UInt;
GraphicsDeviceManager.DeviceCreationFlags = DeviceCreationFlags.Debug;
GraphicsDeviceManager.PreferredGraphicsProfile = new[] { GraphicsProfile.Level_11_0 };
StopOnFrameCount = -1;
AutoLoadDefaultSettings = false;
}
protected override void Update(GameTime gameTime)
{
base.Update(gameTime);
if (Input.IsKeyDown(Keys.Escape))
{
Exit();
}
if (gameTime.FrameCount == StopOnFrameCount)
{
Exit();
}
}
protected override async Task LoadContent()
{
await base.LoadContent();
spriteBatch = new SpriteBatch(GraphicsDevice);
font = Asset.Load<SpriteFont>("Font");
wireframeState = RasterizerState.New(GraphicsDevice, new RasterizerStateDescription(CullMode.Back) { FillMode = FillMode.Wireframe });
var x = EffectSystem.FileProvider.RootPath;
mainCamera = new Entity
{
new CameraComponent
{
UseCustomAspectRatio = true,
AspectRatio = 8/4.8f,
FarClipPlane = 5,
NearClipPlane = 1,
VerticalFieldOfView = MathUtil.RadiansToDegrees(0.6f),
UseCustomViewMatrix = true,
ViewMatrix = Matrix.LookAtRH(new Vector3(2,1,2), new Vector3(), Vector3.UnitY),
},
new TransformComponent
{
Position = new Vector3(2,1,2)
}
};
CreatePipeline();
var primitive = GeometricPrimitive.Teapot.New(GraphicsDevice);
var drawPrimitive = primitive.ToMeshDraw();
var material1 = Asset.Load<Material>("BasicMaterial");
var material2 = Asset.Load<Material>("common_metal_0");
var cube = new Entity("Cube") { new ModelComponent(new ProceduralModelDescriptor(new CubeProceduralModel { Size = new Vector3(1), MaterialInstance = { Material = material2 } }).GenerateModel(Services)) };
var sphere = new Entity("Sphere") { new ModelComponent(new ProceduralModelDescriptor(new SphereProceduralModel { Diameter = 1, Tessellation = 5, MaterialInstance = { Material = material2 } }).GenerateModel(Services)) };
/*
var megalodon = new Entity { new ModelComponent { Model = Asset.Load<Model>("megalodon Model") } };
megalodon.Transform.Position = new Vector3(0, -30f, -10f);
var knight = new Entity { new ModelComponent { Model = Asset.Load<Model>("knight Model") } };
knight.Transform.RotationEulerXYZ = new Vector3(-MathUtil.Pi / 2, MathUtil.Pi / 4, 0);
knight.Transform.Position = new Vector3(0, -50f, 20f);
knight.Transform.Scale = new Vector3(0.6f);
*/
teapot = new Entity
{
new ModelComponent
{
Model = new Model
{
material2,
new Mesh
{
Draw = drawPrimitive,
MaterialIndex = 0,
}
}
},
new TransformComponent()
};
/*
CameraComponent = camera.Camera;
Script.Add(camera);
camera.Position = new Vector3(25, 45, 80);
camera.SetTarget(currentEntity, true);
*/
var ambientLight = new Entity("Ambient Light") { new LightComponent { Type = new LightAmbient(), Intensity = 1.0f } };
//scene.AddChild(teapot);
//scene.AddChild(cube);
scene.AddChild(cube);
scene.AddChild(mainCamera);
scene.AddChild(ambientLight);
/*
var modelComponent = sphere.Get<ModelComponent>();
modelComponent.Materials.Clear();
for (int j = 0; j < modelComponent.Model.Materials.Count; j++)
modelComponent.Materials.Add(material1);
*/
// Add a custom script
//if (rotateModel)
// Script.AddTask(GameScript1);
//bool isWireframe = true;
//material1.Parameters.Set(Effect.RasterizerStateKey, isWireframe ? wireframeState : GraphicsDevice.RasterizerStates.CullBack);
//LightingKeys.EnableFixedAmbientLight(GraphicsDevice.Parameters, true);
//GraphicsDevice.Parameters.Set(EnvironmentLightKeys.GetParameterKey(LightSimpleAmbientKeys.AmbientLight, 0), (Color3)Color.White);
}
private void CreatePipeline()
{
const int TargetWidth = 800;
const int TargetHeight = 480;
// Create render targets
textures = new[]
{
Texture.New2D(GraphicsDevice, TargetWidth, TargetHeight, PixelFormat.R8G8B8A8_UNorm, TextureFlags.RenderTarget | TextureFlags.ShaderResource),
Texture.New2D(GraphicsDevice, TargetWidth, TargetHeight, PixelFormat.R8G8B8A8_UNorm, TextureFlags.RenderTarget | TextureFlags.ShaderResource),
Texture.New2D(GraphicsDevice, TargetWidth, TargetHeight, PixelFormat.R8G8B8A8_UNorm, TextureFlags.RenderTarget | TextureFlags.ShaderResource)
};
var depthBuffer = Texture.New2D(GraphicsDevice, TargetWidth, TargetHeight, PixelFormat.D24_UNorm_S8_UInt, TextureFlags.DepthStencil);
var multipleRenderFrames = new DirectRenderFrameProvider(RenderFrame.FromTexture(textures, depthBuffer));
// Setup the default rendering pipeline
scene = new Scene
{
Settings =
{
GraphicsCompositor = new SceneGraphicsCompositorLayers
{
Cameras = { mainCamera.Get<CameraComponent>() },
Master =
{
Renderers =
{
new ClearRenderFrameRenderer { Color = Color.Black, Output = multipleRenderFrames },
//new SceneCameraRenderer { Mode = new CameraRendererModeForward { ModelEffect = "MultipleRenderTargetsEffect" }, Output = multipleRenderFrames},
new SceneCameraRenderer { Mode = new CameraRendererModeForward { ModelEffect = "SoftInstanceEffect" }, Output = multipleRenderFrames},
new ClearRenderFrameRenderer { Output = new MasterRenderFrameProvider() },
new SceneDelegateRenderer(DisplayGBuffer) { Name = "DisplayGBuffer" },
//new SceneDelegateRenderer(PostCameraRendererDraw),
}
}
}
}
};
SceneSystem.SceneInstance = new SceneInstance(this.Services, scene);
}
private void DisplayGBuffer(RenderContext context, RenderFrame frame)
{
GraphicsDevice.DrawTexture(textures[renderTargetToDisplayIndex]);
}
protected void PostCameraRendererDraw(RenderContext context, RenderFrame frame)
{
spriteBatch.Begin();
spriteBatch.DrawString(font, "FPS: {0}".ToFormat(DrawTime.FramePerSecond), new Vector2(0, 20), Color.White);
spriteBatch.End();
}
}
}