more toon effect + remove material from MeshPart
parent
565be374bb
commit
2fb20747e4
|
@ -11,6 +11,9 @@ namespace Kav
|
||||||
|
|
||||||
EffectParameter eyePositionParam;
|
EffectParameter eyePositionParam;
|
||||||
EffectParameter directionalLightDirectionParam;
|
EffectParameter directionalLightDirectionParam;
|
||||||
|
EffectParameter directionalLightColorParam;
|
||||||
|
|
||||||
|
EffectParameter softnessParam;
|
||||||
|
|
||||||
public Texture2D GPosition { get; set; }
|
public Texture2D GPosition { get; set; }
|
||||||
public Texture2D GAlbedo { get; set; }
|
public Texture2D GAlbedo { get; set; }
|
||||||
|
@ -18,6 +21,9 @@ namespace Kav
|
||||||
|
|
||||||
public Vector3 EyePosition { get; set; }
|
public Vector3 EyePosition { get; set; }
|
||||||
public Vector3 DirectionalLightDirection { get; set; }
|
public Vector3 DirectionalLightDirection { get; set; }
|
||||||
|
public Vector3 DirectionalLightColor { get; set; }
|
||||||
|
|
||||||
|
public float Softness { get; set; }
|
||||||
|
|
||||||
public Deferred_ToonEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.Deferred_ToonEffect)
|
public Deferred_ToonEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.Deferred_ToonEffect)
|
||||||
{
|
{
|
||||||
|
@ -32,6 +38,9 @@ namespace Kav
|
||||||
|
|
||||||
eyePositionParam.SetValue(EyePosition);
|
eyePositionParam.SetValue(EyePosition);
|
||||||
directionalLightDirectionParam.SetValue(DirectionalLightDirection);
|
directionalLightDirectionParam.SetValue(DirectionalLightDirection);
|
||||||
|
directionalLightColorParam.SetValue(DirectionalLightColor);
|
||||||
|
|
||||||
|
softnessParam.SetValue(Softness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CacheEffectParameters()
|
void CacheEffectParameters()
|
||||||
|
@ -42,6 +51,9 @@ namespace Kav
|
||||||
|
|
||||||
eyePositionParam = Parameters["EyePosition"];
|
eyePositionParam = Parameters["EyePosition"];
|
||||||
directionalLightDirectionParam = Parameters["DirectionalLightDirection"];
|
directionalLightDirectionParam = Parameters["DirectionalLightDirection"];
|
||||||
|
directionalLightColorParam = Parameters["DirectionalLightColor"];
|
||||||
|
|
||||||
|
softnessParam = Parameters["Softness"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
Effects/FXB/Deferred_ToonEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/Deferred_ToonEffect.fxb (Stored with Git LFS)
Binary file not shown.
|
@ -9,7 +9,9 @@ BEGIN_CONSTANTS
|
||||||
float3 EyePosition _ps(c0) _cb(c0);
|
float3 EyePosition _ps(c0) _cb(c0);
|
||||||
|
|
||||||
float3 DirectionalLightDirection _ps(c1) _cb(c1);
|
float3 DirectionalLightDirection _ps(c1) _cb(c1);
|
||||||
float3 AmbientLightColor _ps(c2) _cb(c2);
|
float3 DirectionalLightColor _ps(c2) _cb(c2);
|
||||||
|
|
||||||
|
float Softness _ps(c3) _cb(c3);
|
||||||
|
|
||||||
END_CONSTANTS
|
END_CONSTANTS
|
||||||
|
|
||||||
|
@ -44,10 +46,39 @@ float4 main_ps(PixelInput input) : SV_TARGET0
|
||||||
float3 V = normalize(EyePosition - worldPosition);
|
float3 V = normalize(EyePosition - worldPosition);
|
||||||
float3 L = normalize(DirectionalLightDirection);
|
float3 L = normalize(DirectionalLightDirection);
|
||||||
float3 N = normalize(normal);
|
float3 N = normalize(normal);
|
||||||
float NdotL = dot(N, L);
|
float3 H = normalize(V + L);
|
||||||
|
|
||||||
float lightIntensity = (NdotL > 0.0) ? 1.0 : 0.0;
|
float NdotL = dot(N, L);
|
||||||
return float4(albedo * (lightIntensity, 1.0);
|
float NdotH = max(dot(N, H), 0.0);
|
||||||
|
|
||||||
|
float lightIntensity;
|
||||||
|
if (Softness > 0.0)
|
||||||
|
{
|
||||||
|
lightIntensity = smoothstep(0, Softness, NdotL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lightIntensity = (NdotL > 0.0) ? 1.0 : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 light = lightIntensity * DirectionalLightColor;
|
||||||
|
|
||||||
|
float specularIntensity = pow(NdotH * lightIntensity, 32 * 32);
|
||||||
|
float specularSmooth = smoothstep(0.005, 0.01, specularIntensity);
|
||||||
|
|
||||||
|
float3 specular = specularSmooth * float3(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
|
float rimColor = float3(1.0, 1.0, 1.0);
|
||||||
|
float rimThreshold = 0.1;
|
||||||
|
float rimAmount = 0.76;
|
||||||
|
float rimDot = 1 - dot(V, N);
|
||||||
|
float rimIntensity = rimDot * pow(max(NdotL, 0.0), rimThreshold);
|
||||||
|
rimIntensity = smoothstep(rimAmount - 0.01, rimAmount + 0.01, rimIntensity);
|
||||||
|
float3 rim = rimIntensity * rimColor;
|
||||||
|
|
||||||
|
float3 color = albedo * (light + specular + rim);
|
||||||
|
|
||||||
|
return float4(color, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Technique Deferred_Toon
|
Technique Deferred_Toon
|
||||||
|
|
|
@ -9,15 +9,47 @@ namespace Kav
|
||||||
public VertexBuffer VertexBuffer { get; }
|
public VertexBuffer VertexBuffer { get; }
|
||||||
public Triangle[] Triangles { get; }
|
public Triangle[] Triangles { get; }
|
||||||
public Vector3[] Positions { get; }
|
public Vector3[] Positions { get; }
|
||||||
public Effect Effect { get; }
|
|
||||||
|
|
||||||
public MeshPart(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, Vector3[] positions, Triangle[] triangles, Effect effect)
|
private Texture2D albedoTexture = null;
|
||||||
|
private Texture2D normalTexture = null;
|
||||||
|
private Texture2D metallicRoughnessTexture = null;
|
||||||
|
|
||||||
|
public Texture2D AlbedoTexture
|
||||||
{
|
{
|
||||||
|
get { return DisableAlbedoMap ? null : albedoTexture; }
|
||||||
|
set { albedoTexture = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Texture2D NormalTexture
|
||||||
|
{
|
||||||
|
get { return DisableNormalMap ? null : normalTexture; }
|
||||||
|
set { normalTexture = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Texture2D MetallicRoughnessTexture
|
||||||
|
{
|
||||||
|
get { return DisableMetallicRoughnessMap ? null : metallicRoughnessTexture; }
|
||||||
|
set { metallicRoughnessTexture = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 Albedo { get; set; } = Vector3.One;
|
||||||
|
public float Metallic { get; set; } = 0.5f;
|
||||||
|
public float Roughness { get; set; } = 0.5f;
|
||||||
|
|
||||||
|
public bool DisableAlbedoMap { get; set; } = false;
|
||||||
|
public bool DisableNormalMap { get; set; } = false;
|
||||||
|
public bool DisableMetallicRoughnessMap { get; set; } = false;
|
||||||
|
|
||||||
|
public MeshPart(
|
||||||
|
VertexBuffer vertexBuffer,
|
||||||
|
IndexBuffer indexBuffer,
|
||||||
|
Vector3[] positions,
|
||||||
|
Triangle[] triangles
|
||||||
|
) {
|
||||||
VertexBuffer = vertexBuffer;
|
VertexBuffer = vertexBuffer;
|
||||||
IndexBuffer = indexBuffer;
|
IndexBuffer = indexBuffer;
|
||||||
Positions = positions;
|
Positions = positions;
|
||||||
Triangles = triangles;
|
Triangles = triangles;
|
||||||
Effect = effect;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,59 @@ namespace Kav
|
||||||
{
|
{
|
||||||
public Mesh[] Meshes { get; }
|
public Mesh[] Meshes { get; }
|
||||||
|
|
||||||
|
private Color albedoValue;
|
||||||
|
|
||||||
|
public Color Albedo
|
||||||
|
{
|
||||||
|
get { return albedoValue; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
foreach (var mesh in Meshes)
|
||||||
|
{
|
||||||
|
foreach (var meshPart in mesh.MeshParts)
|
||||||
|
{
|
||||||
|
meshPart.Albedo = value.ToVector3();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Model(Mesh[] meshes)
|
public Model(Mesh[] meshes)
|
||||||
{
|
{
|
||||||
Meshes = meshes;
|
Meshes = meshes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DisableAlbedoMaps()
|
||||||
|
{
|
||||||
|
foreach (var mesh in Meshes)
|
||||||
|
{
|
||||||
|
foreach (var meshPart in mesh.MeshParts)
|
||||||
|
{
|
||||||
|
meshPart.DisableAlbedoMap = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisableNormalMaps()
|
||||||
|
{
|
||||||
|
foreach (var mesh in Meshes)
|
||||||
|
{
|
||||||
|
foreach (var meshPart in mesh.MeshParts)
|
||||||
|
{
|
||||||
|
meshPart.DisableNormalMap = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisableMetallicRoughnessMaps()
|
||||||
|
{
|
||||||
|
foreach (var mesh in Meshes)
|
||||||
|
{
|
||||||
|
foreach (var meshPart in mesh.MeshParts)
|
||||||
|
{
|
||||||
|
meshPart.DisableMetallicRoughnessMap = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,19 +15,6 @@ namespace Kav
|
||||||
|
|
||||||
foreach (var meshPartData in meshData.MeshParts)
|
foreach (var meshPartData in meshData.MeshParts)
|
||||||
{
|
{
|
||||||
var effect = new Kav.DeferredPBR_GBufferEffect(
|
|
||||||
graphicsDevice
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Albedo = meshPartData.Albedo,
|
|
||||||
Metallic = meshPartData.Metallic,
|
|
||||||
Roughness = meshPartData.Roughness,
|
|
||||||
|
|
||||||
AlbedoTexture = meshPartData.AlbedoTexture,
|
|
||||||
NormalTexture = meshPartData.NormalTexture,
|
|
||||||
MetallicRoughnessTexture = meshPartData.MetallicRoughnessTexture
|
|
||||||
};
|
|
||||||
|
|
||||||
var triangles = new Kav.Triangle[meshPartData.Triangles.Length];
|
var triangles = new Kav.Triangle[meshPartData.Triangles.Length];
|
||||||
for (int i = 0; i < meshPartData.Triangles.Length; i++)
|
for (int i = 0; i < meshPartData.Triangles.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -40,13 +27,22 @@ namespace Kav
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
meshParts.Add(new Kav.MeshPart(
|
var meshPart = new Kav.MeshPart(
|
||||||
meshPartData.VertexBuffer,
|
meshPartData.VertexBuffer,
|
||||||
meshPartData.IndexBuffer,
|
meshPartData.IndexBuffer,
|
||||||
meshPartData.Positions,
|
meshPartData.Positions,
|
||||||
triangles,
|
triangles
|
||||||
effect
|
);
|
||||||
));
|
|
||||||
|
meshPart.Albedo = meshPartData.Albedo;
|
||||||
|
meshPart.Metallic = meshPartData.Metallic;
|
||||||
|
meshPart.Roughness = meshPartData.Roughness;
|
||||||
|
|
||||||
|
meshPart.AlbedoTexture = meshPartData.AlbedoTexture;
|
||||||
|
meshPart.NormalTexture = meshPartData.NormalTexture;
|
||||||
|
meshPart.MetallicRoughnessTexture = meshPartData.MetallicRoughnessTexture;
|
||||||
|
|
||||||
|
meshParts.Add(meshPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
meshes.Add(new Kav.Mesh(meshParts.ToArray()));
|
meshes.Add(new Kav.Mesh(meshParts.ToArray()));
|
||||||
|
|
98
Renderer.cs
98
Renderer.cs
|
@ -21,6 +21,8 @@ namespace Kav
|
||||||
private RenderTarget2D[] ShadowRenderTargets { get; }
|
private RenderTarget2D[] ShadowRenderTargets { get; }
|
||||||
|
|
||||||
private DeferredPBREffect DeferredPBREffect { get; }
|
private DeferredPBREffect DeferredPBREffect { get; }
|
||||||
|
/* FIXME: these next two dont actually have anything to do with PBR */
|
||||||
|
private DeferredPBR_GBufferEffect Deferred_GBufferEffect { get; }
|
||||||
private DeferredPBR_AmbientLightEffect DeferredAmbientLightEffect { get; }
|
private DeferredPBR_AmbientLightEffect DeferredAmbientLightEffect { get; }
|
||||||
private DeferredPBR_PointLightEffect DeferredPointLightEffect { get; }
|
private DeferredPBR_PointLightEffect DeferredPointLightEffect { get; }
|
||||||
private DeferredPBR_DirectionalLightEffect DeferredDirectionalLightEffect { get; }
|
private DeferredPBR_DirectionalLightEffect DeferredDirectionalLightEffect { get; }
|
||||||
|
@ -132,6 +134,8 @@ namespace Kav
|
||||||
|
|
||||||
SimpleDepthEffect = new SimpleDepthEffect(GraphicsDevice);
|
SimpleDepthEffect = new SimpleDepthEffect(GraphicsDevice);
|
||||||
DeferredPBREffect = new DeferredPBREffect(GraphicsDevice);
|
DeferredPBREffect = new DeferredPBREffect(GraphicsDevice);
|
||||||
|
|
||||||
|
Deferred_GBufferEffect = new DeferredPBR_GBufferEffect(GraphicsDevice);
|
||||||
DeferredAmbientLightEffect = new DeferredPBR_AmbientLightEffect(GraphicsDevice);
|
DeferredAmbientLightEffect = new DeferredPBR_AmbientLightEffect(GraphicsDevice);
|
||||||
DeferredPointLightEffect = new DeferredPBR_PointLightEffect(GraphicsDevice);
|
DeferredPointLightEffect = new DeferredPBR_PointLightEffect(GraphicsDevice);
|
||||||
DeferredDirectionalLightEffect = new DeferredPBR_DirectionalLightEffect(GraphicsDevice);
|
DeferredDirectionalLightEffect = new DeferredPBR_DirectionalLightEffect(GraphicsDevice);
|
||||||
|
@ -199,7 +203,7 @@ namespace Kav
|
||||||
|
|
||||||
GraphicsDevice.SetRenderTarget(null);
|
GraphicsDevice.SetRenderTarget(null);
|
||||||
GraphicsDevice.Clear(Color.Black);
|
GraphicsDevice.Clear(Color.Black);
|
||||||
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, ToneMapEffect);
|
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, null);
|
||||||
SpriteBatch.Draw(ColorRenderTarget, Vector2.Zero, Color.White);
|
SpriteBatch.Draw(ColorRenderTarget, Vector2.Zero, Color.White);
|
||||||
SpriteBatch.End();
|
SpriteBatch.End();
|
||||||
}
|
}
|
||||||
|
@ -219,17 +223,22 @@ namespace Kav
|
||||||
{
|
{
|
||||||
foreach (var meshPart in modelMesh.MeshParts)
|
foreach (var meshPart in modelMesh.MeshParts)
|
||||||
{
|
{
|
||||||
|
Deferred_GBufferEffect.World = transform;
|
||||||
|
Deferred_GBufferEffect.View = camera.View;
|
||||||
|
Deferred_GBufferEffect.Projection = camera.Projection;
|
||||||
|
|
||||||
|
Deferred_GBufferEffect.Albedo = meshPart.Albedo;
|
||||||
|
Deferred_GBufferEffect.Metallic = meshPart.Metallic;
|
||||||
|
Deferred_GBufferEffect.Roughness = meshPart.Roughness;
|
||||||
|
|
||||||
|
Deferred_GBufferEffect.AlbedoTexture = meshPart.AlbedoTexture;
|
||||||
|
Deferred_GBufferEffect.NormalTexture = meshPart.NormalTexture;
|
||||||
|
Deferred_GBufferEffect.MetallicRoughnessTexture = meshPart.MetallicRoughnessTexture;
|
||||||
|
|
||||||
GraphicsDevice.SetVertexBuffer(meshPart.VertexBuffer);
|
GraphicsDevice.SetVertexBuffer(meshPart.VertexBuffer);
|
||||||
GraphicsDevice.Indices = meshPart.IndexBuffer;
|
GraphicsDevice.Indices = meshPart.IndexBuffer;
|
||||||
|
|
||||||
if (meshPart.Effect is TransformEffect transformEffect)
|
foreach (var pass in Deferred_GBufferEffect.CurrentTechnique.Passes)
|
||||||
{
|
|
||||||
transformEffect.World = transform;
|
|
||||||
transformEffect.View = camera.View;
|
|
||||||
transformEffect.Projection = camera.Projection;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var pass in meshPart.Effect.CurrentTechnique.Passes)
|
|
||||||
{
|
{
|
||||||
pass.Apply();
|
pass.Apply();
|
||||||
|
|
||||||
|
@ -353,12 +362,16 @@ namespace Kav
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
DirectionalLight directionalLight
|
DirectionalLight directionalLight
|
||||||
) {
|
) {
|
||||||
Deferred_ToonEffect.EyePosition = camera.Position;
|
|
||||||
Deferred_ToonEffect.DirectionalLightDirection = directionalLight.Direction;
|
|
||||||
|
|
||||||
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
|
||||||
GraphicsDevice.BlendState = BlendState.Additive;
|
GraphicsDevice.BlendState = BlendState.Additive;
|
||||||
|
|
||||||
|
Deferred_ToonEffect.EyePosition = camera.Position;
|
||||||
|
Deferred_ToonEffect.DirectionalLightDirection = directionalLight.Direction;
|
||||||
|
Deferred_ToonEffect.DirectionalLightColor =
|
||||||
|
directionalLight.Color.ToVector3() * directionalLight.Intensity;
|
||||||
|
|
||||||
|
Deferred_ToonEffect.Softness = 0.01f;
|
||||||
|
|
||||||
foreach (EffectPass pass in Deferred_ToonEffect.CurrentTechnique.Passes)
|
foreach (EffectPass pass in Deferred_ToonEffect.CurrentTechnique.Passes)
|
||||||
{
|
{
|
||||||
pass.Apply();
|
pass.Apply();
|
||||||
|
@ -456,66 +469,5 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Render(
|
|
||||||
PerspectiveCamera camera,
|
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
|
||||||
IEnumerable<PointLight> pointLights,
|
|
||||||
IEnumerable<DirectionalLight> directionalLights
|
|
||||||
) {
|
|
||||||
Render(camera.View, camera.Projection, modelTransforms, pointLights, directionalLights);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Render(
|
|
||||||
Matrix view,
|
|
||||||
Matrix projection,
|
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms,
|
|
||||||
IEnumerable<PointLight> pointLights,
|
|
||||||
IEnumerable<DirectionalLight> directionalLights
|
|
||||||
) {
|
|
||||||
foreach (var (model, transform) in modelTransforms)
|
|
||||||
{
|
|
||||||
foreach (var modelMesh in model.Meshes)
|
|
||||||
{
|
|
||||||
foreach (var meshPart in modelMesh.MeshParts)
|
|
||||||
{
|
|
||||||
GraphicsDevice.SetVertexBuffer(meshPart.VertexBuffer);
|
|
||||||
GraphicsDevice.Indices = meshPart.IndexBuffer;
|
|
||||||
|
|
||||||
if (meshPart.Effect is TransformEffect transformEffect)
|
|
||||||
{
|
|
||||||
transformEffect.World = transform;
|
|
||||||
transformEffect.View = view;
|
|
||||||
transformEffect.Projection = projection;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meshPart.Effect is PointLightEffect pointLightEffect)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
foreach (var pointLight in pointLights)
|
|
||||||
{
|
|
||||||
if (i > pointLightEffect.MaxPointLights) { break; }
|
|
||||||
pointLightEffect.PointLights[i] = pointLight;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var pass in meshPart.Effect.CurrentTechnique.Passes)
|
|
||||||
{
|
|
||||||
pass.Apply();
|
|
||||||
|
|
||||||
GraphicsDevice.DrawIndexedPrimitives(
|
|
||||||
PrimitiveType.TriangleList,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
meshPart.VertexBuffer.VertexCount,
|
|
||||||
0,
|
|
||||||
meshPart.Triangles.Length
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue