diff --git a/P3D/Battle/BattleSystemV2/BattleScreen.vb b/P3D/Battle/BattleSystemV2/BattleScreen.vb index c928ae1c5..7d056181b 100644 --- a/P3D/Battle/BattleSystemV2/BattleScreen.vb +++ b/P3D/Battle/BattleSystemV2/BattleScreen.vb @@ -153,7 +153,7 @@ Screen.ImageView.Showing = False Screen.ChooseBox.Showing = False - Effect = New BasicEffect(Core.GraphicsDevice) + Effect = New BasicEffectWithAlphaTest(Core.GraphicsDevice) Effect.FogEnabled = True SkyDome = New SkyDome() Camera = New BattleCamera() diff --git a/P3D/Content/Effects/BasicEffectWithAlphaTest.mgfxdx b/P3D/Content/Effects/BasicEffectWithAlphaTest.mgfxdx new file mode 100644 index 000000000..fee6ce8d1 Binary files /dev/null and b/P3D/Content/Effects/BasicEffectWithAlphaTest.mgfxdx differ diff --git a/P3D/Overworld/OverworldScreen.vb b/P3D/Overworld/OverworldScreen.vb index 018a12405..0236bd413 100644 --- a/P3D/Overworld/OverworldScreen.vb +++ b/P3D/Overworld/OverworldScreen.vb @@ -122,7 +122,7 @@ Public Class OverworldScreen Me.MouseVisible = False 'Set up 3D environment variables (Effect, Camera, SkyDome and Level): - Effect = New BasicEffect(Core.GraphicsDevice) + Effect = New BasicEffectWithAlphaTest(Core.GraphicsDevice) Effect.FogEnabled = True Camera = New OverworldCamera() diff --git a/P3D/Overworld/OverworldStorage.vb b/P3D/Overworld/OverworldStorage.vb index 48ccd03fc..6a08bf048 100644 --- a/P3D/Overworld/OverworldStorage.vb +++ b/P3D/Overworld/OverworldStorage.vb @@ -6,7 +6,7 @@ Public Class OverworldStorage Public OverworldScreen As Screen Public Level As Level Public Camera As Camera - Public Effect As BasicEffect + Public Effect As BasicEffectWithAlphaTest Public SkyDome As SkyDome ''' diff --git a/P3D/Overworld/SecretBase/SecretBaseScreen.vb b/P3D/Overworld/SecretBase/SecretBaseScreen.vb index 38b228b16..49333db1a 100644 --- a/P3D/Overworld/SecretBase/SecretBaseScreen.vb +++ b/P3D/Overworld/SecretBase/SecretBaseScreen.vb @@ -16,7 +16,7 @@ Me.SecretBase = New SecretBase() - Effect = New BasicEffect(Core.GraphicsDevice) + Effect = New BasicEffectWithAlphaTest(Core.GraphicsDevice) Camera = New SecretBaseCamera() Level = New Level() diff --git a/P3D/P3D.vbproj b/P3D/P3D.vbproj index 77ab3290b..46b449f16 100644 --- a/P3D/P3D.vbproj +++ b/P3D/P3D.vbproj @@ -10997,6 +10997,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -32572,6 +32575,8 @@ + + diff --git a/P3D/Resources/Shader/BasicEffectWithAlphaTest.vb b/P3D/Resources/Shader/BasicEffectWithAlphaTest.vb new file mode 100644 index 000000000..b51585a03 --- /dev/null +++ b/P3D/Resources/Shader/BasicEffectWithAlphaTest.vb @@ -0,0 +1,358 @@ +Imports System +Imports System.IO +Imports Microsoft.Xna.Framework +Imports Microsoft.Xna.Framework.Graphics + +Public NotInheritable Class BasicEffectWithAlphaTest + Inherits Effect + Implements IEffectMatrices, IEffectLights, IEffectFog + + Public Property DirectionalLight0 As DirectionalLight Implements IEffectLights.DirectionalLight0 + Public Property DirectionalLight1 As DirectionalLight Implements IEffectLights.DirectionalLight1 + Public Property DirectionalLight2 As DirectionalLight Implements IEffectLights.DirectionalLight2 + + Public Property World As Matrix Implements IEffectMatrices.World + Get + Return _world + End Get + Set(ByVal value As Matrix) + _world = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.World Or EffectDirtyFlags.WorldViewProj Or EffectDirtyFlags.Fog + End Set + End Property + + Public Property View As Matrix Implements IEffectMatrices.View + Get + Return _view + End Get + Set(ByVal value As Matrix) + _view = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.WorldViewProj Or EffectDirtyFlags.EyePosition Or EffectDirtyFlags.Fog + End Set + End Property + + Public Property Projection As Matrix Implements IEffectMatrices.Projection + Get + Return _projection + End Get + Set(ByVal value As Matrix) + _projection = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.WorldViewProj + End Set + End Property + + Public Property DiffuseColor As Vector3 + Get + Return _diffuseColor + End Get + Set(ByVal value As Vector3) + _diffuseColor = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.MaterialColor + End Set + End Property + + Public Property EmissiveColor As Vector3 + Get + Return _emissiveColor + End Get + Set(ByVal value As Vector3) + _emissiveColor = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.MaterialColor + End Set + End Property + + Public Property SpecularColor As Vector3 + Get + Return _specularColorParam.GetValueVector3() + End Get + Set(ByVal value As Vector3) + _specularColorParam.SetValue(value) + End Set + End Property + + Public Property SpecularPower As Single + Get + Return _specularPowerParam.GetValueSingle() + End Get + Set(ByVal value As Single) + _specularPowerParam.SetValue(value) + End Set + End Property + + Public Property Alpha As Single + Get + Return _alpha + End Get + Set(ByVal value As Single) + _alpha = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.MaterialColor + End Set + End Property + + Public Property LightingEnabled As Boolean Implements IEffectLights.LightingEnabled + Get + Return _lightingEnabled + End Get + Set(ByVal value As Boolean) + If _lightingEnabled <> value Then + _lightingEnabled = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.ShaderIndex Or EffectDirtyFlags.MaterialColor + End If + End Set + End Property + + Public Property PreferPerPixelLighting As Boolean + Get + Return _preferPerPixelLighting + End Get + Set(ByVal value As Boolean) + If _preferPerPixelLighting <> value Then + _preferPerPixelLighting = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.ShaderIndex + End If + End Set + End Property + + Public Property AmbientLightColor As Vector3 Implements IEffectLights.AmbientLightColor + Get + Return _ambientLightColor + End Get + Set(ByVal value As Vector3) + _ambientLightColor = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.MaterialColor + End Set + End Property + + Public Property FogEnabled As Boolean Implements IEffectFog.FogEnabled + Get + Return _fogEnabled + End Get + Set(ByVal value As Boolean) + If _fogEnabled <> value Then + _fogEnabled = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.ShaderIndex Or EffectDirtyFlags.FogEnable + End If + End Set + End Property + + Public Property FogStart As Single Implements IEffectFog.FogStart + Get + Return _fogStart + End Get + Set(ByVal value As Single) + _fogStart = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.Fog + End Set + End Property + + Public Property FogEnd As Single Implements IEffectFog.FogEnd + Get + Return _fogEnd + End Get + Set(ByVal value As Single) + _fogEnd = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.Fog + End Set + End Property + + Public Property FogColor As Vector3 Implements IEffectFog.FogColor + Get + Return _fogColorParam.GetValueVector3() + End Get + Set(ByVal value As Vector3) + _fogColorParam.SetValue(value) + End Set + End Property + + Public Property TextureEnabled As Boolean + Get + Return _textureEnabled + End Get + Set(ByVal value As Boolean) + If _textureEnabled <> value Then + _textureEnabled = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.ShaderIndex + End If + End Set + End Property + + Public Property Texture As Texture2D + Get + Return _textureParam.GetValueTexture2D() + End Get + Set(ByVal value As Texture2D) + _textureParam.SetValue(value) + End Set + End Property + + Public Property VertexColorEnabled As Boolean + Get + Return _vertexColorEnabled + End Get + Set(ByVal value As Boolean) + If _vertexColorEnabled <> value Then + _vertexColorEnabled = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.ShaderIndex + End If + End Set + End Property + + Public Property AlphaCutoff As Single + Get + Return _alphaTestParam.GetValueSingle() + End Get + Set(ByVal value As Single) + _alphaTestParam.SetValue(value) + End Set + End Property + + Public Property EnableHardwareInstancing As Boolean + Get + Return _hwEnabled + End Get + Set(ByVal value As Boolean) + If _hwEnabled <> value Then + _hwEnabled = value + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.ShaderIndex + End If + End Set + End Property + + Private _textureParam As EffectParameter + Private _diffuseColorParam As EffectParameter + Private _emissiveColorParam As EffectParameter + Private _specularColorParam As EffectParameter + Private _specularPowerParam As EffectParameter + Private _eyePositionParam As EffectParameter + Private _fogColorParam As EffectParameter + Private _fogVectorParam As EffectParameter + Private _worldParam As EffectParameter + Private _worldInverseTransposeParam As EffectParameter + Private _worldViewProjParam As EffectParameter + Private _alphaTestParam As EffectParameter + Private _lightingEnabled As Boolean + Private _preferPerPixelLighting As Boolean + Private _oneLight As Boolean + Private _fogEnabled As Boolean + Private _textureEnabled As Boolean + Private _vertexColorEnabled As Boolean + Private _world As Matrix = Matrix.Identity + Private _view As Matrix = Matrix.Identity + Private _projection As Matrix = Matrix.Identity + Private _worldView As Matrix + Private _diffuseColor As Vector3 = Vector3.One + Private _emissiveColor As Vector3 = Vector3.Zero + Private _ambientLightColor As Vector3 = Vector3.Zero + Private _alpha As Single = 1 + Private _fogStart As Single + Private _fogEnd As Single = 1 + Private _hwEnabled As Boolean + Private _dirtyFlags As EffectDirtyFlags = EffectDirtyFlags.All + + Public Sub New(ByVal device As GraphicsDevice) + MyBase.New(device, File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory), "Content", "Effects", "BasicEffectWithAlphaTest.mgfxdx"))) + CacheEffectParameters(Nothing) + DirectionalLight0.Enabled = True + SpecularColor = Vector3.One + SpecularPower = 16 + AlphaCutoff = 0 + End Sub + + Private Sub New(ByVal cloneSource As BasicEffectWithAlphaTest) + MyBase.New(cloneSource) + CacheEffectParameters(cloneSource) + _lightingEnabled = cloneSource.lightingEnabled + _preferPerPixelLighting = cloneSource.preferPerPixelLighting + _fogEnabled = cloneSource.fogEnabled + _textureEnabled = cloneSource.textureEnabled + _vertexColorEnabled = cloneSource.vertexColorEnabled + _world = cloneSource.world + _view = cloneSource.view + _projection = cloneSource.projection + _diffuseColor = cloneSource.diffuseColor + _emissiveColor = cloneSource.emissiveColor + _ambientLightColor = cloneSource.ambientLightColor + _alpha = cloneSource.alpha + _fogStart = cloneSource.fogStart + _fogEnd = cloneSource.fogEnd + End Sub + + Public Overrides Function Clone() As Effect + Return New BasicEffectWithAlphaTest(Me) + End Function + + Public Sub EnableDefaultLighting() Implements IEffectLights.EnableDefaultLighting + LightingEnabled = True + AmbientLightColor = EffectHelpers.EnableDefaultLighting(DirectionalLight0, DirectionalLight1, DirectionalLight2) + End Sub + + Protected Overrides Sub OnApply() + _dirtyFlags = EffectHelpers.SetWorldViewProjAndFog(_dirtyFlags, _world, _view, _projection, _worldView, _fogEnabled, _fogStart, _fogEnd, _worldViewProjParam, _fogVectorParam) + + If (_dirtyFlags And EffectDirtyFlags.MaterialColor) <> 0 Then + EffectHelpers.SetMaterialColor(_lightingEnabled, _alpha, _diffuseColor, _emissiveColor, _ambientLightColor, _diffuseColorParam, _emissiveColorParam) + _dirtyFlags = _dirtyFlags And Not EffectDirtyFlags.MaterialColor + End If + + If _lightingEnabled Then + _dirtyFlags = EffectHelpers.SetLightingMatrices(_dirtyFlags, _world, _view, _worldParam, _worldInverseTransposeParam, _eyePositionParam) + Dim newOneLight = Not DirectionalLight1.Enabled AndAlso Not DirectionalLight2.Enabled + + If _oneLight <> newOneLight Then + _oneLight = newOneLight + _dirtyFlags = _dirtyFlags Or EffectDirtyFlags.ShaderIndex + End If + End If + + If (_dirtyFlags And EffectDirtyFlags.ShaderIndex) <> 0 Then + Dim shaderIndex = 0 + + If Not _fogEnabled Then + shaderIndex += 1 + End If + + If _vertexColorEnabled Then + shaderIndex += 2 + End If + + If _textureEnabled Then + shaderIndex += 4 + End If + + If _lightingEnabled Then + If _preferPerPixelLighting Then + shaderIndex += 24 + ElseIf _oneLight Then + shaderIndex += 16 + Else + shaderIndex += 8 + End If + End If + + If _hwEnabled Then + shaderIndex += 32 + End If + + _dirtyFlags = _dirtyFlags And Not EffectDirtyFlags.ShaderIndex + CurrentTechnique = Techniques(shaderIndex) + End If + End Sub + + Private Sub CacheEffectParameters(ByVal cloneSource As BasicEffectWithAlphaTest) + _textureParam = Parameters("Texture") + _diffuseColorParam = Parameters("DiffuseColor") + _emissiveColorParam = Parameters("EmissiveColor") + _specularColorParam = Parameters("SpecularColor") + _specularPowerParam = Parameters("SpecularPower") + _eyePositionParam = Parameters("EyePosition") + _fogColorParam = Parameters("FogColor") + _fogVectorParam = Parameters("FogVector") + _worldParam = Parameters("World") + _worldInverseTransposeParam = Parameters("WorldInverseTranspose") + _worldViewProjParam = Parameters("WorldViewProj") + _alphaTestParam = Parameters("AlphaTest") + DirectionalLight0 = New DirectionalLight(Parameters("DirLight0Direction"), Parameters("DirLight0DiffuseColor"), Parameters("DirLight0SpecularColor"), cloneSource?.DirectionalLight0) + DirectionalLight1 = New DirectionalLight(Parameters("DirLight1Direction"), Parameters("DirLight1DiffuseColor"), Parameters("DirLight1SpecularColor"), cloneSource?.DirectionalLight1) + DirectionalLight2 = New DirectionalLight(Parameters("DirLight2Direction"), Parameters("DirLight2DiffuseColor"), Parameters("DirLight2SpecularColor"), cloneSource?.DirectionalLight2) + End Sub +End Class diff --git a/P3D/Resources/Shader/EffectHelpers.vb b/P3D/Resources/Shader/EffectHelpers.vb new file mode 100644 index 000000000..7c3c59653 --- /dev/null +++ b/P3D/Resources/Shader/EffectHelpers.vb @@ -0,0 +1,120 @@ +Imports System +Imports Microsoft.Xna.Framework +Imports Microsoft.Xna.Framework.Graphics + + +Public Enum EffectDirtyFlags + WorldViewProj = 1 + World = 2 + EyePosition = 4 + MaterialColor = 8 + Fog = 16 + FogEnable = 32 + AlphaTest = 64 + ShaderIndex = 128 + All = -1 +End Enum + +Public Module EffectHelpers + Public Function EnableDefaultLighting(ByVal light0 As DirectionalLight, ByVal light1 As DirectionalLight, ByVal light2 As DirectionalLight) As Vector3 + light0.Direction = New Vector3(-0.5265408F, -0.5735765F, -0.6275069F) + light0.DiffuseColor = New Vector3(1, 0.9607844F, 0.8078432F) + light0.SpecularColor = New Vector3(1, 0.9607844F, 0.8078432F) + light0.Enabled = True + + light1.Direction = New Vector3(0.7198464F, 0.3420201F, 0.6040227F) + light1.DiffuseColor = New Vector3(0.9647059F, 0.7607844F, 0.4078432F) + light1.SpecularColor = Vector3.Zero + light1.Enabled = True + + light2.Direction = New Vector3(0.4545195F, -0.7660444F, 0.4545195F) + light2.DiffuseColor = New Vector3(0.3231373F, 0.3607844F, 0.3937255F) + light2.SpecularColor = New Vector3(0.3231373F, 0.3607844F, 0.3937255F) + light2.Enabled = True + + Return New Vector3(0.05333332F, 0.09882354F, 0.1819608F) + End Function + + Public Function SetWorldViewProjAndFog(ByVal dirtyFlags As EffectDirtyFlags, ByRef world As Matrix, ByRef view As Matrix, ByRef projection As Matrix, ByRef worldView As Matrix, ByVal fogEnabled As Boolean, ByVal fogStart As Single, ByVal fogEnd As Single, ByVal worldViewProjParam As EffectParameter, ByVal fogVectorParam As EffectParameter) As EffectDirtyFlags + If (dirtyFlags And EffectDirtyFlags.WorldViewProj) <> 0 Then + Dim worldViewProj As Matrix = Nothing + Matrix.Multiply(world, view, worldView) + Matrix.Multiply(worldView, projection, worldViewProj) + worldViewProjParam.SetValue(worldViewProj) + dirtyFlags = dirtyFlags And Not EffectDirtyFlags.WorldViewProj + End If + + If fogEnabled Then + If (dirtyFlags And (EffectDirtyFlags.Fog Or EffectDirtyFlags.FogEnable)) <> 0 Then + SetFogVector(worldView, fogStart, fogEnd, fogVectorParam) + dirtyFlags = dirtyFlags And Not (EffectDirtyFlags.Fog Or EffectDirtyFlags.FogEnable) + End If + Else + If (dirtyFlags And EffectDirtyFlags.FogEnable) <> 0 Then + fogVectorParam.SetValue(Vector4.Zero) + dirtyFlags = dirtyFlags And Not EffectDirtyFlags.FogEnable + End If + End If + + Return dirtyFlags + End Function + + Public Function SetLightingMatrices(ByVal dirtyFlags As EffectDirtyFlags, ByRef world As Matrix, ByRef view As Matrix, ByVal worldParam As EffectParameter, ByVal worldInverseTransposeParam As EffectParameter, ByVal eyePositionParam As EffectParameter) As EffectDirtyFlags + If (dirtyFlags And EffectDirtyFlags.World) <> 0 Then + Dim worldTranspose As Matrix = Nothing, worldInverseTranspose As Matrix = Nothing + Matrix.Invert(world, worldTranspose) + Matrix.Transpose(worldTranspose, worldInverseTranspose) + worldParam.SetValue(world) + worldInverseTransposeParam.SetValue(worldInverseTranspose) + dirtyFlags = dirtyFlags And Not EffectDirtyFlags.World + End If + + If (dirtyFlags And EffectDirtyFlags.EyePosition) <> 0 Then + Dim viewInverse As Matrix = Nothing + Matrix.Invert(view, viewInverse) + eyePositionParam.SetValue(viewInverse.Translation) + dirtyFlags = dirtyFlags And Not EffectDirtyFlags.EyePosition + End If + + Return dirtyFlags + End Function + + Public Sub SetMaterialColor(ByVal lightingEnabled As Boolean, ByVal alpha As Single, ByRef diffuseColor As Vector3, ByRef emissiveColor As Vector3, ByRef ambientLightColor As Vector3, ByVal diffuseColorParam As EffectParameter, ByVal emissiveColorParam As EffectParameter) + If lightingEnabled Then + Dim diffuse = New Vector4() + Dim emissive = New Vector3() + diffuse.X = diffuseColor.X * alpha + diffuse.Y = diffuseColor.Y * alpha + diffuse.Z = diffuseColor.Z * alpha + diffuse.W = alpha + emissive.X = (emissiveColor.X + ambientLightColor.X * diffuseColor.X) * alpha + emissive.Y = (emissiveColor.Y + ambientLightColor.Y * diffuseColor.Y) * alpha + emissive.Z = (emissiveColor.Z + ambientLightColor.Z * diffuseColor.Z) * alpha + diffuseColorParam.SetValue(diffuse) + emissiveColorParam.SetValue(emissive) + Else + Dim diffuse = New Vector4 With { + .X = (diffuseColor.X + emissiveColor.X) * alpha, + .Y = (diffuseColor.Y + emissiveColor.Y) * alpha, + .Z = (diffuseColor.Z + emissiveColor.Z) * alpha, + .W = alpha + } + diffuseColorParam.SetValue(diffuse) + End If + End Sub + + Private Sub SetFogVector(ByRef worldView As Matrix, ByVal fogStart As Single, ByVal fogEnd As Single, ByVal fogVectorParam As EffectParameter) + If fogStart = fogEnd Then + fogVectorParam.SetValue(New Vector4(0, 0, 0, 1)) + Else + Dim scale = 1F / (fogStart - fogEnd) + Dim fogVector = New Vector4 With { + .X = worldView.M13 * scale, + .Y = worldView.M23 * scale, + .Z = worldView.M33 * scale, + .W = (worldView.M43 + fogStart) * scale + } + fogVectorParam.SetValue(fogVector) + End If + End Sub +End Module diff --git a/P3D/Screens/Credits/CreditsScreen.vb b/P3D/Screens/Credits/CreditsScreen.vb index 69a007d44..623cb2c09 100644 --- a/P3D/Screens/Credits/CreditsScreen.vb +++ b/P3D/Screens/Credits/CreditsScreen.vb @@ -34,7 +34,7 @@ Public Class CreditsScreen Screen.ImageView.Showing = False Screen.ChooseBox.Showing = False - Effect = New BasicEffect(Core.GraphicsDevice) + Effect = New BasicEffectWithAlphaTest(Core.GraphicsDevice) Effect.FogEnabled = True SkyDome = New SkyDome() Camera = New CreditsCamera() diff --git a/P3D/Screens/MainMenu/NewNewGameScreen.vb b/P3D/Screens/MainMenu/NewNewGameScreen.vb index 5893bcc81..efad81567 100644 --- a/P3D/Screens/MainMenu/NewNewGameScreen.vb +++ b/P3D/Screens/MainMenu/NewNewGameScreen.vb @@ -32,7 +32,7 @@ PokemonForms.Initialize() 'Set up 3D environment variables (Effect, Camera, SkyDome and Level): - Effect = New BasicEffect(GraphicsDevice) + Effect = New BasicEffectWithAlphaTest(GraphicsDevice) Effect.FogEnabled = True 'Reset Construct: diff --git a/P3D/Screens/MapPreview/MapPreviewScreen.vb b/P3D/Screens/MapPreview/MapPreviewScreen.vb index 67cc59818..be0055c0f 100644 --- a/P3D/Screens/MapPreview/MapPreviewScreen.vb +++ b/P3D/Screens/MapPreview/MapPreviewScreen.vb @@ -26,7 +26,7 @@ Me.CanMuteAudio = False Me.CanTakeScreenshot = True - Effect = New BasicEffect(Core.GraphicsDevice) + Effect = New BasicEffectWithAlphaTest(Core.GraphicsDevice) Effect.FogEnabled = True Camera = New MapPreviewCamera() diff --git a/P3D/Screens/PC/HallOfFameScreen.vb b/P3D/Screens/PC/HallOfFameScreen.vb index 9b045fe10..c2bf0f896 100644 --- a/P3D/Screens/PC/HallOfFameScreen.vb +++ b/P3D/Screens/PC/HallOfFameScreen.vb @@ -137,7 +137,7 @@ Screen.ImageView.Showing = False Screen.ChooseBox.Showing = False - Effect = New BasicEffect(Core.GraphicsDevice) + Effect = New BasicEffectWithAlphaTest(Core.GraphicsDevice) Effect.FogEnabled = True SkyDome = New SkyDome() Camera = New BattleSystem.BattleCamera() diff --git a/P3D/Screens/Screen.vb b/P3D/Screens/Screen.vb index 764fca5fe..994c0bd4e 100644 --- a/P3D/Screens/Screen.vb +++ b/P3D/Screens/Screen.vb @@ -126,7 +126,7 @@ Public MustInherit Class Screen ''' ''' A global BasicEffect instance, that carries over screen instances. ''' - Public Shared Property Effect() As BasicEffect + Public Shared Property Effect() As BasicEffectWithAlphaTest ''' ''' A global SkyDome instance, that carries over screen instances. diff --git a/P3D/World/Lighting.vb b/P3D/World/Lighting.vb index f6796de16..cc4379917 100644 --- a/P3D/World/Lighting.vb +++ b/P3D/World/Lighting.vb @@ -87,7 +87,65 @@ Public Class Lighting ''' A reference to the BasicEffect that should receive the lighting update. ''' Checks, if the lighting update on the effect should be forced. Public Shared Sub UpdateLighting(ByRef refEffect As BasicEffect, Optional ByVal ForceLighting As Boolean = False) - If Core.GameOptions.LightingEnabled = True Or ForceLighting = True Then ' Only update the lighting if either the currently loaded level instance allows this, or it's getting forced. + If Core.GameOptions.LightingEnabled = True OrElse ForceLighting = True Then ' Only update the lighting if either the currently loaded level instance allows this, or it's getting forced. + ' Set default parameters: + refEffect.LightingEnabled = True ' Enable lighting (gets disabled later, if not used) + refEffect.PreferPerPixelLighting = True ' Yes. Please. + refEffect.SpecularPower = 2000.0F + + ' LightType results: + ' 0 = Night + ' 1 = Morning + ' 2 = Day + ' 3 = Evening + ' Anything higher than 3 = No Lighting + + Select Case GetLightingType() + + Case 0 ' Night + refEffect.AmbientLightColor = GetEnvironmentColor(1) + + refEffect.DirectionalLight0.DiffuseColor = GetEnvironmentColor(0) + refEffect.DirectionalLight0.Direction = Vector3.Normalize(New Vector3(1.0F, 1.0F, -1.0F)) + refEffect.DirectionalLight0.SpecularColor = New Vector3(0.0F) + refEffect.DirectionalLight0.Enabled = True + Case 1 ' Morning + refEffect.AmbientLightColor = GetEnvironmentColor(1) + + refEffect.DirectionalLight0.DiffuseColor = GetEnvironmentColor(0) + refEffect.DirectionalLight0.Direction = Vector3.Normalize(New Vector3(-1.0F, 0.0F, 1.0F)) + refEffect.DirectionalLight0.SpecularColor = New Vector3(0.0F) + refEffect.DirectionalLight0.Enabled = True + Case 2 ' Day + refEffect.AmbientLightColor = GetEnvironmentColor(1) + + refEffect.DirectionalLight0.DiffuseColor = GetEnvironmentColor(0) + refEffect.DirectionalLight0.Direction = Vector3.Normalize(New Vector3(-1.0F, 0.0F, 1.0F)) + refEffect.DirectionalLight0.SpecularColor = New Vector3(0.0F) + refEffect.DirectionalLight0.Enabled = True + Case 3 ' Evening + refEffect.AmbientLightColor = GetEnvironmentColor(1) + + refEffect.DirectionalLight0.DiffuseColor = GetEnvironmentColor(0) + refEffect.DirectionalLight0.Direction = Vector3.Normalize(New Vector3(1.0F, 1.0F, -1.0F)) + refEffect.DirectionalLight0.SpecularColor = New Vector3(0.0F) + refEffect.DirectionalLight0.Enabled = True + Case Else 'Disable lighting on the effect + refEffect.LightingEnabled = False + End Select + Else + ' Disable lighting if the effect isn't supposed to have light. + refEffect.LightingEnabled = False + End If + End Sub + + ''' + ''' Updates the lighting values of a BasicEffect instance. + ''' + ''' A reference to the BasicEffect that should receive the lighting update. + ''' Checks, if the lighting update on the effect should be forced. + Public Shared Sub UpdateLighting(ByRef refEffect As BasicEffectWithAlphaTest, Optional ByVal ForceLighting As Boolean = False) + If Core.GameOptions.LightingEnabled = True OrElse ForceLighting = True Then ' Only update the lighting if either the currently loaded level instance allows this, or it's getting forced. ' Set default parameters: refEffect.LightingEnabled = True ' Enable lighting (gets disabled later, if not used) refEffect.PreferPerPixelLighting = True ' Yes. Please. diff --git a/lib/P3D.ContentPipeline/Content/Effects/BasicEffectWithAlphaTest.fx b/lib/P3D.ContentPipeline/Content/Effects/BasicEffectWithAlphaTest.fx new file mode 100644 index 000000000..9fd90d74e --- /dev/null +++ b/lib/P3D.ContentPipeline/Content/Effects/BasicEffectWithAlphaTest.fx @@ -0,0 +1,832 @@ +//----------------------------------------------------------------------------- +// BasicEffect.fx +// +// Microsoft XNA Community Game Platform +// Copyright (C) Microsoft Corporation. All rights reserved. +//----------------------------------------------------------------------------- + +#include "Macros.fxh" + + +DECLARE_TEXTURE(Texture, 0); + + +BEGIN_CONSTANTS + + float4 DiffuseColor _vs(c0) _ps(c1) _cb(c0); + float3 EmissiveColor _vs(c1) _ps(c2) _cb(c1); + float3 SpecularColor _vs(c2) _ps(c3) _cb(c2); + float SpecularPower _vs(c3) _ps(c4) _cb(c2.w); + + float3 DirLight0Direction _vs(c4) _ps(c5) _cb(c3); + float3 DirLight0DiffuseColor _vs(c5) _ps(c6) _cb(c4); + float3 DirLight0SpecularColor _vs(c6) _ps(c7) _cb(c5); + + float3 DirLight1Direction _vs(c7) _ps(c8) _cb(c6); + float3 DirLight1DiffuseColor _vs(c8) _ps(c9) _cb(c7); + float3 DirLight1SpecularColor _vs(c9) _ps(c10) _cb(c8); + + float3 DirLight2Direction _vs(c10) _ps(c11) _cb(c9); + float3 DirLight2DiffuseColor _vs(c11) _ps(c12) _cb(c10); + float3 DirLight2SpecularColor _vs(c12) _ps(c13) _cb(c11); + + float3 EyePosition _vs(c13) _ps(c14) _cb(c12); + + float3 FogColor _ps(c0) _cb(c13); + float4 FogVector _vs(c14) _cb(c14); + + float4x4 World _vs(c19) _cb(c15); + float3x3 WorldInverseTranspose _vs(c23) _cb(c19); + + float AlphaTest _ps(c15) _cb(c20); + +MATRIX_CONSTANTS + + float4x4 WorldViewProj _vs(c15) _cb(c0); + +END_CONSTANTS + + +#include "Structures.fxh" +#include "Common.fxh" +#include "Lighting.fxh" + + +// Vertex shader: basic. +VSOutput VSBasic(VSInput vin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position); + SetCommonVSOutputParams; + + return vout; +} + + +// Vertex shader: basic. +VSOutput VSHWBasic(VSInput vin, VSHWInputInstance vhwin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position + vhwin.Position); + SetCommonVSOutputParams; + + return vout; +} + + +// Vertex shader: no fog. +VSOutputNoFog VSBasicNoFog(VSInput vin) +{ + VSOutputNoFog vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position); + SetCommonVSOutputParamsNoFog; + + return vout; +} + + +// Vertex shader: no fog. +VSOutputNoFog VSHWBasicNoFog(VSInput vin, VSHWInputInstance vhwin) +{ + VSOutputNoFog vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position + vhwin.Position); + SetCommonVSOutputParamsNoFog; + + return vout; +} + + +// Vertex shader: vertex color. +VSOutput VSBasicVc(VSInputVc vin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position); + SetCommonVSOutputParams; + + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: vertex color. +VSOutput VSHWBasicVc(VSInputVc vin, VSHWInputInstance vhwin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position + vhwin.Position); + SetCommonVSOutputParams; + + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: vertex color, no fog. +VSOutputNoFog VSBasicVcNoFog(VSInputVc vin) +{ + VSOutputNoFog vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position); + SetCommonVSOutputParamsNoFog; + + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: vertex color, no fog. +VSOutputNoFog VSHWBasicVcNoFog(VSInputVc vin, VSHWInputInstance vhwin) +{ + VSOutputNoFog vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position + vhwin.Position); + SetCommonVSOutputParamsNoFog; + + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: texture. +VSOutputTx VSBasicTx(VSInputTx vin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Vertex shader: texture. +VSOutputTx VSHWBasicTx(VSInputTx vin, VSHWInputInstance vhwin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position + vhwin.Position); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Vertex shader: texture, no fog. +VSOutputTxNoFog VSBasicTxNoFog(VSInputTx vin) +{ + VSOutputTxNoFog vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position); + SetCommonVSOutputParamsNoFog; + + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Vertex shader: texture, no fog. +VSOutputTxNoFog VSHWBasicTxNoFog(VSInputTx vin, VSHWInputInstance vhwin) +{ + VSOutputTxNoFog vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position + vhwin.Position); + SetCommonVSOutputParamsNoFog; + + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Vertex shader: texture + vertex color. +VSOutputTx VSBasicTxVc(VSInputTxVc vin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: texture + vertex color. +VSOutputTx VSHWBasicTxVc(VSInputTxVc vin, VSHWInputInstance vhwin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position + vhwin.Position); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: texture + vertex color, no fog. +VSOutputTxNoFog VSBasicTxVcNoFog(VSInputTxVc vin) +{ + VSOutputTxNoFog vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position); + SetCommonVSOutputParamsNoFog; + + vout.TexCoord = vin.TexCoord; + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: texture + vertex color, no fog. +VSOutputTxNoFog VSHWBasicTxVcNoFog(VSInputTxVc vin, VSHWInputInstance vhwin) +{ + VSOutputTxNoFog vout; + + CommonVSOutput cout = ComputeCommonVSOutput(vin.Position + vhwin.Position); + SetCommonVSOutputParamsNoFog; + + vout.TexCoord = vin.TexCoord; + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: vertex lighting. +VSOutput VSBasicVertexLighting(VSInputNm vin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3); + SetCommonVSOutputParams; + + return vout; +} + + +// Vertex shader: vertex lighting. +VSOutput VSHWBasicVertexLighting(VSInputNm vin, VSHWInputInstance vhwin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position + vhwin.Position, vin.Normal, 3); + SetCommonVSOutputParams; + + return vout; +} + + +// Vertex shader: vertex lighting + vertex color. +VSOutput VSBasicVertexLightingVc(VSInputNmVc vin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3); + SetCommonVSOutputParams; + + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: vertex lighting + vertex color. +VSOutput VSHWBasicVertexLightingVc(VSInputNmVc vin, VSHWInputInstance vhwin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position + vhwin.Position, vin.Normal, 3); + SetCommonVSOutputParams; + + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: vertex lighting + texture. +VSOutputTx VSBasicVertexLightingTx(VSInputNmTx vin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Vertex shader: vertex lighting + texture. +VSOutputTx VSHWBasicVertexLightingTx(VSInputNmTx vin, VSHWInputInstance vhwin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position + vhwin.Position, vin.Normal, 3); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Vertex shader: vertex lighting + texture + vertex color. +VSOutputTx VSBasicVertexLightingTxVc(VSInputNmTxVc vin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: vertex lighting + texture + vertex color. +VSOutputTx VSHWBasicVertexLightingTxVc(VSInputNmTxVc vin, VSHWInputInstance vhwin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position + vhwin.Position, vin.Normal, 3); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: one light. +VSOutput VSBasicOneLight(VSInputNm vin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1); + SetCommonVSOutputParams; + + return vout; +} + + +// Vertex shader: one light. +VSOutput VSHWBasicOneLight(VSInputNm vin, VSHWInputInstance vhwin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position + vhwin.Position, vin.Normal, 1); + SetCommonVSOutputParams; + + return vout; +} + + +// Vertex shader: one light + vertex color. +VSOutput VSBasicOneLightVc(VSInputNmVc vin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1); + SetCommonVSOutputParams; + + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: one light + vertex color. +VSOutput VSHWBasicOneLightVc(VSInputNmVc vin, VSHWInputInstance vhwin) +{ + VSOutput vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position + vhwin.Position, vin.Normal, 1); + SetCommonVSOutputParams; + + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: one light + texture. +VSOutputTx VSBasicOneLightTx(VSInputNmTx vin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Vertex shader: one light + texture. +VSOutputTx VSHWBasicOneLightTx(VSInputNmTx vin, VSHWInputInstance vhwin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position + vhwin.Position, vin.Normal, 1); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Vertex shader: one light + texture + vertex color. +VSOutputTx VSBasicOneLightTxVc(VSInputNmTxVc vin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: one light + texture + vertex color. +VSOutputTx VSHWBasicOneLightTxVc(VSInputNmTxVc vin, VSHWInputInstance vhwin) +{ + VSOutputTx vout; + + CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position + vhwin.Position, vin.Normal, 1); + SetCommonVSOutputParams; + + vout.TexCoord = vin.TexCoord; + vout.Diffuse *= vin.Color; + + return vout; +} + + +// Vertex shader: pixel lighting. +VSOutputPixelLighting VSBasicPixelLighting(VSInputNm vin) +{ + VSOutputPixelLighting vout; + + CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal); + SetCommonVSOutputParamsPixelLighting; + + vout.Diffuse = float4(1, 1, 1, DiffuseColor.a); + + return vout; +} + + +// Vertex shader: pixel lighting. +VSOutputPixelLighting VSHWBasicPixelLighting(VSInputNm vin, VSHWInputInstance vhwin) +{ + VSOutputPixelLighting vout; + + CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position + vhwin.Position, vin.Normal); + SetCommonVSOutputParamsPixelLighting; + + vout.Diffuse = float4(1, 1, 1, DiffuseColor.a); + + return vout; +} + + +// Vertex shader: pixel lighting + vertex color. +VSOutputPixelLighting VSBasicPixelLightingVc(VSInputNmVc vin) +{ + VSOutputPixelLighting vout; + + CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal); + SetCommonVSOutputParamsPixelLighting; + + vout.Diffuse.rgb = vin.Color.rgb; + vout.Diffuse.a = vin.Color.a * DiffuseColor.a; + + return vout; +} + + +// Vertex shader: pixel lighting + vertex color. +VSOutputPixelLighting VSHWBasicPixelLightingVc(VSInputNmVc vin, VSHWInputInstance vhwin) +{ + VSOutputPixelLighting vout; + + CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position + vhwin.Position, vin.Normal); + SetCommonVSOutputParamsPixelLighting; + + vout.Diffuse.rgb = vin.Color.rgb; + vout.Diffuse.a = vin.Color.a * DiffuseColor.a; + + return vout; +} + + +// Vertex shader: pixel lighting + texture. +VSOutputPixelLightingTx VSBasicPixelLightingTx(VSInputNmTx vin) +{ + VSOutputPixelLightingTx vout; + + CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal); + SetCommonVSOutputParamsPixelLighting; + + vout.Diffuse = float4(1, 1, 1, DiffuseColor.a); + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Vertex shader: pixel lighting + texture. +VSOutputPixelLightingTx VSHWBasicPixelLightingTx(VSInputNmTx vin, VSHWInputInstance vhwin) +{ + VSOutputPixelLightingTx vout; + + CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position + vhwin.Position, vin.Normal); + SetCommonVSOutputParamsPixelLighting; + + vout.Diffuse = float4(1, 1, 1, DiffuseColor.a); + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Vertex shader: pixel lighting + texture + vertex color. +VSOutputPixelLightingTx VSBasicPixelLightingTxVc(VSInputNmTxVc vin) +{ + VSOutputPixelLightingTx vout; + + CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal); + SetCommonVSOutputParamsPixelLighting; + + vout.Diffuse.rgb = vin.Color.rgb; + vout.Diffuse.a = vin.Color.a * DiffuseColor.a; + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Vertex shader: pixel lighting + texture + vertex color. +VSOutputPixelLightingTx VSHWBasicPixelLightingTxVc(VSInputNmTxVc vin, VSHWInputInstance vhwin) +{ + VSOutputPixelLightingTx vout; + + CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position + vhwin.Position, vin.Normal); + SetCommonVSOutputParamsPixelLighting; + + vout.Diffuse.rgb = vin.Color.rgb; + vout.Diffuse.a = vin.Color.a * DiffuseColor.a; + vout.TexCoord = vin.TexCoord; + + return vout; +} + + +// Pixel shader: basic. +float4 PSBasic(VSOutput pin) : SV_Target0 +{ + float4 color = pin.Diffuse; + + clip(color.a <= AlphaTest ? -1 : 1); + + ApplyFog(color, pin.Specular.w); + + return color; +} + + +// Pixel shader: no fog. +float4 PSBasicNoFog(VSOutputNoFog pin) : SV_Target0 +{ + float4 color = pin.Diffuse; + + clip(color.a <= AlphaTest ? -1 : 1); + + return color; +} + + +// Pixel shader: texture. +float4 PSBasicTx(VSOutputTx pin) : SV_Target0 +{ + float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse; + + clip(color.a <= AlphaTest ? -1 : 1); + + ApplyFog(color, pin.Specular.w); + + return color; +} + + +// Pixel shader: texture, no fog. +float4 PSBasicTxNoFog(VSOutputTxNoFog pin) : SV_Target0 +{ + float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse; + + clip(color.a <= AlphaTest ? -1 : 1); + + return color; +} + + +// Pixel shader: vertex lighting. +float4 PSBasicVertexLighting(VSOutput pin) : SV_Target0 +{ + float4 color = pin.Diffuse; + + clip(color.a <= AlphaTest ? -1 : 1); + + AddSpecular(color, pin.Specular.rgb); + ApplyFog(color, pin.Specular.w); + + return color; +} + + +// Pixel shader: vertex lighting, no fog. +float4 PSBasicVertexLightingNoFog(VSOutput pin) : SV_Target0 +{ + float4 color = pin.Diffuse; + + clip(color.a <= AlphaTest ? -1 : 1); + + AddSpecular(color, pin.Specular.rgb); + + return color; +} + + +// Pixel shader: vertex lighting + texture. +float4 PSBasicVertexLightingTx(VSOutputTx pin) : SV_Target0 +{ + float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse; + + clip(color.a <= AlphaTest ? -1 : 1); + + AddSpecular(color, pin.Specular.rgb); + ApplyFog(color, pin.Specular.w); + + return color; +} + + +// Pixel shader: vertex lighting + texture, no fog. +float4 PSBasicVertexLightingTxNoFog(VSOutputTx pin) : SV_Target0 +{ + float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse; + + clip(color.a <= AlphaTest ? -1 : 1); + + AddSpecular(color, pin.Specular.rgb); + + return color; +} + + +// Pixel shader: pixel lighting. +float4 PSBasicPixelLighting(VSOutputPixelLighting pin) : SV_Target0 +{ + float4 color = pin.Diffuse; + + float3 eyeVector = normalize(EyePosition - pin.PositionWS.xyz); + float3 worldNormal = normalize(pin.NormalWS); + + ColorPair lightResult = ComputeLights(eyeVector, worldNormal, 3); + + color.rgb *= lightResult.Diffuse; + + clip(color.a <= AlphaTest ? -1 : 1); + + AddSpecular(color, lightResult.Specular); + ApplyFog(color, pin.PositionWS.w); + + return color; +} + + +// Pixel shader: pixel lighting + texture. +float4 PSBasicPixelLightingTx(VSOutputPixelLightingTx pin) : SV_Target0 +{ + float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse; + + float3 eyeVector = normalize(EyePosition - pin.PositionWS.xyz); + float3 worldNormal = normalize(pin.NormalWS); + + ColorPair lightResult = ComputeLights(eyeVector, worldNormal, 3); + + color.rgb *= lightResult.Diffuse; + + clip(color.a <= AlphaTest ? -1 : 1); + + AddSpecular(color, lightResult.Specular); + ApplyFog(color, pin.PositionWS.w); + + return color; +} + + +// NOTE: The order of the techniques here are +// defined to match the indexing in BasicEffect.cs. + +TECHNIQUE( BasicEffect, VSBasic, PSBasic ); +TECHNIQUE( BasicEffect_NoFog, VSBasicNoFog, PSBasicNoFog ); +TECHNIQUE( BasicEffect_VertexColor, VSBasicVc, PSBasic ); +TECHNIQUE( BasicEffect_VertexColor_NoFog, VSBasicVcNoFog, PSBasicNoFog ); +TECHNIQUE( BasicEffect_Texture, VSBasicTx, PSBasicTx ); +TECHNIQUE( BasicEffect_Texture_NoFog, VSBasicTxNoFog, PSBasicTxNoFog ); +TECHNIQUE( BasicEffect_Texture_VertexColor, VSBasicTxVc, PSBasicTx ); +TECHNIQUE( BasicEffect_Texture_VertexColor_NoFog, VSBasicTxVcNoFog, PSBasicTxNoFog ); + +TECHNIQUE( BasicEffect_VertexLighting, VSBasicVertexLighting, PSBasicVertexLighting ); +TECHNIQUE( BasicEffect_VertexLighting_NoFog, VSBasicVertexLighting, PSBasicVertexLightingNoFog ); +TECHNIQUE( BasicEffect_VertexLighting_VertexColor, VSBasicVertexLightingVc, PSBasicVertexLighting ); +TECHNIQUE( BasicEffect_VertexLighting_VertexColor_NoFog, VSBasicVertexLightingVc, PSBasicVertexLightingNoFog ); +TECHNIQUE( BasicEffect_VertexLighting_Texture, VSBasicVertexLightingTx, PSBasicVertexLightingTx ); +TECHNIQUE( BasicEffect_VertexLighting_Texture_NoFog, VSBasicVertexLightingTx, PSBasicVertexLightingTxNoFog ); +TECHNIQUE( BasicEffect_VertexLighting_Texture_VertexColor, VSBasicVertexLightingTxVc, PSBasicVertexLightingTx ); +TECHNIQUE( BasicEffect_VertexLighting_Texture_VertexColor_NoFog, VSBasicVertexLightingTxVc, PSBasicVertexLightingTxNoFog ); + +TECHNIQUE( BasicEffect_OneLight, VSBasicOneLight, PSBasicVertexLighting ); +TECHNIQUE( BasicEffect_OneLight_NoFog, VSBasicOneLight, PSBasicVertexLightingNoFog ); +TECHNIQUE( BasicEffect_OneLight_VertexColor, VSBasicOneLightVc, PSBasicVertexLighting ); +TECHNIQUE( BasicEffect_OneLight_VertexColor_NoFog, VSBasicOneLightVc, PSBasicVertexLightingNoFog ); +TECHNIQUE( BasicEffect_OneLight_Texture, VSBasicOneLightTx, PSBasicVertexLightingTx ); +TECHNIQUE( BasicEffect_OneLight_Texture_NoFog, VSBasicOneLightTx, PSBasicVertexLightingTxNoFog ); +TECHNIQUE( BasicEffect_OneLight_Texture_VertexColor, VSBasicOneLightTxVc, PSBasicVertexLightingTx ); +TECHNIQUE( BasicEffect_OneLight_Texture_VertexColor_NoFog, VSBasicOneLightTxVc, PSBasicVertexLightingTxNoFog ); + +TECHNIQUE( BasicEffect_PixelLighting, VSBasicPixelLighting, PSBasicPixelLighting ); +TECHNIQUE( BasicEffect_PixelLighting_NoFog, VSBasicPixelLighting, PSBasicPixelLighting ); +TECHNIQUE( BasicEffect_PixelLighting_VertexColor, VSBasicPixelLightingVc, PSBasicPixelLighting ); +TECHNIQUE( BasicEffect_PixelLighting_VertexColor_NoFog, VSBasicPixelLightingVc, PSBasicPixelLighting ); +TECHNIQUE( BasicEffect_PixelLighting_Texture, VSBasicPixelLightingTx, PSBasicPixelLightingTx ); +TECHNIQUE( BasicEffect_PixelLighting_Texture_NoFog, VSBasicPixelLightingTx, PSBasicPixelLightingTx ); +TECHNIQUE( BasicEffect_PixelLighting_Texture_VertexColor, VSBasicPixelLightingTxVc, PSBasicPixelLightingTx ); +TECHNIQUE( BasicEffect_PixelLighting_Texture_VertexColor_NoFog, VSBasicPixelLightingTxVc, PSBasicPixelLightingTx ); + +TECHNIQUE( BasicEffect_HardwareInstancing, VSHWBasic, PSBasic ); +TECHNIQUE( BasicEffect_HardwareInstancing_NoFog, VSHWBasicNoFog, PSBasicNoFog ); +TECHNIQUE( BasicEffect_HardwareInstancing_VertexColor, VSHWBasicVc, PSBasic ); +TECHNIQUE( BasicEffect_HardwareInstancing_VertexColor_NoFog, VSHWBasicVcNoFog, PSBasicNoFog ); +TECHNIQUE( BasicEffect_HardwareInstancing_Texture, VSHWBasicTx, PSBasicTx ); +TECHNIQUE( BasicEffect_HardwareInstancing_Texture_NoFog, VSHWBasicTxNoFog, PSBasicTxNoFog ); +TECHNIQUE( BasicEffect_HardwareInstancing_Texture_VertexColor, VSHWBasicTxVc, PSBasicTx ); +TECHNIQUE( BasicEffect_HardwareInstancing_Texture_VertexColor_NoFog, VSHWBasicTxVcNoFog, PSBasicTxNoFog ); + +TECHNIQUE( BasicEffect_HardwareInstancing_VertexLighting, VSHWBasicVertexLighting, PSBasicVertexLighting ); +TECHNIQUE( BasicEffect_HardwareInstancing_VertexLighting_NoFog, VSHWBasicVertexLighting, PSBasicVertexLightingNoFog ); +TECHNIQUE( BasicEffect_HardwareInstancing_VertexLighting_VertexColor, VSHWBasicVertexLightingVc, PSBasicVertexLighting ); +TECHNIQUE( BasicEffect_HardwareInstancing_VertexLighting_VertexColor_NoFog, VSHWBasicVertexLightingVc, PSBasicVertexLightingNoFog ); +TECHNIQUE( BasicEffect_HardwareInstancing_VertexLighting_Texture, VSHWBasicVertexLightingTx, PSBasicVertexLightingTx ); +TECHNIQUE( BasicEffect_HardwareInstancing_VertexLighting_Texture_NoFog, VSHWBasicVertexLightingTx, PSBasicVertexLightingTxNoFog ); +TECHNIQUE( BasicEffect_HardwareInstancing_VertexLighting_Texture_VertexColor, VSHWBasicVertexLightingTxVc, PSBasicVertexLightingTx ); +TECHNIQUE( BasicEffect_HardwareInstancing_VertexLighting_Texture_VertexColor_NoFog, VSHWBasicVertexLightingTxVc, PSBasicVertexLightingTxNoFog ); + +TECHNIQUE( BasicEffect_HardwareInstancing_OneLight, VSHWBasicOneLight, PSBasicVertexLighting ); +TECHNIQUE( BasicEffect_HardwareInstancing_OneLight_NoFog, VSHWBasicOneLight, PSBasicVertexLightingNoFog ); +TECHNIQUE( BasicEffect_HardwareInstancing_OneLight_VertexColor, VSHWBasicOneLightVc, PSBasicVertexLighting ); +TECHNIQUE( BasicEffect_HardwareInstancing_OneLight_VertexColor_NoFog, VSHWBasicOneLightVc, PSBasicVertexLightingNoFog ); +TECHNIQUE( BasicEffect_HardwareInstancing_OneLight_Texture, VSHWBasicOneLightTx, PSBasicVertexLightingTx ); +TECHNIQUE( BasicEffect_HardwareInstancing_OneLight_Texture_NoFog, VSHWBasicOneLightTx, PSBasicVertexLightingTxNoFog ); +TECHNIQUE( BasicEffect_HardwareInstancing_OneLight_Texture_VertexColor, VSHWBasicOneLightTxVc, PSBasicVertexLightingTx ); +TECHNIQUE( BasicEffect_HardwareInstancing_OneLight_Texture_VertexColor_NoFog, VSHWBasicOneLightTxVc, PSBasicVertexLightingTxNoFog ); + +TECHNIQUE( BasicEffect_HardwareInstancing_PixelLighting, VSHWBasicPixelLighting, PSBasicPixelLighting ); +TECHNIQUE( BasicEffect_HardwareInstancing_PixelLighting_NoFog, VSHWBasicPixelLighting, PSBasicPixelLighting ); +TECHNIQUE( BasicEffect_HardwareInstancing_PixelLighting_VertexColor, VSHWBasicPixelLightingVc, PSBasicPixelLighting ); +TECHNIQUE( BasicEffect_HardwareInstancing_PixelLighting_VertexColor_NoFog, VSHWBasicPixelLightingVc, PSBasicPixelLighting ); +TECHNIQUE( BasicEffect_HardwareInstancing_PixelLighting_Texture, VSHWBasicPixelLightingTx, PSBasicPixelLightingTx ); +TECHNIQUE( BasicEffect_HardwareInstancing_PixelLighting_Texture_NoFog, VSHWBasicPixelLightingTx, PSBasicPixelLightingTx ); +TECHNIQUE( BasicEffect_HardwareInstancing_PixelLighting_Texture_VertexColor, VSHWBasicPixelLightingTxVc, PSBasicPixelLightingTx ); +TECHNIQUE( BasicEffect_HardwareInstancing_PixelLighting_Texture_VertexColor_NoFog, VSHWBasicPixelLightingTxVc, PSBasicPixelLightingTx ); \ No newline at end of file diff --git a/lib/P3D.ContentPipeline/Content/Effects/Common.fxh b/lib/P3D.ContentPipeline/Content/Effects/Common.fxh new file mode 100644 index 000000000..33f121be0 --- /dev/null +++ b/lib/P3D.ContentPipeline/Content/Effects/Common.fxh @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// Common.fxh +// +// Microsoft XNA Community Game Platform +// Copyright (C) Microsoft Corporation. All rights reserved. +//----------------------------------------------------------------------------- + + +float ComputeFogFactor(float4 position) +{ + return saturate(dot(position, FogVector)); +} + + +void ApplyFog(inout float4 color, float fogFactor) +{ + color.rgb = lerp(color.rgb, FogColor * color.a, fogFactor); +} + + +void AddSpecular(inout float4 color, float3 specular) +{ + color.rgb += specular * color.a; +} + + +struct CommonVSOutput +{ + float4 Pos_ps; + float4 Diffuse; + float3 Specular; + float FogFactor; +}; + + +CommonVSOutput ComputeCommonVSOutput(float4 position) +{ + CommonVSOutput vout; + + vout.Pos_ps = mul(position, WorldViewProj); + vout.Diffuse = DiffuseColor; + vout.Specular = 0; + vout.FogFactor = ComputeFogFactor(position); + + return vout; +} + + +#define SetCommonVSOutputParams \ + vout.PositionPS = cout.Pos_ps; \ + vout.Diffuse = cout.Diffuse; \ + vout.Specular = float4(cout.Specular, cout.FogFactor); + + +#define SetCommonVSOutputParamsNoFog \ + vout.PositionPS = cout.Pos_ps; \ + vout.Diffuse = cout.Diffuse; + diff --git a/lib/P3D.ContentPipeline/Content/Effects/Lighting.fxh b/lib/P3D.ContentPipeline/Content/Effects/Lighting.fxh new file mode 100644 index 000000000..6b82db49d --- /dev/null +++ b/lib/P3D.ContentPipeline/Content/Effects/Lighting.fxh @@ -0,0 +1,94 @@ +//----------------------------------------------------------------------------- +// Lighting.fxh +// +// Microsoft XNA Community Game Platform +// Copyright (C) Microsoft Corporation. All rights reserved. +//----------------------------------------------------------------------------- + + +struct ColorPair +{ + float3 Diffuse; + float3 Specular; +}; + + +ColorPair ComputeLights(float3 eyeVector, float3 worldNormal, uniform int numLights) +{ + float3x3 lightDirections = 0; + float3x3 lightDiffuse = 0; + float3x3 lightSpecular = 0; + float3x3 halfVectors = 0; + + [unroll] + for (int i = 0; i < numLights; i++) + { + lightDirections[i] = float3x3(DirLight0Direction, DirLight1Direction, DirLight2Direction) [i]; + lightDiffuse[i] = float3x3(DirLight0DiffuseColor, DirLight1DiffuseColor, DirLight2DiffuseColor) [i]; + lightSpecular[i] = float3x3(DirLight0SpecularColor, DirLight1SpecularColor, DirLight2SpecularColor)[i]; + + halfVectors[i] = normalize(eyeVector - lightDirections[i]); + } + + float3 dotL = mul(-lightDirections, worldNormal); + float3 dotH = mul(halfVectors, worldNormal); + + float3 zeroL = step(float3(0,0,0), dotL); + + float3 diffuse = zeroL * dotL; + float3 specular = pow(max(dotH, 0) * zeroL, SpecularPower); + + ColorPair result; + + result.Diffuse = mul(diffuse, lightDiffuse) * DiffuseColor.rgb + EmissiveColor; + result.Specular = mul(specular, lightSpecular) * SpecularColor; + + return result; +} + + +CommonVSOutput ComputeCommonVSOutputWithLighting(float4 position, float3 normal, uniform int numLights) +{ + CommonVSOutput vout; + + float4 pos_ws = mul(position, World); + float3 eyeVector = normalize(EyePosition - pos_ws.xyz); + float3 worldNormal = normalize(mul(normal, WorldInverseTranspose)); + + ColorPair lightResult = ComputeLights(eyeVector, worldNormal, numLights); + + vout.Pos_ps = mul(position, WorldViewProj); + vout.Diffuse = float4(lightResult.Diffuse, DiffuseColor.a); + vout.Specular = lightResult.Specular; + vout.FogFactor = ComputeFogFactor(position); + + return vout; +} + + +struct CommonVSOutputPixelLighting +{ + float4 Pos_ps; + float3 Pos_ws; + float3 Normal_ws; + float FogFactor; +}; + + +CommonVSOutputPixelLighting ComputeCommonVSOutputPixelLighting(float4 position, float3 normal) +{ + CommonVSOutputPixelLighting vout; + + vout.Pos_ps = mul(position, WorldViewProj); + vout.Pos_ws = mul(position, World).xyz; + vout.Normal_ws = normalize(mul(normal, WorldInverseTranspose)); + vout.FogFactor = ComputeFogFactor(position); + + return vout; +} + + +#define SetCommonVSOutputParamsPixelLighting \ + vout.PositionPS = cout.Pos_ps; \ + vout.PositionWS = float4(cout.Pos_ws, cout.FogFactor); \ + vout.NormalWS = cout.Normal_ws; diff --git a/lib/P3D.ContentPipeline/Content/Effects/Macros.fxh b/lib/P3D.ContentPipeline/Content/Effects/Macros.fxh new file mode 100644 index 000000000..7b1d31e05 --- /dev/null +++ b/lib/P3D.ContentPipeline/Content/Effects/Macros.fxh @@ -0,0 +1,61 @@ +//----------------------------------------------------------------------------- +// Macros.fxh +// +// Microsoft XNA Community Game Platform +// Copyright (C) Microsoft Corporation. All rights reserved. +//----------------------------------------------------------------------------- + +#ifdef SM4 + +// Macros for targetting shader model 4.0 (DX11) + +#define TECHNIQUE(name, vsname, psname ) \ + technique name { pass { VertexShader = compile vs_4_0_level_9_1 vsname (); PixelShader = compile ps_4_0_level_9_1 psname(); } } + +#define BEGIN_CONSTANTS cbuffer Parameters : register(b0) { +#define MATRIX_CONSTANTS +#define END_CONSTANTS }; + +#define _vs(r) +#define _ps(r) +#define _cb(r) + +#define DECLARE_TEXTURE(Name, index) \ + Texture2D Name : register(t##index); \ + sampler Name##Sampler : register(s##index) + +#define DECLARE_CUBEMAP(Name, index) \ + TextureCube Name : register(t##index); \ + sampler Name##Sampler : register(s##index) + +#define SAMPLE_TEXTURE(Name, texCoord) Name.Sample(Name##Sampler, texCoord) +#define SAMPLE_CUBEMAP(Name, texCoord) Name.Sample(Name##Sampler, texCoord) + + +#else + + +// Macros for targetting shader model 2.0 (DX9) + +#define TECHNIQUE(name, vsname, psname ) \ + technique name { pass { VertexShader = compile vs_2_0 vsname (); PixelShader = compile ps_2_0 psname(); } } + +#define BEGIN_CONSTANTS +#define MATRIX_CONSTANTS +#define END_CONSTANTS + +#define _vs(r) : register(vs, r) +#define _ps(r) : register(ps, r) +#define _cb(r) + +#define DECLARE_TEXTURE(Name, index) \ + sampler2D Name : register(s##index); + +#define DECLARE_CUBEMAP(Name, index) \ + samplerCUBE Name : register(s##index); + +#define SAMPLE_TEXTURE(Name, texCoord) tex2D(Name, texCoord) +#define SAMPLE_CUBEMAP(Name, texCoord) texCUBE(Name, texCoord) + + +#endif diff --git a/lib/P3D.ContentPipeline/Content/Effects/Structures.fxh b/lib/P3D.ContentPipeline/Content/Effects/Structures.fxh new file mode 100644 index 000000000..817b557a9 --- /dev/null +++ b/lib/P3D.ContentPipeline/Content/Effects/Structures.fxh @@ -0,0 +1,166 @@ +//----------------------------------------------------------------------------- +// Structurs.fxh +// +// Microsoft XNA Community Game Platform +// Copyright (C) Microsoft Corporation. All rights reserved. +//----------------------------------------------------------------------------- + + +// Vertex shader input structures. + +struct VSHWInputInstance +{ + float4 Position : POSITION1; +}; + +struct VSInput +{ + float4 Position : POSITION0; +}; + +struct VSInputVc +{ + float4 Position : POSITION0; + float4 Color : COLOR; +}; + +struct VSInputTx +{ + float4 Position : POSITION0; + float2 TexCoord : TEXCOORD; +}; + +struct VSInputTxVc +{ + float4 Position : POSITION0; + float2 TexCoord : TEXCOORD; + float4 Color : COLOR; +}; + +struct VSInputNm +{ + float4 Position : POSITION0; + float3 Normal : NORMAL; +}; + +struct VSInputNmVc +{ + float4 Position : POSITION0; + float3 Normal : NORMAL; + float4 Color : COLOR; +}; + +struct VSInputNmTx +{ + float4 Position : POSITION0; + float3 Normal : NORMAL; + float2 TexCoord : TEXCOORD; +}; + +struct VSInputNmTxVc +{ + float4 Position : POSITION0; + float3 Normal : NORMAL; + float2 TexCoord : TEXCOORD; + float4 Color : COLOR; +}; + +struct VSInputTx2 +{ + float4 Position : POSITION0; + float2 TexCoord : TEXCOORD0; + float2 TexCoord2 : TEXCOORD1; +}; + +struct VSInputTx2Vc +{ + float4 Position : POSITION0; + float2 TexCoord : TEXCOORD0; + float2 TexCoord2 : TEXCOORD1; + float4 Color : COLOR; +}; + +struct VSInputNmTxWeights +{ + float4 Position : POSITION0; + float3 Normal : NORMAL0; + float2 TexCoord : TEXCOORD0; + uint4 Indices : BLENDINDICES0; + float4 Weights : BLENDWEIGHT0; +}; + + + +// Vertex shader output structures. + +struct VSOutput +{ + float4 PositionPS : SV_Position; + float4 Diffuse : COLOR0; + float4 Specular : COLOR1; +}; + +struct VSOutputNoFog +{ + float4 PositionPS : SV_Position; + float4 Diffuse : COLOR0; +}; + +struct VSOutputTx +{ + float4 PositionPS : SV_Position; + float4 Diffuse : COLOR0; + float4 Specular : COLOR1; + float2 TexCoord : TEXCOORD0; +}; + +struct VSOutputTxNoFog +{ + float4 PositionPS : SV_Position; + float4 Diffuse : COLOR0; + float2 TexCoord : TEXCOORD0; +}; + +struct VSOutputPixelLighting +{ + float4 PositionPS : SV_Position; + float4 PositionWS : TEXCOORD0; + float3 NormalWS : TEXCOORD1; + float4 Diffuse : COLOR0; +}; + +struct VSOutputPixelLightingTx +{ + float4 PositionPS : SV_Position; + float2 TexCoord : TEXCOORD0; + float4 PositionWS : TEXCOORD1; + float3 NormalWS : TEXCOORD2; + float4 Diffuse : COLOR0; +}; + +struct VSOutputTx2 +{ + float4 PositionPS : SV_Position; + float4 Diffuse : COLOR0; + float4 Specular : COLOR1; + float2 TexCoord : TEXCOORD0; + float2 TexCoord2 : TEXCOORD1; +}; + +struct VSOutputTx2NoFog +{ + float4 PositionPS : SV_Position; + float4 Diffuse : COLOR0; + float2 TexCoord : TEXCOORD0; + float2 TexCoord2 : TEXCOORD1; +}; + +struct VSOutputTxEnvMap +{ + float4 PositionPS : SV_Position; + float4 Diffuse : COLOR0; + float4 Specular : COLOR1; + float2 TexCoord : TEXCOORD0; + float3 EnvCoord : TEXCOORD1; +}; +