feat: shadow mapping — depth-only render pass from light POV + PCF
- VulkanShadowMap.cs: 2048x2048 D32_SFLOAT image, sampler (clamp-to-border), separate shadow pipeline (depth-only, no color, depth bias enabled, CULL_NONE) - Shadow shaders: shadow.vert (lightViewProj * model * pos), shadow.frag (empty) - Main shaders updated: fragLightSpacePos output from vertex, PCF 3x3 in fragment - Push constants expanded to 160B: model(64) + lightPos(16) + lightColor(16) + lightViewProj(64) - 3 push constant ranges: Vertex(model), Fragment(light), Vertex|Fragment(lightViewProj) - Descriptor set: 2 bindings — UBO(vp) + CombinedImageSampler(shadowMap) - Shadow pass: before main pass, renders scene depth from light position - Image transitions: shadow map UNDEFINED→DEPTH→SHADER_READ_ONLY each frame - vkCmdSetDepthBias(1.25, 0, 1.75) for acne prevention - Light VP: CreateLookAt(lightPos, origin, up) * Perspective(60°, 1.0, 0.1, 60) - 0 validation errors on build
This commit is contained in:
@@ -140,19 +140,25 @@ internal sealed unsafe class VulkanFrameResources : IDisposable
|
||||
|
||||
private void CreateDescriptorPoolAndSets(VkDescriptorSetLayout layout)
|
||||
{
|
||||
var poolSize = new VkDescriptorPoolSize
|
||||
var poolSizes = stackalloc VkDescriptorPoolSize[2];
|
||||
poolSizes[0] = new VkDescriptorPoolSize
|
||||
{
|
||||
type = VkDescriptorType.UniformBuffer,
|
||||
descriptorCount = MaxFramesInFlight,
|
||||
};
|
||||
poolSizes[1] = new VkDescriptorPoolSize
|
||||
{
|
||||
type = VkDescriptorType.CombinedImageSampler,
|
||||
descriptorCount = MaxFramesInFlight,
|
||||
};
|
||||
|
||||
var poolInfo = new VkDescriptorPoolCreateInfo
|
||||
{
|
||||
sType = VkStructureType.DescriptorPoolCreateInfo,
|
||||
flags = VkDescriptorPoolCreateFlags.FreeDescriptorSet,
|
||||
maxSets = MaxFramesInFlight,
|
||||
poolSizeCount = 1,
|
||||
pPoolSizes = &poolSize,
|
||||
poolSizeCount = 2,
|
||||
pPoolSizes = poolSizes,
|
||||
};
|
||||
|
||||
var descPool = VkDescriptorPool.Null;
|
||||
@@ -204,6 +210,29 @@ internal sealed unsafe class VulkanFrameResources : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateShadowDescriptor(int frameIndex, VkSampler sampler, VkImageView shadowView)
|
||||
{
|
||||
var imageInfo = new VkDescriptorImageInfo
|
||||
{
|
||||
sampler = sampler,
|
||||
imageView = shadowView,
|
||||
imageLayout = VkImageLayout.ShaderReadOnlyOptimal,
|
||||
};
|
||||
|
||||
var write = new VkWriteDescriptorSet
|
||||
{
|
||||
sType = VkStructureType.WriteDescriptorSet,
|
||||
dstSet = DescriptorSets[frameIndex],
|
||||
dstBinding = 1,
|
||||
dstArrayElement = 0,
|
||||
descriptorCount = 1,
|
||||
descriptorType = VkDescriptorType.CombinedImageSampler,
|
||||
pImageInfo = (nint)(&imageInfo),
|
||||
};
|
||||
|
||||
Vk.vkUpdateDescriptorSets(_device, 1, &write, 0, 0);
|
||||
}
|
||||
|
||||
public void UpdateUbo(int frameIndex, void* data, ulong size)
|
||||
{
|
||||
void* pData = null;
|
||||
|
||||
Reference in New Issue
Block a user