basic toon shading + controllable ambient light setting
							parent
							
								
									66d4e5bf6e
								
							
						
					
					
						commit
						565be374bb
					
				|  | @ -1,3 +1,4 @@ | |||
| using Microsoft.Xna.Framework; | ||||
| using Microsoft.Xna.Framework.Graphics; | ||||
| 
 | ||||
| namespace Kav | ||||
|  | @ -8,9 +9,13 @@ namespace Kav | |||
|         EffectParameter gPositionParam; | ||||
|         EffectParameter gAlbedoParam; | ||||
| 
 | ||||
|         EffectParameter ambientColorParam; | ||||
| 
 | ||||
|         public Texture2D GPosition { get; set; } | ||||
|         public Texture2D GAlbedo { get; set; } | ||||
| 
 | ||||
|         public Vector3 AmbientColor { get; set; } | ||||
| 
 | ||||
|         public DeferredPBR_AmbientLightEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DeferredPBR_AmbientLightEffect) | ||||
|         { | ||||
|             CacheEffectParameters(); | ||||
|  | @ -20,12 +25,14 @@ namespace Kav | |||
|         { | ||||
|             gPositionParam.SetValue(GPosition); | ||||
|             gAlbedoParam.SetValue(GAlbedo); | ||||
|             ambientColorParam.SetValue(AmbientColor); | ||||
|         } | ||||
| 
 | ||||
|         void CacheEffectParameters() | ||||
|         { | ||||
|             gPositionParam                 = Parameters["gPosition"]; | ||||
|             gAlbedoParam                   = Parameters["gAlbedo"]; | ||||
|             gPositionParam    = Parameters["gPosition"]; | ||||
|             gAlbedoParam      = Parameters["gAlbedo"]; | ||||
|             ambientColorParam = Parameters["AmbientLightColor"]; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,47 @@ | |||
| using Microsoft.Xna.Framework; | ||||
| using Microsoft.Xna.Framework.Graphics; | ||||
| 
 | ||||
| namespace Kav | ||||
| { | ||||
|     public class Deferred_ToonEffect : Effect | ||||
|     { | ||||
|         EffectParameter gPositionParam; | ||||
|         EffectParameter gAlbedoParam; | ||||
|         EffectParameter gNormalParam; | ||||
| 
 | ||||
|         EffectParameter eyePositionParam; | ||||
|         EffectParameter directionalLightDirectionParam; | ||||
| 
 | ||||
|         public Texture2D GPosition { get; set; } | ||||
|         public Texture2D GAlbedo { get; set; } | ||||
|         public Texture2D GNormal { get; set; } | ||||
| 
 | ||||
|         public Vector3 EyePosition { get; set; } | ||||
|         public Vector3 DirectionalLightDirection { get; set; } | ||||
| 
 | ||||
|         public Deferred_ToonEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.Deferred_ToonEffect) | ||||
|         { | ||||
|             CacheEffectParameters();    | ||||
|         } | ||||
| 
 | ||||
|         protected override void OnApply() | ||||
|         { | ||||
|             gPositionParam.SetValue(GPosition); | ||||
|             gAlbedoParam.SetValue(GAlbedo); | ||||
|             gNormalParam.SetValue(GNormal); | ||||
|              | ||||
|             eyePositionParam.SetValue(EyePosition); | ||||
|             directionalLightDirectionParam.SetValue(DirectionalLightDirection); | ||||
|         } | ||||
| 
 | ||||
|         void CacheEffectParameters() | ||||
|         { | ||||
|             gPositionParam                 = Parameters["gPosition"]; | ||||
|             gAlbedoParam                   = Parameters["gAlbedo"]; | ||||
|             gNormalParam                   = Parameters["gNormal"]; | ||||
| 
 | ||||
|             eyePositionParam               = Parameters["EyePosition"]; | ||||
|             directionalLightDirectionParam = Parameters["DirectionalLightDirection"]; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								Effects/FXB/DeferredPBR_AmbientLightEffect.fxb (Stored with Git LFS)
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								Effects/FXB/DeferredPBR_AmbientLightEffect.fxb (Stored with Git LFS)
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -3,6 +3,12 @@ | |||
| DECLARE_TEXTURE(gPosition, 0); | ||||
| DECLARE_TEXTURE(gAlbedo, 1); | ||||
| 
 | ||||
| BEGIN_CONSTANTS | ||||
| 
 | ||||
| float3 AmbientLightColor _ps(c0)   _cb(c0); | ||||
| 
 | ||||
| END_CONSTANTS | ||||
| 
 | ||||
| struct VertexInput | ||||
| { | ||||
|     float4 Position : POSITION; | ||||
|  | @ -29,7 +35,7 @@ float4 ComputeColor( | |||
|     float3 worldPosition, | ||||
|     float3 albedo | ||||
| ) { | ||||
|     float3 color = float3(0.03, 0.03, 0.03) * albedo; | ||||
|     float3 color = AmbientLightColor * albedo; | ||||
|     return float4(color, 1.0); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,60 @@ | |||
| #include "Macros.fxh" | ||||
| 
 | ||||
| DECLARE_TEXTURE(gPosition, 0); | ||||
| DECLARE_TEXTURE(gAlbedo, 1); | ||||
| DECLARE_TEXTURE(gNormal, 2); | ||||
| 
 | ||||
| BEGIN_CONSTANTS | ||||
| 
 | ||||
| float3 EyePosition                  _ps(c0)     _cb(c0); | ||||
| 
 | ||||
| float3 DirectionalLightDirection    _ps(c1)     _cb(c1); | ||||
| float3 AmbientLightColor            _ps(c2)     _cb(c2); | ||||
| 
 | ||||
| END_CONSTANTS | ||||
| 
 | ||||
| struct VertexInput | ||||
| { | ||||
|     float4 Position : POSITION; | ||||
|     float2 TexCoord : TEXCOORD; | ||||
| }; | ||||
| 
 | ||||
| struct PixelInput | ||||
| { | ||||
|     float4 Position : SV_POSITION; | ||||
|     float2 TexCoord : TEXCOORD0; | ||||
| }; | ||||
| 
 | ||||
| PixelInput main_vs(VertexInput input) | ||||
| { | ||||
|     PixelInput output; | ||||
| 
 | ||||
|     output.Position = input.Position; | ||||
|     output.TexCoord = input.TexCoord; | ||||
| 
 | ||||
|     return output; | ||||
| } | ||||
| 
 | ||||
| float4 main_ps(PixelInput input) : SV_TARGET0 | ||||
| { | ||||
|     float3 worldPosition = SAMPLE_TEXTURE(gPosition, input.TexCoord).rgb; | ||||
|     float3 normal = SAMPLE_TEXTURE(gNormal, input.TexCoord).xyz; | ||||
|     float3 albedo = SAMPLE_TEXTURE(gAlbedo, input.TexCoord).rgb; | ||||
| 
 | ||||
|     float3 V = normalize(EyePosition - worldPosition); | ||||
|     float3 L = normalize(DirectionalLightDirection); | ||||
|     float3 N = normalize(normal); | ||||
|     float NdotL = dot(N, L); | ||||
| 
 | ||||
|     float lightIntensity = (NdotL > 0.0) ? 1.0 : 0.0; | ||||
|     return float4(albedo * (lightIntensity, 1.0); | ||||
| } | ||||
| 
 | ||||
| Technique Deferred_Toon | ||||
| { | ||||
|     Pass | ||||
|     { | ||||
|         VertexShader = compile vs_3_0 main_vs(); | ||||
|         PixelShader = compile ps_3_0 main_ps(); | ||||
|     } | ||||
| } | ||||
|  | @ -30,6 +30,9 @@ | |||
|     <EmbeddedResource Include="Effects\FXB\ToneMapEffect.fxb"> | ||||
|       <LogicalName>Kav.Resources.ToneMapEffect.fxb</LogicalName> | ||||
|     </EmbeddedResource> | ||||
|     <EmbeddedResource Include="Effects\FXB\Deferred_ToonEffect.fxb"> | ||||
|       <LogicalName>Kav.Resources.Deferred_ToonEffect.fxb</LogicalName> | ||||
|     </EmbeddedResource> | ||||
|     <EmbeddedResource Include="Effects\FXB\DeferredPBREffect.fxb"> | ||||
|       <LogicalName>Kav.Resources.DeferredPBREffect.fxb</LogicalName> | ||||
|     </EmbeddedResource> | ||||
|  |  | |||
|  | @ -30,6 +30,9 @@ | |||
|     <EmbeddedResource Include="Effects\FXB\ToneMapEffect.fxb"> | ||||
|       <LogicalName>Kav.Resources.ToneMapEffect.fxb</LogicalName> | ||||
|     </EmbeddedResource> | ||||
|     <EmbeddedResource Include="Effects\FXB\Deferred_ToonEffect.fxb"> | ||||
|       <LogicalName>Kav.Resources.Deferred_ToonEffect.fxb</LogicalName> | ||||
|     </EmbeddedResource> | ||||
|     <EmbeddedResource Include="Effects\FXB\DeferredPBREffect.fxb"> | ||||
|       <LogicalName>Kav.Resources.DeferredPBREffect.fxb</LogicalName> | ||||
|     </EmbeddedResource> | ||||
|  |  | |||
|  | @ -0,0 +1,14 @@ | |||
| using Microsoft.Xna.Framework; | ||||
| 
 | ||||
| namespace Kav | ||||
| { | ||||
|     public struct AmbientLight | ||||
|     { | ||||
|         public Color Color { get; set; } | ||||
| 
 | ||||
|         public AmbientLight(Color color) | ||||
|         { | ||||
|             Color = color; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -4,9 +4,9 @@ namespace Kav | |||
| { | ||||
|     public struct DirectionalLight | ||||
|     { | ||||
|         public Vector3 Direction { get; set; } | ||||
|         public Color Color { get; set; } | ||||
|         public float Intensity { get; set; } | ||||
|         public Vector3 Direction { get; } | ||||
|         public Color Color { get; } | ||||
|         public float Intensity { get; } | ||||
| 
 | ||||
|         public Matrix View | ||||
|         { | ||||
|  |  | |||
							
								
								
									
										98
									
								
								Renderer.cs
								
								
								
								
							
							
						
						
									
										98
									
								
								Renderer.cs
								
								
								
								
							|  | @ -24,6 +24,7 @@ namespace Kav | |||
|         private DeferredPBR_AmbientLightEffect DeferredAmbientLightEffect { get; } | ||||
|         private DeferredPBR_PointLightEffect DeferredPointLightEffect { get; } | ||||
|         private DeferredPBR_DirectionalLightEffect DeferredDirectionalLightEffect { get; } | ||||
|         private Deferred_ToonEffect Deferred_ToonEffect { get; } | ||||
|         private SimpleDepthEffect SimpleDepthEffect { get; } | ||||
|         private Effect ToneMapEffect { get; } | ||||
| 
 | ||||
|  | @ -136,6 +137,7 @@ namespace Kav | |||
|             DeferredDirectionalLightEffect = new DeferredPBR_DirectionalLightEffect(GraphicsDevice); | ||||
|             DeferredDirectionalLightEffect.ShadowMapSize = ShadowMapSize; | ||||
|             ToneMapEffect = new Effect(graphicsDevice, Resources.ToneMapEffect); | ||||
|             Deferred_ToonEffect = new Deferred_ToonEffect(GraphicsDevice); | ||||
| 
 | ||||
|             FullscreenTriangle = new VertexBuffer(GraphicsDevice, typeof(VertexPositionTexture), 3, BufferUsage.WriteOnly); | ||||
|             FullscreenTriangle.SetData(new VertexPositionTexture[3] { | ||||
|  | @ -150,11 +152,62 @@ namespace Kav | |||
|         public void DeferredRender( | ||||
|             PerspectiveCamera camera, | ||||
|             IEnumerable<(Model, Matrix)> modelTransforms, | ||||
|             AmbientLight ambientLight, | ||||
|             IEnumerable<PointLight> pointLights, | ||||
|             DirectionalLight directionalLight | ||||
|         ) { | ||||
|             // g-buffer pass | ||||
|             GBufferRender(camera, modelTransforms); | ||||
| 
 | ||||
|             GraphicsDevice.SetRenderTarget(ColorRenderTarget); | ||||
|             GraphicsDevice.Clear(Color.Black); | ||||
| 
 | ||||
|             AmbientLightRender(ambientLight); | ||||
| 
 | ||||
|             DeferredPointLightEffect.EyePosition = camera.Position; | ||||
| 
 | ||||
|             foreach (var pointLight in pointLights) | ||||
|             { | ||||
|                 PointLightRender(pointLight); | ||||
|             } | ||||
| 
 | ||||
|             DirectionalLightRender(camera, modelTransforms, directionalLight); | ||||
| 
 | ||||
|             GraphicsDevice.SetRenderTarget(null); | ||||
|             GraphicsDevice.Clear(Color.Black); | ||||
|             SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, ToneMapEffect); | ||||
|             SpriteBatch.Draw(ColorRenderTarget, Vector2.Zero, Color.White); | ||||
|             SpriteBatch.End(); | ||||
|         } | ||||
| 
 | ||||
|         public void DeferredToonRender( | ||||
|             PerspectiveCamera camera, | ||||
|             IEnumerable<(Model, Matrix)> modelTransforms, | ||||
|             AmbientLight ambientLight, | ||||
|             DirectionalLight directionalLight | ||||
|         ) { | ||||
|             GBufferRender(camera, modelTransforms); | ||||
|              | ||||
|             GraphicsDevice.SetRenderTarget(ColorRenderTarget); | ||||
|             GraphicsDevice.Clear(Color.Black); | ||||
| 
 | ||||
|             AmbientLightRender(ambientLight); | ||||
| 
 | ||||
|             Deferred_ToonEffect.GPosition = gPosition; | ||||
|             Deferred_ToonEffect.GAlbedo = gAlbedo; | ||||
|             Deferred_ToonEffect.GNormal = gNormal; | ||||
|             DirectionalLightToonRender(camera, directionalLight); | ||||
| 
 | ||||
|             GraphicsDevice.SetRenderTarget(null); | ||||
|             GraphicsDevice.Clear(Color.Black); | ||||
|             SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, ToneMapEffect); | ||||
|             SpriteBatch.Draw(ColorRenderTarget, Vector2.Zero, Color.White); | ||||
|             SpriteBatch.End(); | ||||
|         } | ||||
| 
 | ||||
|         private void GBufferRender( | ||||
|             PerspectiveCamera camera, | ||||
|             IEnumerable<(Model, Matrix)> modelTransforms | ||||
|         ) { | ||||
|             GraphicsDevice.SetRenderTargets(GBuffer); | ||||
|             GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1f, 0); | ||||
|             GraphicsDevice.DepthStencilState = DepthStencilState.Default; | ||||
|  | @ -192,14 +245,17 @@ namespace Kav | |||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void AmbientLightRender(AmbientLight ambientLight) | ||||
|         { | ||||
|             GraphicsDevice.SetRenderTarget(ColorRenderTarget); | ||||
|             GraphicsDevice.Clear(Color.Black); | ||||
|             GraphicsDevice.BlendState = BlendState.Additive; | ||||
|             GraphicsDevice.DepthStencilState = DepthStencilState.None; | ||||
| 
 | ||||
|             DeferredAmbientLightEffect.GPosition = gPosition; | ||||
|             DeferredAmbientLightEffect.GAlbedo = gAlbedo; | ||||
|             DeferredAmbientLightEffect.AmbientColor = ambientLight.Color.ToVector3(); | ||||
| 
 | ||||
|             foreach (var pass in DeferredAmbientLightEffect.CurrentTechnique.Passes) | ||||
|             { | ||||
|  | @ -207,26 +263,6 @@ namespace Kav | |||
|                 GraphicsDevice.SetVertexBuffer(FullscreenTriangle); | ||||
|                 GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1); | ||||
|             } | ||||
| 
 | ||||
|             DeferredPointLightEffect.EyePosition = camera.Position; | ||||
| 
 | ||||
|             foreach (var pointLight in pointLights) | ||||
|             { | ||||
|                 PointLightRender(pointLight); | ||||
|             } | ||||
| 
 | ||||
|             DirectionalLightRender(camera, modelTransforms, directionalLight); | ||||
|             // return; | ||||
|             // GraphicsDevice.SetRenderTarget(null); | ||||
|             // SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied); | ||||
|             // SpriteBatch.Draw(DirectionalRenderTarget, Vector2.Zero, Color.White); | ||||
|             // SpriteBatch.End(); | ||||
| 
 | ||||
|             GraphicsDevice.SetRenderTarget(null); | ||||
|             GraphicsDevice.Clear(Color.Black); | ||||
|             SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, ToneMapEffect); | ||||
|             SpriteBatch.Draw(ColorRenderTarget, Vector2.Zero, Color.White); | ||||
|             SpriteBatch.End(); | ||||
|         } | ||||
| 
 | ||||
|         private void PointLightRender(PointLight pointLight)  | ||||
|  | @ -313,6 +349,24 @@ namespace Kav | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void DirectionalLightToonRender( | ||||
|             PerspectiveCamera camera, | ||||
|             DirectionalLight directionalLight | ||||
|         ) { | ||||
|             Deferred_ToonEffect.EyePosition = camera.Position; | ||||
|             Deferred_ToonEffect.DirectionalLightDirection = directionalLight.Direction; | ||||
| 
 | ||||
|             GraphicsDevice.SetRenderTarget(ColorRenderTarget); | ||||
|             GraphicsDevice.BlendState = BlendState.Additive; | ||||
| 
 | ||||
|             foreach (EffectPass pass in Deferred_ToonEffect.CurrentTechnique.Passes) | ||||
|             { | ||||
|                 pass.Apply(); | ||||
|                 GraphicsDevice.SetVertexBuffer(FullscreenTriangle); | ||||
|                 GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void RenderShadowMap( | ||||
|             PerspectiveCamera camera,  | ||||
|             IEnumerable<(Model, Matrix)> modelTransforms,  | ||||
|  |  | |||
							
								
								
									
										13
									
								
								Resources.cs
								
								
								
								
							
							
						
						
									
										13
									
								
								Resources.cs
								
								
								
								
							|  | @ -63,6 +63,18 @@ namespace Kav | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static byte[] Deferred_ToonEffect | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (deferredToonEffect == null) | ||||
|                 { | ||||
|                     deferredToonEffect = GetResource("Deferred_ToonEffect"); | ||||
|                 } | ||||
|                 return deferredToonEffect; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static byte[] DeferredPBREffect | ||||
|         { | ||||
|             get | ||||
|  | @ -104,6 +116,7 @@ namespace Kav | |||
|         private static byte[] directionalLightEffect; | ||||
|         private static byte[] gBufferEffect; | ||||
|         private static byte[] toneMapEffect; | ||||
|         private static byte[] deferredToonEffect; | ||||
|         private static byte[] deferredPBREffect; | ||||
|         private static byte[] pbrEffect; | ||||
|         private static byte[] simpleDepthEffect; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue