diff --git a/samples/04_scenes/asset_loader.cpp b/samples/04_scenes/asset_loader.cpp index d877329..df1a889 100644 --- a/samples/04_scenes/asset_loader.cpp +++ b/samples/04_scenes/asset_loader.cpp @@ -540,7 +540,8 @@ AssetLoader::ProcessNode(tinygltf::Model *model, eastl::vector *vertexPosi perspective); dynamicTransform.m_Rotation = glm::conjugate(dynamicTransform.m_Rotation); } - else { + else + { dynamicTransform = { .m_Position = VectorToVec3(node->translation), .m_Rotation = VectorToQuat(node->rotation), @@ -861,6 +862,17 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name) u32 index = Cast(materials.size()); auto *material = &model.materials[materialIdx]; + + f32 alphaBlendValue = -1; + if (material->alphaMode == "BLEND") + { + alphaBlendValue = 2; + } + else if (material->alphaMode == "MASK") + { + alphaBlendValue = material->alphaCutoff; + } + materials.push_back({ .m_AlbedoFactor = VectorToVec4(material->pbrMetallicRoughness.baseColorFactor), .m_EmissionFactor = VectorToVec3(material->emissiveFactor), @@ -871,6 +883,7 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name) .m_MetalRoughTex = getTextureHandle(material->pbrMetallicRoughness.metallicRoughnessTexture.index, false), .m_OcclusionTex = getTextureHandle(material->occlusionTexture.index, false), .m_EmissionTex = getTextureHandle(material->emissiveTexture.index, true), + .m_AlphaBlend = alphaBlendValue, }); materialsIndirection[materialIdx] = index; return index; diff --git a/samples/04_scenes/asset_loader.h b/samples/04_scenes/asset_loader.h index bd7564d..f842d48 100644 --- a/samples/04_scenes/asset_loader.h +++ b/samples/04_scenes/asset_loader.h @@ -35,9 +35,14 @@ struct Material TextureHandle m_MetalRoughTex; // 04 48 TextureHandle m_OcclusionTex; // 04 52 TextureHandle m_EmissionTex; // 04 56 + f32 m_AlphaBlend; /* 04 60 + AlphaBlend < 0 means Opaque + AlphaBlend > 1 means Blend + AlphaBlend in [0,1] means cutoff */ }; -static_assert(sizeof(Material) == 56); +// If this is changed, ensure the shaders are changed accordingly. +static_assert(sizeof(Material) == 60); struct VertexData { @@ -61,7 +66,9 @@ struct Model void Destroy(RenderResourceManager *resourceManager, EcsRegistry *registry); }; -struct CModel {}; +struct CModel +{ +}; struct AssetLoader { @@ -97,7 +104,8 @@ struct AssetLoader TextureHandle LoadImageToGpu(StagingBuffer *stagingBuffer, tinygltf::Image *image, bool isSrgb) const; void ProcessNode(tinygltf::Model *model, eastl::vector *vertexPositions, eastl::vector *vertexData, - eastl::vector *indices, eastl::vector *entities, const std::function &loadMaterial, int current, Entity parent); + eastl::vector *indices, eastl::vector *entities, + const std::function &loadMaterial, int current, Entity parent); public: DISALLOW_COPY_AND_ASSIGN(AssetLoader); diff --git a/samples/04_scenes/main.cpp b/samples/04_scenes/main.cpp index 410fbd0..38cdc03 100644 --- a/samples/04_scenes/main.cpp +++ b/samples/04_scenes/main.cpp @@ -26,7 +26,7 @@ constexpr u32 MAX_FRAMES_IN_FLIGHT = 3; constexpr auto PIPELINE_CACHE_FILE = "PipelineCacheData.bin"; -constexpr auto MODEL_FILE = "model/DamagedHelmet.glb"; +constexpr auto MODEL_FILE = "model/AlphaBlendModeTest.glb"; constexpr auto MODEL_FILE2 = "model/Box.glb"; constexpr auto BACKDROP_FILE = "image/photo_studio_loft_hall_4k.hdr"; constexpr u32 INIT_WIDTH = 640; @@ -46,7 +46,7 @@ main(int, char *[]) vk::Extent2D internalResolution = {1920, 1080}; internalResolution.width = (internalResolution.height * INIT_WIDTH) / INIT_HEIGHT; - CameraController cameraController = {vec3{0.0f, 2.0f, 4.0f}, vec3{0.0f, 0.0f, 0.0f}, 70_deg, + CameraController cameraController = {vec3{0.0f, 1.0f, 4.0f}, vec3{0.0f, 0.0f, 0.0f}, 70_deg, Cast(internalResolution.width) / Cast(internalResolution.height)}; INFO("Using {} as the primary device.", deviceToUse.m_DeviceProperties.deviceName.data()); @@ -111,15 +111,8 @@ main(int, char *[]) lightManager.SetEnvironment(&environment); eastl::vector models; - for (int i = -1; i <= 1; ++i) - { - for (int j = -1; j <= 1; ++j) - { - INFO("{}, {}", i, j); - auto &model = models.emplace_back(assetLoader.LoadModelToGpu(MODEL_FILE, "Main Model")); - registry.get(model.m_RootEntity).m_Position = vec3(2 * i, 0, 2 * j); - } - } + models.emplace_back(assetLoader.LoadModelToGpu(MODEL_FILE, "Main Model")); + //registry.get(model.m_RootEntity).m_Position = vec3(2 * i, 0, 2 * j); UniformBuffer ubo; constexpr usize uboLightManagerOffset = sizeof cameraController.m_Camera; @@ -355,12 +348,12 @@ main(int, char *[]) { Time::Update(); - u32 index = 0; - for (auto [entity, dynTrans] : rootModel.each()) - { - dynTrans.m_Rotation = - glm::rotate(dynTrans.m_Rotation, Cast(30_deg * (++index) * Time::m_Delta), vec3{0.0f, 1.0f, 0.0f}); - } + //u32 index = 0; + //for (auto [entity, dynTrans] : rootModel.each()) + //{ + // dynTrans.m_Rotation = + // glm::rotate(dynTrans.m_Rotation, Cast(30_deg * (++index) * Time::m_Delta), vec3{0.0f, 1.0f, 0.0f}); + //} Frame *currentFrame = frameManager.GetNextFrame(&swapchain, &window); diff --git a/samples/04_scenes/pipeline_utils.cpp b/samples/04_scenes/pipeline_utils.cpp index 5604abd..4ecd5aa 100644 --- a/samples/04_scenes/pipeline_utils.cpp +++ b/samples/04_scenes/pipeline_utils.cpp @@ -102,9 +102,9 @@ CreatePipeline(const Device *device, vk::Format attachmentFormat, const RenderRe .depthCompareOp = vk::CompareOp::eLess, }; vk::PipelineColorBlendAttachmentState colorBlendAttachmentState = { - .blendEnable = false, - .srcColorBlendFactor = vk::BlendFactor::eSrcColor, - .dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcColor, + .blendEnable = true, + .srcColorBlendFactor = vk::BlendFactor::eSrcAlpha, + .dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha, .colorBlendOp = vk::BlendOp::eAdd, .srcAlphaBlendFactor = vk::BlendFactor::eSrcAlpha, .dstAlphaBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha, diff --git a/samples/04_scenes/shader/bindless_structs.glsl b/samples/04_scenes/shader/bindless_structs.glsl index 91e861e..3f9a823 100644 --- a/samples/04_scenes/shader/bindless_structs.glsl +++ b/samples/04_scenes/shader/bindless_structs.glsl @@ -17,6 +17,12 @@ struct Material uint m_MetalRoughTex; // 04 48 uint m_OcclusionTex; // 04 52 uint m_EmissionTex; // 04 56 + /* + AlphaBlend < 0 means Opaque + AlphaBlend > 1 means Blend + AlphaBlend in [0,1] means cutoff + */ + float AlphaBlend; // 04 60 // We might be able to go upto 64 without pains. }; diff --git a/samples/04_scenes/shader/model.frag.glsl b/samples/04_scenes/shader/model.frag.glsl index 8a12303..69ea493 100644 --- a/samples/04_scenes/shader/model.frag.glsl +++ b/samples/04_scenes/shader/model.frag.glsl @@ -276,13 +276,23 @@ vec3 GetAmbientInfluence(vec3 albedo, float metal, float roughness, vec3 Positio return (K_Diffuse * DiffuseIrradiance + Specular) * Occlusion; } +float processAlpha(float sourceAlpha, float alphaBlendValue) { + if (alphaBlendValue < 0) { + return 1.0; + } else if (alphaBlendValue > 1) { + return sourceAlpha; + } else { + return step(alphaBlendValue, sourceAlpha); + } +} + void main() { Material material = nodes.nodes[nonuniformEXT(in_DrawID)].pMaterial.material; vec4 albedoA = GetAlbedo(material.m_AlbedoFactor, material.m_AlbedoTex, in_Color0, in_TexCoord0); vec3 albedo = albedoA.rgb; - float alpha = albedoA.a; + float alpha = processAlpha(albedoA.a, material.AlphaBlend); vec3 normal = GetNormal(material.m_NormalTex, in_Position.xyz, normalize(in_Normal.xyz), in_TexCoord0);