Toon Shading + Point Shadows #1
2
Kav
2
Kav
|
@ -1 +1 @@
|
||||||
Subproject commit 66d4e5bf6e78949f6e5b2fc9eb1983d438047f0b
|
Subproject commit cb0baf0bf0b2c8c830c239c1566ca7a2fcacced9
|
|
@ -0,0 +1,15 @@
|
||||||
|
using Encompass;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KavTest.Components
|
||||||
|
{
|
||||||
|
public struct AmbientLightComponent : IComponent
|
||||||
|
{
|
||||||
|
public Color Color { get; }
|
||||||
|
|
||||||
|
public AmbientLightComponent(Color color)
|
||||||
|
{
|
||||||
|
Color = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using Encompass;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KavTest
|
||||||
|
{
|
||||||
|
public struct ContinuousRotationComponent : IComponent
|
||||||
|
{
|
||||||
|
public Quaternion Quaternion { get; }
|
||||||
|
|
||||||
|
public ContinuousRotationComponent(Vector3 axis, float angle)
|
||||||
|
{
|
||||||
|
Quaternion = Quaternion.CreateFromAxisAngle(axis, angle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using Encompass;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace KavTest.Components
|
||||||
|
{
|
||||||
|
public struct SkyboxComponent : IComponent
|
||||||
|
{
|
||||||
|
public TextureCube Skybox { get; }
|
||||||
|
|
||||||
|
public SkyboxComponent(TextureCube skybox)
|
||||||
|
{
|
||||||
|
Skybox = skybox;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 723 KiB |
Binary file not shown.
After Width: | Height: | Size: 274 KiB |
Binary file not shown.
After Width: | Height: | Size: 462 KiB |
Binary file not shown.
After Width: | Height: | Size: 588 KiB |
Binary file not shown.
After Width: | Height: | Size: 525 KiB |
Binary file not shown.
After Width: | Height: | Size: 338 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -5,7 +5,7 @@ using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
namespace KavTest.Engines
|
namespace KavTest.Engines
|
||||||
{
|
{
|
||||||
[Reads(typeof(AngularVelocityComponent))]
|
[Reads(typeof(AngularVelocityComponent), typeof(ContinuousRotationComponent))]
|
||||||
[Sends(typeof(LocalRotationMessage))]
|
[Sends(typeof(LocalRotationMessage))]
|
||||||
public class AngularVelocityEngine : Engine
|
public class AngularVelocityEngine : Engine
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,12 @@ namespace KavTest.Engines
|
||||||
|
|
||||||
SendMessage(new LocalRotationMessage(entity, Quaternion.CreateFromYawPitchRoll(angularVelocity.X, angularVelocity.Y, angularVelocity.Z)));
|
SendMessage(new LocalRotationMessage(entity, Quaternion.CreateFromYawPitchRoll(angularVelocity.X, angularVelocity.Y, angularVelocity.Z)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var entity in ReadEntities<ContinuousRotationComponent>())
|
||||||
|
{
|
||||||
|
ref readonly var rotationComponent = ref GetComponent<ContinuousRotationComponent>(entity);
|
||||||
|
SendMessage(new LocalRotationMessage(entity, rotationComponent.Quaternion));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace KavTest.Spawners
|
||||||
|
|
||||||
AddComponent(entity, new Transform3DComponent(new Transform3D(Vector3.Zero, message.Orientation)));
|
AddComponent(entity, new Transform3DComponent(new Transform3D(Vector3.Zero, message.Orientation)));
|
||||||
AddComponent(entity, new DirectionalLightComponent(message.Color, message.Intensity));
|
AddComponent(entity, new DirectionalLightComponent(message.Color, message.Intensity));
|
||||||
|
var forward = Matrix.CreateFromQuaternion(message.Orientation).Forward;
|
||||||
|
AddComponent(entity, new ContinuousRotationComponent(forward, 0.01f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@ namespace KavTest
|
||||||
public KavTestGame()
|
public KavTestGame()
|
||||||
{
|
{
|
||||||
graphics = new GraphicsDeviceManager(this);
|
graphics = new GraphicsDeviceManager(this);
|
||||||
graphics.PreferredBackBufferWidth = 1280;
|
graphics.PreferredBackBufferWidth = 1600;
|
||||||
graphics.PreferredBackBufferHeight = 720;
|
graphics.PreferredBackBufferHeight = 900;
|
||||||
graphics.PreferMultiSampling = false;
|
graphics.PreferMultiSampling = false;
|
||||||
Content.RootDirectory = "Content";
|
Content.RootDirectory = "Content";
|
||||||
|
|
||||||
|
@ -50,8 +50,17 @@ namespace KavTest
|
||||||
|
|
||||||
var rustyBallModel = Kav.ModelLoader.Load(
|
var rustyBallModel = Kav.ModelLoader.Load(
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/rustysphere.glb"))
|
Smuggler.Importer.ImportGLB(
|
||||||
|
GraphicsDevice,
|
||||||
|
File.OpenRead("Content/rustysphere.glb")
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
rustyBallModel.DisableNormalMaps();
|
||||||
|
rustyBallModel.DisableAlbedoMaps();
|
||||||
|
rustyBallModel.DisableMetallicRoughnessMaps();
|
||||||
|
rustyBallModel.Albedo = Color.DeepSkyBlue;
|
||||||
|
rustyBallModel.Metallic = 0.5f;
|
||||||
|
rustyBallModel.Roughness = 0.284f;
|
||||||
|
|
||||||
var lightBulbModel = Kav.ModelLoader.Load(
|
var lightBulbModel = Kav.ModelLoader.Load(
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
|
@ -62,12 +71,104 @@ namespace KavTest
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/floor.glb"))
|
Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/floor.glb"))
|
||||||
);
|
);
|
||||||
|
floorModel.Metallic = 0f;
|
||||||
|
floorModel.Roughness = 0f;
|
||||||
|
|
||||||
var avocadoModel = Kav.ModelLoader.Load(
|
var avocadoModel = Kav.ModelLoader.Load(
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/avocado.glb"))
|
Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/avocado.glb"))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var redCylinderModel = Kav.ModelLoader.Load(
|
||||||
|
GraphicsDevice,
|
||||||
|
Smuggler.Importer.ImportGLB(
|
||||||
|
GraphicsDevice,
|
||||||
|
File.OpenRead("Content/redcylinder.glb")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
var pinkConeModel = Kav.ModelLoader.Load(
|
||||||
|
GraphicsDevice,
|
||||||
|
Smuggler.Importer.ImportGLB(
|
||||||
|
GraphicsDevice,
|
||||||
|
File.OpenRead("Content/pinkcone.glb")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
var blueTorusModel = Kav.ModelLoader.Load(
|
||||||
|
GraphicsDevice,
|
||||||
|
Smuggler.Importer.ImportGLB(
|
||||||
|
GraphicsDevice,
|
||||||
|
File.OpenRead("Content/bluetorus.glb")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
var cubeModel = Kav.ModelLoader.Load(
|
||||||
|
GraphicsDevice,
|
||||||
|
Smuggler.Importer.ImportGLB(
|
||||||
|
GraphicsDevice,
|
||||||
|
File.OpenRead("Content/cube.glb")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
var toonShadeRuinsModel = Kav.ModelLoader.Load(
|
||||||
|
GraphicsDevice,
|
||||||
|
Smuggler.Importer.ImportGLB(
|
||||||
|
GraphicsDevice,
|
||||||
|
File.OpenRead("Content/ToonShadeRuins.glb")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
Texture2D.TextureDataFromStreamEXT(
|
||||||
|
File.OpenRead("Content/Skybox/front.jpg"),
|
||||||
|
out var skyboxSize,
|
||||||
|
out _,
|
||||||
|
out byte[] frontPixels
|
||||||
|
);
|
||||||
|
|
||||||
|
Texture2D.TextureDataFromStreamEXT(
|
||||||
|
File.OpenRead("Content/Skybox/back.jpg"),
|
||||||
|
out _,
|
||||||
|
out _,
|
||||||
|
out byte[] backPixels
|
||||||
|
);
|
||||||
|
|
||||||
|
Texture2D.TextureDataFromStreamEXT(
|
||||||
|
File.OpenRead("Content/Skybox/right.jpg"),
|
||||||
|
out _,
|
||||||
|
out _,
|
||||||
|
out byte[] rightPixels
|
||||||
|
);
|
||||||
|
|
||||||
|
Texture2D.TextureDataFromStreamEXT(
|
||||||
|
File.OpenRead("Content/Skybox/left.jpg"),
|
||||||
|
out _,
|
||||||
|
out _,
|
||||||
|
out byte[] leftPixels
|
||||||
|
);
|
||||||
|
|
||||||
|
Texture2D.TextureDataFromStreamEXT(
|
||||||
|
File.OpenRead("Content/Skybox/top.jpg"),
|
||||||
|
out _,
|
||||||
|
out _,
|
||||||
|
out byte[] topPixels
|
||||||
|
);
|
||||||
|
|
||||||
|
Texture2D.TextureDataFromStreamEXT(
|
||||||
|
File.OpenRead("Content/Skybox/bottom.jpg"),
|
||||||
|
out _,
|
||||||
|
out _,
|
||||||
|
out byte[] bottomPixels
|
||||||
|
);
|
||||||
|
|
||||||
|
var skybox = new TextureCube(GraphicsDevice, skyboxSize, false, SurfaceFormat.Color);
|
||||||
|
skybox.SetData(CubeMapFace.PositiveZ, frontPixels);
|
||||||
|
skybox.SetData(CubeMapFace.NegativeZ, backPixels);
|
||||||
|
skybox.SetData(CubeMapFace.PositiveX, rightPixels);
|
||||||
|
skybox.SetData(CubeMapFace.NegativeX, leftPixels);
|
||||||
|
skybox.SetData(CubeMapFace.PositiveY, topPixels);
|
||||||
|
skybox.SetData(CubeMapFace.NegativeY, bottomPixels);
|
||||||
|
|
||||||
WorldBuilder.AddEngine(new InputEngine(this));
|
WorldBuilder.AddEngine(new InputEngine(this));
|
||||||
WorldBuilder.AddEngine(new AngularVelocityEngine());
|
WorldBuilder.AddEngine(new AngularVelocityEngine());
|
||||||
WorldBuilder.AddEngine(new MoveAlongCurve3DEngine());
|
WorldBuilder.AddEngine(new MoveAlongCurve3DEngine());
|
||||||
|
@ -94,35 +195,97 @@ namespace KavTest
|
||||||
// new Vector3(-1, 1, 1)
|
// new Vector3(-1, 1, 1)
|
||||||
// ));
|
// ));
|
||||||
|
|
||||||
|
// WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
|
// new Transform3D(new Vector3(0, 1, 0), Quaternion.Identity, new Vector3(1f, 1f, 1f)),
|
||||||
|
// rustyBallModel
|
||||||
|
// ));
|
||||||
|
|
||||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
new Transform3D(new Vector3(0, -3, 0), Quaternion.Identity, new Vector3(10f, 1f, 10f)),
|
new Transform3D(new Vector3(0, -3, 0), Quaternion.Identity, new Vector3(10f, 1f, 10f)),
|
||||||
floorModel
|
floorModel
|
||||||
));
|
));
|
||||||
|
|
||||||
var entity = WorldBuilder.CreateEntity();
|
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
|
|
||||||
WorldBuilder.SetComponent(entity, new Transform3DComponent(
|
|
||||||
new Transform3D(
|
new Transform3D(
|
||||||
new Vector3(0, 1, 0),
|
new Vector3(0, 1, 0),
|
||||||
Quaternion.CreateFromAxisAngle(Vector3.Right, -Microsoft.Xna.Framework.MathHelper.PiOver2),
|
Quaternion.CreateFromAxisAngle(
|
||||||
new Vector3(30, 30, 30))
|
Vector3.Right,
|
||||||
|
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
||||||
|
),
|
||||||
|
new Vector3(1f, 1f, 1f)
|
||||||
|
),
|
||||||
|
redCylinderModel
|
||||||
|
));
|
||||||
|
|
||||||
|
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
|
new Transform3D(
|
||||||
|
new Vector3(-3, 1, 0),
|
||||||
|
Quaternion.CreateFromAxisAngle(
|
||||||
|
Vector3.Right,
|
||||||
|
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
||||||
|
),
|
||||||
|
new Vector3(1f, 1f, 1f)
|
||||||
|
),
|
||||||
|
blueTorusModel
|
||||||
|
));
|
||||||
|
|
||||||
|
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
|
new Transform3D(
|
||||||
|
new Vector3(3, 1, 0),
|
||||||
|
Quaternion.CreateFromAxisAngle(
|
||||||
|
Vector3.Right,
|
||||||
|
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
||||||
|
),
|
||||||
|
new Vector3(1f, 1f, 1f)
|
||||||
|
),
|
||||||
|
cubeModel
|
||||||
|
));
|
||||||
|
|
||||||
|
// WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
|
// Transform3D.Identity,
|
||||||
|
// toonShadeRuinsModel
|
||||||
|
// ));
|
||||||
|
|
||||||
|
var lightEntity = WorldBuilder.CreateEntity();
|
||||||
|
WorldBuilder.SetComponent(
|
||||||
|
lightEntity,
|
||||||
|
new Transform3DComponent(
|
||||||
|
new Transform3D(
|
||||||
|
new Vector3(0, 3, 3),
|
||||||
|
Quaternion.Identity,
|
||||||
|
new Vector3(0.1f, 0.1f, 0.1f)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
WorldBuilder.SetComponent(entity, new ModelComponent(avocadoModel));
|
WorldBuilder.SetComponent(
|
||||||
|
lightEntity,
|
||||||
|
new PointLightComponent(Color.Blue, 1000f)
|
||||||
|
);
|
||||||
|
WorldBuilder.SetComponent(
|
||||||
|
lightEntity,
|
||||||
|
new ModelComponent(cubeModel)
|
||||||
|
);
|
||||||
|
|
||||||
for (var i = 0; i < 1; i++)
|
// for (var i = 0; i < 1; i++)
|
||||||
{
|
// {
|
||||||
var start = RandomHelper.RandomVector3(-5, 5);
|
// var start = RandomHelper.RandomVector3(2, 5);
|
||||||
|
|
||||||
WorldBuilder.SendMessage(new LightBulbSpawnMessage(
|
// WorldBuilder.SendMessage(new LightBulbSpawnMessage(
|
||||||
new Transform3D(start.ToXNAVector(), Quaternion.Identity, new Vector3(0.1f, 0.1f, 0.1f)),
|
// new Transform3D(start.ToXNAVector(), Quaternion.Identity, new Vector3(0.1f, 0.1f, 0.1f)),
|
||||||
RandomHelper.RandomColor(),
|
// RandomHelper.RandomColor(),
|
||||||
1f,
|
// 5f,
|
||||||
RandomHelper.RandomLoop(start, -15, 15, 3, 10)
|
// RandomHelper.RandomLoop(start, 2, 5, 3, 10)
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
|
|
||||||
|
var ambientLightEntity = WorldBuilder.CreateEntity();
|
||||||
|
|
||||||
|
WorldBuilder.SetComponent(ambientLightEntity, new AmbientLightComponent(
|
||||||
|
new Color(0.4f, 0.4f, 0.4f)
|
||||||
));
|
));
|
||||||
}
|
|
||||||
|
|
||||||
WorldBuilder.SendMessage(new DirectionalLightSpawnMessage(
|
WorldBuilder.SendMessage(new DirectionalLightSpawnMessage(
|
||||||
|
//Quaternion.CreateFromAxisAngle(Vector3.Right, Microsoft.Xna.Framework.MathHelper.Pi / 3f),
|
||||||
Quaternion.CreateFromAxisAngle(Vector3.Right, Microsoft.Xna.Framework.MathHelper.PiOver4),
|
Quaternion.CreateFromAxisAngle(Vector3.Right, Microsoft.Xna.Framework.MathHelper.PiOver4),
|
||||||
Color.LightGoldenrodYellow,
|
Color.LightGoldenrodYellow,
|
||||||
0.7f
|
0.7f
|
||||||
|
@ -155,6 +318,11 @@ namespace KavTest
|
||||||
100f
|
100f
|
||||||
));
|
));
|
||||||
|
|
||||||
|
var skyboxEntity = WorldBuilder.CreateEntity();
|
||||||
|
WorldBuilder.SetComponent(skyboxEntity, new SkyboxComponent(
|
||||||
|
skybox
|
||||||
|
));
|
||||||
|
|
||||||
World = WorldBuilder.Build();
|
World = WorldBuilder.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace KavTest.Renderers
|
||||||
{
|
{
|
||||||
foreach (var entity in ReadEntitiesAsEnumerable<ModelComponent>())
|
foreach (var entity in ReadEntitiesAsEnumerable<ModelComponent>())
|
||||||
{
|
{
|
||||||
|
/* FIXME: this transformation should definitely not go here */
|
||||||
var transformComponent = GetComponent<Transform3DComponent>(entity);
|
var transformComponent = GetComponent<Transform3DComponent>(entity);
|
||||||
var modelComponent = GetComponent<ModelComponent>(entity);
|
var modelComponent = GetComponent<ModelComponent>(entity);
|
||||||
if (HasComponent<OverrideAlbedoComponent>(entity))
|
if (HasComponent<OverrideAlbedoComponent>(entity))
|
||||||
|
@ -29,11 +30,8 @@ namespace KavTest.Renderers
|
||||||
{
|
{
|
||||||
foreach (var meshPart in mesh.MeshParts)
|
foreach (var meshPart in mesh.MeshParts)
|
||||||
{
|
{
|
||||||
if (meshPart.Effect is DeferredPBR_GBufferEffect gBufferEffect)
|
meshPart.DisableAlbedoMap = true;
|
||||||
{
|
meshPart.Albedo = overrideAlbedoComponent.Color;
|
||||||
gBufferEffect.AlbedoTexture = null;
|
|
||||||
gBufferEffect.Albedo = overrideAlbedoComponent.Color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +40,21 @@ namespace KavTest.Renderers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AmbientLight AmbientLight
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (SomeComponent<AmbientLightComponent>())
|
||||||
|
{
|
||||||
|
return new AmbientLight(ReadComponent<AmbientLightComponent>().Color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new AmbientLight(Color.Black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IEnumerable<PointLight> PointLights
|
private IEnumerable<PointLight> PointLights
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -118,11 +131,21 @@ namespace KavTest.Renderers
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
Renderer.DeferredRender(
|
// Renderer.DeferredRender(
|
||||||
|
// camera,
|
||||||
|
// ModelTransforms,
|
||||||
|
// AmbientLight,
|
||||||
|
// PointLights,
|
||||||
|
// DirectionalLight()
|
||||||
|
// );
|
||||||
|
|
||||||
|
Renderer.DeferredToonRender(
|
||||||
camera,
|
camera,
|
||||||
ModelTransforms,
|
ModelTransforms,
|
||||||
|
AmbientLight,
|
||||||
PointLights,
|
PointLights,
|
||||||
DirectionalLight()
|
DirectionalLight(),
|
||||||
|
ReadComponent<SkyboxComponent>().Skybox
|
||||||
);
|
);
|
||||||
|
|
||||||
// foreach (var directionalLight in DirectionalLights)
|
// foreach (var directionalLight in DirectionalLights)
|
||||||
|
|
Loading…
Reference in New Issue