Files
HelloVulkan/Engine/include/Engine/Vulkan/Texture.h
T
atdunbg 5d88ed2057 Improve PBR quality: mip chains, anisotropic filtering, baseColorFactor
Root causes behind blurry/unphysical materials (4K pocket watch render
mushy, glass fully opaque, watch hands unreadable):

- Textures loaded via stbi had a single mip level: 4096x4096 albedo/MR
  maps sampled with no LOD -> minification aliasing turned fine detail
  (watch hands) into noise. Generate a full blit-based mip chain with
  per-level layout transitions.
- samplerAnisotropy was never enabled on the device and every sampler
  was created with anisotropy disabled: grazing-angle surfaces (watch
  face, ground) collapsed into a blur. Enable the device feature and
  16x anisotropic filtering on material texture samplers.
- glTF baseColorFactor was ignored: the glass material (alphaMode
  BLEND, no baseColor texture, baseColorFactor.a = 0.3) fell back to
  the default white texture with alpha = 1 and rendered fully opaque.
  MaterialParams gains a baseColor vec4 (rgb tints albedo, a scales
  the blend alpha) threaded through both PBR shaders.
- alphaMode MASK was treated as opaque: add a factors.w switch that
  performs an alpha cutout test in the opaque shader.
- Fix material cache key dropping factors.z (separate-roughness
  switch); it now encodes the full factors and baseColor vectors.
2026-10-05 12:01:07 +08:00

86 lines
2.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// Created by atdunbg on 2026/9/20.
//
#ifndef HELLOVULKAN_TEXTURE_H
#define HELLOVULKAN_TEXTURE_H
#pragma once
#include <Engine/Core/Types.h>
#include <vulkan/vulkan.hpp>
#include <array>
#include <string>
#include "MemoryAllocator.h"
namespace Engine {
class Device;
class MemoryAllocator;
class Texture {
public:
// 从磁盘图片加载(按扩展名分发:.dds → DdsLoader,其它 → stbi)。
// srgb:颜色贴图语义(BaseColor/Emissive)为 true;数据图
//(Normal/Specular 等)为 false —— 决定 vk 格式的 _SRGB 变体
Texture(Device& device, MemoryAllocator& allocator, const std::string& path,
bool srgb = true);
// 程序化纹理:纯色(1x1),用于地面/调试等不依赖磁盘资产的场景
struct ProceduralTag {};
static Scope<Texture> CreateSolidColor(Device& device, MemoryAllocator& allocator,
u8 r, u8 g, u8 b, bool srgb = true);
// 带 alpha 的纯色纹理(透明管线验证等)
static Scope<Texture> CreateSolidColorRGBA(Device& device, MemoryAllocator& allocator,
u8 r, u8 g, u8 b, u8 a, bool srgb = true);
~Texture();
Texture(const Texture&) = delete;
Texture& operator=(const Texture&) = delete;
vk::Image Get() const { return m_Image; }
vk::ImageView GetView() const { return m_View; }
u32 GetWidth() const { return m_Width; }
u32 GetHeight() const { return m_Height; }
vk::Format GetFormat() const { return m_Format; }
u32 GetMipLevels() const { return m_MipLevels; }
vk::Sampler GetSampler() const { return m_Sampler; }
private:
// 两段式构造:先确定像素来源(磁盘 / 程序化),再走公共上传路径
Texture(Device& device, MemoryAllocator& allocator, ProceduralTag,
const std::array<u8, 4>& rgba, bool srgb);
// 公共路径:staging → device local image → blit 生成完整 mip 链 →
// view/sampler(RGBA8,各向异性过滤)
void InitFromPixels(const void* pixels, u32 width, u32 height, bool srgb);
// DDS 路径:压缩数据直传(BC 硬件采样解码)+ 文件自带 mip 链
void InitFromDds(const std::string& path, bool srgb);
Device& m_Device;
vk::Image m_Image;
vk::ImageView m_View;
vk::Format m_Format = vk::Format::eUndefined;
u32 m_MipLevels = 1;
vk::Sampler m_Sampler;
u32 m_Width = 0;
u32 m_Height = 0;
u64 m_TextureBytes = 0;
MemoryAllocator::Allocation m_ImageAllocation;
MemoryAllocator& m_Allocator;
};
} // namespace Engine
#endif //HELLOVULKAN_TEXTURE_H