invisible ambient color
This commit is contained in:
parent
2516d12eea
commit
f735077faa
7 changed files with 196 additions and 31 deletions
19
shadersrc/rainbow_lit.frag
Normal file
19
shadersrc/rainbow_lit.frag
Normal 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);
|
||||
}
|
|
@ -24,7 +24,7 @@ import qualified VulkanMemoryAllocator as VMA
|
|||
import Devices
|
||||
import Types
|
||||
import Memory
|
||||
import Util (getFrame)
|
||||
import Util
|
||||
|
||||
frameOverlap :: Int
|
||||
frameOverlap = 2
|
||||
|
@ -41,6 +41,8 @@ createFrames physicalDevice logicalDevice allocator descriptorPool setLayout = d
|
|||
|
||||
queueFamilyIndex <- getQueueFamily physicalDevice Vk.QUEUE_GRAPHICS_BIT
|
||||
|
||||
deviceProperties <- Vk.getPhysicalDeviceProperties physicalDevice
|
||||
|
||||
let poolCreateInfo = Vk.zero
|
||||
{ Vk.flags = Vk.COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
|
||||
, Vk.queueFamilyIndex = queueFamilyIndex
|
||||
|
@ -49,7 +51,7 @@ createFrames physicalDevice logicalDevice allocator descriptorPool setLayout = d
|
|||
graphicsQueue <- Vk.getDeviceQueue logicalDevice queueFamilyIndex 0
|
||||
|
||||
frames <- V.mapM
|
||||
(\_ -> do
|
||||
(\index -> do
|
||||
|
||||
commandPool <- snd <$> allocate
|
||||
(Vk.createCommandPool logicalDevice poolCreateInfo Nothing)
|
||||
|
@ -87,7 +89,6 @@ createFrames physicalDevice logicalDevice allocator descriptorPool setLayout = d
|
|||
)
|
||||
|
||||
cameraBuffer <- createAllocatedBuffer
|
||||
logicalDevice
|
||||
allocator
|
||||
(sizeOf (GPUCameraData identity identity identity))
|
||||
Vk.BUFFER_USAGE_UNIFORM_BUFFER_BIT
|
||||
|
@ -101,20 +102,35 @@ createFrames physicalDevice logicalDevice allocator descriptorPool setLayout = d
|
|||
|
||||
globalDescriptor <- Vk.allocateDescriptorSets logicalDevice allocationInfo
|
||||
|
||||
let bufferInfo = Vk.zero
|
||||
let cameraInfo = Vk.zero
|
||||
{ Vk.buffer = allocatedBuffer cameraBuffer
|
||||
, Vk.offset = 0
|
||||
, Vk.range = fromIntegral $ sizeOf (GPUCameraData identity identity identity)
|
||||
} :: Vk.DescriptorBufferInfo
|
||||
setWrite = Vk.zero
|
||||
{ Vk.dstBinding = 0
|
||||
, Vk.dstSet = V.head globalDescriptor
|
||||
, Vk.descriptorCount = 1
|
||||
, Vk.descriptorType = Vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER
|
||||
, Vk.bufferInfo = V.singleton bufferInfo
|
||||
}
|
||||
sceneInfo = Vk.zero
|
||||
{ Vk.buffer = allocatedBuffer cameraBuffer
|
||||
, Vk.offset = padUniformBufferSize
|
||||
(fromIntegral $ sizeOf (undefinedGPUSceneData) * fromIntegral index)
|
||||
deviceProperties
|
||||
, 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
|
||||
{ framePresentSemaphore = presentSemaphore
|
||||
|
@ -140,6 +156,9 @@ recordCommandBuffer
|
|||
-> Vk.Pipeline
|
||||
-> Vk.PipelineLayout
|
||||
-> VMA.Allocator
|
||||
-> GPUSceneData
|
||||
-> AllocatedBuffer
|
||||
-> Vk.PhysicalDeviceProperties
|
||||
-> FrameData
|
||||
-> Int
|
||||
-> m ()
|
||||
|
@ -151,6 +170,9 @@ recordCommandBuffer
|
|||
graphicsPipeline
|
||||
meshLayout
|
||||
allocator
|
||||
sceneParameters
|
||||
sceneParameterBuffer
|
||||
deviceProps
|
||||
frame
|
||||
frameNumber
|
||||
= do
|
||||
|
@ -204,6 +226,24 @@ recordCommandBuffer
|
|||
Vk.cmdSetViewport commandBuffer 0 (V.singleton viewport)
|
||||
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
|
||||
meshMap <- (liftIO . STM.atomically . STM.readTMVar) =<< asks meshLibrary
|
||||
materialMap <- (liftIO . STM.atomically . STM.readTMVar) =<< asks materialLibrary
|
||||
|
|
|
@ -63,6 +63,9 @@ drawFrame engineData frameNumber = do
|
|||
(materialPipeline $ matLibrary M.! "defaultMesh")
|
||||
(meshPipelineLayout engineData)
|
||||
(engineAllocator engineData)
|
||||
(engineSceneParameters engineData)
|
||||
(engineSceneParameterBuffer engineData)
|
||||
(enginePhysicalDeviceProperties engineData)
|
||||
frame
|
||||
frameNumber
|
||||
|
||||
|
|
40
src/Init.hs
40
src/Init.hs
|
@ -10,17 +10,18 @@ import Control.Monad
|
|||
import Control.Monad.IO.Class
|
||||
import Control.Monad.Reader
|
||||
import Control.Monad.Trans.Resource
|
||||
import Data.Bits (Bits(bit))
|
||||
import Data.Bits ((.|.))
|
||||
import qualified Data.Vector as V
|
||||
import qualified SDL hiding (V2)
|
||||
import qualified SDL.Video.Vulkan as SDL
|
||||
import Foreign (sizeOf)
|
||||
import Foreign.Ptr
|
||||
import Linear as L
|
||||
import qualified VulkanMemoryAllocator as VMA
|
||||
import qualified Vulkan.Core10 as Vk
|
||||
import qualified Vulkan.Extensions.VK_KHR_swapchain as Khr
|
||||
import qualified Vulkan.Extensions.VK_KHR_surface as Khr
|
||||
import qualified Vulkan.Zero as Vk
|
||||
import qualified VulkanMemoryAllocator as VMA
|
||||
|
||||
-- internal imports
|
||||
|
||||
|
@ -32,6 +33,7 @@ import Memory
|
|||
import Types
|
||||
import Mesh
|
||||
import CommandBuffer
|
||||
import Util
|
||||
|
||||
initEngine
|
||||
:: Render EngineData
|
||||
|
@ -99,7 +101,7 @@ initVulkan window = do
|
|||
createSwapchain vulkanSurface surfaceFormats dimensions vulkanLogicalDevice allocator
|
||||
imageViews <- getImageViewHandles swapchain surfaceFormat vulkanLogicalDevice
|
||||
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
|
||||
meshLayout <- createMeshPipelineLayout vulkanLogicalDevice descriptorSetLayout
|
||||
let meshContainer = ShaderContainer (Just meshVertexShader) (Just meshFragmentShader)
|
||||
|
@ -138,6 +140,19 @@ initVulkan window = do
|
|||
descriptorSetLayout
|
||||
descriptorPool
|
||||
<$> 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 = do
|
||||
|
@ -175,15 +190,20 @@ initDescriptors
|
|||
=> Vk.Device
|
||||
-> m (Vk.DescriptorSetLayout, Vk.DescriptorPool)
|
||||
initDescriptors device = do
|
||||
let cameraBufferBinding = Vk.zero
|
||||
{ Vk.binding = 0
|
||||
, Vk.descriptorCount = 1
|
||||
, Vk.descriptorType = Vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER
|
||||
, Vk.stageFlags = Vk.SHADER_STAGE_VERTEX_BIT
|
||||
}
|
||||
let cameraBind = descriptorsetLayoutBinding
|
||||
Vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER
|
||||
Vk.SHADER_STAGE_VERTEX_BIT
|
||||
0
|
||||
sceneBind = descriptorsetLayoutBinding
|
||||
Vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
|
||||
(Vk.SHADER_STAGE_VERTEX_BIT .|. Vk.SHADER_STAGE_FRAGMENT_BIT)
|
||||
1
|
||||
setInfo = Vk.zero
|
||||
{ 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
|
||||
{ Vk.flags = Vk.DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT
|
||||
|
|
|
@ -49,13 +49,12 @@ initAllocator physicalDevice device instance' = do
|
|||
|
||||
createAllocatedBuffer
|
||||
:: (MonadResource m, MonadIO m)
|
||||
=> Vk.Device
|
||||
-> VMA.Allocator
|
||||
=> VMA.Allocator
|
||||
-> Int
|
||||
-> Vk.BufferUsageFlags
|
||||
-> VMA.MemoryUsage
|
||||
-> m AllocatedBuffer
|
||||
createAllocatedBuffer device allocator allocationSize usage memoryUsage = do
|
||||
createAllocatedBuffer allocator allocationSize usage memoryUsage = do
|
||||
let bufferInfo = Vk.zero
|
||||
{ Vk.size = fromIntegral allocationSize
|
||||
, Vk.usage = usage
|
||||
|
|
46
src/Types.hs
46
src/Types.hs
|
@ -42,6 +42,8 @@ data EngineData = EngineData
|
|||
, engineGlobalSetLayout :: Vk.DescriptorSetLayout
|
||||
, engineDescriptorPool :: Vk.DescriptorPool
|
||||
, enginePhysicalDeviceProperties :: Vk.PhysicalDeviceProperties
|
||||
, engineSceneParameters :: GPUSceneData
|
||||
, engineSceneParameterBuffer :: AllocatedBuffer
|
||||
}
|
||||
|
||||
data AllocatedBuffer = AllocatedBuffer
|
||||
|
@ -200,14 +202,46 @@ data GPUCameraData = GPUCameraData
|
|||
|
||||
instance Storable GPUCameraData where
|
||||
|
||||
sizeOf (GPUCameraData view projection viewProjection) =
|
||||
sizeOf view + sizeOf projection + sizeOf viewProjection
|
||||
sizeOf (GPUCameraData pview pprojection pviewProjection) =
|
||||
sizeOf pview + sizeOf pprojection + sizeOf pviewProjection
|
||||
|
||||
alignment = undefined
|
||||
|
||||
peek _ = undefined
|
||||
|
||||
poke ptr (GPUCameraData view projection viewProjection) = do
|
||||
poke (castPtr ptr) view
|
||||
poke (castPtr ptr `plusPtr` sizeOf view) projection
|
||||
poke (castPtr ptr `plusPtr` sizeOf view `plusPtr` sizeOf projection) viewProjection
|
||||
poke ptr (GPUCameraData pview pprojection pviewProjection) = do
|
||||
poke (castPtr ptr) pview
|
||||
poke (castPtr ptr `plusPtr` sizeOf pview) pprojection
|
||||
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
|
||||
|
|
50
src/Util.hs
50
src/Util.hs
|
@ -1,7 +1,17 @@
|
|||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
module Util where
|
||||
|
||||
import Data.Bits
|
||||
|
||||
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
|
||||
|
||||
import Types
|
||||
|
@ -11,3 +21,43 @@ getFrame engineData frame =
|
|||
let frameVector = engineFrames engineData
|
||||
in
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue