~ Changed Pipelines

(Default2DPipeline: Has Lights, Post-ProcessingEffects, etc.)
(Basic2DPipeline: Simple Color and Texture stuff, thats it)
This commit is contained in:
Michel Fedde 2020-12-19 18:31:44 +01:00
parent 1ed03fec3f
commit 5d4b360b05
23 changed files with 243 additions and 59 deletions

View file

@ -42,15 +42,14 @@ namespace SM.Base.Drawing
CleanUp(); CleanUp();
GL.UseProgram(0); GL.UseProgram(0);
context.ShaderArguments.Clear();
} }
/// <summary> /// <summary>
/// Draws the context. /// Draws the context.
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected virtual void DrawProcess(DrawContext context) protected abstract void DrawProcess(DrawContext context);
{
}
} }
} }

View file

@ -12,7 +12,7 @@ namespace SM.Base.Objects
/// <summary> /// <summary>
/// While initializing, it will add the <see cref="Color" /> to the data index. /// While initializing, it will add the <see cref="Color" /> to the data index.
/// </summary> /// </summary>
protected Mesh() public Mesh()
{ {
Attributes.Add(3, "color", Color); Attributes.Add(3, "color", Color);
} }

View file

@ -24,7 +24,7 @@ namespace SM.Base.PostProcess
Init(); Init();
} }
public virtual void Draw(Framebuffer main) public virtual void Draw(Framebuffer main, Framebuffer target)
{ {
} }

View file

@ -53,12 +53,11 @@ namespace SM.Base.PostProcess
Uniforms["MVP"].SetMatrix4(PostProcessEffect.Mvp); Uniforms["MVP"].SetMatrix4(PostProcessEffect.Mvp);
Uniforms["ModelMatrix"].SetMatrix4(PostProcessEffect.Model); Uniforms["ModelMatrix"].SetMatrix4(PostProcessEffect.Model);
Uniforms["renderedTexture"].SetTexture(color, 0); Uniforms["renderedTexture"].SetTexture(color);
GL.DrawArrays(PrimitiveType.Quads, 0, 4); GL.DrawArrays(PrimitiveType.Quads, 0, 4);
GL.BindTexture(TextureTarget.Texture2D, 0); CleanUp();
GL.BindVertexArray(0);
GL.UseProgram(0); GL.UseProgram(0);
} }
@ -74,14 +73,13 @@ namespace SM.Base.PostProcess
Uniforms["MVP"].SetMatrix4(PostProcessEffect.Mvp); Uniforms["MVP"].SetMatrix4(PostProcessEffect.Mvp);
Uniforms["ModelMatrix"].SetMatrix4(PostProcessEffect.Model); Uniforms["ModelMatrix"].SetMatrix4(PostProcessEffect.Model);
Uniforms["renderedTexture"].SetTexture(color, 0); Uniforms["renderedTexture"].SetTexture(color);
setUniformAction(Uniforms); setUniformAction(Uniforms);
GL.DrawArrays(PrimitiveType.Quads, 0, 4); GL.DrawArrays(PrimitiveType.Quads, 0, 4);
GL.BindTexture(TextureTarget.Texture2D, 0); CleanUp();
GL.BindVertexArray(0);
GL.UseProgram(0); GL.UseProgram(0);
} }
} }

View file

@ -1,6 +1,7 @@
#region usings #region usings
using System.Collections.Generic; using System.Collections.Generic;
using System.Dynamic;
using OpenTK; using OpenTK;
using SM.Base.Drawing; using SM.Base.Drawing;
using SM.Base.Scene; using SM.Base.Scene;
@ -71,6 +72,11 @@ namespace SM.Base.Contexts
/// </summary> /// </summary>
public object LastPassthough; public object LastPassthough;
/// <summary>
/// Arguments for shaders
/// </summary>
public IDictionary<string, object> ShaderArguments;
/// <summary> /// <summary>
/// Returns the appropriate shader. /// Returns the appropriate shader.
/// <para> /// <para>

View file

@ -268,6 +268,7 @@ namespace SM.Base
new Instance new Instance
{ModelMatrix = Matrix4.Identity, TexturePosition = Vector2.Zero, TextureScale = Vector2.One} {ModelMatrix = Matrix4.Identity, TexturePosition = Vector2.Zero, TextureScale = Vector2.One}
}, },
ShaderArguments = new Dictionary<string, object>(),
Mesh = Plate.Object, Mesh = Plate.Object,
ForceViewport = ForceViewportCamera, ForceViewport = ForceViewportCamera,
WorldScale = _worldScale, WorldScale = _worldScale,

View file

@ -88,9 +88,9 @@ namespace SM.Base
{ {
} }
protected Framebuffer CreateWindowFramebuffer() public static Framebuffer CreateWindowFramebuffer()
{ {
Framebuffer framebuffer = new Framebuffer(window: _window); Framebuffer framebuffer = new Framebuffer(window: SMRenderer.CurrentWindow);
framebuffer.Append("color", 0); framebuffer.Append("color", 0);
framebuffer.Compile(); framebuffer.Compile();
return framebuffer; return framebuffer;

View file

@ -458,7 +458,7 @@ namespace SM.OGL.Shaders
/// <param name="texture"></param> /// <param name="texture"></param>
public void SetTexture(TextureBase texture) public void SetTexture(TextureBase texture)
{ {
if (Parent != null) SetTexture(texture, Parent.NextTexture++); if (Parent != null) SetTexture(texture, Parent.NextTexture);
} }
/// <summary> /// <summary>
@ -468,6 +468,7 @@ namespace SM.OGL.Shaders
/// <param name="texturePos"></param> /// <param name="texturePos"></param>
public void SetTexture(TextureBase texture, int texturePos) public void SetTexture(TextureBase texture, int texturePos)
{ {
Parent.NextTexture = texturePos + 1;
GL.ActiveTexture(TextureUnit.Texture0 + texturePos); GL.ActiveTexture(TextureUnit.Texture0 + texturePos);
GL.BindTexture(TextureTarget.Texture2D, texture); GL.BindTexture(TextureTarget.Texture2D, texture);
SetUniform1(texturePos); SetUniform1(texturePos);

View file

@ -10,7 +10,7 @@ namespace SM.OGL.Shaders
{ {
public class UniformCollection : Dictionary<string, IUniform> public class UniformCollection : Dictionary<string, IUniform>
{ {
internal int NextTexture = 0; public int NextTexture = 0;
internal string KeyString = ""; internal string KeyString = "";
public GenericShader ParentShader { get; internal set; } public GenericShader ParentShader { get; internal set; }

View file

@ -16,6 +16,8 @@ namespace SM2D.Drawing
{ {
public int ZIndex { get; set; } public int ZIndex { get; set; }
public bool ShadowCaster = false;
public Texture Texture public Texture Texture
{ {
get => (Texture) _material.Texture; get => (Texture) _material.Texture;
@ -31,6 +33,7 @@ namespace SM2D.Drawing
protected override void DrawContext(ref DrawContext context) protected override void DrawContext(ref DrawContext context)
{ {
base.DrawContext(ref context); base.DrawContext(ref context);
context.ShaderArguments["occluder"] = ShadowCaster;
context.Shader.Draw(context); context.Shader.Draw(context);
} }
@ -64,5 +67,6 @@ namespace SM2D.Drawing
_mesh = pol; _mesh = pol;
return pol; return pol;
} }
} }
} }

View file

@ -38,7 +38,7 @@ namespace SM2D
base.OnLoaded(); base.OnLoaded();
SMRenderer.DefaultMaterialShader = Default2DShader.MaterialShader; SMRenderer.DefaultMaterialShader = Default2DShader.MaterialShader;
SetRenderPipeline(new Basic2DPipeline()); SetRenderPipeline(Default2DPipeline.Pipeline);
} }
protected override void OnRenderFrame(FrameEventArgs e) protected override void OnRenderFrame(FrameEventArgs e)

View file

@ -1,5 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using SM.Base;
using SM.Base.Types; using SM.Base.Types;
using SM.OGL.Shaders; using SM.OGL.Shaders;
@ -7,6 +9,7 @@ namespace SM2D.Light
{ {
public abstract class LightObject public abstract class LightObject
{ {
private Vector2 _posNorm => Vector2.Divide(Position, (SMRenderer.CurrentWindow as GLWindow2D).WorldScale);
internal abstract int Type { get; } internal abstract int Type { get; }
public CVector2 Position = new CVector2(0); public CVector2 Position = new CVector2(0);

View file

@ -8,12 +8,16 @@ namespace SM2D.Light
internal override int Type { get; } = 0; internal override int Type { get; } = 0;
public float Power = 5; public float Power = 5;
public float InnerCircle = 1;
public float OuterCircle = 1;
internal override void SetUniforms(Dictionary<string, Uniform> uniforms) internal override void SetUniforms(Dictionary<string, Uniform> uniforms)
{ {
base.SetUniforms(uniforms); base.SetUniforms(uniforms);
uniforms["Power"].SetUniform1(Power); uniforms["Power"].SetUniform1(Power);
uniforms["Inner"].SetUniform1(1 / InnerCircle);
uniforms["Outer"].SetUniform1(1 / OuterCircle);
} }
} }
} }

View file

@ -1,9 +1,11 @@
using System.Reflection; using System.Reflection;
using SM.Base;
using SM.Base.PostProcess; using SM.Base.PostProcess;
using SM.Base.Scene; using SM.Base.Scene;
using SM.OGL.Framebuffer; using SM.OGL.Framebuffer;
using SM.OGL.Shaders; using SM.OGL.Shaders;
using SM.Utility; using SM.Utility;
using SM2D.Scene;
namespace SM2D.Light namespace SM2D.Light
{ {
@ -12,14 +14,25 @@ namespace SM2D.Light
private PostProcessShader _shader = new PostProcessShader(AssemblyUtility.ReadAssemblyFile("SM2D.Light.light.frag")); private PostProcessShader _shader = new PostProcessShader(AssemblyUtility.ReadAssemblyFile("SM2D.Light.light.frag"));
private LightSceneExtension sceneExtension; private LightSceneExtension sceneExtension;
public override void Draw(Framebuffer main) public override void Init(Framebuffer main)
{ {
base.Draw(main); base.Init(main);
main.Append("occluder", 1);
}
public override void Draw(Framebuffer main, Framebuffer target)
{
base.Draw(main, target);
_shader.Draw(main.ColorAttachments["color"], collection => _shader.Draw(main.ColorAttachments["color"], collection =>
{ {
collection["FragSize"].SetUniform2((SMRenderer.CurrentWindow as GLWindow2D).WorldScale);
collection["Ambient"].SetUniform4(sceneExtension.Ambient); collection["Ambient"].SetUniform4(sceneExtension.Ambient);
collection["LightCount"].SetUniform1(sceneExtension.Lights.Count); collection["LightCount"].SetUniform1(sceneExtension.Lights.Count);
collection["OccluderMap"].SetTexture(main.ColorAttachments["occluder"]);
collection["ShadowSensitivty"].SetUniform1(1f);
UniformArray array = collection.GetArray("Lights"); UniformArray array = collection.GetArray("Lights");
for (int i = 0; i < sceneExtension.Lights.Count; i++) for (int i = 0; i < sceneExtension.Lights.Count; i++)

View file

@ -8,15 +8,22 @@ struct Light {
// pointStuff; // pointStuff;
float Power; float Power;
float Inner;
float Outer;
}; };
in vec2 vTexture; in vec2 vTexture;
in vec2 FragPos; in vec2 FragPos;
uniform vec2 FragSize;
uniform vec4 Ambient = vec4(1); uniform vec4 Ambient = vec4(1);
uniform Light[24] Lights; uniform Light[24] Lights;
uniform int LightCount; uniform int LightCount;
uniform float ShadowSensitivty;
uniform sampler2D OccluderMap;
layout(location = 0) out vec4 color; layout(location = 0) out vec4 color;
vec4 GetRenderColor(); vec4 GetRenderColor();
@ -24,10 +31,27 @@ vec4 GetRenderColor();
vec3 calcPointLight(Light light) { vec3 calcPointLight(Light light) {
vec2 diff = light.Position - FragPos; vec2 diff = light.Position - FragPos;
float dif = light.Power / length(diff); float dif = 20 / length(diff);
float intensity = 4 * PI * dif * (dif * dif); float intensity = light.Power * (dif) * (dif * dif);
return vec3(intensity); return vec3(light.Color * intensity);
}
float occluded(Light light) {
float occluder = 1 - length(texture(OccluderMap, vTexture).rgb);
if (occluder != 0) {
vec2 diff = light.Position - FragPos;
vec2 dir = normalize(diff);
float steps = length(diff) / ShadowSensitivty;
vec2 curPos = FragPos;
for(int i = 0; i < steps; i++) {
curPos += dir * i * ShadowSensitivty;
}
}
return occluder;
} }
vec3 calcLight() { vec3 calcLight() {
@ -36,11 +60,13 @@ vec3 calcLight() {
for(int i = 0; i < LightCount; i++) { for(int i = 0; i < LightCount; i++) {
Light light = Lights[i]; Light light = Lights[i];
vec3 lightColor;
switch(light.Type) { switch(light.Type) {
case 0: case 0:
addedLight += calcPointLight(light); lightColor += calcPointLight(light);
break; break;
} }
addedLight += lightColor * occluded(light);
} }
return addedLight; return addedLight;
@ -51,5 +77,5 @@ void main() {
color = render * Ambient; color = render * Ambient;
color += vec4(calcLight() * render.xyz, 1); color += vec4(calcLight(), 1);
} }

View file

@ -1,52 +1,30 @@
#region usings using System;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using SM.Base; using SM.Base;
using SM.Base.Contexts; using SM.Base.Contexts;
using SM.Base.Scene; using SM.Base.Drawing;
using SM.OGL.Framebuffer; using SM.OGL.Framebuffer;
using SM2D.Light;
using SM2D.Shader; using SM2D.Shader;
#endregion
namespace SM2D.Pipelines namespace SM2D.Pipelines
{ {
public class Basic2DPipeline : RenderPipeline<Scene.Scene> public class Basic2DPipeline : RenderPipeline<Scene.Scene>
{ {
private Framebuffer _tempWindow; public static Basic2DPipeline Pipeline = new Basic2DPipeline();
private Light.LightPostEffect _lightEffect;
protected override void Initialization(GenericWindow window) protected override MaterialShader _defaultShader { get; } = Basic2DShader.Shader;
private Basic2DPipeline()
{ {
_tempWindow = CreateWindowFramebuffer(); Console.WriteLine();
_lightEffect = new LightPostEffect();
} }
protected override void Render(ref DrawContext context, Scene.Scene scene) protected override void Render(ref DrawContext context, Scene.Scene scene)
{ {
base.Render(ref context, scene); base.Render(ref context, scene);
_tempWindow.Activate(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
if (scene != null)
{
scene.DrawBackground(context);
scene.DrawMainObjects(context);
Framebuffer.Screen.Activate(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); Framebuffer.Screen.Activate(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
_lightEffect.Draw(_tempWindow); if (scene != null) scene.Draw(context);
scene.DrawHUD(context);
scene.DrawDebug(context);
}
}
protected override void SceneChanged(Scene.Scene scene)
{
base.SceneChanged(scene);
_lightEffect.SceneChanged(scene);
} }
} }
} }

View file

@ -0,0 +1,65 @@
#region usings
using System.Collections.Generic;
using OpenTK.Graphics.OpenGL4;
using SM.Base;
using SM.Base.Contexts;
using SM.Base.Scene;
using SM.OGL.Framebuffer;
using SM2D.Light;
using SM2D.Shader;
#endregion
namespace SM2D.Pipelines
{
public class Default2DPipeline : RenderPipeline<Scene.Scene>
{
public static Default2DPipeline Pipeline = new Default2DPipeline();
private Framebuffer _tempWindow;
private Light.LightPostEffect _lightEffect;
protected override List<Framebuffer> _framebuffers { get; } = new List<Framebuffer>();
private Default2DPipeline()
{
}
protected override void Initialization(GenericWindow window)
{
_tempWindow = CreateWindowFramebuffer();
_lightEffect = new LightPostEffect();
_framebuffers.Add(_tempWindow);
_lightEffect.Init(_tempWindow);
}
protected override void Render(ref DrawContext context, Scene.Scene scene)
{
base.Render(ref context, scene);
if (scene != null)
{
_tempWindow.Activate(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
scene.DrawBackground(context);
scene.DrawMainObjects(context);
Framebuffer.Screen.Activate();
_lightEffect.Draw(_tempWindow, Framebuffer.Screen);
scene.DrawHUD(context);
scene.DrawDebug(context);
}
}
protected override void SceneChanged(Scene.Scene scene)
{
base.SceneChanged(scene);
_lightEffect.SceneChanged(scene);
}
}
}

View file

@ -53,11 +53,13 @@
<Compile Include="Object\PolygonVertex.cs" /> <Compile Include="Object\PolygonVertex.cs" />
<Compile Include="Pipelines\Adv2DPipeline.cs" /> <Compile Include="Pipelines\Adv2DPipeline.cs" />
<Compile Include="Pipelines\Basic2DPipeline.cs" /> <Compile Include="Pipelines\Basic2DPipeline.cs" />
<Compile Include="Pipelines\Default2DPipeline.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Scene\Camera.cs" /> <Compile Include="Scene\Camera.cs" />
<Compile Include="Scene\I2DShowItem.cs" /> <Compile Include="Scene\I2DShowItem.cs" />
<Compile Include="Scene\ItemCollection.cs" /> <Compile Include="Scene\ItemCollection.cs" />
<Compile Include="Scene\Scene.cs" /> <Compile Include="Scene\Scene.cs" />
<Compile Include="Shader\Basic2DShader.cs" />
<Compile Include="Shader\Default2DShader.cs" /> <Compile Include="Shader\Default2DShader.cs" />
<Compile Include="Types\Transformation.cs" /> <Compile Include="Types\Transformation.cs" />
</ItemGroup> </ItemGroup>
@ -82,6 +84,8 @@
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Light\light.frag" /> <EmbeddedResource Include="Light\light.frag" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup>
<EmbeddedResource Include="Shader\ShaderFiles\basic.glsl" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View file

@ -0,0 +1,40 @@
using SM.Base.Contexts;
using SM.Base.Drawing;
using SM.OGL.Shaders;
using SM.Utility;
namespace SM2D.Shader
{
public class Basic2DShader : MaterialShader
{
public static Basic2DShader Shader = new Basic2DShader();
private Basic2DShader() : base(AssemblyUtility.ReadAssemblyFile("SM2D.Shader.ShaderFiles.basic.glsl"))
{
}
protected override void DrawProcess(DrawContext context)
{
// Vertex Uniforms
Uniforms["MVP"].SetMatrix4(context.ModelMaster * context.View * context.World);
Uniforms["HasVColor"]
.SetUniform1(context.Mesh.Attributes["color"] != null);
UniformArray instances = Uniforms.GetArray("Instances");
for (int i = 0; i < context.Instances.Count; i++)
{
var shaderInstance = instances[i];
var instance = context.Instances[i];
shaderInstance["ModelMatrix"].SetMatrix4(instance.ModelMatrix);
shaderInstance["TextureOffset"].SetUniform2(instance.TexturePosition);
shaderInstance["TextureScale"].SetUniform2(instance.TextureScale);
}
// Fragment Uniforms
Uniforms["Tint"].SetUniform4(context.Material.Tint);
Uniforms["Texture"].SetTexture(context.Material.Texture, Uniforms["UseTexture"]);
DrawObject(context.Mesh, context.Instances.Count);
}
}
}

View file

@ -27,6 +27,7 @@ namespace SM2D.Shader
Uniforms["MVP"].SetMatrix4(context.ModelMaster * context.View * context.World); Uniforms["MVP"].SetMatrix4(context.ModelMaster * context.View * context.World);
Uniforms["HasVColor"] Uniforms["HasVColor"]
.SetUniform1(context.Mesh.Attributes["color"] != null); .SetUniform1(context.Mesh.Attributes["color"] != null);
Uniforms["occlude"].SetUniform1(context.ShaderArguments.ContainsKey("occluder"));
UniformArray instances = Uniforms.GetArray("Instances"); UniformArray instances = Uniforms.GetArray("Instances");
for (int i = 0; i < context.Instances.Count; i++) for (int i = 0; i < context.Instances.Count; i++)

View file

@ -0,0 +1,28 @@
#version 330
//# region vertex
//# import SM_base_vertex_basic
void ApplyTexModifier();
void CheckVertexColor();
void ApplyModelTransformation();
void vmain() {
ApplyTexModifier();
CheckVertexColor();
ApplyModelTransformation();
}
//# region fragment
in vec2 vTexture;
in vec4 vColor;
uniform vec4 Tint;
uniform bool UseTexture;
uniform sampler2D Texture;
layout(location = 0) out vec4 color;
void fmain() {
color = vColor * Tint;
if (UseTexture) color *= texture(Texture, vTexture);
}

View file

@ -17,13 +17,18 @@ void vmain() {
in vec2 vTexture; in vec2 vTexture;
in vec4 vColor; in vec4 vColor;
uniform bool occlude;
uniform vec4 Tint; uniform vec4 Tint;
uniform bool UseTexture; uniform bool UseTexture;
uniform sampler2D Texture; uniform sampler2D Texture;
layout(location = 0) out vec4 color; layout(location = 0) out vec4 color;
layout(location = 1) out vec4 occluder;
void fmain() { void fmain() {
color = vColor * Tint; color = vColor * Tint;
if (UseTexture) color *= texture(Texture, vTexture); if (UseTexture) color *= texture(Texture, vTexture);
occluder = vec4(occlude,0,0,1);
} }

View file

@ -16,6 +16,7 @@ using SM2D;
using SM2D.Drawing; using SM2D.Drawing;
using SM2D.Light; using SM2D.Light;
using SM2D.Object; using SM2D.Object;
using SM2D.Pipelines;
using SM2D.Scene; using SM2D.Scene;
using Font = SM.Base.Drawing.Text.Font; using Font = SM.Base.Drawing.Text.Font;
using Vector2 = OpenTK.Vector2; using Vector2 = OpenTK.Vector2;
@ -38,6 +39,7 @@ namespace SM_TEST
window = new GLWindow2D {Scaling = new Vector2(0, 1000)}; window = new GLWindow2D {Scaling = new Vector2(0, 1000)};
//window.GrabCursor(); //window.GrabCursor();
window.SetRenderPipeline(Basic2DPipeline.Pipeline);
window.SetScene(scene = new Scene()); window.SetScene(scene = new Scene());
window.Load += WindowOnLoad; window.Load += WindowOnLoad;
window.RenderFrame += WindowOnUpdateFrame; window.RenderFrame += WindowOnUpdateFrame;
@ -59,16 +61,22 @@ namespace SM_TEST
scene.ShowAxisHelper = true; scene.ShowAxisHelper = true;
DrawObject2D kasten = new DrawObject2D(); DrawObject2D kasten = new DrawObject2D();
kasten.ShadowCaster = true;
kasten.Texture = new Texture(new Bitmap("herosword.png")); kasten.Texture = new Texture(new Bitmap("herosword.png"));
kasten.Transform.ApplyTextureSize(kasten.Texture, 500); kasten.Transform.ApplyTextureSize(kasten.Texture, 500);
scene.Objects.Add(kasten); scene.Objects.Add(kasten);
//scene.Background.Color = Color4.White;
DrawText text = new DrawText(font, "Text"); DrawText text = new DrawText(font, "Text");
text.Transform.Position.Set(0, 500); text.Transform.Position.Set(0, 500);
scene.Objects.Add(text); scene.Objects.Add(text);
light = new PointLight(); light = new PointLight
light.Color = new Color4(0, 1,0,1); {
Color = new Color4(0, 1, 1, 1),
Power = 100
};
scene.LightInformations.Lights.Add(light); scene.LightInformations.Lights.Add(light);
scene.LightInformations.Ambient = Color4.White; scene.LightInformations.Ambient = Color4.White;