c++ 体素世界中的无缝纹理

siv3szwd  于 2023-02-17  发布在  其他
关注(0)|答案(1)|浏览(166)

我最近一直在做一个minecraft的克隆,我已经能够生成简单的无限世界,有一些噪音的高度图等,但我面临的问题是纹理。正如你可以看到下面的图像纹理有某种边界。他们不是无缝的。我用一个精灵表发送一个单一的纹理到GPU,然后使用不同的纹理坐标为不同的块类型。我也'我使用Vulkan作为渲染后端,这里有一些纹理细节。我真的很感激一些关于如何解决这个问题的见解。

VkSamplerCreateInfo sInfo{};
    sInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
    sInfo.pNext = nullptr;

    sInfo.magFilter = VK_FILTER_NEAREST;
    sInfo.minFilter = VK_FILTER_LINEAR;
    sInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
    sInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
    sInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
    sInfo.anisotropyEnable = VK_TRUE;

    VkPhysicalDeviceProperties Props;
    vkGetPhysicalDeviceProperties(Engine::Get().GetGpuHandle(), &Props);

    sInfo.maxAnisotropy = Props.limits.maxSamplerAnisotropy;
    sInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
    sInfo.unnormalizedCoordinates = VK_FALSE;
    sInfo.compareEnable = VK_FALSE;
    sInfo.compareOp = VK_COMPARE_OP_ALWAYS;
    sInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
    sInfo.mipLodBias = 0.f;
    sInfo.minLod = 0.f;
    sInfo.maxLod = 1;

    VkImageCreateInfo iInfo{};
    iInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    iInfo.pNext = nullptr;
    iInfo.arrayLayers = 1;
    iInfo.extent = { extent.width,extent.height,1 };
    iInfo.imageType = VK_IMAGE_TYPE_2D;
    iInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    iInfo.mipLevels = 1;
    iInfo.samples = samples;
    iInfo.flags = 0;
    iInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
    Info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
    iInfo.format = format;
    iInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   
    VkImageViewCreateInfo vInfo{};
    vInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    vInfo.pNext = nullptr;
    vInfo.image = m_Image;
    vInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
    vInfo.format = format;
    vInfo.flags = 0;
    vInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    vInfo.subresourceRange.baseMipLevel = 0;
    vInfo.subresourceRange.levelCount = 1;
    vInfo.subresourceRange.baseArrayLayer = 0;
    vInfo.subresourceRange.layerCount = 1;

首先我认为这是我的精灵表的问题,所以我不同的,但这似乎不是问题。然后我尝试了其他几个采样器参数组合,但仍然没有运气

3pmvbmvn

3pmvbmvn1#

纹理边界是在游戏中使用纹理Map集(精灵表单)时遇到的常见问题。原因是纹理坐标并不总是与纹理的像素边界完全对齐,这可能导致从相邻像素采样并引入接缝或伪像。有几种技术可用于解决此问题,其中一些是:1.纹理坐标偏移2.纹理贴图
在您的代码中,您似乎使用了VK_SAMPLER_ADDRESS_MODE_REPEAT模式的纹理包裹,这可能会加剧纹理洇色问题。缓解此问题的一种方法是使用与纹理边缘像素匹配的边框颜色来减少可见接缝。您可以使用VkSamplerCreateInfo结构的sInfo.borderColor成员设置边框颜色。
总的来说,尝试纹理填充、坐标偏移和纹理贴图集的不同组合可能会有所帮助,以找到适合您特定情况的最佳解决方案。此外,您可能需要考虑使用TexturePacker或Sprite Sheet Packer等工具来生成具有填充和其他优化功能的优化纹理贴图集,以减少可见接缝。

相关问题