keid-render-basic 0.1.6.1 → 0.1.7.0
raw patch · 29 files changed
+2088/−1248 lines, 29 filesdep ~keid-corePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: keid-core
API changes (from Hackage documentation)
- Render.Basic: data Pipelines
+ Render.Basic: [$sel:pSceneLayout:Pipelines] :: PipelinesF (f :: Type -> Type) -> Tagged '[Scene] DescriptorSetLayout
+ Render.Basic: [$sel:pShadowBinds:Pipelines] :: PipelinesF (f :: Type -> Type) -> Tagged Sun DsBindings
+ Render.Basic: [$sel:pShadowLayout:Pipelines] :: PipelinesF (f :: Type -> Type) -> Tagged '[Sun] DescriptorSetLayout
+ Render.Basic: allocateObservers :: RenderPasses -> PipelineWorkers -> ResourceT (StageRIO rs) PipelineObservers
+ Render.Basic: allocateWorkers :: Tagged Scene DsBindings -> SampleCountFlagBits -> RenderPasses -> ResourceT (StageRIO st) PipelineWorkers
+ Render.Basic: data PipelinesF (f :: Type -> Type)
+ Render.Basic: observePipelines :: RenderPasses -> PipelineWorkers -> PipelineObservers -> StageFrameRIO rp p fr rs ()
+ Render.Basic: rendering_ :: Rendering st
+ Render.Basic: shaderDir :: FilePath
+ Render.Basic: stageSources :: Map Text StageCode
+ Render.Basic: type PipelineObservers = PipelinesF Observers
+ Render.Basic: type PipelineWorkers = PipelinesF ConfigureGraphics
+ Render.Basic: type Pipelines = PipelinesF Identity
+ Render.Basic: type Rendering = Rendering RenderPasses Pipelines
+ Render.Debug.Code: frag :: Code
+ Render.Debug.Code: vert :: Code
+ Render.Debug.Pipeline: config :: Mode -> Tagged Scene DsBindings -> Config
+ Render.Debug.Pipeline: stageCode :: StageCode
+ Render.Debug.Pipeline: stageSpirv :: StageSpirv
+ Render.Debug.Pipeline: type Config = Configure Pipeline
+ Render.DepthOnly.Code: vert :: Code
+ Render.DepthOnly.Pipeline: stageCode :: StageCode
+ Render.DepthOnly.Pipeline: stageSpirv :: StageSpirv
+ Render.Font.EvanwSdf.Code: frag :: Code
+ Render.Font.EvanwSdf.Code: vert :: Code
+ Render.Font.EvanwSdf.Pipeline: config :: Tagged Scene DsBindings -> Config
+ Render.Font.EvanwSdf.Pipeline: stageCode :: StageCode
+ Render.Font.EvanwSdf.Pipeline: stageSpirv :: StageSpirv
+ Render.Font.EvanwSdf.Pipeline: type Config = Configure Pipeline
+ Render.Lit.Colored.Code: frag :: Code
+ Render.Lit.Colored.Code: vert :: Code
+ Render.Lit.Colored.Pipeline: stageCode :: StageCode
+ Render.Lit.Colored.Pipeline: stageSpirv :: StageSpirv
+ Render.Lit.Material.Code: frag :: Code
+ Render.Lit.Material.Code: vert :: Code
+ Render.Lit.Material.Pipeline: stageCode :: StageCode
+ Render.Lit.Material.Pipeline: stageSpirv :: StageSpirv
+ Render.Lit.Textured.Code: frag :: Code
+ Render.Lit.Textured.Code: vert :: Code
+ Render.Lit.Textured.Pipeline: stageCode :: StageCode
+ Render.Lit.Textured.Pipeline: stageSpirv :: StageSpirv
+ Render.ShadowMap.Code: vert :: Code
+ Render.ShadowMap.Pipeline: stageCode :: StageCode
+ Render.ShadowMap.Pipeline: stageSpirv :: StageSpirv
+ Render.Skybox.Code: frag :: Code
+ Render.Skybox.Code: vert :: Code
+ Render.Skybox.Pipeline: config :: Tagged Scene DsBindings -> Config
+ Render.Skybox.Pipeline: stageCode :: StageCode
+ Render.Skybox.Pipeline: stageSpirv :: StageSpirv
+ Render.Skybox.Pipeline: type Config = Configure Pipeline
+ Render.Unlit.Colored.Code: frag :: Code
+ Render.Unlit.Colored.Code: vert :: Code
+ Render.Unlit.Colored.Pipeline: stageCode :: StageCode
+ Render.Unlit.Colored.Pipeline: stageSpirv :: StageSpirv
+ Render.Unlit.Sprite.Code: frag :: Code
+ Render.Unlit.Sprite.Code: vert :: Code
+ Render.Unlit.Sprite.Pipeline: config :: Maybe Float -> Bool -> Tagged Scene DsBindings -> Config
+ Render.Unlit.Sprite.Pipeline: stageCode :: StageCode
+ Render.Unlit.Sprite.Pipeline: stageSpirv :: StageSpirv
+ Render.Unlit.Sprite.Pipeline: type Config = Configure Pipeline
+ Render.Unlit.Textured.Code: frag :: Code
+ Render.Unlit.Textured.Code: vert :: Code
+ Render.Unlit.Textured.Pipeline: stageCode :: StageCode
+ Render.Unlit.Textured.Pipeline: stageSpirv :: StageSpirv
+ Render.Unlit.TileMap.Code: frag :: Code
+ Render.Unlit.TileMap.Code: vert :: Code
+ Render.Unlit.TileMap.Pipeline: stageCode :: StageCode
- Render.Basic: Pipelines :: SampleCountFlagBits -> Tagged Scene DsBindings -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipelines
+ Render.Basic: Pipelines :: SampleCountFlagBits -> Tagged Scene DsBindings -> Tagged '[Scene] DescriptorSetLayout -> Tagged Sun DsBindings -> Tagged '[Sun] DescriptorSetLayout -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> (f ^ Pipeline) -> PipelinesF (f :: Type -> Type)
- Render.Basic: [$sel:pDebugShadow:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pDebugShadow:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pDebugTexture:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pDebugTexture:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pDebugUV:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pDebugUV:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pDepthOnly:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pDepthOnly:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pEvanwSdf:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pEvanwSdf:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pLitColored:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pLitColored:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pLitColoredBlend:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pLitColoredBlend:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pLitMaterial:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pLitMaterial:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pLitMaterialBlend:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pLitMaterialBlend:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pLitTextured:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pLitTextured:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pLitTexturedBlend:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pLitTexturedBlend:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pMSAA:Pipelines] :: Pipelines -> SampleCountFlagBits
+ Render.Basic: [$sel:pMSAA:Pipelines] :: PipelinesF (f :: Type -> Type) -> SampleCountFlagBits
- Render.Basic: [$sel:pSceneBinds:Pipelines] :: Pipelines -> Tagged Scene DsBindings
+ Render.Basic: [$sel:pSceneBinds:Pipelines] :: PipelinesF (f :: Type -> Type) -> Tagged Scene DsBindings
- Render.Basic: [$sel:pShadowCast:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pShadowCast:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pSkybox:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pSkybox:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pSprite:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pSprite:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pSpriteOutline:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pSpriteOutline:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pTileMap:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pTileMap:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pTileMapBlend:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pTileMapBlend:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pUnlitColored:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pUnlitColored:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pUnlitColoredNoDepth:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pUnlitColoredNoDepth:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pUnlitTextured:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pUnlitTextured:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pUnlitTexturedBlend:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pUnlitTexturedBlend:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pWireframe:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pWireframe:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: [$sel:pWireframeNoDepth:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pWireframeNoDepth:Pipelines] :: PipelinesF (f :: Type -> Type) -> f ^ Pipeline
- Render.Basic: getSceneLayout :: Pipelines -> Tagged '[Scene] DescriptorSetLayout
+ Render.Basic: getSceneLayout :: PipelinesF f -> Tagged '[Scene] DescriptorSetLayout
- Render.DepthOnly.Pipeline: type Config = Configure Pipeline ()
+ Render.DepthOnly.Pipeline: type Config = Configure Pipeline
- Render.Lit.Colored.Pipeline: type Config = Configure Pipeline ()
+ Render.Lit.Colored.Pipeline: type Config = Configure Pipeline
- Render.Lit.Material.Pipeline: type Config = Configure Pipeline ()
+ Render.Lit.Material.Pipeline: type Config = Configure Pipeline
- Render.Lit.Textured.Pipeline: type Config = Configure Pipeline ()
+ Render.Lit.Textured.Pipeline: type Config = Configure Pipeline
- Render.ShadowMap.Pipeline: type Config = Configure Pipeline ()
+ Render.ShadowMap.Pipeline: type Config = Configure Pipeline
- Render.Unlit.Colored.Pipeline: type Config = Configure Pipeline ()
+ Render.Unlit.Colored.Pipeline: type Config = Configure Pipeline
- Render.Unlit.Textured.Pipeline: type Config = Configure Pipeline ()
+ Render.Unlit.Textured.Pipeline: type Config = Configure Pipeline
- Render.Unlit.TileMap.Pipeline: type Config = Configure Pipeline ()
+ Render.Unlit.TileMap.Pipeline: type Config = Configure Pipeline
Files
- ChangeLog.md +11/−0
- keid-render-basic.cabal +14/−2
- src/Render/Basic.hs +576/−42
- src/Render/Debug/Code.hs +123/−0
- src/Render/Debug/Pipeline.hs +30/−128
- src/Render/DepthOnly/Code.hs +37/−0
- src/Render/DepthOnly/Pipeline.hs +21/−38
- src/Render/Font/EvanwSdf/Code.hs +114/−0
- src/Render/Font/EvanwSdf/Pipeline.hs +34/−121
- src/Render/Lit/Colored/Code.hs +100/−0
- src/Render/Lit/Colored/Pipeline.hs +25/−103
- src/Render/Lit/Material/Code.hs +175/−0
- src/Render/Lit/Material/Pipeline.hs +28/−181
- src/Render/Lit/Textured/Code.hs +120/−0
- src/Render/Lit/Textured/Pipeline.hs +28/−126
- src/Render/ShadowMap/Code.hs +33/−0
- src/Render/ShadowMap/Pipeline.hs +24/−36
- src/Render/Skybox/Code.hs +64/−0
- src/Render/Skybox/Pipeline.hs +29/−65
- src/Render/Unlit/Colored/Code.hs +50/−0
- src/Render/Unlit/Colored/Pipeline.hs +31/−59
- src/Render/Unlit/Sprite/Code.hs +125/−0
- src/Render/Unlit/Sprite/Pipeline.hs +29/−131
- src/Render/Unlit/Textured/Code.hs +83/−0
- src/Render/Unlit/Textured/Pipeline.hs +26/−86
- src/Render/Unlit/TileMap/Code.hs +111/−0
- src/Render/Unlit/TileMap/Pipeline.hs +25/−112
- src/Stage/Loader/Render.hs +3/−3
- src/Stage/Loader/Setup.hs +19/−15
ChangeLog.md view
@@ -1,5 +1,16 @@ # Changelog for keid-render-basic +## 0.1.7.0++- Pipelines updated to use `Engine.Vulkan.Pipeline.Graphics`.+- Pipelines wrapped in a HKD.+ * The `Pipelines` is now an alias for `Identity` wrapper.+ * The data type is now `PipelinesF f` with a hole for HKD parameter.+ * The constructor name is still `Pipelines`, with all the fields intact.+- Added a bunch of functions to work with runtime-reloadable pipelines.+- Expose `stageCode` and `stageSpirv` for all pipelines.+- Added `Render.Basic.rendering` reusable stage component.+ ## 0.1.6.1 - `withFrozenCallStack` fixes for GHC-9.0.
keid-render-basic.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: keid-render-basic-version: 0.1.6.1+version: 0.1.7.0 synopsis: Basic rendering programs for Keid engine. category: Game Engine homepage: https://keid.haskell-game.dev@@ -37,32 +37,44 @@ Global.Resource.Texture.Base.Paths Render.Basic Render.Code.Lit+ Render.Debug.Code Render.Debug.Model Render.Debug.Pipeline+ Render.DepthOnly.Code Render.DepthOnly.Pipeline Render.DescSets.Set0 Render.DescSets.Set0.Code Render.DescSets.Sun+ Render.Font.EvanwSdf.Code Render.Font.EvanwSdf.Model Render.Font.EvanwSdf.Pipeline Render.ForwardMsaa+ Render.Lit.Colored.Code Render.Lit.Colored.Model Render.Lit.Colored.Pipeline Render.Lit.Material+ Render.Lit.Material.Code Render.Lit.Material.Collect Render.Lit.Material.Model Render.Lit.Material.Pipeline+ Render.Lit.Textured.Code Render.Lit.Textured.Model Render.Lit.Textured.Pipeline+ Render.ShadowMap.Code Render.ShadowMap.Pipeline Render.ShadowMap.RenderPass+ Render.Skybox.Code Render.Skybox.Pipeline+ Render.Unlit.Colored.Code Render.Unlit.Colored.Model Render.Unlit.Colored.Pipeline+ Render.Unlit.Sprite.Code Render.Unlit.Sprite.Model Render.Unlit.Sprite.Pipeline+ Render.Unlit.Textured.Code Render.Unlit.Textured.Model Render.Unlit.Textured.Pipeline+ Render.Unlit.TileMap.Code Render.Unlit.TileMap.Model Render.Unlit.TileMap.Pipeline Resource.Font@@ -143,7 +155,7 @@ , derive-storable-plugin , file-embed >=0.0.10 , geomancy- , keid-core >=0.1.6.1+ , keid-core >=0.1.7.0 , keid-geometry , neat-interpolation , resourcet
src/Render/Basic.hs view
@@ -1,3 +1,6 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE OverloadedLists #-}+ {- | All the provided render passes and pipelines packaged and delivered. -}@@ -7,18 +10,27 @@ import RIO import Control.Monad.Trans.Resource (ResourceT)+import Data.Kind (Type) import Data.Tagged (Tagged(..))+import RIO.FilePath ((</>), (<.>)) import RIO.Vector.Partial as Vector (headM) import Vulkan.Core10 qualified as Vk import Vulkan.Zero (Zero(..)) -- keid-core +import Engine.Stage.Component qualified as Stage import Engine.Types (StageRIO) import Engine.Types qualified as Engine import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.External (type (^))+import Engine.Vulkan.Pipeline.External qualified as External+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics+import Engine.Vulkan.Shader qualified as Shader import Engine.Vulkan.Swapchain qualified as Swapchain import Engine.Vulkan.Types (DsBindings, HasSwapchain, HasVulkan, RenderPass(..))+import Engine.Worker qualified as Worker+import Resource.Region qualified as Region -- keid-render-basic @@ -48,6 +60,16 @@ type Frame = Engine.Frame RenderPasses Pipelines type StageFrameRIO r s a = Engine.StageFrameRIO RenderPasses Pipelines r s a +-- | Basic rendering component without any extensions.+type Rendering = Stage.Rendering RenderPasses Pipelines++-- | Basic rendering component without any extensions and resources.+rendering_ :: Rendering st+rendering_ = Stage.Rendering+ { rAllocateRP = allocate_+ , rAllocateP = allocatePipelines_+ }+ data RenderPasses = RenderPasses { rpForwardMsaa :: ForwardMsaa , rpShadowPass :: ShadowMap@@ -102,39 +124,47 @@ -> ResourceT (RIO env) RenderPasses allocate_ = allocate zero -data Pipelines = Pipelines+type Pipelines = PipelinesF Identity+type PipelineObservers = PipelinesF External.Observers+type PipelineWorkers = PipelinesF External.ConfigureGraphics++data PipelinesF (f :: Type -> Type) = Pipelines { pMSAA :: Vk.SampleCountFlagBits , pSceneBinds :: Tagged Scene DsBindings+ , pSceneLayout :: Tagged '[Scene] Vk.DescriptorSetLayout - , pEvanwSdf :: EvanwSdf.Pipeline- , pSkybox :: Skybox.Pipeline+ , pShadowBinds :: Tagged Sun DsBindings+ , pShadowLayout :: Tagged '[Sun] Vk.DescriptorSetLayout - , pDebugUV :: Debug.Pipeline- , pDebugTexture :: Debug.Pipeline- , pDebugShadow :: Debug.Pipeline+ , pEvanwSdf :: f ^ EvanwSdf.Pipeline+ , pSkybox :: f ^ Skybox.Pipeline - , pDepthOnly :: DepthOnly.Pipeline+ , pDebugUV :: f ^ Debug.Pipeline+ , pDebugTexture :: f ^ Debug.Pipeline+ , pDebugShadow :: f ^ Debug.Pipeline - , pLitColored :: LitColored.Pipeline- , pLitColoredBlend :: LitColored.Pipeline- , pLitMaterial :: LitMaterial.Pipeline- , pLitMaterialBlend :: LitMaterial.Pipeline- , pLitTextured :: LitTextured.Pipeline- , pLitTexturedBlend :: LitTextured.Pipeline+ , pDepthOnly :: f ^ DepthOnly.Pipeline - , pUnlitColored :: UnlitColored.Pipeline- , pUnlitColoredNoDepth :: UnlitColored.Pipeline- , pUnlitTextured :: UnlitTextured.Pipeline- , pUnlitTexturedBlend :: UnlitTextured.Pipeline+ , pLitColored :: f ^ LitColored.Pipeline+ , pLitColoredBlend :: f ^ LitColored.Pipeline+ , pLitMaterial :: f ^ LitMaterial.Pipeline+ , pLitMaterialBlend :: f ^ LitMaterial.Pipeline+ , pLitTextured :: f ^ LitTextured.Pipeline+ , pLitTexturedBlend :: f ^ LitTextured.Pipeline - , pSprite :: UnlitSprite.Pipeline- , pSpriteOutline :: UnlitSprite.Pipeline- , pTileMap :: UnlitTileMap.Pipeline- , pTileMapBlend :: UnlitTileMap.Pipeline- , pWireframe :: UnlitColored.Pipeline- , pWireframeNoDepth :: UnlitColored.Pipeline+ , pUnlitColored :: f ^ UnlitColored.Pipeline+ , pUnlitColoredNoDepth :: f ^ UnlitColored.Pipeline+ , pUnlitTextured :: f ^ UnlitTextured.Pipeline+ , pUnlitTexturedBlend :: f ^ UnlitTextured.Pipeline - , pShadowCast :: ShadowPipe.Pipeline+ , pSprite :: f ^ UnlitSprite.Pipeline+ , pSpriteOutline :: f ^ UnlitSprite.Pipeline+ , pTileMap :: f ^ UnlitTileMap.Pipeline+ , pTileMapBlend :: f ^ UnlitTileMap.Pipeline+ , pWireframe :: f ^ UnlitColored.Pipeline+ , pWireframeNoDepth :: f ^ UnlitColored.Pipeline++ , pShadowCast :: f ^ ShadowPipe.Pipeline } allocatePipelines_@@ -157,13 +187,13 @@ -> RenderPasses -> ResourceT (StageRIO st) Pipelines allocatePipelines pSceneBinds pMSAA RenderPasses{..} = do+ pEvanwSdf <- EvanwSdf.allocate pMSAA pSceneBinds rpForwardMsaa+ pSkybox <- Skybox.allocate pMSAA pSceneBinds rpForwardMsaa+ pDebugUV <- Debug.allocate Debug.UV pMSAA pSceneBinds rpForwardMsaa pDebugTexture <- Debug.allocate Debug.Texture pMSAA pSceneBinds rpForwardMsaa pDebugShadow <- Debug.allocate (Debug.Shadow 1) pMSAA pSceneBinds rpForwardMsaa - pEvanwSdf <- EvanwSdf.allocate pMSAA pSceneBinds rpForwardMsaa- pSkybox <- Skybox.allocate pMSAA pSceneBinds rpForwardMsaa- pDepthOnly <- DepthOnly.allocate pMSAA pSceneBinds rpForwardMsaa pLitColored <- LitColored.allocate pMSAA pSceneBinds rpForwardMsaa@@ -184,23 +214,527 @@ pWireframe <- UnlitColored.allocateWireframe True pMSAA pSceneBinds rpForwardMsaa pWireframeNoDepth <- UnlitColored.allocateWireframe False pMSAA pSceneBinds rpForwardMsaa - let sunBinds = Sun.set0- pShadowCast <- ShadowPipe.allocate sunBinds rpShadowPass ShadowPipe.defaults+ let pShadowBinds = Sun.set0+ pShadowCast <- ShadowPipe.allocate pShadowBinds rpShadowPass ShadowPipe.defaults + let+ pSceneLayout =+ case Vector.headM (unTagged $ Pipeline.pDescLayouts pLitColored) of+ Nothing ->+ error "pLitColored has at least set0 in layout"+ Just set0layout ->+ Tagged set0layout++ pShadowLayout =+ case Vector.headM (unTagged $ Pipeline.pDescLayouts pShadowCast) of+ Nothing ->+ error "pShadowCast has at least set0 in layout"+ Just set0layout ->+ Tagged set0layout+ pure Pipelines{..} -getSceneLayout :: Pipelines -> Tagged '[Scene] Vk.DescriptorSetLayout-getSceneLayout Pipelines{pLitColored} =- case Vector.headM (unTagged $ Pipeline.pDescLayouts pLitColored) of- Nothing ->- error "pLitColored has at least set0 in layout"- Just set0layout ->- Tagged set0layout+allocateWorkers+ :: Tagged Scene DsBindings+ -> Vk.SampleCountFlagBits+ -> RenderPasses+ -> ResourceT (StageRIO st) PipelineWorkers+allocateWorkers sceneBinds pMSAA renderPasses = do+ builtin <- allocatePipelines sceneBinds pMSAA renderPasses + let+ evanwSdfFiles =+ Graphics.basicStages+ (shaderDir </> "evanw-sdf" <.> "vert" <.> "spv")+ (shaderDir </> "evanw-sdf" <.> "frag" <.> "spv")++ evanwSdfWorker <- Region.local . Worker.registered $+ External.spawnReflect "evanw-sdf" evanwSdfFiles \(stageCode, reflect) ->+ (EvanwSdf.config sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ let+ skyboxFiles =+ Graphics.basicStages+ (shaderDir </> "skybox" <.> "vert" <.> "spv")+ (shaderDir </> "skybox" <.> "frag" <.> "spv")++ skyboxWorker <- Region.local . Worker.registered $+ External.spawnReflect "skybox" skyboxFiles \(stageCode, reflect) ->+ (Skybox.config sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ let+ debugFiles =+ Graphics.basicStages+ (shaderDir </> "debug" <.> "vert" <.> "spv")+ (shaderDir </> "debug" <.> "frag" <.> "spv")++ debugUVWorker <- Region.local . Worker.registered $+ External.spawnReflect "debug-uv" debugFiles \(stageCode, reflect) ->+ (Debug.config Debug.UV sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ debugTextureWorker <- Region.local . Worker.registered $+ External.spawnReflect "debug-texture" debugFiles \(stageCode, reflect) ->+ (Debug.config Debug.Texture sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ debugShadowWorker <- Region.local . Worker.registered $+ External.spawnReflect "debug-shadow" debugFiles \(stageCode, reflect) ->+ (Debug.config (Debug.Shadow 1) sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ let+ depthOnlyFiles = Graphics.vertexOnly+ (shaderDir </> "depth-only" <.> "vert" <.> "spv")++ depthOnlyWorker <- Region.local . Worker.registered $+ External.spawnReflect "debug" depthOnlyFiles \(stageCode, reflect) ->+ (DepthOnly.config sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ let+ litColoredFiles =+ Graphics.basicStages+ (shaderDir </> "lit-colored" <.> "vert" <.> "spv")+ (shaderDir </> "lit-colored" <.> "frag" <.> "spv")++ litColoredWorker <- Region.local . Worker.registered $+ External.spawnReflect "lit-colored" litColoredFiles \(stageCode, reflect) ->+ (LitColored.config sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ litColoredBlendWorker <- Region.local . Worker.registered $+ External.spawnReflect "lit-colored-blend" litColoredFiles \(stageCode, reflect) ->+ (LitColored.configBlend sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ let+ litMaterialFiles =+ Graphics.basicStages+ (shaderDir </> "lit-material" <.> "vert" <.> "spv")+ (shaderDir </> "lit-material" <.> "frag" <.> "spv")++ litMaterialWorker <- Region.local . Worker.registered $+ External.spawnReflect "lit-material" litMaterialFiles \(stageCode, reflect) ->+ (LitMaterial.config sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ litMaterialBlendWorker <- Region.local . Worker.registered $+ External.spawnReflect "lit-material-blend" litMaterialFiles \(stageCode, reflect) ->+ (LitMaterial.configBlend sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ let+ litTexturedFiles =+ Graphics.basicStages+ (shaderDir </> "lit-textured" <.> "vert" <.> "spv")+ (shaderDir </> "lit-textured" <.> "frag" <.> "spv")++ litTexturedWorker <- Region.local . Worker.registered $+ External.spawnReflect "lit-textured" litTexturedFiles \(stageCode, reflect) ->+ (LitTextured.config sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ litTexturedBlendWorker <- Region.local . Worker.registered $+ External.spawnReflect "lit-textured-blend" litTexturedFiles \(stageCode, reflect) ->+ (LitTextured.configBlend sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ let+ unlitColoredFiles =+ Graphics.basicStages+ (shaderDir </> "unlit-colored" <.> "vert" <.> "spv")+ (shaderDir </> "unlit-colored" <.> "frag" <.> "spv")++ unlitColoredWorker <- Region.local . Worker.registered $+ External.spawnReflect "unlit-colored" unlitColoredFiles \(stageCode, reflect) ->+ (UnlitColored.config True sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ unlitColoredNoDepthWorker <- Region.local . Worker.registered $+ External.spawnReflect "unlit-colored-nodepth" unlitColoredFiles \(stageCode, reflect) ->+ (UnlitColored.config False sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ let+ unlitTexturedFiles =+ Graphics.basicStages+ (shaderDir </> "unlit-textured" <.> "vert" <.> "spv")+ (shaderDir </> "unlit-textured" <.> "frag" <.> "spv")++ unlitTexturedWorker <- Region.local . Worker.registered $+ External.spawnReflect "unlit-textured" unlitTexturedFiles \(stageCode, reflect) ->+ (UnlitTextured.config sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ unlitTexturedBlendWorker <- Region.local . Worker.registered $+ External.spawnReflect "unlit-textured" unlitTexturedFiles \(stageCode, reflect) ->+ (UnlitTextured.configBlend sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ let+ spriteFiles =+ Graphics.basicStages+ (shaderDir </> "sprite" <.> "vert" <.> "spv")+ (shaderDir </> "sprite" <.> "frag" <.> "spv")++ spriteWorker <- Region.local . Worker.registered $+ External.spawnReflect "sprite" spriteFiles \(stageCode, reflect) ->+ (UnlitSprite.config Nothing False sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ spriteOutlineWorker <- Region.local . Worker.registered $+ External.spawnReflect "sprite" spriteFiles \(stageCode, reflect) ->+ (UnlitSprite.config Nothing True sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ let+ tileMapFiles =+ Graphics.basicStages+ (shaderDir </> "tilemap" <.> "vert" <.> "spv")+ (shaderDir </> "tilemap" <.> "frag" <.> "spv")++ tileMapWorker <- Region.local . Worker.registered $+ External.spawnReflect "tilemap" tileMapFiles \(stageCode, reflect) ->+ (UnlitTileMap.config sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ tileMapBlendWorker <- Region.local . Worker.registered $+ External.spawnReflect "tilemap" tileMapFiles \(stageCode, reflect) ->+ (UnlitTileMap.configBlend sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ wireframeWorker <- Region.local . Worker.registered $+ External.spawnReflect "wireframe" unlitColoredFiles \(stageCode, reflect) ->+ (UnlitColored.configWireframe True sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ wireframeNoDepthWorker <- Region.local . Worker.registered $+ External.spawnReflect "wireframe-nodepth" unlitColoredFiles \(stageCode, reflect) ->+ (UnlitColored.configWireframe False sceneBinds)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ let+ shadowCastFiles =+ Graphics.vertexOnly+ (shaderDir </> "shadow-cast" <.> "vert" <.> "spv")++ shadowCastWorker <- Region.local . Worker.registered $+ External.spawnReflect "shadow-cast" shadowCastFiles \(stageCode, reflect) ->+ (ShadowPipe.config (pShadowBinds builtin) ShadowPipe.defaults)+ { Graphics.cStages = stageCode+ , Graphics.cReflect = Just reflect+ }++ pure builtin+ { pEvanwSdf = evanwSdfWorker+ , pSkybox = skyboxWorker+ , pDebugUV = debugUVWorker+ , pDebugTexture = debugTextureWorker+ , pDebugShadow = debugShadowWorker+ , pDepthOnly = depthOnlyWorker+ , pLitColored = litColoredWorker+ , pLitColoredBlend = litColoredBlendWorker+ , pLitMaterial = litMaterialWorker+ , pLitMaterialBlend = litMaterialBlendWorker+ , pLitTextured = litTexturedWorker+ , pLitTexturedBlend = litTexturedBlendWorker+ , pUnlitColored = unlitColoredWorker+ , pUnlitColoredNoDepth = unlitColoredNoDepthWorker+ , pUnlitTextured = unlitTexturedWorker+ , pUnlitTexturedBlend = unlitTexturedBlendWorker+ , pSprite = spriteWorker+ , pSpriteOutline = spriteOutlineWorker+ , pTileMap = tileMapWorker+ , pTileMapBlend = tileMapBlendWorker+ , pWireframe = wireframeWorker+ , pWireframeNoDepth = wireframeNoDepthWorker+ , pShadowCast = shadowCastWorker+ }++allocateObservers+ :: RenderPasses+ -> PipelineWorkers+ -> ResourceT (Engine.StageRIO rs) PipelineObservers+allocateObservers renderPasses Pipelines{..} = do+ evanwSdfExt <- External.newObserverGraphics+ forward+ pMSAA+ pEvanwSdf++ skyboxExt <- External.newObserverGraphics+ forward+ pMSAA+ pSkybox++ debugUVExt <- External.newObserverGraphics+ forward+ pMSAA+ pDebugUV++ debugTextureExt <- External.newObserverGraphics+ forward+ pMSAA+ pDebugTexture++ debugShadowExt <- External.newObserverGraphics+ forward+ pMSAA+ pDebugShadow++ depthOnlyExt <- External.newObserverGraphics+ forward+ pMSAA+ pDepthOnly++ litColoredExt <- External.newObserverGraphics+ forward+ pMSAA+ pLitColored++ litColoredBlendExt <- External.newObserverGraphics+ forward+ pMSAA+ pLitColoredBlend++ litMaterialExt <- External.newObserverGraphics+ forward+ pMSAA+ pLitMaterial++ litMaterialBlendExt <- External.newObserverGraphics+ forward+ pMSAA+ pLitMaterialBlend++ litTexturedExt <- External.newObserverGraphics+ forward+ pMSAA+ pLitTextured++ litTexturedBlendExt <- External.newObserverGraphics+ forward+ pMSAA+ pLitTexturedBlend++ unlitColoredExt <- External.newObserverGraphics+ forward+ pMSAA+ pUnlitColored++ unlitColoredNoDepthExt <- External.newObserverGraphics+ forward+ pMSAA+ pUnlitColoredNoDepth++ unlitTexturedExt <- External.newObserverGraphics+ forward+ pMSAA+ pUnlitTextured++ unlitTexturedBlendExt <- External.newObserverGraphics+ forward+ pMSAA+ pUnlitTexturedBlend++ spriteExt <- External.newObserverGraphics+ forward+ pMSAA+ pSprite++ spriteOutlineExt <- External.newObserverGraphics+ forward+ pMSAA+ pSpriteOutline++ tileMapExt <- External.newObserverGraphics+ forward+ pMSAA+ pTileMap++ tileMapBlendExt <- External.newObserverGraphics+ forward+ pMSAA+ pTileMapBlend++ wireframeExt <- External.newObserverGraphics+ forward+ pMSAA+ pWireframe++ wireframeNoDepthExt <- External.newObserverGraphics+ forward+ pMSAA+ pWireframeNoDepth++ shadowCastExt <- External.newObserverGraphics+ forward+ pMSAA+ pShadowCast++ pure Pipelines+ { pEvanwSdf = evanwSdfExt+ , pSkybox = skyboxExt+ , pDebugUV = debugUVExt+ , pDebugTexture = debugTextureExt+ , pDebugShadow = debugShadowExt+ , pDepthOnly = depthOnlyExt+ , pLitColored = litColoredExt+ , pLitColoredBlend = litColoredBlendExt+ , pLitMaterial = litMaterialExt+ , pLitMaterialBlend = litMaterialBlendExt+ , pLitTextured = litTexturedExt+ , pLitTexturedBlend = litTexturedBlendExt+ , pUnlitColored = unlitColoredExt+ , pUnlitColoredNoDepth = unlitColoredNoDepthExt+ , pUnlitTextured = unlitTexturedExt+ , pUnlitTexturedBlend = unlitTexturedBlendExt+ , pSprite = spriteExt+ , pSpriteOutline = spriteOutlineExt+ , pTileMap = tileMapExt+ , pTileMapBlend = tileMapBlendExt+ , pWireframe = wireframeExt+ , pWireframeNoDepth = wireframeNoDepthExt+ , pShadowCast = shadowCastExt+ , ..+ }+ where+ forward = rpForwardMsaa renderPasses++observePipelines+ :: RenderPasses+ -> PipelineWorkers+ -> PipelineObservers+ -> Engine.StageFrameRIO rp p fr rs ()+observePipelines fRenderpass workers pipelines = do+ observe @EvanwSdf.Pipeline pEvanwSdf++ observe @Skybox.Pipeline pSkybox++ observe @Debug.Pipeline pDebugUV+ observe @Debug.Pipeline pDebugTexture+ observe @Debug.Pipeline pDebugShadow++ observe @DepthOnly.Pipeline pDepthOnly++ observe @LitColored.Pipeline pLitColored+ observe @LitColored.Pipeline pLitColoredBlend++ observe @LitTextured.Pipeline pLitTextured+ observe @LitTextured.Pipeline pLitTexturedBlend++ observe @LitMaterial.Pipeline pLitMaterial+ observe @LitMaterial.Pipeline pLitMaterialBlend++ observe @UnlitColored.Pipeline pUnlitColored+ observe @UnlitColored.Pipeline pUnlitColoredNoDepth++ observe @UnlitTextured.Pipeline pUnlitTextured+ observe @UnlitTextured.Pipeline pUnlitTexturedBlend++ observe @UnlitSprite.Pipeline pSprite+ observe @UnlitSprite.Pipeline pSpriteOutline++ observe @UnlitTileMap.Pipeline pTileMap+ observe @UnlitTileMap.Pipeline pTileMapBlend++ observe @UnlitColored.Pipeline pWireframe+ observe @UnlitColored.Pipeline pWireframeNoDepth++ External.observeGraphics+ (rpShadowPass fRenderpass) -- XXX: different RP here+ (pMSAA workers)+ (Tagged [unTagged $ pSceneBinds pipelines])+ (pShadowCast workers)+ (pShadowCast pipelines)+ where+ observe+ :: forall+ p+ s vs is+ rps ps fr rs+ . ( p ~ Graphics.Pipeline s vs is+ , Shader.Specialization (Graphics.Specialization p)+ )+ => (forall a . PipelinesF a -> a ^ p)+ -> Engine.StageFrameRIO rps ps fr rs ()+ observe =+ External.observeField+ @PipelinesF+ @p+ (rpForwardMsaa fRenderpass)+ (pMSAA workers)+ (pSceneBinds pipelines)+ workers+ pipelines++getSceneLayout :: PipelinesF f -> Tagged '[Scene] Vk.DescriptorSetLayout+getSceneLayout = pSceneLayout+ getSunLayout :: Pipelines -> Tagged '[Sun] Vk.DescriptorSetLayout-getSunLayout Pipelines{pShadowCast} =- case Vector.headM (unTagged $ Pipeline.pDescLayouts pShadowCast) of- Nothing ->- error "pShadowCast has at least set0 in layout"- Just set0layout ->- Tagged set0layout+getSunLayout = pShadowLayout++shaderDir :: FilePath+shaderDir = "data" </> "shaders" </> "basic"++stageSources :: Map Text Graphics.StageCode+stageSources =+ [ ("evanw-sdf", EvanwSdf.stageCode)+ , ("skybox", Skybox.stageCode)+ , ("debug", Debug.stageCode)+ , ("depth-only", DepthOnly.stageCode)+ , ("lit-colored", LitColored.stageCode)+ , ("lit-material", LitMaterial.stageCode)+ , ("lit-textured", LitTextured.stageCode)+ , ("unlit-colored", UnlitColored.stageCode)+ , ("unlit-textured", UnlitTextured.stageCode)+ , ("sprite", UnlitSprite.stageCode)+ , ("tilemap", UnlitTileMap.stageCode)+ , ("shadow-cast", ShadowPipe.stageCode)+ ]
+ src/Render/Debug/Code.hs view
@@ -0,0 +1,123 @@+module Render.Debug.Code+ ( vert+ , frag+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2, set0binding3, set0binding5color)++vert :: Code+vert = fromString+ [glsl|+ #version 450++ ${set0binding0}++ // vertexPos+ layout(location = 0) in vec3 vPosition;+ // vertexAttrs+ layout(location = 1) in vec2 vTexCoord;+ // textureParams+ layout(location = 2) in vec4 iTextureScaleOffset;+ layout(location = 3) in vec4 iTextureGamma;+ layout(location = 4) in ivec2 iTextureIds;++ // transformMat+ layout(location = 5) in mat4 iModel;++ layout(location = 0) out vec2 fTexCoord;+ layout(location = 1) flat out vec4 fTextureGamma;+ layout(location = 2) flat out ivec2 fTextureIds;++ void main() {+ vec4 fPosition = iModel * vec4(vPosition, 1.0);++ gl_Position+ = scene.projection+ * scene.view+ * fPosition;++ fTexCoord = vTexCoord * iTextureScaleOffset.st + iTextureScaleOffset.pq;+ fTextureGamma = iTextureGamma;+ fTextureIds = iTextureIds;+ }+ |]++frag :: Code+frag = fromString+ [glsl|+ #version 450+ #extension GL_EXT_nonuniform_qualifier : enable++ ${set0binding1}+ ${set0binding2}+ ${set0binding3}+ ${set0binding5color}++ layout(location = 0) in vec2 fTexCoord;+ layout(location = 1) flat in vec4 fTextureGamma;+ layout(location = 2) flat in ivec2 fTextureIds;++ layout(location = 0) out vec4 oColor;++ layout (constant_id=0) const uint mode = 0;+ layout (constant_id=1) const uint shadow_mask = 0;++ void main() {+ vec4 texel = vec4(0);++ switch(mode) {+ case 0:+ texel = vec4(fTexCoord, 0, 1);+ break;++ case 1:+ if ((fTextureIds.t < 0) || (fTextureIds.s < 0)) break;++ texel = texture(+ sampler2D(+ textures[nonuniformEXT(fTextureIds.t)],+ samplers[nonuniformEXT(fTextureIds.s)]+ ),+ fTexCoord+ );+ break;++ case 2:+ float d0 = 1.0;+ if ((shadow_mask & 1) == 1)+ d0 = texture(+ shadowmaps,+ vec3(fTexCoord, 0.0)+ ).x;++ float d1 = 1.0;+ if ((shadow_mask & 2) == 2)+ d1 = texture(+ shadowmaps,+ vec3(fTexCoord, 1.0)+ ).x;++ float d2 = 1.0;+ if ((shadow_mask & 4) == 4)+ d2 = texture(+ shadowmaps,+ vec3(fTexCoord, 2.0)+ ).x;++ texel = vec4(1-d0, 1-d1, 1-d2, 1.0);+ break;++ default:+ break;+ }++ vec3 color = pow(texel.rgb, fTextureGamma.rgb);+ float combinedAlpha = texel.a * fTextureGamma.a;++ // XXX: premultiply alpha due to additive blending+ oColor = vec4(color * combinedAlpha, combinedAlpha);+ }+ |]
src/Render/Debug/Pipeline.hs view
@@ -1,7 +1,11 @@ module Render.Debug.Pipeline- ( Pipeline+ ( Config+ , config+ , Pipeline , allocate , Mode(..)+ , stageCode+ , stageSpirv ) where import RIO@@ -10,15 +14,17 @@ import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk -import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Shader qualified as Shader import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, compileFrag, glsl)+import Render.Code (compileVert, compileFrag)+import Render.Debug.Code qualified as Code import Render.Debug.Model qualified as Model import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform)-import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2, set0binding3, set0binding5color) -type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Pipeline = Graphics.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = Mode data Mode = UV@@ -44,136 +50,32 @@ -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline-allocate mode multisample (Tagged set0) = do- fmap snd . Pipeline.allocate Nothing multisample config- where- config = Pipeline.baseConfig- { Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cVertexCode = Just vertCode- , Pipeline.cVertexInput = vertexInput- , Pipeline.cFragmentCode = Just fragCode- , Pipeline.cSpecialization = mode- }+allocate mode multisample tset0 = do+ fmap snd . Graphics.allocate Nothing multisample (config mode tset0) - vertexInput = Pipeline.vertexInput+config :: Mode -> Tagged Scene DsBindings -> Config+config mode (Tagged set0) = Graphics.baseConfig+ { Graphics.cDescLayouts = Tagged @'[Scene] [set0]+ , Graphics.cStages = stageSpirv+ , Graphics.cVertexInput = vertexInput+ , Graphics.cSpecialization = mode+ }+ where+ vertexInput = Graphics.vertexInput [ vertexPos -- vPosition , (Vk.VERTEX_INPUT_RATE_VERTEX, Model.vkVertexAttrs) , (Vk.VERTEX_INPUT_RATE_INSTANCE, Model.vkInstanceTexture) , instanceTransform ] -vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable-- ${set0binding0}-- // vertexPos- layout(location = 0) in vec3 vPosition;- // vertexAttrs- layout(location = 1) in vec2 vTexCoord;- // textureParams- layout(location = 2) in vec4 iTextureScaleOffset;- layout(location = 3) in vec4 iTextureGamma;- layout(location = 4) in ivec2 iTextureIds;-- // transformMat- layout(location = 5) in mat4 iModel;-- layout(location = 0) out vec2 fTexCoord;- layout(location = 1) flat out vec4 fTextureGamma;- layout(location = 2) flat out ivec2 fTextureIds;-- void main() {- vec4 fPosition = iModel * vec4(vPosition, 1.0);-- gl_Position- = scene.projection- * scene.view- * fPosition;-- fTexCoord = vTexCoord * iTextureScaleOffset.st + iTextureScaleOffset.pq;- fTextureGamma = iTextureGamma;- fTextureIds = iTextureIds;- }- |])--fragCode :: ByteString-fragCode =- $(compileFrag [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable- #extension GL_EXT_nonuniform_qualifier : enable-- ${set0binding1}- ${set0binding2}- ${set0binding3}- ${set0binding5color}-- layout(location = 0) in vec2 fTexCoord;- layout(location = 1) flat in vec4 fTextureGamma;- layout(location = 2) flat in ivec2 fTextureIds;-- layout(location = 0) out vec4 oColor;-- layout (constant_id=0) const uint mode = 0;- layout (constant_id=1) const uint shadow_mask = 0;-- void main() {- vec4 texel = vec4(0);-- switch(mode) {- case 0:- texel = vec4(fTexCoord, 0, 1);- break;-- case 1:- if ((fTextureIds.t < 0) || (fTextureIds.s < 0)) break;-- texel = texture(- sampler2D(- textures[nonuniformEXT(fTextureIds.t)],- samplers[nonuniformEXT(fTextureIds.s)]- ),- fTexCoord- );- break;-- case 2:- float d0 = 1.0;- if ((shadow_mask & 1) == 1)- d0 = texture(- shadowmaps,- vec3(fTexCoord, 0.0)- ).x;-- float d1 = 1.0;- if ((shadow_mask & 2) == 2)- d1 = texture(- shadowmaps,- vec3(fTexCoord, 1.0)- ).x;-- float d2 = 1.0;- if ((shadow_mask & 4) == 4)- d2 = texture(- shadowmaps,- vec3(fTexCoord, 2.0)- ).x;-- texel = vec4(1-d0, 1-d1, 1-d2, 1.0);- break;+stageCode :: Graphics.StageCode+stageCode = Graphics.basicStages Code.vert Code.frag - default:- break;- }+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.basicStages vertSpirv fragSpirv - vec3 color = pow(texel.rgb, fTextureGamma.rgb);- float combinedAlpha = texel.a * fTextureGamma.a;+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert) - // XXX: premultiply alpha due to additive blending- oColor = vec4(color * combinedAlpha, combinedAlpha);- }- |])+fragSpirv :: ByteString+fragSpirv = $(compileFrag Code.frag)
+ src/Render/DepthOnly/Code.hs view
@@ -0,0 +1,37 @@+module Render.DepthOnly.Code+ ( vert+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.DescSets.Set0.Code (set0binding0)++vert :: Code+vert = fromString+ [glsl|+ #version 450+ #extension GL_ARB_separate_shader_objects : enable++ invariant gl_Position;++ ${set0binding0}++ layout(location = 0) in vec3 vPosition;+ layout(location = 1) in mat4 iModel;++ // layout(location = 0) out vec4 fColor;++ void main() {+ vec4 fPosition = iModel * vec4(vPosition, 1.0);++ gl_Position+ = scene.projection+ * scene.view+ * fPosition;++ // XXX: needed for alpha cut-outs+ // fColor = vColor;+ // fColor.rgb * fColor.a;+ }+ |]
src/Render/DepthOnly/Pipeline.hs view
@@ -4,6 +4,9 @@ , Config , config++ , stageCode+ , stageSpirv ) where import RIO@@ -13,14 +16,15 @@ import Vulkan.Core10 qualified as Vk import Geomancy (Transform)-import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, {- compileFrag, -} glsl)+import Render.Code (compileVert)+import Render.DepthOnly.Code qualified as Code import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform)-import Render.DescSets.Set0.Code (set0binding0) -type Config = Pipeline.Configure Pipeline ()-type Pipeline = Pipeline.Pipeline '[Scene] () Transform+type Pipeline = Graphics.Pipeline '[Scene] () Transform+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = () allocate :: ( HasVulkan env@@ -31,7 +35,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocate multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (config tset0)@@ -39,43 +43,22 @@ pure p config :: Tagged Scene DsBindings -> Config-config (Tagged set0) = Pipeline.baseConfig- { Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cVertexCode = Just vertCode- , Pipeline.cVertexInput = vertexInput- , Pipeline.cFragmentCode = Nothing -- XXX: needed for alpha cut-outs+config (Tagged set0) = Graphics.baseConfig+ { Graphics.cDescLayouts = Tagged @'[Scene] [set0]+ , Graphics.cStages = stageSpirv+ , Graphics.cVertexInput = vertexInput } where- vertexInput = Pipeline.vertexInput+ vertexInput = Graphics.vertexInput [ vertexPos , instanceTransform ] -vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable-- invariant gl_Position;-- ${set0binding0}-- layout(location = 0) in vec3 vPosition;- layout(location = 1) in mat4 iModel;-- // layout(location = 0) out vec4 fColor;-- void main() {- vec4 fPosition = iModel * vec4(vPosition, 1.0);+stageCode :: Graphics.StageCode+stageCode = Graphics.vertexOnly Code.vert - gl_Position- = scene.projection- * scene.view- * fPosition;+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.vertexOnly vertSpirv - // XXX: needed for alpha cut-outs- // fColor = vColor;- // fColor.rgb * fColor.a;- }- |])+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert)
+ src/Render/Font/EvanwSdf/Code.hs view
@@ -0,0 +1,114 @@+module Render.Font.EvanwSdf.Code+ ( vert+ , frag+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2)++vert :: Code+vert = fromString+ [glsl|+ #version 450++ ${set0binding0}++ layout(location = 0) in vec4 iVert;+ layout(location = 1) in vec4 iFrag;+ layout(location = 2) in vec4 iColor;+ layout(location = 3) in vec4 iOutlineColor;+ layout(location = 4) in ivec2 iTextureIds;+ layout(location = 5) in vec2 iSdf;++ layout(location = 0) out vec2 fTexCoord;+ layout(location = 1) flat out vec4 fColor;+ layout(location = 2) flat out vec4 fOutlineColor;+ layout(location = 3) flat out ivec2 fTextureIds;+ layout(location = 4) flat out vec2 fSdf;++ vec2 positions[6] = vec2[](+ vec2(-0.5, 0.5),+ vec2(0.5, 0.5),+ vec2(-0.5, -0.5),++ vec2(0.5, -0.5),+ vec2(-0.5, -0.5),+ vec2(0.5, 0.5)+ );++ vec2 texCoords[6] = vec2[](+ vec2(0.0, 0.0),+ vec2(1.0, 0.0),+ vec2(0.0, 1.0),++ vec2(1.0, 1.0),+ vec2(0.0, 1.0),+ vec2(1.0, 0.0)+ );++ void main() {+ vec2 pos = positions[gl_VertexIndex];++ gl_Position+ = scene.projection+ * scene.view+ // TODO: * iModel+ * vec4(iVert.xy + pos * iVert.zw, 0, 1.0);++ vec2 uv = texCoords[gl_VertexIndex];+ fTexCoord = iFrag.xy + uv * iFrag.zw;++ fColor = iColor;+ fOutlineColor = iOutlineColor;+ fTextureIds = iTextureIds;+ fSdf = iSdf;+ }+ |]++frag :: Code+frag = fromString+ [glsl|+ #version 450+ #extension GL_EXT_nonuniform_qualifier : enable++ ${set0binding1}+ ${set0binding2}++ layout(location = 0) in vec2 fTexCoord;+ layout(location = 1) flat in vec4 fColor;+ layout(location = 2) flat in vec4 fOutlineColor;+ layout(location = 3) flat in ivec2 fTextureIds;+ layout(location = 4) flat in vec2 fSdf;++ layout(location = 0) out vec4 outColor;++ void main() {+ float sdf = texture(+ sampler2D(+ textures[nonuniformEXT(fTextureIds.t)],+ samplers[nonuniformEXT(fTextureIds.s)]+ ),+ fTexCoord+ ).r;++ float smoothing = fSdf[0];+ float outlineWidth = fSdf[1];++ float outerEdgeCenter = 0.5 - outlineWidth;++ float alpha = smoothstep(+ outerEdgeCenter - smoothing,+ outerEdgeCenter + smoothing,+ sdf+ );+ float border = smoothstep(+ 0.5 - smoothing,+ 0.5 + smoothing,+ sdf+ );+ outColor = mix(fOutlineColor, fColor, border);+ outColor *= alpha;+ }+ |]
src/Render/Font/EvanwSdf/Pipeline.hs view
@@ -1,8 +1,12 @@ {-# LANGUAGE OverloadedLists #-} module Render.Font.EvanwSdf.Pipeline- ( Pipeline+ ( Config+ , config+ , Pipeline , allocate+ , stageCode+ , stageSpirv ) where import RIO@@ -11,14 +15,16 @@ import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk -import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, compileFrag, glsl)+import Render.Code (compileVert, compileFrag) import Render.DescSets.Set0 (Scene)-import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2)+import Render.Font.EvanwSdf.Code qualified as Code import Render.Font.EvanwSdf.Model qualified as Model -type Pipeline = Pipeline.Pipeline '[Scene] () Model.InstanceAttrs+type Pipeline = Graphics.Pipeline '[Scene] () Model.InstanceAttrs+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = () allocate :: ( HasVulkan env@@ -28,128 +34,35 @@ -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline-allocate multisample (Tagged set0) = do- fmap snd . Pipeline.allocate+allocate multisample tset0 = do+ fmap snd . Graphics.allocate Nothing multisample- Pipeline.baseConfig- { Pipeline.cVertexCode = Just vertCode- , Pipeline.cFragmentCode = Just fragCode- , Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cVertexInput = vertexInput- , Pipeline.cDepthTest = False- , Pipeline.cDepthWrite = False- , Pipeline.cBlend = True- , Pipeline.cCull = Vk.CULL_MODE_NONE- }+ (config tset0)++config :: Tagged Scene DsBindings -> Config+config (Tagged set0) = Graphics.baseConfig+ { Graphics.cDescLayouts = Tagged @'[Scene] [set0]+ , Graphics.cStages = stageSpirv+ , Graphics.cVertexInput = vertexInput+ , Graphics.cDepthTest = False+ , Graphics.cDepthWrite = False+ , Graphics.cBlend = True+ , Graphics.cCull = Vk.CULL_MODE_NONE+ } where- vertexInput = Pipeline.vertexInput+ vertexInput = Graphics.vertexInput [ (Vk.VERTEX_INPUT_RATE_INSTANCE, Model.vkInstanceAttrs) ] -vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable-- ${set0binding0}-- layout(location = 0) in vec4 iVert;- layout(location = 1) in vec4 iFrag;- layout(location = 2) in vec4 iColor;- layout(location = 3) in vec4 iOutlineColor;- layout(location = 4) in ivec2 iTextureIds;- layout(location = 5) in vec2 iSdf;-- layout(location = 0) out vec2 fTexCoord;- layout(location = 1) flat out vec4 fColor;- layout(location = 2) flat out vec4 fOutlineColor;- layout(location = 3) flat out ivec2 fTextureIds;- layout(location = 4) flat out vec2 fSdf;-- vec2 positions[6] = vec2[](- vec2(-0.5, 0.5),- vec2(0.5, 0.5),- vec2(-0.5, -0.5),-- vec2(0.5, -0.5),- vec2(-0.5, -0.5),- vec2(0.5, 0.5)- );-- vec2 texCoords[6] = vec2[](- vec2(0.0, 0.0),- vec2(1.0, 0.0),- vec2(0.0, 1.0),-- vec2(1.0, 1.0),- vec2(0.0, 1.0),- vec2(1.0, 0.0)- );-- void main() {- vec2 pos = positions[gl_VertexIndex];-- gl_Position- = scene.projection- * scene.view- // TODO: * iModel- * vec4(iVert.xy + pos * iVert.zw, 0, 1.0);-- vec2 uv = texCoords[gl_VertexIndex];- fTexCoord = iFrag.xy + uv * iFrag.zw;-- fColor = iColor;- fOutlineColor = iOutlineColor;- fTextureIds = iTextureIds;- fSdf = iSdf;- }- |])--fragCode :: ByteString-fragCode =- $(compileFrag [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable- #extension GL_EXT_nonuniform_qualifier : enable-- ${set0binding1}- ${set0binding2}-- layout(location = 0) in vec2 fTexCoord;- layout(location = 1) flat in vec4 fColor;- layout(location = 2) flat in vec4 fOutlineColor;- layout(location = 3) flat in ivec2 fTextureIds;- layout(location = 4) flat in vec2 fSdf;-- layout(location = 0) out vec4 outColor;-- void main() {- float sdf = texture(- sampler2D(- textures[nonuniformEXT(fTextureIds.t)],- samplers[nonuniformEXT(fTextureIds.s)]- ),- fTexCoord- ).r;+stageCode :: Graphics.StageCode+stageCode = Graphics.basicStages Code.vert Code.frag - float smoothing = fSdf[0];- float outlineWidth = fSdf[1];+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.basicStages vertSpirv fragSpirv - float outerEdgeCenter = 0.5 - outlineWidth;+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert) - float alpha = smoothstep(- outerEdgeCenter - smoothing,- outerEdgeCenter + smoothing,- sdf- );- float border = smoothstep(- 0.5 - smoothing,- 0.5 + smoothing,- sdf- );- outColor = mix(fOutlineColor, fColor, border);- outColor *= alpha;- }- |])+fragSpirv :: ByteString+fragSpirv = $(compileFrag Code.frag)
+ src/Render/Lit/Colored/Code.hs view
@@ -0,0 +1,100 @@+module Render.Lit.Colored.Code+ ( vert+ , frag+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.Code.Lit (litMain, shadowFuns, structLight, brdfSpecular)+import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2, set0binding3, set0binding4, set0binding5)++vert :: Code+vert = fromString+ [glsl|+ #version 450++ invariant gl_Position;++ ${set0binding0}++ layout(location = 0) in vec3 vPosition;+ layout(location = 1) in vec4 vBaseColor;+ layout(location = 2) in vec4 vEmissiveColor;+ layout(location = 3) in vec2 vMetallicRoughness;+ layout(location = 4) in vec3 vNormal;++ layout(location = 5) in mat4 iModel;++ layout(location = 0) out vec4 fPosition;+ layout(location = 1) out vec4 fColor;+ layout(location = 2) out vec4 fEmissiveColor;+ layout(location = 3) out vec2 fMetallicRoughness;+ layout(location = 4) out vec3 fNormal;++ void main() {+ fPosition = iModel * vec4(vPosition, 1.0);++ gl_Position+ = scene.projection+ * scene.view+ * fPosition;++ fNormal = transpose(mat3(inverse(iModel))) * vNormal; // TODO: use modelInv++ fColor = vBaseColor;+ fColor.rgb *= vBaseColor.a;++ fEmissiveColor = vEmissiveColor;+ fMetallicRoughness = vMetallicRoughness;+ }+ |]++frag :: Code+frag = fromString+ [glsl|+ #version 450+ #extension GL_EXT_nonuniform_qualifier : enable++ layout(early_fragment_tests) in;++ // TODO: move to spec constant+ const uint MAX_LIGHTS = 255;+ const float PCF_STEP = 1.5 / 4096;++ // TODO: move to material+ const float reflectivity = 1.0/256.0;++ ${structLight}++ ${set0binding0}+ ${set0binding1}+ ${set0binding2}+ ${set0binding3}+ ${set0binding4}+ ${set0binding5}++ layout(location = 0) in vec4 fPosition;+ layout(location = 1) in vec4 fColor;+ layout(location = 2) in vec4 fEmissiveColor;+ layout(location = 3) in vec2 fMetallicRoughness;+ layout(location = 4) in vec3 fNormal;++ layout(location = 0) out vec4 oColor;++ ${shadowFuns}+ ${brdfSpecular}++ void main() {+ vec4 baseColor = fColor; // XXX: assuming premultiplied alpha+ float metallic = fMetallicRoughness[0];+ float roughness = fMetallicRoughness[1];+ float nonOcclusion = 1.0;++ vec3 normal = normalize(fNormal);++ ${litMain}++ oColor.rgb += pow(fEmissiveColor.rgb, vec3(2.2));+ }+ |]
src/Render/Lit/Colored/Pipeline.hs view
@@ -6,6 +6,9 @@ , Config , config , configBlend++ , stageCode+ , stageSpirv ) where import RIO@@ -14,16 +17,16 @@ import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk -import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, compileFrag, glsl)-import Render.Code.Lit (litMain, structLight, shadowFuns, brdfSpecular)+import Render.Code (compileVert, compileFrag) import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform)-import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2, set0binding3, set0binding4, set0binding5)+import Render.Lit.Colored.Code qualified as Code import Render.Lit.Colored.Model qualified as Model -type Config = Pipeline.Configure Pipeline ()-type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Pipeline = Graphics.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = () allocate :: ( HasVulkan env@@ -34,7 +37,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocate multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (config tset0)@@ -50,7 +53,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocateBlend multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (configBlend tset0)@@ -58,14 +61,13 @@ pure p config :: Tagged Scene DsBindings -> Config-config (Tagged set0) = Pipeline.baseConfig- { Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cVertexCode = Just vertCode- , Pipeline.cVertexInput = vertexInput- , Pipeline.cFragmentCode = Just fragCode+config (Tagged set0) = Graphics.baseConfig+ { Graphics.cDescLayouts = Tagged @'[Scene] [set0]+ , Graphics.cStages = stageSpirv+ , Graphics.cVertexInput = vertexInput } where- vertexInput = Pipeline.vertexInput+ vertexInput = Graphics.vertexInput [ vertexPos , (Vk.VERTEX_INPUT_RATE_VERTEX, Model.vkVertexAttrs) , instanceTransform@@ -73,97 +75,17 @@ configBlend :: Tagged Scene DsBindings -> Config configBlend tset0 = (config tset0)- { Pipeline.cBlend = True+ { Graphics.cBlend = True } -vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable-- invariant gl_Position;-- ${set0binding0}-- layout(location = 0) in vec3 vPosition;- layout(location = 1) in vec4 vBaseColor;- layout(location = 2) in vec4 vEmissiveColor;- layout(location = 3) in vec2 vMetallicRoughness;- layout(location = 4) in vec3 vNormal;-- layout(location = 5) in mat4 iModel;-- layout(location = 0) out vec4 fPosition;- layout(location = 1) out vec4 fColor;- layout(location = 2) out vec4 fEmissiveColor;- layout(location = 3) out vec2 fMetallicRoughness;- layout(location = 4) out vec3 fNormal;-- void main() {- fPosition = iModel * vec4(vPosition, 1.0);-- gl_Position- = scene.projection- * scene.view- * fPosition;-- fNormal = transpose(mat3(inverse(iModel))) * vNormal; // TODO: use modelInv-- fColor = vBaseColor;- fColor.rgb *= vBaseColor.a;-- fEmissiveColor = vEmissiveColor;- fMetallicRoughness = vMetallicRoughness;- }- |])--fragCode :: ByteString-fragCode =- $(compileFrag [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable- #extension GL_EXT_nonuniform_qualifier : enable-- layout(early_fragment_tests) in;-- // TODO: move to spec constant- const uint MAX_LIGHTS = 255;- const float PCF_STEP = 1.5 / 4096;-- // TODO: move to material- const float reflectivity = 1.0/256.0;-- ${structLight}-- ${set0binding0}- ${set0binding1}- ${set0binding2}- ${set0binding3}- ${set0binding4}- ${set0binding5}-- layout(location = 0) in vec4 fPosition;- layout(location = 1) in vec4 fColor;- layout(location = 2) in vec4 fEmissiveColor;- layout(location = 3) in vec2 fMetallicRoughness;- layout(location = 4) in vec3 fNormal;-- layout(location = 0) out vec4 oColor;-- ${shadowFuns}- ${brdfSpecular}-- void main() {- vec4 baseColor = fColor; // XXX: assuming premultiplied alpha- float metallic = fMetallicRoughness[0];- float roughness = fMetallicRoughness[1];- float nonOcclusion = 1.0;+stageCode :: Graphics.StageCode+stageCode = Graphics.basicStages Code.vert Code.frag - vec3 normal = normalize(fNormal);+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.basicStages vertSpirv fragSpirv - ${litMain}+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert) - oColor.rgb += pow(fEmissiveColor.rgb, vec3(2.2));- }- |])+fragSpirv :: ByteString+fragSpirv = $(compileFrag Code.frag)
+ src/Render/Lit/Material/Code.hs view
@@ -0,0 +1,175 @@+module Render.Lit.Material.Code+ ( vert+ , frag+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.Code.Lit (litMain, shadowFuns, structLight, structMaterial, brdfSpecular)+import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2, set0binding3, set0binding4, set0binding5, set0binding6)++vert :: Code+vert = fromString+ [glsl|+ #version 450++ invariant gl_Position;++ ${set0binding0}++ // vertexPos+ layout(location = 0) in vec3 vPosition;+ // vertexAttrs+ layout(location = 1) in vec2 vTexCoord0;+ layout(location = 2) in vec2 vTexCoord1;+ layout(location = 3) in vec3 vNormal;+ layout(location = 4) in vec3 vTangent;+ layout(location = 5) in uint vMaterial;++ // transformMat+ layout(location = 6) in mat4 iModel;++ layout(location = 0) out vec4 fPosition;+ layout(location = 1) out vec2 fTexCoord0;+ layout(location = 2) out vec2 fTexCoord1;+ layout(location = 3) flat out uint fMaterial;+ layout(location = 4) out mat3 fTBN;++ void main() {+ fPosition = iModel * vec4(vPosition, 1.0);++ gl_Position+ = scene.projection+ * scene.view+ * fPosition;++ fTexCoord0 = vTexCoord0;+ fTexCoord1 = vTexCoord1;++ vec3 t = normalize(vec3(iModel * vec4(vTangent, 0.0)));+ vec3 n = normalize(vec3(iModel * vec4(vNormal, 0.0)));+ vec3 to = normalize(t - dot(t, n) * n); // re-orthogonalize T with respect to N+ fTBN = mat3(to, cross(n, to), n);++ fMaterial = vMaterial;+ }+ |]++frag :: Code+frag = fromString+ [glsl|+ #version 450+ #extension GL_EXT_nonuniform_qualifier : enable++ layout(early_fragment_tests) in;++ // XXX: copypasta from Lit.Colored+ // TODO: move to spec constant+ const uint MAX_LIGHTS = 255;+ const float PCF_STEP = 1.5 / 4096;++ const uint MAX_MATERIALS = 2048;++ ${structLight}+ ${structMaterial}++ ${set0binding0}+ ${set0binding1}+ ${set0binding2}+ ${set0binding3}+ ${set0binding4} // lights+ ${set0binding5} // shadowmap+ ${set0binding6} // materials++ layout(location = 0) in vec4 fPosition;+ layout(location = 1) in vec2 fTexCoord0;+ layout(location = 2) in vec2 fTexCoord1;+ layout(location = 3) flat in uint fMaterial;+ layout(location = 4) in mat3 fTBN;++ layout(location = 0) out vec4 oColor;++ ${shadowFuns}+ ${brdfSpecular}++ void main() {+ Material material = materials[fMaterial];+ vec4 baseColor = material.baseColor;+ float metallic = material.metallicRoughness[0];+ float roughness = material.metallicRoughness[1];+ float nonOcclusion = 1.0;+ vec4 emissive = material.emissive;++ if (material.baseColorTex > -1) {+ baseColor *= texture(+ sampler2D(+ textures[nonuniformEXT(material.baseColorTex)],+ samplers[0]+ ),+ fTexCoord0+ );+ }++ if (baseColor.a < material.alphaCutoff) {+ discard;+ }++ baseColor.rgb *= baseColor.a;++ if (material.metallicRoughnessTex > -1) {+ vec3 packed = texture(+ sampler2D(+ textures[nonuniformEXT(material.metallicRoughnessTex)],+ samplers[0]+ ),+ fTexCoord0+ ).rgb;+ // XXX: assuming sRGB textures, even for AMR+ packed = pow(packed, vec3(1.0/2.2));+ nonOcclusion -= packed.r;+ metallic *= packed.b;+ roughness *= packed.g;+ }++ // // TODO: combine with MR as channel R.+ // float occlusion = texture(+ // sampler2D(+ // textures[nonuniformEXT(max(0, material.ambientOcclusionTex))],+ // samplers[0]+ // ),+ // fTexCoord0+ // ).r;+ // nonOcclusion -= pow(occlusion, 1.0/2.2);++ if (material.emissiveTex > -1) {+ emissive *= texture(+ sampler2D(+ textures[nonuniformEXT(material.emissiveTex)],+ samplers[0]+ ),+ fTexCoord0+ );+ }++ vec3 normal = fTBN[2];+ if (material.normalTex > -1) {+ vec3 normalsColor = texture(+ sampler2D(+ textures[nonuniformEXT(material.normalTex)],+ samplers[0]+ ),+ fTexCoord0+ ).rgb;++ // XXX: convert normal non-colors to linear values from sRGB texture colorspace+ vec3 normals = pow(normalsColor, vec3(1.0/2.2)) * 2.0 - 1.0;++ normal = normalize(fTBN * normals);+ }++ ${litMain}++ oColor.rgb += pow(emissive.rgb, vec3(2.2));+ }+ |]
src/Render/Lit/Material/Pipeline.hs view
@@ -6,6 +6,9 @@ , Config , config , configBlend++ , stageCode+ , stageSpirv ) where import RIO@@ -14,16 +17,16 @@ import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk -import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, compileFrag, glsl)+import Render.Code (compileVert, compileFrag) import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform)-import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2, set0binding3, set0binding4, set0binding5, set0binding6)-import Render.Code.Lit (litMain, shadowFuns, structLight, structMaterial, brdfSpecular)+import Render.Lit.Material.Code qualified as Code import Render.Lit.Material.Model qualified as Model -type Config = Pipeline.Configure Pipeline ()-type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Pipeline = Graphics.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = () allocate :: ( HasVulkan env@@ -34,7 +37,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocate multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (config tset0)@@ -50,7 +53,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocateBlend multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (configBlend tset0)@@ -58,16 +61,15 @@ pure p config :: Tagged Scene DsBindings -> Config-config (Tagged set0) = Pipeline.baseConfig- { Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cVertexCode = Just vertCode- , Pipeline.cVertexInput = vertexInput- , Pipeline.cFragmentCode = Just fragCode- , Pipeline.cDepthWrite = False -- XXX: Lit pipelines require depth pre-pass- , Pipeline.cDepthCompare = Vk.COMPARE_OP_EQUAL+config (Tagged set0) = Graphics.baseConfig+ { Graphics.cDescLayouts = Tagged @'[Scene] [set0]+ , Graphics.cStages = stageSpirv+ , Graphics.cVertexInput = vertexInput+ , Graphics.cDepthWrite = False -- XXX: Lit pipelines require depth pre-pass+ , Graphics.cDepthCompare = Vk.COMPARE_OP_EQUAL } where- vertexInput = Pipeline.vertexInput+ vertexInput = Graphics.vertexInput [ vertexPos -- vPosition , (Vk.VERTEX_INPUT_RATE_VERTEX, Model.vkVertexAttrs) , instanceTransform@@ -75,176 +77,21 @@ configBlend :: Tagged Scene DsBindings -> Config configBlend tset0 = (config tset0)- { Pipeline.cBlend =+ { Graphics.cBlend = True- , Pipeline.cDepthCompare =+ , Graphics.cDepthCompare = -- XXX: blended objects aren't a part of depth prepass Vk.COMPARE_OP_LESS_OR_EQUAL } -vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable-- invariant gl_Position;-- ${set0binding0}-- // vertexPos- layout(location = 0) in vec3 vPosition;- // vertexAttrs- layout(location = 1) in vec2 vTexCoord0;- layout(location = 2) in vec2 vTexCoord1;- layout(location = 3) in vec3 vNormal;- layout(location = 4) in vec3 vTangent;- layout(location = 5) in uint vMaterial;-- // transformMat- layout(location = 6) in mat4 iModel;-- layout(location = 0) out vec4 fPosition;- layout(location = 1) out vec2 fTexCoord0;- layout(location = 2) out vec2 fTexCoord1;- layout(location = 3) flat out uint fMaterial;- layout(location = 4) out mat3 fTBN;-- void main() {- fPosition = iModel * vec4(vPosition, 1.0);-- gl_Position- = scene.projection- * scene.view- * fPosition;-- fTexCoord0 = vTexCoord0;- fTexCoord1 = vTexCoord1;-- vec3 t = normalize(vec3(iModel * vec4(vTangent, 0.0)));- vec3 n = normalize(vec3(iModel * vec4(vNormal, 0.0)));- vec3 to = normalize(t - dot(t, n) * n); // re-orthogonalize T with respect to N- fTBN = mat3(to, cross(n, to), n);-- fMaterial = vMaterial;- }- |])--fragCode :: ByteString-fragCode =- $(compileFrag [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable- #extension GL_EXT_nonuniform_qualifier : enable-- layout(early_fragment_tests) in;-- // XXX: copypasta from Lit.Colored- // TODO: move to spec constant- const uint MAX_LIGHTS = 255;- const float PCF_STEP = 1.5 / 4096;-- const uint MAX_MATERIALS = 2048;-- ${structLight}- ${structMaterial}-- ${set0binding0}- ${set0binding1}- ${set0binding2}- ${set0binding3}- ${set0binding4} // lights- ${set0binding5} // shadowmap- ${set0binding6} // materials-- layout(location = 0) in vec4 fPosition;- layout(location = 1) in vec2 fTexCoord0;- layout(location = 2) in vec2 fTexCoord1;- layout(location = 3) flat in uint fMaterial;- layout(location = 4) in mat3 fTBN;-- layout(location = 0) out vec4 oColor;-- ${shadowFuns}- ${brdfSpecular}-- void main() {- Material material = materials[fMaterial];- vec4 baseColor = material.baseColor;- float metallic = material.metallicRoughness[0];- float roughness = material.metallicRoughness[1];- float nonOcclusion = 1.0;- vec4 emissive = material.emissive;-- if (material.baseColorTex > -1) {- baseColor *= texture(- sampler2D(- textures[nonuniformEXT(material.baseColorTex)],- samplers[0]- ),- fTexCoord0- );- }-- if (baseColor.a < material.alphaCutoff) {- discard;- }-- baseColor.rgb *= baseColor.a;-- if (material.metallicRoughnessTex > -1) {- vec3 packed = texture(- sampler2D(- textures[nonuniformEXT(material.metallicRoughnessTex)],- samplers[0]- ),- fTexCoord0- ).rgb;- // XXX: assuming sRGB textures, even for AMR- packed = pow(packed, vec3(1.0/2.2));- nonOcclusion -= packed.r;- metallic *= packed.b;- roughness *= packed.g;- }-- // // TODO: combine with MR as channel R.- // float occlusion = texture(- // sampler2D(- // textures[nonuniformEXT(max(0, material.ambientOcclusionTex))],- // samplers[0]- // ),- // fTexCoord0- // ).r;- // nonOcclusion -= pow(occlusion, 1.0/2.2);-- if (material.emissiveTex > -1) {- emissive *= texture(- sampler2D(- textures[nonuniformEXT(material.emissiveTex)],- samplers[0]- ),- fTexCoord0- );- }-- vec3 normal = fTBN[2];- if (material.normalTex > -1) {- vec3 normalsColor = texture(- sampler2D(- textures[nonuniformEXT(material.normalTex)],- samplers[0]- ),- fTexCoord0- ).rgb;-- // XXX: convert normal non-colors to linear values from sRGB texture colorspace- vec3 normals = pow(normalsColor, vec3(1.0/2.2)) * 2.0 - 1.0;+stageCode :: Graphics.StageCode+stageCode = Graphics.basicStages Code.vert Code.frag - normal = normalize(fTBN * normals);- }+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.basicStages vertSpirv fragSpirv - ${litMain}+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert) - oColor.rgb += pow(emissive.rgb, vec3(2.2));- }- |])+fragSpirv :: ByteString+fragSpirv = $(compileFrag Code.frag)
+ src/Render/Lit/Textured/Code.hs view
@@ -0,0 +1,120 @@+module Render.Lit.Textured.Code+ ( vert+ , frag+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.Code.Lit (litMain, shadowFuns, structLight, brdfSpecular)+import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2, set0binding3, set0binding4, set0binding5)++vert :: Code+vert = fromString+ [glsl|+ #version 450++ invariant gl_Position;++ ${set0binding0}++ // vertexPos+ layout(location = 0) in vec3 vPosition;+ // vertexAttrs+ layout(location = 1) in vec2 vTexCoord;+ layout(location = 2) in vec3 vNormal;+ // textureParams+ layout(location = 3) in vec4 iTextureScaleOffset;+ layout(location = 4) in vec4 iTextureGamma;+ layout(location = 5) in ivec2 iTextureIds;++ // transformMat+ layout(location = 6) in mat4 iModel;++ layout(location = 0) out vec4 fPosition;+ layout(location = 1) out vec3 fNormal;+ layout(location = 2) out vec2 fTexCoord;+ layout(location = 3) flat out vec4 fTextureGamma;+ layout(location = 4) flat out ivec2 fTextureIds;++ void main() {+ fPosition = iModel * vec4(vPosition, 1.0);++ gl_Position+ = scene.projection+ * scene.view+ * fPosition;++ fNormal = transpose(mat3(inverse(iModel))) * vNormal; // TODO: use modelInv++ fTexCoord = vTexCoord * iTextureScaleOffset.st + iTextureScaleOffset.pq;+ fTextureGamma = iTextureGamma;+ fTextureIds = iTextureIds;+ }+ |]++frag :: Code+frag = fromString+ [glsl|+ #version 450+ #extension GL_EXT_nonuniform_qualifier : enable++ layout(early_fragment_tests) in;++ // XXX: copypasta from Lit.Colored+ // TODO: move to spec constant+ const uint MAX_LIGHTS = 255;+ const float PCF_STEP = 1.5 / 4096;++ // TODO: move to material+ const float reflectivity = 1.0/256.0;++ ${structLight}++ ${set0binding0}+ ${set0binding1}+ ${set0binding2}+ ${set0binding3}+ ${set0binding4}+ ${set0binding5}++ layout(location = 0) in vec4 fPosition;+ layout(location = 1) in vec3 fNormal;+ layout(location = 2) in vec2 fTexCoord;+ layout(location = 3) flat in vec4 fTextureGamma;+ layout(location = 4) flat in ivec2 fTextureIds;++ layout(location = 0) out vec4 oColor;++ ${shadowFuns}+ ${brdfSpecular}++ void main() {+ // XXX: fall back to solid color+ vec4 baseColor = fTextureGamma;+ if ((fTextureIds.t > -1) && (fTextureIds.s > -1)) {+ vec4 texel = texture(+ sampler2D(+ textures[nonuniformEXT(fTextureIds.t)],+ samplers[nonuniformEXT(fTextureIds.s)]+ ),+ fTexCoord+ );++ if (texel.a < 0.5) discard;++ vec3 color = pow(texel.rgb, fTextureGamma.rgb);+ float combinedAlpha = texel.a * fTextureGamma.a;+ baseColor = vec4(color * combinedAlpha, combinedAlpha);+ }++ // TODO: get from textures+ float metallic = 0.0;+ float roughness = 0.6;+ float nonOcclusion = 1.0;++ vec3 normal = normalize(fNormal);++ ${litMain}+ }+ |]
src/Render/Lit/Textured/Pipeline.hs view
@@ -6,6 +6,9 @@ , Config , config , configBlend++ , stageCode+ , stageSpirv ) where import RIO@@ -14,16 +17,16 @@ import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk -import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, compileFrag, glsl)+import Render.Code (compileVert, compileFrag) import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform)-import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2, set0binding3, set0binding4, set0binding5)-import Render.Code.Lit (litMain, shadowFuns, structLight, brdfSpecular)+import Render.Lit.Textured.Code qualified as Code import Render.Lit.Textured.Model qualified as Model -type Config = Pipeline.Configure Pipeline ()-type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Pipeline = Graphics.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = () allocate :: ( HasVulkan env@@ -34,7 +37,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocate multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (config tset0)@@ -50,7 +53,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocateBlend multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (configBlend tset0)@@ -58,16 +61,15 @@ pure p config :: Tagged Scene DsBindings -> Config-config (Tagged set0) = Pipeline.baseConfig- { Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cVertexCode = Just vertCode- , Pipeline.cVertexInput = vertexInput- , Pipeline.cFragmentCode = Just fragCode- , Pipeline.cDepthWrite = False -- XXX: Lit pipelines require depth pre-pass- , Pipeline.cDepthCompare = Vk.COMPARE_OP_EQUAL+config (Tagged set0) = Graphics.baseConfig+ { Graphics.cDescLayouts = Tagged @'[Scene] [set0]+ , Graphics.cStages = stageSpirv+ , Graphics.cVertexInput = vertexInput+ , Graphics.cDepthWrite = False -- XXX: Lit pipelines require depth pre-pass+ , Graphics.cDepthCompare = Vk.COMPARE_OP_EQUAL } where- vertexInput = Pipeline.vertexInput+ vertexInput = Graphics.vertexInput [ vertexPos -- vPosition , (Vk.VERTEX_INPUT_RATE_VERTEX, Model.vkVertexAttrs) , (Vk.VERTEX_INPUT_RATE_INSTANCE, Model.vkInstanceTexture)@@ -76,118 +78,18 @@ configBlend :: Tagged Scene DsBindings -> Config configBlend tset0 = (config tset0)- { Pipeline.cBlend = True- , Pipeline.cDepthCompare = Vk.COMPARE_OP_LESS_OR_EQUAL+ { Graphics.cBlend = True+ , Graphics.cDepthCompare = Vk.COMPARE_OP_LESS_OR_EQUAL } -vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable-- invariant gl_Position;-- ${set0binding0}-- // vertexPos- layout(location = 0) in vec3 vPosition;- // vertexAttrs- layout(location = 1) in vec2 vTexCoord;- layout(location = 2) in vec3 vNormal;- // textureParams- layout(location = 3) in vec4 iTextureScaleOffset;- layout(location = 4) in vec4 iTextureGamma;- layout(location = 5) in ivec2 iTextureIds;-- // transformMat- layout(location = 6) in mat4 iModel;-- layout(location = 0) out vec4 fPosition;- layout(location = 1) out vec3 fNormal;- layout(location = 2) out vec2 fTexCoord;- layout(location = 3) flat out vec4 fTextureGamma;- layout(location = 4) flat out ivec2 fTextureIds;-- void main() {- fPosition = iModel * vec4(vPosition, 1.0);-- gl_Position- = scene.projection- * scene.view- * fPosition;-- fNormal = transpose(mat3(inverse(iModel))) * vNormal; // TODO: use modelInv-- fTexCoord = vTexCoord * iTextureScaleOffset.st + iTextureScaleOffset.pq;- fTextureGamma = iTextureGamma;- fTextureIds = iTextureIds;- }- |])--fragCode :: ByteString-fragCode =- $(compileFrag [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable- #extension GL_EXT_nonuniform_qualifier : enable-- layout(early_fragment_tests) in;-- // XXX: copypasta from Lit.Colored- // TODO: move to spec constant- const uint MAX_LIGHTS = 255;- const float PCF_STEP = 1.5 / 4096;-- // TODO: move to material- const float reflectivity = 1.0/256.0;-- ${structLight}-- ${set0binding0}- ${set0binding1}- ${set0binding2}- ${set0binding3}- ${set0binding4}- ${set0binding5}-- layout(location = 0) in vec4 fPosition;- layout(location = 1) in vec3 fNormal;- layout(location = 2) in vec2 fTexCoord;- layout(location = 3) flat in vec4 fTextureGamma;- layout(location = 4) flat in ivec2 fTextureIds;-- layout(location = 0) out vec4 oColor;-- ${shadowFuns}- ${brdfSpecular}-- void main() {- // XXX: fall back to solid color- vec4 baseColor = fTextureGamma;- if ((fTextureIds.t > -1) && (fTextureIds.s > -1)) {- vec4 texel = texture(- sampler2D(- textures[nonuniformEXT(fTextureIds.t)],- samplers[nonuniformEXT(fTextureIds.s)]- ),- fTexCoord- );-- if (texel.a < 0.5) discard;-- vec3 color = pow(texel.rgb, fTextureGamma.rgb);- float combinedAlpha = texel.a * fTextureGamma.a;- baseColor = vec4(color * combinedAlpha, combinedAlpha);- }+stageCode :: Graphics.StageCode+stageCode = Graphics.basicStages Code.vert Code.frag - // TODO: get from textures- float metallic = 0.0;- float roughness = 0.6;- float nonOcclusion = 1.0;+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.basicStages vertSpirv fragSpirv - vec3 normal = normalize(fNormal);+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert) - ${litMain}- }- |])+fragSpirv :: ByteString+fragSpirv = $(compileFrag Code.frag)
+ src/Render/ShadowMap/Code.hs view
@@ -0,0 +1,33 @@+module Render.ShadowMap.Code+ ( vert+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.Code.Lit (structLight)+import Render.DescSets.Sun (pattern MAX_VIEWS)++vert :: Code+vert = fromString+ [glsl|+ #version 450+ #extension GL_EXT_multiview : enable++ ${structLight}++ layout(set=0, binding=0, std140) uniform Globals {+ Light lights[${MAX_VIEWS}];+ };++ layout(location = 0) in vec3 vPosition;++ layout(location = 1) in mat4 iModel;++ void main() {+ gl_Position+ = lights[gl_ViewIndex].viewProjection+ * iModel+ * vec4(vPosition, 1.0);+ }+ |]
src/Render/ShadowMap/Pipeline.hs view
@@ -7,6 +7,9 @@ , Config , config++ , stageCode+ , stageSpirv ) where import RIO@@ -16,15 +19,16 @@ import Geomancy (Transform) import Vulkan.Core10 qualified as Vk -import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, glsl)-import Render.Code.Lit (structLight)+import Render.Code (compileVert) import Render.DescSets.Set0 (vertexPos, instanceTransform)-import Render.DescSets.Sun (Sun, pattern MAX_VIEWS)+import Render.DescSets.Sun (Sun)+import Render.ShadowMap.Code qualified as Code -type Config = Pipeline.Configure Pipeline ()-type Pipeline = Pipeline.Pipeline '[Sun] () Transform+type Pipeline = Graphics.Pipeline '[Sun] () Transform+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = () data Settings = Settings { cull :: Vk.CullModeFlagBits@@ -46,7 +50,7 @@ -> Settings -> ResourceT (RIO env) Pipeline allocate tset0 rp settings = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing Vk.SAMPLE_COUNT_1_BIT (config tset0 settings)@@ -54,40 +58,24 @@ pure p config :: Tagged Sun DsBindings -> Settings -> Config-config (Tagged set0) Settings{..} = Pipeline.baseConfig- { Pipeline.cDescLayouts = Tagged @'[Sun] [set0]- , Pipeline.cVertexCode = Just vertCode- , Pipeline.cVertexInput = vertexInput- , Pipeline.cDepthBias = depthBias- , Pipeline.cCull = cull+config (Tagged set0) Settings{..} = Graphics.baseConfig+ { Graphics.cDescLayouts = Tagged @'[Sun] [set0]+ , Graphics.cStages = stageSpirv+ , Graphics.cVertexInput = vertexInput+ , Graphics.cDepthBias = depthBias+ , Graphics.cCull = cull } where- vertexInput = Pipeline.vertexInput+ vertexInput = Graphics.vertexInput [ vertexPos , instanceTransform ] -vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable- #extension GL_EXT_multiview : enable-- ${structLight}-- layout(set=0, binding=0, std140) uniform Globals {- Light lights[${MAX_VIEWS}];- };-- layout(location = 0) in vec3 vPosition;+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.vertexOnly vertSpirv - layout(location = 1) in mat4 iModel;+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert) - void main() {- gl_Position- = lights[gl_ViewIndex].viewProjection- * iModel- * vec4(vPosition, 1.0);- }- |])+stageCode :: Graphics.StageCode+stageCode = Graphics.vertexOnly Code.vert
+ src/Render/Skybox/Code.hs view
@@ -0,0 +1,64 @@+module Render.Skybox.Code+ ( vert+ , frag+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding3)++vert :: Code+vert = fromString+ [glsl|+ #version 450++ ${set0binding0}++ layout(location = 0) out vec3 fragUVW;++ float farZ = 0.9999; // 1 - 1e-7;++ void main() {+ vec4 pos = vec4(0.0);+ switch(gl_VertexIndex) {+ case 0: pos = vec4(-1.0, 3.0, farZ, 1.0); break;+ case 1: pos = vec4(-1.0, -1.0, farZ, 1.0); break; // XXX: swapped with 2. culling?+ case 2: pos = vec4( 3.0, -1.0, farZ, 1.0); break;+ }++ vec3 unProjected = (scene.invProjection * pos).xyz;+ unProjected *= -1;+ fragUVW = mat3(scene.invView) * unProjected;++ gl_Position = pos;+ }+ |]++frag :: Code+frag = fromString+ [glsl|+ #version 450+ #extension GL_EXT_nonuniform_qualifier : enable++ ${set0binding0}++ ${set0binding1}+ ${set0binding3}++ layout(location = 0) in vec3 fragUVW;++ layout(location = 0) out vec4 outColor;++ void main() {+ if (scene.envCubeId > -1) {+ outColor = texture(+ samplerCube(+ cubes[nonuniformEXT(scene.envCubeId)],+ samplers[3] // XXX: linear+ ),+ fragUVW+ );+ }+ }+ |]
src/Render/Skybox/Pipeline.hs view
@@ -1,8 +1,13 @@ {-# LANGUAGE OverloadedLists #-} module Render.Skybox.Pipeline- ( Pipeline+ ( Config+ , config+ , Pipeline , allocate++ , stageCode+ , stageSpirv ) where import RIO@@ -11,13 +16,15 @@ import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk -import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, compileFrag, glsl)+import Render.Code (compileVert, compileFrag) import Render.DescSets.Set0 (Scene)-import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding3)+import Render.Skybox.Code qualified as Code -type Pipeline = Pipeline.Pipeline '[Scene] () ()+type Pipeline = Graphics.Pipeline '[Scene] () ()+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = () allocate :: ( HasVulkan env@@ -27,70 +34,27 @@ -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline-allocate multisample (Tagged set0) = do- fmap snd . Pipeline.allocate+allocate multisample tset0 = do+ fmap snd . Graphics.allocate Nothing multisample- Pipeline.baseConfig- { Pipeline.cVertexCode = Just vertCode- , Pipeline.cFragmentCode = Just fragCode- , Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cCull = Vk.CULL_MODE_NONE- }--vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable-- ${set0binding0}-- layout(location = 0) out vec3 fragUVW;-- float farZ = 0.9999; // 1 - 1e-7;-- void main() {- vec4 pos = vec4(0.0);- switch(gl_VertexIndex) {- case 0: pos = vec4(-1.0, 3.0, farZ, 1.0); break;- case 1: pos = vec4(-1.0, -1.0, farZ, 1.0); break; // XXX: swapped with 2. culling?- case 2: pos = vec4( 3.0, -1.0, farZ, 1.0); break;- }-- vec3 unProjected = (scene.invProjection * pos).xyz;- unProjected *= -1;- fragUVW = mat3(scene.invView) * unProjected;-- gl_Position = pos;- }- |])--fragCode :: ByteString-fragCode =- $(compileFrag [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable- #extension GL_EXT_nonuniform_qualifier : enable+ (config tset0) - ${set0binding0}+config :: Tagged Scene DsBindings -> Config+config (Tagged set0) = Graphics.baseConfig+ { Graphics.cStages = stageSpirv+ , Graphics.cDescLayouts = Tagged @'[Scene] [set0]+ , Graphics.cCull = Vk.CULL_MODE_NONE+ } - ${set0binding1}- ${set0binding3}+stageCode :: Graphics.StageCode+stageCode = Graphics.basicStages Code.vert Code.frag - layout(location = 0) in vec3 fragUVW;+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.basicStages vertSpirv fragSpirv - layout(location = 0) out vec4 outColor;+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert) - void main() {- if (scene.envCubeId > -1) {- outColor = texture(- samplerCube(- cubes[nonuniformEXT(scene.envCubeId)],- samplers[3] // XXX: linear- ),- fragUVW- );- }- }- |])+fragSpirv :: ByteString+fragSpirv = $(compileFrag Code.frag)
+ src/Render/Unlit/Colored/Code.hs view
@@ -0,0 +1,50 @@+module Render.Unlit.Colored.Code+ ( vert+ , frag+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.DescSets.Set0.Code (set0binding0)++vert :: Code+vert = fromString+ [glsl|+ #version 450++ ${set0binding0}++ layout(location = 0) in vec3 vPosition;+ layout(location = 1) in vec4 vColor;++ layout(location = 2) in mat4 iModel;++ layout(location = 0) out vec4 fColor;++ void main() {+ vec4 fPosition = iModel * vec4(vPosition, 1.0);++ gl_Position+ = scene.projection+ * scene.view+ * fPosition;++ fColor = vColor;+ fColor.rgb * fColor.a;+ }+ |]++frag :: Code+frag = fromString+ [glsl|+ #version 450++ layout(location = 0) in vec4 fragColor;++ layout(location = 0) out vec4 outColor;++ void main() {+ outColor = fragColor;+ }+ |]
src/Render/Unlit/Colored/Pipeline.hs view
@@ -6,6 +6,9 @@ , Config , config , configWireframe++ , stageCode+ , stageSpirv ) where import RIO@@ -14,15 +17,16 @@ import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk -import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, compileFrag, glsl)+import Render.Code (compileVert, compileFrag) import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform)-import Render.DescSets.Set0.Code (set0binding0)+import Render.Unlit.Colored.Code qualified as Code import Render.Unlit.Colored.Model qualified as Model -type Config = Pipeline.Configure Pipeline ()-type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Pipeline = Graphics.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = () allocate :: ( HasVulkan env@@ -34,7 +38,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocate useDepth multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (config useDepth tset0)@@ -51,7 +55,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocateWireframe useDepth multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (configWireframe useDepth tset0)@@ -59,66 +63,34 @@ pure p config :: Bool -> Tagged Scene DsBindings -> Config-config useDepth (Tagged set0) = Pipeline.baseConfig- { Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cVertexCode = Just vertCode- , Pipeline.cVertexInput = vertexInput- , Pipeline.cFragmentCode = Just fragCode- , Pipeline.cBlend = True- , Pipeline.cDepthTest = useDepth- , Pipeline.cDepthWrite = useDepth+config useDepth (Tagged set0) = Graphics.baseConfig+ { Graphics.cDescLayouts = Tagged @'[Scene] [set0]+ , Graphics.cStages = stageSpirv+ , Graphics.cVertexInput = vertexInput+ , Graphics.cBlend = True+ , Graphics.cDepthTest = useDepth+ , Graphics.cDepthWrite = useDepth } where- vertexInput = Pipeline.vertexInput+ vertexInput = Graphics.vertexInput [ vertexPos , (Vk.VERTEX_INPUT_RATE_VERTEX, Model.vkVertexAttrs) , instanceTransform ] -configWireframe :: Bool -> Tagged Scene DsBindings -> Config-configWireframe useDepth tset0 = (config useDepth tset0)- { Pipeline.cTopology = Vk.PRIMITIVE_TOPOLOGY_LINE_LIST- }--vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable-- ${set0binding0}-- layout(location = 0) in vec3 vPosition;- layout(location = 1) in vec4 vColor;-- layout(location = 2) in mat4 iModel;-- layout(location = 0) out vec4 fColor;-- void main() {- vec4 fPosition = iModel * vec4(vPosition, 1.0);-- gl_Position- = scene.projection- * scene.view- * fPosition;-- fColor = vColor;- fColor.rgb * fColor.a;- }- |])+stageCode :: Graphics.StageCode+stageCode = Graphics.basicStages Code.vert Code.frag -fragCode :: ByteString-fragCode =- $(compileFrag [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.basicStages vertSpirv fragSpirv - layout(location = 0) in vec4 fragColor;+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert) - layout(location = 0) out vec4 outColor;+fragSpirv :: ByteString+fragSpirv = $(compileFrag Code.frag) - void main() {- outColor = fragColor;- }- |])+configWireframe :: Bool -> Tagged Scene DsBindings -> Config+configWireframe useDepth tset0 = (config useDepth tset0)+ { Graphics.cTopology = Vk.PRIMITIVE_TOPOLOGY_LINE_LIST+ }
+ src/Render/Unlit/Sprite/Code.hs view
@@ -0,0 +1,125 @@+module Render.Unlit.Sprite.Code+ ( vert+ , frag+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2)++vert :: Code+vert = fromString+ [glsl|+ #version 450++ ${set0binding0}++ layout(location = 0) in vec4 iVert;+ layout(location = 1) in vec4 iFrag;+ layout(location = 2) in vec4 iTint;+ layout(location = 3) in vec4 iOutline;+ layout(location = 4) in ivec2 iTextureIds;+ layout(location = 5) in uvec2 iTextureSize;++ layout(location = 0) out vec2 fTexCoord;+ layout(location = 1) flat out vec4 fTint;+ layout(location = 2) flat out vec4 fOutline;+ layout(location = 3) flat out ivec2 fTextureIds;+ layout(location = 4) flat out uvec2 fTextureSize;++ vec2 positions[6] = vec2[](+ vec2(-0.5, -0.5),+ vec2(0.5, -0.5),+ vec2(-0.5, 0.5),++ vec2(0.5, 0.5),+ vec2(-0.5, 0.5),+ vec2(0.5, -0.5)+ );++ vec2 texCoords[6] = vec2[](+ vec2(0.0, 0.0),+ vec2(1.0, 0.0),+ vec2(0.0, 1.0),++ vec2(1.0, 1.0),+ vec2(0.0, 1.0),+ vec2(1.0, 0.0)+ );++ void main() {+ vec2 pos = positions[gl_VertexIndex];++ gl_Position+ = scene.projection+ * scene.view+ * vec4(iVert.xy + pos * iVert.zw, 0, 1.0);++ vec2 uv = texCoords[gl_VertexIndex];+ fTexCoord = iFrag.xy + uv * iFrag.zw;++ fTint = iTint;+ fOutline = iOutline;+ fTextureIds = iTextureIds;+ fTextureSize = iTextureSize;+ }+ |]++frag :: Code+frag = fromString+ [glsl|+ #version 450+ #extension GL_EXT_nonuniform_qualifier : enable++ ${set0binding1}+ ${set0binding2}++ layout(location = 0) in vec2 fTexCoord;+ layout(location = 1) flat in vec4 fTint;+ layout(location = 2) flat in vec4 fOutline;+ layout(location = 3) flat in ivec2 fTextureIds;+ layout(location = 4) flat in uvec2 fTextureSize;++ layout(location = 0) out vec4 outColor;++ layout(constant_id=0) const float discardAlpha = 0.0;+ layout(constant_id=1) const bool doOutline = false;++ vec4 tap(vec2 uv) {+ return texture(+ sampler2D(+ textures[nonuniformEXT(fTextureIds.t)],+ samplers[nonuniformEXT(fTextureIds.s)]+ ),+ fTexCoord + uv+ );+ }++ vec2 step_size = 1.0 / vec2(fTextureSize);++ void main() {+ vec4 texel = tap(vec2(0));++ if (discardAlpha != 0.0) {+ if (texel.a < discardAlpha) {+ discard;+ }+ }++ outColor = texel * fTint * texel.a;++ if (doOutline) {+ if (fOutline.a > 0.0 && texel.a < 1.0) {+ float alpha = 0.0;++ alpha += tap(vec2(step_size.x, 0.0) ).a / 4.0;+ alpha += tap(vec2(-step_size.x, 0.0) ).a / 4.0;+ alpha += tap(vec2(0.0, step_size.y) ).a / 4.0;+ alpha += tap(vec2(0.0, -step_size.y)).a / 4.0;++ outColor += fOutline * alpha;+ }+ }+ }+ |]
src/Render/Unlit/Sprite/Pipeline.hs view
@@ -2,8 +2,12 @@ module Render.Unlit.Sprite.Pipeline ( Pipeline+ , Config+ , config , allocate -- , allocateOutline+ , stageCode+ , stageSpirv ) where import RIO@@ -12,15 +16,16 @@ import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk -import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, compileFrag, glsl)+import Render.Code (compileVert, compileFrag) import Render.DescSets.Set0 (Scene)-import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2)+import Render.Unlit.Sprite.Code qualified as Code import Render.Unlit.Sprite.Model qualified as Model -type Config = Pipeline.Configure Pipeline (Float, Bool)-type Pipeline = Pipeline.Pipeline '[Scene] () Model.InstanceAttrs+type Pipeline = Graphics.Pipeline '[Scene] () Model.InstanceAttrs+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = (Float, Bool) allocate :: ( HasVulkan env@@ -33,7 +38,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocate multisample discardAlpha outline set0 = do- fmap snd . Pipeline.allocate+ fmap snd . Graphics.allocate Nothing multisample (config discardAlpha outline set0)@@ -44,19 +49,18 @@ -> Tagged Scene DsBindings -> Config config discardAlpha outline (Tagged set0) =- Pipeline.baseConfig- { Pipeline.cVertexCode = Just vertCode- , Pipeline.cFragmentCode = Just fragCode- , Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cVertexInput = vertexInput- , Pipeline.cDepthTest = False- , Pipeline.cDepthWrite = False- , Pipeline.cBlend = True- , Pipeline.cCull = Vk.CULL_MODE_NONE- , Pipeline.cSpecialization = specs+ Graphics.baseConfig+ { Graphics.cStages = stageSpirv+ , Graphics.cDescLayouts = Tagged @'[Scene] [set0]+ , Graphics.cVertexInput = vertexInput+ , Graphics.cDepthTest = False+ , Graphics.cDepthWrite = False+ , Graphics.cBlend = True+ , Graphics.cCull = Vk.CULL_MODE_NONE+ , Graphics.cSpecialization = specs } where- vertexInput = Pipeline.vertexInput+ vertexInput = Graphics.vertexInput [ (Vk.VERTEX_INPUT_RATE_INSTANCE, Model.vkInstanceAttrs) ] @@ -65,120 +69,14 @@ , outline ) -vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable-- ${set0binding0}-- layout(location = 0) in vec4 iVert;- layout(location = 1) in vec4 iFrag;- layout(location = 2) in vec4 iTint;- layout(location = 3) in vec4 iOutline;- layout(location = 4) in ivec2 iTextureIds;- layout(location = 5) in uvec2 iTextureSize;-- layout(location = 0) out vec2 fTexCoord;- layout(location = 1) flat out vec4 fTint;- layout(location = 2) flat out vec4 fOutline;- layout(location = 3) flat out ivec2 fTextureIds;- layout(location = 4) flat out uvec2 fTextureSize;-- vec2 positions[6] = vec2[](- vec2(-0.5, -0.5),- vec2(0.5, -0.5),- vec2(-0.5, 0.5),-- vec2(0.5, 0.5),- vec2(-0.5, 0.5),- vec2(0.5, -0.5)- );-- vec2 texCoords[6] = vec2[](- vec2(0.0, 0.0),- vec2(1.0, 0.0),- vec2(0.0, 1.0),-- vec2(1.0, 1.0),- vec2(0.0, 1.0),- vec2(1.0, 0.0)- );-- void main() {- vec2 pos = positions[gl_VertexIndex];-- gl_Position- = scene.projection- * scene.view- * vec4(iVert.xy + pos * iVert.zw, 0, 1.0);-- vec2 uv = texCoords[gl_VertexIndex];- fTexCoord = iFrag.xy + uv * iFrag.zw;-- fTint = iTint;- fOutline = iOutline;- fTextureIds = iTextureIds;- fTextureSize = iTextureSize;- }- |])--fragCode :: ByteString-fragCode =- $(compileFrag [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable- #extension GL_EXT_nonuniform_qualifier : enable-- ${set0binding1}- ${set0binding2}-- layout(location = 0) in vec2 fTexCoord;- layout(location = 1) flat in vec4 fTint;- layout(location = 2) flat in vec4 fOutline;- layout(location = 3) flat in ivec2 fTextureIds;- layout(location = 4) flat in uvec2 fTextureSize;-- layout(location = 0) out vec4 outColor;-- layout(constant_id=0) const float discardAlpha = 0.0;- layout(constant_id=1) const bool doOutline = false;-- vec4 tap(vec2 uv) {- return texture(- sampler2D(- textures[nonuniformEXT(fTextureIds.t)],- samplers[nonuniformEXT(fTextureIds.s)]- ),- fTexCoord + uv- );- }-- vec2 step_size = 1.0 / vec2(fTextureSize);-- void main() {- vec4 texel = tap(vec2(0));-- if (discardAlpha != 0.0) {- if (texel.a < discardAlpha) {- discard;- }- }-- outColor = texel * fTint * texel.a;+stageCode :: Graphics.StageCode+stageCode = Graphics.basicStages Code.vert Code.frag - if (doOutline) {- if (fOutline.a > 0.0 && texel.a < 1.0) {- float alpha = 0.0;+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.basicStages vertSpirv fragSpirv - alpha += tap(vec2(step_size.x, 0.0) ).a / 4.0;- alpha += tap(vec2(-step_size.x, 0.0) ).a / 4.0;- alpha += tap(vec2(0.0, step_size.y) ).a / 4.0;- alpha += tap(vec2(0.0, -step_size.y)).a / 4.0;+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert) - outColor += fOutline * alpha;- }- }- }- |])+fragSpirv :: ByteString+fragSpirv = $(compileFrag Code.frag)
+ src/Render/Unlit/Textured/Code.hs view
@@ -0,0 +1,83 @@+module Render.Unlit.Textured.Code+ ( vert+ , frag+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2)++vert :: Code+vert = fromString+ [glsl|+ #version 450++ ${set0binding0}++ // vertexPos+ layout(location = 0) in vec3 vPosition;+ // vertexAttrs+ layout(location = 1) in vec2 vTexCoord;+ // textureParams+ layout(location = 2) in vec4 iTextureScaleOffset;+ layout(location = 3) in vec4 iTextureGamma;+ layout(location = 4) in ivec2 iTextureIds;++ // transformMat+ layout(location = 5) in mat4 iModel;++ layout(location = 0) out vec2 fTexCoord;+ layout(location = 1) flat out vec4 fTextureGamma;+ layout(location = 2) flat out ivec2 fTextureIds;++ void main() {+ vec4 fPosition = iModel * vec4(vPosition, 1.0);++ gl_Position+ = scene.projection+ * scene.view+ * fPosition;++ fTexCoord = vTexCoord * iTextureScaleOffset.st + iTextureScaleOffset.pq;+ fTextureGamma = iTextureGamma;+ fTextureIds = iTextureIds;+ }+ |]++frag :: Code+frag = fromString+ [glsl|+ #version 450+ #extension GL_ARB_separate_shader_objects : enable+ #extension GL_EXT_nonuniform_qualifier : enable++ ${set0binding1}+ ${set0binding2}++ layout(location = 0) in vec2 fTexCoord;+ layout(location = 1) flat in vec4 fTextureGamma;+ layout(location = 2) flat in ivec2 fTextureIds;++ layout(location = 0) out vec4 oColor;++ void main() {+ vec3 color = vec3(0);+ float combinedAlpha = 0;++ if (fTextureIds.t > -1 && fTextureIds.s > -1) {+ vec4 texel = texture(+ sampler2D(+ textures[nonuniformEXT(fTextureIds.t)],+ samplers[nonuniformEXT(fTextureIds.s)]+ ),+ fTexCoord+ );+ color = pow(texel.rgb, fTextureGamma.rgb);+ combinedAlpha = texel.a * fTextureGamma.a;+ }++ // XXX: premultiply alpha due to additive blending+ oColor = vec4(color * combinedAlpha, combinedAlpha);+ }+ |]
src/Render/Unlit/Textured/Pipeline.hs view
@@ -6,23 +6,27 @@ , Config , config , configBlend++ , stageCode+ , stageSpirv ) where import RIO-import Render.DescSets.Set0.Code import Control.Monad.Trans.Resource (ResourceT) import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk -import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, compileFrag, glsl)+import Render.Code (compileVert, compileFrag) import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform)+import Render.Unlit.Textured.Code qualified as Code import Render.Unlit.Textured.Model qualified as Model -type Config = Pipeline.Configure Pipeline ()-type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Pipeline = Graphics.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = () allocate :: ( HasVulkan env@@ -33,7 +37,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocate multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (config tset0)@@ -49,7 +53,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocateBlend multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (configBlend tset0)@@ -57,14 +61,13 @@ pure p config :: Tagged Scene DsBindings -> Config-config (Tagged set0) = Pipeline.baseConfig- { Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cVertexCode = Just vertCode- , Pipeline.cVertexInput = vertexInput- , Pipeline.cFragmentCode = Just fragCode+config (Tagged set0) = Graphics.baseConfig+ { Graphics.cDescLayouts = Tagged @'[Scene] [set0]+ , Graphics.cStages = stageSpirv+ , Graphics.cVertexInput = vertexInput } where- vertexInput = Pipeline.vertexInput+ vertexInput = Graphics.vertexInput [ vertexPos -- vPosition , (Vk.VERTEX_INPUT_RATE_VERTEX, Model.vkVertexAttrs) , (Vk.VERTEX_INPUT_RATE_INSTANCE, Model.vkInstanceTexture)@@ -73,81 +76,18 @@ configBlend :: Tagged Scene DsBindings -> Config configBlend tset0 = (config tset0)- { Pipeline.cBlend = True- , Pipeline.cDepthWrite = False+ { Graphics.cBlend = True+ , Graphics.cDepthWrite = False } -vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable-- ${set0binding0}-- // vertexPos- layout(location = 0) in vec3 vPosition;- // vertexAttrs- layout(location = 1) in vec2 vTexCoord;- // textureParams- layout(location = 2) in vec4 iTextureScaleOffset;- layout(location = 3) in vec4 iTextureGamma;- layout(location = 4) in ivec2 iTextureIds;-- // transformMat- layout(location = 5) in mat4 iModel;-- layout(location = 0) out vec2 fTexCoord;- layout(location = 1) flat out vec4 fTextureGamma;- layout(location = 2) flat out ivec2 fTextureIds;-- void main() {- vec4 fPosition = iModel * vec4(vPosition, 1.0);-- gl_Position- = scene.projection- * scene.view- * fPosition;-- fTexCoord = vTexCoord * iTextureScaleOffset.st + iTextureScaleOffset.pq;- fTextureGamma = iTextureGamma;- fTextureIds = iTextureIds;- }- |])--fragCode :: ByteString-fragCode =- $(compileFrag [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable- #extension GL_EXT_nonuniform_qualifier : enable-- ${set0binding1}- ${set0binding2}-- layout(location = 0) in vec2 fTexCoord;- layout(location = 1) flat in vec4 fTextureGamma;- layout(location = 2) flat in ivec2 fTextureIds;-- layout(location = 0) out vec4 oColor;+stageCode :: Graphics.StageCode+stageCode = Graphics.basicStages Code.vert Code.frag - void main() {- vec3 color = vec3(0);- float combinedAlpha = 0;+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.basicStages vertSpirv fragSpirv - if (fTextureIds.t > -1 && fTextureIds.s > -1) {- vec4 texel = texture(- sampler2D(- textures[nonuniformEXT(fTextureIds.t)],- samplers[nonuniformEXT(fTextureIds.s)]- ),- fTexCoord- );- color = pow(texel.rgb, fTextureGamma.rgb);- combinedAlpha = texel.a * fTextureGamma.a;- }+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert) - // XXX: premultiply alpha due to additive blending- oColor = vec4(color * combinedAlpha, combinedAlpha);- }- |])+fragSpirv :: ByteString+fragSpirv = $(compileFrag Code.frag)
+ src/Render/Unlit/TileMap/Code.hs view
@@ -0,0 +1,111 @@+module Render.Unlit.TileMap.Code+ ( vert+ , frag+ ) where++import RIO++import Render.Code (Code, glsl)+import Render.Samplers qualified as Samplers+import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2)++vert :: Code+vert = fromString+ [glsl|+ #version 450++ ${set0binding0}++ // vertexPos+ layout(location = 0) in vec3 vPosition;+ // vertexAttrs+ layout(location = 1) in vec2 vTexCoord;+ // tilemapParams+ layout(location = 2) in ivec4 iTextureIds; // combined: tileset, tileset sampler, map, repeat+ layout(location = 3) in vec2 iViewOffset;+ layout(location = 4) in vec2 iViewportSize;+ layout(location = 5) in vec2 iMapTextureSize;+ layout(location = 6) in vec2 iTilesetTextureSize;+ layout(location = 7) in vec2 iTileSize;++ // transformMat+ layout(location = 8) in mat4 iModel;++ layout(location = 0) out vec2 fTexCoord;+ layout(location = 1) out vec2 fPixCoord;+ layout(location = 2) flat out ivec4 fTextureIds;+ layout(location = 3) flat out vec2 fTilesetTextureSize;+ layout(location = 4) flat out vec2 fTileSize;++ void main() {+ vec4 fPosition = iModel * vec4(vPosition, 1.0);++ gl_Position+ = scene.projection+ * scene.view+ * fPosition;++ fPixCoord = (vTexCoord * iViewportSize) + iViewOffset;+ fTexCoord = fPixCoord / iMapTextureSize / iTileSize;++ fTextureIds = iTextureIds;+ fTilesetTextureSize = iTilesetTextureSize;+ fTileSize = iTileSize;+ }+ |]++frag :: Code+frag = fromString+ [glsl|+ #version 450+ #extension GL_EXT_nonuniform_qualifier : enable++ ${set0binding1}+ ${set0binding2}++ layout(location = 0) in vec2 fTexCoord;+ layout(location = 1) in vec2 fPixCoord;++ // combined: tileset, tileset sampler, map, repeat+ layout(location = 2) flat in ivec4 fTextureIds;+ layout(location = 3) flat in vec2 fTilesetTextureSize;+ layout(location = 4) flat in vec2 fTileSize;++ layout(location = 0) out vec4 oColor;++ int tilesetTextureIx = fTextureIds[0];+ int tilesetSamplerIx = fTextureIds[1];+ int mapTextureIx = fTextureIds[2];+ int repeatTiles = fTextureIds[3];++ // TODO+ // const vec4 fTextureGamma = vec4(1.0);++ void main() {+ if (repeatTiles == 0 && (fTexCoord.x < 0.0 || fTexCoord.y < 0.0 || fTexCoord.x > 1.0 || fTexCoord.y > 1.0)) {+ discard;+ }++ vec4 map = texture(+ sampler2D(+ textures[nonuniformEXT(mapTextureIx)],+ samplers[$samplerId]+ ),+ fTexCoord+ );++ vec2 spriteOffset = floor(map.xy * 256.0) * fTileSize;+ vec2 spriteCoord = mod(fPixCoord, fTileSize);+ vec2 spriteUV = round(spriteOffset + spriteCoord) / fTilesetTextureSize;++ oColor = texture(+ sampler2D(+ textures[nonuniformEXT(tilesetTextureIx)],+ samplers[nonuniformEXT(tilesetSamplerIx)]+ ),+ spriteUV+ );+ }+ |]+ where+ samplerId = Samplers.nearest Samplers.indices
src/Render/Unlit/TileMap/Pipeline.hs view
@@ -6,23 +6,26 @@ , Config , config , configBlend++ , stageCode ) where import RIO-import Render.DescSets.Set0.Code import Control.Monad.Trans.Resource (ResourceT) import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk -import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)-import Render.Code (compileVert, compileFrag, glsl)+import Render.Code (compileVert, compileFrag) import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform)+import Render.Unlit.TileMap.Code qualified as Code import Render.Unlit.TileMap.Model qualified as Model -type Config = Pipeline.Configure Pipeline ()-type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Pipeline = Graphics.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Graphics.Configure Pipeline+type instance Graphics.Specialization Pipeline = () allocate :: ( HasVulkan env@@ -33,7 +36,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocate multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (config tset0)@@ -49,7 +52,7 @@ -> renderpass -> ResourceT (RIO env) Pipeline allocateBlend multisample tset0 rp = do- (_, p) <- Pipeline.allocate+ (_, p) <- Graphics.allocate Nothing multisample (configBlend tset0)@@ -57,14 +60,13 @@ pure p config :: Tagged Scene DsBindings -> Config-config (Tagged set0) = Pipeline.baseConfig- { Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cVertexCode = Just vertCode- , Pipeline.cVertexInput = vertexInput- , Pipeline.cFragmentCode = Just fragCode+config (Tagged set0) = Graphics.baseConfig+ { Graphics.cDescLayouts = Tagged @'[Scene] [set0]+ , Graphics.cStages = stageSpirv+ , Graphics.cVertexInput = vertexInput } where- vertexInput = Pipeline.vertexInput+ vertexInput = Graphics.vertexInput [ vertexPos , (Vk.VERTEX_INPUT_RATE_VERTEX, Model.vkVertexAttrs) , (Vk.VERTEX_INPUT_RATE_INSTANCE, Model.vkInstanceTileMap)@@ -73,107 +75,18 @@ configBlend :: Tagged Scene DsBindings -> Config configBlend tset0 = (config tset0)- { Pipeline.cBlend = True- , Pipeline.cDepthWrite = False+ { Graphics.cBlend = True+ , Graphics.cDepthWrite = False } -vertCode :: ByteString-vertCode =- $(compileVert [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable-- ${set0binding0}-- // vertexPos- layout(location = 0) in vec3 vPosition;- // vertexAttrs- layout(location = 1) in vec2 vTexCoord;- // tilemapParams- layout(location = 2) in ivec4 iTextureIds; // combined: tileset, tileset sampler, map, repeat- layout(location = 3) in vec2 iViewOffset;- layout(location = 4) in vec2 iViewportSize;- layout(location = 5) in vec2 iMapTextureSize;- layout(location = 6) in vec2 iTilesetTextureSize;- layout(location = 7) in vec2 iTileSize;-- // transformMat- layout(location = 8) in mat4 iModel;-- layout(location = 0) out vec2 fTexCoord;- layout(location = 1) out vec2 fPixCoord;- layout(location = 2) flat out ivec4 fTextureIds;- layout(location = 3) flat out vec2 fTilesetTextureSize;- layout(location = 4) flat out vec2 fTileSize;-- void main() {- vec4 fPosition = iModel * vec4(vPosition, 1.0);-- gl_Position- = scene.projection- * scene.view- * fPosition;-- fPixCoord = (vTexCoord * iViewportSize) + iViewOffset;- fTexCoord = fPixCoord / iMapTextureSize / iTileSize;-- fTextureIds = iTextureIds;- fTilesetTextureSize = iTilesetTextureSize;- fTileSize = iTileSize;- }- |])--fragCode :: ByteString-fragCode =- $(compileFrag [glsl|- #version 450- #extension GL_ARB_separate_shader_objects : enable- #extension GL_EXT_nonuniform_qualifier : enable-- ${set0binding1}- ${set0binding2}-- layout(location = 0) in vec2 fTexCoord;- layout(location = 1) in vec2 fPixCoord;-- // combined: tileset, tileset sampler, map, repeat- layout(location = 2) flat in ivec4 fTextureIds;- layout(location = 3) flat in vec2 fTilesetTextureSize;- layout(location = 4) flat in vec2 fTileSize;-- layout(location = 0) out vec4 oColor;-- int tilesetTextureIx = fTextureIds[0];- int tilesetSamplerIx = fTextureIds[1];- int mapTextureIx = fTextureIds[2];- int repeatTiles = fTextureIds[3];-- // TODO- // const vec4 fTextureGamma = vec4(1.0);-- void main() {- if (repeatTiles == 0 && (fTexCoord.x < 0.0 || fTexCoord.y < 0.0 || fTexCoord.x > 1.0 || fTexCoord.y > 1.0)) {- discard;- }+stageCode :: Graphics.StageCode+stageCode = Graphics.basicStages Code.vert Code.frag - vec4 map = texture(- sampler2D(- textures[nonuniformEXT(mapTextureIx)],- samplers[7] // nearest- ),- fTexCoord- );+stageSpirv :: Graphics.StageSpirv+stageSpirv = Graphics.basicStages vertSpirv fragSpirv - vec2 spriteOffset = floor(map.xy * 256.0) * fTileSize;- vec2 spriteCoord = mod(fPixCoord, fTileSize);- vec2 spriteUV = (spriteOffset + spriteCoord) / fTilesetTextureSize;+vertSpirv :: ByteString+vertSpirv = $(compileVert Code.vert) - oColor = texture(- sampler2D(- textures[nonuniformEXT(tilesetTextureIx)],- samplers[nonuniformEXT(tilesetSamplerIx)]- ),- spriteUV- );- }- |])+fragSpirv :: ByteString+fragSpirv = $(compileFrag Code.frag)
src/Stage/Loader/Render.hs view
@@ -8,7 +8,7 @@ import RIO import Engine.Types qualified as Engine-import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Pipeline.Graphics qualified as Graphics import Engine.Vulkan.Swapchain qualified as Swapchain import Engine.Worker qualified as Worker import Render.Draw qualified as Draw@@ -48,9 +48,9 @@ Set0.withBoundSet0 frSceneUi pWireframe cb do -- Render UI- Pipeline.bind cb pUnlitTexturedBlend do+ Graphics.bind cb pUnlitTexturedBlend do Draw.indexed cb (UI.quadUV ui) background Draw.indexed cb (UI.quadUV ui) spinner - Pipeline.bind cb pEvanwSdf $+ Graphics.bind cb pEvanwSdf $ traverse_ (Draw.quads cb) uiMessages
src/Stage/Loader/Setup.hs view
@@ -9,8 +9,9 @@ import Control.Monad.Trans.Resource (ResourceT) import Engine.Camera qualified as Camera+import Engine.Stage.Component qualified as Stage import Engine.StageSwitch (trySwitchStage)-import Engine.Types (StackStage(..), Stage(..), StageSetupRIO)+import Engine.Types (StackStage(..), StageSetupRIO) import Engine.Types qualified as Engine import Engine.UI.Layout qualified as Layout import Engine.UI.Message qualified as Message@@ -120,21 +121,13 @@ -> (loaded -> StackStage) -> UI.Settings textures fonts -> Basic.Stage FrameResources RunState-loaderStage loadAction nextStage uiSettings = Stage- { sTitle = "Loader"-- , sAllocateRP = allocateRenderPass- , sAllocateP = allocatePipelines- , sInitialRS = initialRunState loadAction nextStage uiSettings- , sInitialRR = initialFrameResources uiSettings- , sBeforeLoop = pure ()-- , sUpdateBuffers = Render.updateBuffers- , sRecordCommands = Render.recordCommands-- , sAfterLoop = pure- }+loaderStage loadAction nextStage uiSettings = Stage.assemble "Loader" rendering resources (Just scene) where+ rendering = Stage.Rendering+ { rAllocateRP = allocateRenderPass+ , rAllocateP = allocatePipelines+ }+ allocateRenderPass swapchain = do Basic.allocate Basic.Settings@@ -157,6 +150,17 @@ (UI.combined uiSettings) Nothing 0++ resources = Stage.Resources+ { rInitialRS = initialRunState loadAction nextStage uiSettings+ , rInitialRR = initialFrameResources uiSettings+ }++ scene = Stage.Scene+ { scBeforeLoop = pure ()+ , scUpdateBuffers = Render.updateBuffers+ , scRecordCommands = Render.recordCommands+ } initialRunState :: ((Text -> StageSetupRIO ()) -> StageSetupRIO loaded)