invisible ambient color

This commit is contained in:
nek0 2023-04-02 10:46:02 +02:00
parent 2516d12eea
commit f735077faa
7 changed files with 196 additions and 31 deletions

View file

@ -0,0 +1,19 @@
#version 450
// shader input
layout(location = 0) in vec4 fragColor;
// output write
layout(location = 0) out vec4 outColor;
layout(set = 0, binding = 1) uniform SceneData{
vec4 fogColor; // w is for exponent
vec4 fogDistances; //x for min, y for max, zw unused.
vec4 ambientColor;
vec4 sunlightDirection; //w for sun power
vec4 sunlightColor;
} sceneData;
void main() {
outColor = vec4(fragColor.xyz + sceneData.ambientColor.xyz, 1.0f);
}

View file

@ -24,7 +24,7 @@ import qualified VulkanMemoryAllocator as VMA
import Devices import Devices
import Types import Types
import Memory import Memory
import Util (getFrame) import Util
frameOverlap :: Int frameOverlap :: Int
frameOverlap = 2 frameOverlap = 2
@ -41,6 +41,8 @@ createFrames physicalDevice logicalDevice allocator descriptorPool setLayout = d
queueFamilyIndex <- getQueueFamily physicalDevice Vk.QUEUE_GRAPHICS_BIT queueFamilyIndex <- getQueueFamily physicalDevice Vk.QUEUE_GRAPHICS_BIT
deviceProperties <- Vk.getPhysicalDeviceProperties physicalDevice
let poolCreateInfo = Vk.zero let poolCreateInfo = Vk.zero
{ Vk.flags = Vk.COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT { Vk.flags = Vk.COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
, Vk.queueFamilyIndex = queueFamilyIndex , Vk.queueFamilyIndex = queueFamilyIndex
@ -49,7 +51,7 @@ createFrames physicalDevice logicalDevice allocator descriptorPool setLayout = d
graphicsQueue <- Vk.getDeviceQueue logicalDevice queueFamilyIndex 0 graphicsQueue <- Vk.getDeviceQueue logicalDevice queueFamilyIndex 0
frames <- V.mapM frames <- V.mapM
(\_ -> do (\index -> do
commandPool <- snd <$> allocate commandPool <- snd <$> allocate
(Vk.createCommandPool logicalDevice poolCreateInfo Nothing) (Vk.createCommandPool logicalDevice poolCreateInfo Nothing)
@ -87,7 +89,6 @@ createFrames physicalDevice logicalDevice allocator descriptorPool setLayout = d
) )
cameraBuffer <- createAllocatedBuffer cameraBuffer <- createAllocatedBuffer
logicalDevice
allocator allocator
(sizeOf (GPUCameraData identity identity identity)) (sizeOf (GPUCameraData identity identity identity))
Vk.BUFFER_USAGE_UNIFORM_BUFFER_BIT Vk.BUFFER_USAGE_UNIFORM_BUFFER_BIT
@ -101,20 +102,35 @@ createFrames physicalDevice logicalDevice allocator descriptorPool setLayout = d
globalDescriptor <- Vk.allocateDescriptorSets logicalDevice allocationInfo globalDescriptor <- Vk.allocateDescriptorSets logicalDevice allocationInfo
let bufferInfo = Vk.zero let cameraInfo = Vk.zero
{ Vk.buffer = allocatedBuffer cameraBuffer { Vk.buffer = allocatedBuffer cameraBuffer
, Vk.offset = 0 , Vk.offset = 0
, Vk.range = fromIntegral $ sizeOf (GPUCameraData identity identity identity) , Vk.range = fromIntegral $ sizeOf (GPUCameraData identity identity identity)
} :: Vk.DescriptorBufferInfo } :: Vk.DescriptorBufferInfo
setWrite = Vk.zero sceneInfo = Vk.zero
{ Vk.dstBinding = 0 { Vk.buffer = allocatedBuffer cameraBuffer
, Vk.dstSet = V.head globalDescriptor , Vk.offset = padUniformBufferSize
, Vk.descriptorCount = 1 (fromIntegral $ sizeOf (undefinedGPUSceneData) * fromIntegral index)
, Vk.descriptorType = Vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER deviceProperties
, Vk.bufferInfo = V.singleton bufferInfo , Vk.range = fromIntegral $ sizeOf (undefinedGPUSceneData)
} } :: Vk.DescriptorBufferInfo
cameraWrite = writeDescriptorBuffer
Vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER
(V.head globalDescriptor)
cameraInfo
0
sceneWrite = writeDescriptorBuffer
Vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER
(V.head globalDescriptor)
sceneInfo
1
setWrites = V.fromList
[ cameraWrite
, sceneWrite
]
Vk.updateDescriptorSets logicalDevice (V.singleton (Vk.SomeStruct setWrite)) V.empty
Vk.updateDescriptorSets logicalDevice setWrites V.empty
return FrameData return FrameData
{ framePresentSemaphore = presentSemaphore { framePresentSemaphore = presentSemaphore
@ -140,6 +156,9 @@ recordCommandBuffer
-> Vk.Pipeline -> Vk.Pipeline
-> Vk.PipelineLayout -> Vk.PipelineLayout
-> VMA.Allocator -> VMA.Allocator
-> GPUSceneData
-> AllocatedBuffer
-> Vk.PhysicalDeviceProperties
-> FrameData -> FrameData
-> Int -> Int
-> m () -> m ()
@ -151,6 +170,9 @@ recordCommandBuffer
graphicsPipeline graphicsPipeline
meshLayout meshLayout
allocator allocator
sceneParameters
sceneParameterBuffer
deviceProps
frame frame
frameNumber frameNumber
= do = do
@ -204,6 +226,24 @@ recordCommandBuffer
Vk.cmdSetViewport commandBuffer 0 (V.singleton viewport) Vk.cmdSetViewport commandBuffer 0 (V.singleton viewport)
Vk.cmdSetScissor commandBuffer 0 (V.singleton scissor) Vk.cmdSetScissor commandBuffer 0 (V.singleton scissor)
let framed = fromIntegral frameNumber / 120
ambient = V4 (sin framed) 0 (cos framed) 1
frameIndex = frameNumber `mod` frameOverlap
scenePointer <- VMA.mapMemory allocator (bufferAllocation sceneParameterBuffer)
liftIO $ poke
(castPtr scenePointer `plusPtr`
(fromIntegral $
padUniformBufferSize (fromIntegral $ sizeOf (undefinedGPUSceneData)) deviceProps *
fromIntegral frameIndex))
(sceneParameters
{ ambientColor = ambient
}
)
VMA.unmapMemory allocator (bufferAllocation sceneParameterBuffer)
renderObjects <- (liftIO . STM.atomically . STM.readTMVar) =<< asks renderables renderObjects <- (liftIO . STM.atomically . STM.readTMVar) =<< asks renderables
meshMap <- (liftIO . STM.atomically . STM.readTMVar) =<< asks meshLibrary meshMap <- (liftIO . STM.atomically . STM.readTMVar) =<< asks meshLibrary
materialMap <- (liftIO . STM.atomically . STM.readTMVar) =<< asks materialLibrary materialMap <- (liftIO . STM.atomically . STM.readTMVar) =<< asks materialLibrary

View file

@ -63,6 +63,9 @@ drawFrame engineData frameNumber = do
(materialPipeline $ matLibrary M.! "defaultMesh") (materialPipeline $ matLibrary M.! "defaultMesh")
(meshPipelineLayout engineData) (meshPipelineLayout engineData)
(engineAllocator engineData) (engineAllocator engineData)
(engineSceneParameters engineData)
(engineSceneParameterBuffer engineData)
(enginePhysicalDeviceProperties engineData)
frame frame
frameNumber frameNumber

View file

@ -10,17 +10,18 @@ import Control.Monad
import Control.Monad.IO.Class import Control.Monad.IO.Class
import Control.Monad.Reader import Control.Monad.Reader
import Control.Monad.Trans.Resource import Control.Monad.Trans.Resource
import Data.Bits (Bits(bit)) import Data.Bits ((.|.))
import qualified Data.Vector as V import qualified Data.Vector as V
import qualified SDL hiding (V2) import qualified SDL hiding (V2)
import qualified SDL.Video.Vulkan as SDL import qualified SDL.Video.Vulkan as SDL
import Foreign (sizeOf)
import Foreign.Ptr import Foreign.Ptr
import Linear as L import Linear as L
import qualified VulkanMemoryAllocator as VMA
import qualified Vulkan.Core10 as Vk import qualified Vulkan.Core10 as Vk
import qualified Vulkan.Extensions.VK_KHR_swapchain as Khr import qualified Vulkan.Extensions.VK_KHR_swapchain as Khr
import qualified Vulkan.Extensions.VK_KHR_surface as Khr import qualified Vulkan.Extensions.VK_KHR_surface as Khr
import qualified Vulkan.Zero as Vk import qualified Vulkan.Zero as Vk
import qualified VulkanMemoryAllocator as VMA
-- internal imports -- internal imports
@ -32,6 +33,7 @@ import Memory
import Types import Types
import Mesh import Mesh
import CommandBuffer import CommandBuffer
import Util
initEngine initEngine
:: Render EngineData :: Render EngineData
@ -99,7 +101,7 @@ initVulkan window = do
createSwapchain vulkanSurface surfaceFormats dimensions vulkanLogicalDevice allocator createSwapchain vulkanSurface surfaceFormats dimensions vulkanLogicalDevice allocator
imageViews <- getImageViewHandles swapchain surfaceFormat vulkanLogicalDevice imageViews <- getImageViewHandles swapchain surfaceFormat vulkanLogicalDevice
meshVertexShader <- loadShader vulkanLogicalDevice "shadersrc/mesh.vert" "vert" meshVertexShader <- loadShader vulkanLogicalDevice "shadersrc/mesh.vert" "vert"
meshFragmentShader <- loadShader vulkanLogicalDevice "shadersrc/rainbow.frag" "frag" meshFragmentShader <- loadShader vulkanLogicalDevice "shadersrc/rainbow_lit.frag" "frag"
renderPass <- createRenderPass vulkanLogicalDevice (Khr.format surfaceFormat) Vk.FORMAT_D32_SFLOAT renderPass <- createRenderPass vulkanLogicalDevice (Khr.format surfaceFormat) Vk.FORMAT_D32_SFLOAT
meshLayout <- createMeshPipelineLayout vulkanLogicalDevice descriptorSetLayout meshLayout <- createMeshPipelineLayout vulkanLogicalDevice descriptorSetLayout
let meshContainer = ShaderContainer (Just meshVertexShader) (Just meshFragmentShader) let meshContainer = ShaderContainer (Just meshVertexShader) (Just meshFragmentShader)
@ -138,6 +140,19 @@ initVulkan window = do
descriptorSetLayout descriptorSetLayout
descriptorPool descriptorPool
<$> Vk.getPhysicalDeviceProperties vulkanPhysicalDevice <$> Vk.getPhysicalDeviceProperties vulkanPhysicalDevice
<*> pure (GPUSceneData
(V4 0 0 0 0)
(V4 0 0 0 0)
(V4 0 0 0 0)
(V4 0 0 0 0)
(V4 0 0 0 0)
)
<*> createAllocatedBuffer
allocator
(sizeOf (undefinedGPUSceneData))
Vk.BUFFER_USAGE_UNIFORM_BUFFER_BIT
VMA.MEMORY_USAGE_CPU_TO_GPU
initScene :: (MonadReader ReadState m, MonadIO m) => m () initScene :: (MonadReader ReadState m, MonadIO m) => m ()
initScene = do initScene = do
@ -175,15 +190,20 @@ initDescriptors
=> Vk.Device => Vk.Device
-> m (Vk.DescriptorSetLayout, Vk.DescriptorPool) -> m (Vk.DescriptorSetLayout, Vk.DescriptorPool)
initDescriptors device = do initDescriptors device = do
let cameraBufferBinding = Vk.zero let cameraBind = descriptorsetLayoutBinding
{ Vk.binding = 0 Vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER
, Vk.descriptorCount = 1 Vk.SHADER_STAGE_VERTEX_BIT
, Vk.descriptorType = Vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER 0
, Vk.stageFlags = Vk.SHADER_STAGE_VERTEX_BIT sceneBind = descriptorsetLayoutBinding
} Vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
(Vk.SHADER_STAGE_VERTEX_BIT .|. Vk.SHADER_STAGE_FRAGMENT_BIT)
1
setInfo = Vk.zero setInfo = Vk.zero
{ Vk.flags = Vk.DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT { Vk.flags = Vk.DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT
, Vk.bindings = V.singleton cameraBufferBinding , Vk.bindings = V.fromList
[ cameraBind
, sceneBind
]
} }
poolInfo = Vk.zero poolInfo = Vk.zero
{ Vk.flags = Vk.DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT { Vk.flags = Vk.DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT

View file

@ -49,13 +49,12 @@ initAllocator physicalDevice device instance' = do
createAllocatedBuffer createAllocatedBuffer
:: (MonadResource m, MonadIO m) :: (MonadResource m, MonadIO m)
=> Vk.Device => VMA.Allocator
-> VMA.Allocator
-> Int -> Int
-> Vk.BufferUsageFlags -> Vk.BufferUsageFlags
-> VMA.MemoryUsage -> VMA.MemoryUsage
-> m AllocatedBuffer -> m AllocatedBuffer
createAllocatedBuffer device allocator allocationSize usage memoryUsage = do createAllocatedBuffer allocator allocationSize usage memoryUsage = do
let bufferInfo = Vk.zero let bufferInfo = Vk.zero
{ Vk.size = fromIntegral allocationSize { Vk.size = fromIntegral allocationSize
, Vk.usage = usage , Vk.usage = usage

View file

@ -42,6 +42,8 @@ data EngineData = EngineData
, engineGlobalSetLayout :: Vk.DescriptorSetLayout , engineGlobalSetLayout :: Vk.DescriptorSetLayout
, engineDescriptorPool :: Vk.DescriptorPool , engineDescriptorPool :: Vk.DescriptorPool
, enginePhysicalDeviceProperties :: Vk.PhysicalDeviceProperties , enginePhysicalDeviceProperties :: Vk.PhysicalDeviceProperties
, engineSceneParameters :: GPUSceneData
, engineSceneParameterBuffer :: AllocatedBuffer
} }
data AllocatedBuffer = AllocatedBuffer data AllocatedBuffer = AllocatedBuffer
@ -200,14 +202,46 @@ data GPUCameraData = GPUCameraData
instance Storable GPUCameraData where instance Storable GPUCameraData where
sizeOf (GPUCameraData view projection viewProjection) = sizeOf (GPUCameraData pview pprojection pviewProjection) =
sizeOf view + sizeOf projection + sizeOf viewProjection sizeOf pview + sizeOf pprojection + sizeOf pviewProjection
alignment = undefined alignment = undefined
peek _ = undefined peek _ = undefined
poke ptr (GPUCameraData view projection viewProjection) = do poke ptr (GPUCameraData pview pprojection pviewProjection) = do
poke (castPtr ptr) view poke (castPtr ptr) pview
poke (castPtr ptr `plusPtr` sizeOf view) projection poke (castPtr ptr `plusPtr` sizeOf pview) pprojection
poke (castPtr ptr `plusPtr` sizeOf view `plusPtr` sizeOf projection) viewProjection poke (castPtr ptr `plusPtr` sizeOf pview `plusPtr` sizeOf pprojection) pviewProjection
data GPUSceneData = GPUSceneData
{ fogColor :: V4 Float
, fogDistance :: V4 Float
, ambientColor :: V4 Float
, sunDirection :: V4 Float
, sunColor :: V4 Float
}
undefinedGPUSceneData :: GPUSceneData
undefinedGPUSceneData = GPUSceneData
(V4 0 0 0 0)
(V4 0 0 0 0)
(V4 0 0 0 0)
(V4 0 0 0 0)
(V4 0 0 0 0)
instance Storable GPUSceneData where
sizeOf (GPUSceneData fogCol fogDist ambCol sunDir sunCol) =
sizeOf fogCol + sizeOf fogDist + sizeOf ambCol + sizeOf sunDir + sizeOf sunCol
alignment = undefined
peek _ = undefined
poke ptr (GPUSceneData fogCol fogDist ambCol sunDir sunCol) = do
poke (castPtr ptr) fogCol
poke (castPtr ptr `plusPtr` sizeOf fogCol) fogDist
poke (castPtr ptr `plusPtr` sizeOf fogCol `plusPtr` sizeOf fogDist) ambCol
poke (castPtr ptr `plusPtr` sizeOf fogCol `plusPtr` sizeOf fogDist `plusPtr` sizeOf ambCol) sunDir
poke (castPtr ptr `plusPtr` sizeOf fogCol `plusPtr` sizeOf fogDist `plusPtr` sizeOf ambCol `plusPtr` sizeOf sunDir) sunCol

View file

@ -1,7 +1,17 @@
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE DataKinds #-}
module Util where module Util where
import Data.Bits
import qualified Data.Vector as V import qualified Data.Vector as V
import Data.Word (Word32)
import qualified Vulkan as Vk
import qualified Vulkan.CStruct.Extends as Vk
import qualified Vulkan.Zero as Vk
-- internal imports -- internal imports
import Types import Types
@ -11,3 +21,43 @@ getFrame engineData frame =
let frameVector = engineFrames engineData let frameVector = engineFrames engineData
in in
frameVector V.! (frame `mod` V.length frameVector) frameVector V.! (frame `mod` V.length frameVector)
padUniformBufferSize
:: Vk.DeviceSize
-> Vk.PhysicalDeviceProperties
-> Vk.DeviceSize
padUniformBufferSize origSize gpuProperties =
let minUBOAlignment = Vk.minUniformBufferOffsetAlignment $ Vk.limits gpuProperties
in
if minUBOAlignment > 0
then (origSize + minUBOAlignment - 1) .&. complement (minUBOAlignment - 1)
else origSize
descriptorsetLayoutBinding
:: Vk.DescriptorType
-> Vk.ShaderStageFlags
-> Word32
-> Vk.DescriptorSetLayoutBinding
descriptorsetLayoutBinding type' stageFlags binding =
Vk.zero
{ Vk.binding = binding
, Vk.descriptorCount = 1
, Vk.descriptorType = type'
, Vk.immutableSamplers = V.empty
, Vk.stageFlags = stageFlags
}
writeDescriptorBuffer
:: Vk.DescriptorType
-> Vk.DescriptorSet
-> Vk.DescriptorBufferInfo
-> Word32
-> Vk.SomeStruct Vk.WriteDescriptorSet
writeDescriptorBuffer type' dstSet bufferInfo binding = Vk.SomeStruct $
Vk.zero
{ Vk.dstBinding = binding
, Vk.dstSet = dstSet
, Vk.descriptorCount = 1
, Vk.descriptorType = type'
, Vk.bufferInfo = V.singleton bufferInfo
}