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
|
||||
{
|
||||
[Reads(typeof(AngularVelocityComponent))]
|
||||
[Reads(typeof(AngularVelocityComponent), typeof(ContinuousRotationComponent))]
|
||||
[Sends(typeof(LocalRotationMessage))]
|
||||
public class AngularVelocityEngine : Engine
|
||||
{
|
||||
|
@ -18,6 +18,12 @@ namespace KavTest.Engines
|
|||
|
||||
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 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()
|
||||
{
|
||||
graphics = new GraphicsDeviceManager(this);
|
||||
graphics.PreferredBackBufferWidth = 1280;
|
||||
graphics.PreferredBackBufferHeight = 720;
|
||||
graphics.PreferredBackBufferWidth = 1600;
|
||||
graphics.PreferredBackBufferHeight = 900;
|
||||
graphics.PreferMultiSampling = false;
|
||||
Content.RootDirectory = "Content";
|
||||
|
||||
|
@ -50,8 +50,17 @@ namespace KavTest
|
|||
|
||||
var rustyBallModel = Kav.ModelLoader.Load(
|
||||
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(
|
||||
GraphicsDevice,
|
||||
|
@ -62,12 +71,104 @@ namespace KavTest
|
|||
GraphicsDevice,
|
||||
Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/floor.glb"))
|
||||
);
|
||||
floorModel.Metallic = 0f;
|
||||
floorModel.Roughness = 0f;
|
||||
|
||||
var avocadoModel = Kav.ModelLoader.Load(
|
||||
GraphicsDevice,
|
||||
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 AngularVelocityEngine());
|
||||
WorldBuilder.AddEngine(new MoveAlongCurve3DEngine());
|
||||
|
@ -94,35 +195,97 @@ namespace KavTest
|
|||
// 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(
|
||||
new Transform3D(new Vector3(0, -3, 0), Quaternion.Identity, new Vector3(10f, 1f, 10f)),
|
||||
floorModel
|
||||
));
|
||||
|
||||
var entity = WorldBuilder.CreateEntity();
|
||||
|
||||
WorldBuilder.SetComponent(entity, new Transform3DComponent(
|
||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||
new Transform3D(
|
||||
new Vector3(0, 1, 0),
|
||||
Quaternion.CreateFromAxisAngle(Vector3.Right, -Microsoft.Xna.Framework.MathHelper.PiOver2),
|
||||
new Vector3(30, 30, 30))
|
||||
Quaternion.CreateFromAxisAngle(
|
||||
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++)
|
||||
{
|
||||
var start = RandomHelper.RandomVector3(-5, 5);
|
||||
// for (var i = 0; i < 1; i++)
|
||||
// {
|
||||
// var start = RandomHelper.RandomVector3(2, 5);
|
||||
|
||||
WorldBuilder.SendMessage(new LightBulbSpawnMessage(
|
||||
new Transform3D(start.ToXNAVector(), Quaternion.Identity, new Vector3(0.1f, 0.1f, 0.1f)),
|
||||
RandomHelper.RandomColor(),
|
||||
1f,
|
||||
RandomHelper.RandomLoop(start, -15, 15, 3, 10)
|
||||
// WorldBuilder.SendMessage(new LightBulbSpawnMessage(
|
||||
// new Transform3D(start.ToXNAVector(), Quaternion.Identity, new Vector3(0.1f, 0.1f, 0.1f)),
|
||||
// RandomHelper.RandomColor(),
|
||||
// 5f,
|
||||
// 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(
|
||||
//Quaternion.CreateFromAxisAngle(Vector3.Right, Microsoft.Xna.Framework.MathHelper.Pi / 3f),
|
||||
Quaternion.CreateFromAxisAngle(Vector3.Right, Microsoft.Xna.Framework.MathHelper.PiOver4),
|
||||
Color.LightGoldenrodYellow,
|
||||
0.7f
|
||||
|
@ -155,6 +318,11 @@ namespace KavTest
|
|||
100f
|
||||
));
|
||||
|
||||
var skyboxEntity = WorldBuilder.CreateEntity();
|
||||
WorldBuilder.SetComponent(skyboxEntity, new SkyboxComponent(
|
||||
skybox
|
||||
));
|
||||
|
||||
World = WorldBuilder.Build();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace KavTest.Renderers
|
|||
{
|
||||
foreach (var entity in ReadEntitiesAsEnumerable<ModelComponent>())
|
||||
{
|
||||
/* FIXME: this transformation should definitely not go here */
|
||||
var transformComponent = GetComponent<Transform3DComponent>(entity);
|
||||
var modelComponent = GetComponent<ModelComponent>(entity);
|
||||
if (HasComponent<OverrideAlbedoComponent>(entity))
|
||||
|
@ -29,11 +30,8 @@ namespace KavTest.Renderers
|
|||
{
|
||||
foreach (var meshPart in mesh.MeshParts)
|
||||
{
|
||||
if (meshPart.Effect is DeferredPBR_GBufferEffect gBufferEffect)
|
||||
{
|
||||
gBufferEffect.AlbedoTexture = null;
|
||||
gBufferEffect.Albedo = overrideAlbedoComponent.Color;
|
||||
}
|
||||
meshPart.DisableAlbedoMap = true;
|
||||
meshPart.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
|
||||
{
|
||||
get
|
||||
|
@ -118,11 +131,21 @@ namespace KavTest.Renderers
|
|||
// );
|
||||
// }
|
||||
|
||||
Renderer.DeferredRender(
|
||||
// Renderer.DeferredRender(
|
||||
// camera,
|
||||
// ModelTransforms,
|
||||
// AmbientLight,
|
||||
// PointLights,
|
||||
// DirectionalLight()
|
||||
// );
|
||||
|
||||
Renderer.DeferredToonRender(
|
||||
camera,
|
||||
ModelTransforms,
|
||||
AmbientLight,
|
||||
PointLights,
|
||||
DirectionalLight()
|
||||
DirectionalLight(),
|
||||
ReadComponent<SkyboxComponent>().Skybox
|
||||
);
|
||||
|
||||
// foreach (var directionalLight in DirectionalLights)
|
||||
|
|
Loading…
Reference in New Issue