diff --git a/res/shaders/BasePass.slang b/res/shaders/BasePass.slang index 8921e89..0bf8da6 100644 --- a/res/shaders/BasePass.slang +++ b/res/shaders/BasePass.slang @@ -31,5 +31,8 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target uint lightIndex = pLightCullingData.lightIndexList[startOffset + i]; result += pLightEnv.pointLights[lightIndex].illuminate(lightingParams, brdf); } - return float4(result, 1.0f); + result += brdf.evaluateAmbient(); + result = result / (result + float3(1.0)); + float3 gammaCorrected = pow(result, float3(1.0/2.2)); + return float4(gammaCorrected, 1.0f); } diff --git a/res/shaders/MeshletBasePass.slang b/res/shaders/MeshletBasePass.slang index c10427e..d71f4fa 100644 --- a/res/shaders/MeshletBasePass.slang +++ b/res/shaders/MeshletBasePass.slang @@ -12,7 +12,6 @@ struct MeshPayload groupshared MeshPayload p; groupshared uint head; -groupshared float4x4 localToView; groupshared Frustum viewFrustum; [numthreads(TASK_GROUP_SIZE, 1, 1)] @@ -26,13 +25,13 @@ void taskMain( if(threadID == 0) { head = 0; - localToView = mul(pViewParams.viewMatrix, instance.transformMatrix); float3 origin = float3(0, 0, 0); + const float offset = 0.0f; float3 corners[4] = { - screenToView(float4(0.0f, 0.0f, -1.0f, 1.0f)).xyz, - screenToView(float4(pViewParams.screenDimensions.x, 0.0f, -1.0f, 1.0f)).xyz, - screenToView(float4(0.0f, pViewParams.screenDimensions.y, -1.0f, 1.0f)).xyz, - screenToView(float4(pViewParams.screenDimensions, -1.0f, 1.0f)).xyz + screenToModel(instance.inverseTransformMatrix, float4(offset, offset, -1.0f, 1.0f)).xyz, + screenToModel(instance.inverseTransformMatrix, float4(pViewParams.screenDimensions.x - offset, offset, -1.0f, 1.0f)).xyz, + screenToModel(instance.inverseTransformMatrix, float4(offset, pViewParams.screenDimensions.y - offset, -1.0f, 1.0f)).xyz, + screenToModel(instance.inverseTransformMatrix, float4(pViewParams.screenDimensions - float2(offset, offset), -1.0f, 1.0f)).xyz }; viewFrustum.sides[0] = computePlane(origin, corners[2], corners[0]); viewFrustum.sides[1] = computePlane(origin, corners[1], corners[3]); @@ -47,7 +46,7 @@ void taskMain( { uint m = mesh.meshletOffset + i; MeshletDescription meshlet = pScene.meshletInfos[m]; - if(meshlet.bounding.insideFrustum(localToView, viewFrustum)) + //if(meshlet.bounding.insideFrustum(viewFrustum)) { uint index; InterlockedAdd(head, 1, index); diff --git a/res/shaders/Placeholder.json b/res/shaders/Placeholder.json deleted file mode 100644 index 08d2e12..0000000 --- a/res/shaders/Placeholder.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "Placeholder", - "params": { - }, - "code": [ - { - "exp": "BRDF", - "profile": "BlinnPhong", - "values": { - "baseColor": "float3(0, 1, 0)", - "normal": "float3(0, 0, 1)" - } - } - ] -} \ No newline at end of file diff --git a/res/shaders/lib/BRDF.slang b/res/shaders/lib/BRDF.slang index 6bf42d1..db7b14e 100644 --- a/res/shaders/lib/BRDF.slang +++ b/res/shaders/lib/BRDF.slang @@ -3,22 +3,48 @@ import Common; interface IBRDF { float3 evaluate(float3x3 tbn, float3 viewDir_WS, float3 lightDir_WS, float3 lightColor); + float3 evaluateAmbient(); +}; + +struct Phong : IBRDF +{ + float3 baseColor; + float3 specular; + float3 normal; + float3 ambient; + float shininess; + + __init() + { + normal = float3(0, 0, 1); + } + + float3 evaluate(float3x3 tbn, float3 viewDir_TS, float3 lightDir_TS, float3 lightColor) + { + float3 n = normalize(normal); + float3 nDotL = dot(n, lightDir_TS); + float3 r = 2 * (nDotL) * n - lightDir_TS; + float rDotV = dot(r, viewDir_TS); + + return baseColor * max(nDotL, 0.0) * lightColor + specular * pow(max(rDotV, 0.0), shininess) * lightColor; + } + + float3 evaluateAmbient() + { + return ambient; + } }; struct BlinnPhong : IBRDF { float3 baseColor; - float metallic; + float3 specularColor; float3 normal; - float roughness; - float sheen; + float3 ambient; __init() { - metallic = 0; normal = float3(0, 0, 1); - roughness = 0.5; - sheen = 1; } float3 evaluate(float3x3 tbn, float3 viewDir_TS, float3 lightDir_TS, float3 lightColor) @@ -28,7 +54,12 @@ struct BlinnPhong : IBRDF float3 h = normalize(lightDir_TS + viewDir_TS); float specular = saturate(dot(normal_TS, h)); - return baseColor * (diffuse + specular) * lightColor; + return baseColor;//((baseColor * diffuse) + (specularColor * specular)) * lightColor; + } + + float3 evaluateAmbient() + { + return ambient; } }; @@ -58,4 +89,90 @@ struct CelShading : IBRDF return darkenedBase * lightColor; } } + float3 evaluateAmbient() + { + return float3(0, 0, 0); + } +}; + +// https://learnopengl.com/PBR/Theory +struct CookTorrance : IBRDF +{ + float3 baseColor; + float3 normal; + float roughness; + float metallic; + float ambientOcclusion; + + __init() + { + normal = float3(0, 0, 1); + roughness = 0; + metallic = 0; + ambientOcclusion = 1; + } + + float TrowbridgeReitzGGX(float3 normal, float3 halfway) + { + float a_sqr = roughness * roughness; + float nDotH = max(dot(normal, halfway), 0.0); + float nDotH_sqr = nDotH * nDotH; + + float denom = (nDotH_sqr * (a_sqr - 1.0) + 1.0); + + return a_sqr / (PI * denom * denom); + } + + float SchlickGGX(float nDotV, float k) + { + return nDotV / (nDotV * (1.0 - k) + k); + } + + float Smith(float3 normal, float3 view, float3 light) + { + float k = (roughness + 1); + k = (k * k) / 8; + float nDotV = max(dot(normal, view), 0.0); + float nDotL = max(dot(normal, light), 0.0); + float ggx1 = SchlickGGX(nDotV, k); + float ggx2 = SchlickGGX(nDotL, k); + return ggx1 * ggx2; + } + + float3 FresnelSchlick(float cosTheta, float3 F0) + { + return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); + } + + float3 evaluate(float3x3 tbn, float3 viewDir_TS, float3 lightDir_TS, float3 lightColor) + { + float3 n = normalize(normal); + float3 h = normalize(lightDir_TS + viewDir_TS); + + float3 F0 = float3(0.04); + F0 = lerp(F0, baseColor, metallic); + + float3 F = FresnelSchlick(max(dot(h, viewDir_TS), 0.0), F0); + + float NDF = TrowbridgeReitzGGX(n, h); + float G = Smith(n, viewDir_TS, lightDir_TS); + + float3 num = NDF * G * F; + float denom = 4.0 * max(dot(n, viewDir_TS), 0.0) * max(dot(n, lightDir_TS), 0.0) + 0.000001; + float3 specular = num / denom; + + float3 k_s = F; + float3 k_d = float3(1.0) - k_s; + + k_d *= 1.0 - metallic; + + float nDotL = max(dot(n, lightDir_TS), 0.0); + + float3 result = (k_d * baseColor / PI + specular) * nDotL * lightColor; + return baseColor;//result * ambientOcclusion; + } + float3 evaluateAmbient() + { + return float3(0.03) * baseColor * ambientOcclusion; + } }; diff --git a/res/shaders/lib/Bounding.slang b/res/shaders/lib/Bounding.slang index 2867aa0..303c517 100644 --- a/res/shaders/lib/Bounding.slang +++ b/res/shaders/lib/Bounding.slang @@ -11,15 +11,12 @@ struct BoundingSphere { return centerRadius.w; } - bool insideFrustum(float4x4 transform, Frustum frustum) + bool insideFrustum(Frustum frustum) { - float3 transformed = mul(transform, float4(getCenter(), 1)).xyz; - float maxScale = max(max(transform[0][0], transform[1][1]), transform[2][2]); - float scaledRange = getRadius() * maxScale; bool result = true; for(int i = 0; i < 4 && result; ++i) { - if(dot(frustum.sides[i].n, transformed) - frustum.sides[i].d < -scaledRange) + if(dot(frustum.sides[i].n, centerRadius.xyz) - frustum.sides[i].d < -getRadius()) { result = false; } @@ -34,20 +31,20 @@ struct AABB float pad0; float3 max; float pad1; - bool insideFrustum(float4x4 transform, Frustum frustum) + bool insideFrustum(Frustum frustum) { - float4 corners[8]; - corners[0] = mul(transform, float4(min.x, min.y, min.z, 1.0f)); - corners[1] = mul(transform, float4(min.x, min.y, max.z, 1.0f)); - corners[2] = mul(transform, float4(min.x, max.y, min.z, 1.0f)); - corners[3] = mul(transform, float4(min.x, max.y, max.z, 1.0f)); - corners[4] = mul(transform, float4(max.x, min.y, min.z, 1.0f)); - corners[5] = mul(transform, float4(max.x, min.y, max.z, 1.0f)); - corners[6] = mul(transform, float4(max.x, max.y, min.z, 1.0f)); - corners[7] = mul(transform, float4(max.x, max.y, max.z, 1.0f)); + float3 corners[8]; + corners[0] = float3(min.x, min.y, min.z); + corners[1] = float3(min.x, min.y, max.z); + corners[2] = float3(min.x, max.y, min.z); + corners[3] = float3(min.x, max.y, max.z); + corners[4] = float3(max.x, min.y, min.z); + corners[5] = float3(max.x, min.y, max.z); + corners[6] = float3(max.x, max.y, min.z); + corners[7] = float3(max.x, max.y, max.z); for(int i = 0; i < 8; ++i) { - if(frustum.pointInside(corners[i].xyz)) + if(frustum.pointInside(corners[i])) { return true; } diff --git a/res/shaders/lib/Common.slang b/res/shaders/lib/Common.slang index 82c26c9..108b19b 100644 --- a/res/shaders/lib/Common.slang +++ b/res/shaders/lib/Common.slang @@ -1,10 +1,10 @@ const static float PI = 3.1415926535897932f; -const static uint MAX_PARTICLES = 65536; const static uint BLOCK_SIZE = 32; struct ViewParameter { float4x4 viewMatrix; + float4x4 inverseViewMatrix; float4x4 projectionMatrix; float4x4 inverseProjection; float4 cameraPos_WS; @@ -13,6 +13,24 @@ struct ViewParameter layout(set=0) ParameterBlock pViewParams; +float4 worldToModel(float4x4 inverseTransform, float4 world) +{ + float4 model = mul(inverseTransform, world); + + model = model / model.w; + + return model; +} + +float4 viewToWorld(float4 view) +{ + float4 world = mul(pViewParams.inverseViewMatrix, view); + + world = world / world.w; + + return world; +} + float4 clipToView(float4 clip) { float4 view = mul(pViewParams.inverseProjection, clip); @@ -32,6 +50,15 @@ float4 screenToView(float4 screen) return clipToView(clip); } +float4 screenToModel(float4x4 inverseTransform, float4 screen) +{ + float4 view = screenToView(screen); + + float4 world = viewToWorld(view); + + return worldToModel(inverseTransform, world); +} + struct Plane { float3 n; diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang index e0718cf..7d98e84 100644 --- a/res/shaders/lib/Scene.slang +++ b/res/shaders/lib/Scene.slang @@ -2,7 +2,7 @@ import Bounding; struct MeshletDescription { - BoundingSphere bounding; + AABB bounding; uint32_t vertexCount; uint32_t primitiveCount; uint32_t vertexOffset; @@ -13,13 +13,13 @@ struct MeshletDescription struct MeshData { - BoundingSphere bounding; - uint32_t numMeshlets; - uint32_t meshletOffset; - uint32_t firstIndex; - uint32_t numIndices; - uint32_t indicesOffset; - uint32_t pad0[3]; + AABB bounding; + uint32_t numMeshlets; + uint32_t meshletOffset; + uint32_t firstIndex; + uint32_t numIndices; + uint32_t indicesOffset; + uint32_t pad0[3]; }; static const uint MAX_VERTICES = 256; @@ -31,6 +31,7 @@ static const uint MAX_MESHLETS_PER_MESH = 512; struct InstanceData { float4x4 transformMatrix; + float4x4 inverseTransformMatrix; }; struct Scene diff --git a/res/shaders/slang-stdlib.bin b/res/shaders/slang-stdlib.bin deleted file mode 100644 index 82f8b09..0000000 Binary files a/res/shaders/slang-stdlib.bin and /dev/null differ diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp index 408db6e..f1f94b4 100644 --- a/src/Editor/Asset/MeshLoader.cpp +++ b/src/Editor/Asset/MeshLoader.cpp @@ -94,12 +94,18 @@ void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path& constexpr const char* KEY_DIFFUSE_COLOR = "k_d"; constexpr const char* KEY_SPECULAR_COLOR = "k_s"; constexpr const char* KEY_AMBIENT_COLOR = "k_a"; -constexpr const char* KEY_NORMAL = "n"; +constexpr const char* KEY_SHININESS = "k_shiny"; +constexpr const char* KEY_ROUGHNESS = "k_r"; +constexpr const char* KEY_METALLIC = "k_m"; + constexpr const char* KEY_DIFFUSE_TEXTURE = "tex_d"; constexpr const char* KEY_SPECULAR_TEXTURE = "tex_s"; constexpr const char* KEY_AMBIENT_TEXTURE = "tex_a"; constexpr const char* KEY_NORMAL_TEXTURE = "tex_n"; - +constexpr const char* KEY_SHININESS_TEXTURE = "tex_shiny"; +constexpr const char* KEY_ROUGHNESS_TEXTURE = "tex_r"; +constexpr const char* KEY_METALLIC_TEXTURE = "tex_m"; +constexpr const char* KEY_AMBIENT_OCCLUSION_TEXTURE = "tex_ao"; void MeshLoader::loadMaterials(const aiScene* scene, const Map& textures, const std::string& baseName, const std::filesystem::path& meshDirectory, const std::string& importPath, Array& globalMaterials) { @@ -125,18 +131,26 @@ void MeshLoader::loadMaterials(const aiScene* scene, const MapGet(matKey, type, index, scalar); + expressions.add(new FloatParameter(paramKey, scalar, uniformSize, 0)); + uniformSize += sizeof(float); + parameters.add(paramKey); + }; + auto addVectorParameter = [&](std::string paramKey, const char* matKey, int type, int index) { aiColor3D color; material->Get(matKey, type, index, color); - expressions.add(new VectorParameter(paramKey, Vector(color.r, color.g, color.b), uniformSize, 0)); uniformSize = (uniformSize + sizeof(Vector4) - 1) / sizeof(Vector4) * sizeof(Vector4); + expressions.add(new VectorParameter(paramKey, Vector(color.r, color.g, color.b), uniformSize, 0)); uniformSize += sizeof(Vector); parameters.add(paramKey); }; - - auto addTextureParameter = [&](std::string paramKey, aiTextureType type, int index, std::string& result) + auto addTextureParameter = [&](std::string paramKey, aiTextureType type, int index, std::string& result, StaticArray extractMask = {0, 1, 2, -1}) { aiString texPath; aiTextureMapping mapping; @@ -169,12 +183,14 @@ void MeshLoader::loadMaterials(const aiScene* scene, const MapaddDescriptorBinding(Gfx::DescriptorBinding{ @@ -228,7 +244,7 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Mapinputs["coords"].source = fmt::format("input.texCoords[{0}]", uvIndex); std::string colorExtract = fmt::format("{0}Extract{1}", paramKey, index); - expressions.add(new SwizzleExpression({ 0, 1, 2, -1 })); + expressions.add(new SwizzleExpression(extractMask)); expressions.back()->key = colorExtract; expressions.back()->inputs["target"].source = sampleKey; //TODO: extract alpha, set opacity @@ -289,125 +305,115 @@ void MeshLoader::loadMaterials(const aiScene* scene, const MapGetTextureCount(aiTextureType_DIFFUSE); for (uint32 i = 0; i < numDiffuseTextures; ++i) { addTextureParameter(KEY_DIFFUSE_TEXTURE, aiTextureType_DIFFUSE, i, outputDiffuse); } + + // Specular + addVectorParameter(KEY_SPECULAR_COLOR, AI_MATKEY_COLOR_SPECULAR); + std::string outputSpecular = KEY_SPECULAR_COLOR; uint32 numSpecular = material->GetTextureCount(aiTextureType_SPECULAR); for (uint32 i = 0; i < numSpecular; ++i) { addTextureParameter(KEY_SPECULAR_TEXTURE, aiTextureType_SPECULAR, i, outputSpecular); } - uint32 numAmbient = material->GetTextureCount(aiTextureType_AMBIENT); - for (uint32 i = 0; i < numSpecular; ++i) - { - addTextureParameter(KEY_AMBIENT_COLOR, aiTextureType_AMBIENT, i, outputAmbient); - } + // Normal + std::string outputNormal = ""; uint32 numNormal = material->GetTextureCount(aiTextureType_NORMALS); - if (numNormal > 1) + for (uint32 i = 0; i < numNormal; ++i) { - std::cout << "More than 1 normal??" << std::endl; + addTextureParameter(KEY_NORMAL_TEXTURE, aiTextureType_NORMALS, i, outputNormal); } - else if (numNormal == 1) + + // Ambient Color + addVectorParameter(KEY_AMBIENT_COLOR, AI_MATKEY_COLOR_AMBIENT); + std::string outputAmbient = KEY_AMBIENT_COLOR; + uint32 numAmbient = material->GetTextureCount(aiTextureType_AMBIENT); + for (uint32 i = 0; i < numAmbient; ++i) { - aiString texPath; - aiTextureMapping mapping; - uint32 uvIndex; - if (material->GetTexture(aiTextureType_NORMALS, 0, &texPath, &mapping, &uvIndex) != AI_SUCCESS) - { - std::cout << "fuck" << std::endl; - } - - std::string textureKey = fmt::format("NormalTexture"); - auto texFilename = std::filesystem::path(texPath.C_Str()); - PTextureAsset texture; - if (textures.contains(texFilename.string())) - { - texture = textures[texFilename.string()]; - } - else if (std::filesystem::exists(texFilename)) - { - AssetImporter::importTexture(TextureImportArgs{ - .filePath = texFilename, - .importPath = importPath, - }); - texture = AssetRegistry::findTexture(importPath, texFilename.stem().string()); - } - if (texture != nullptr) - { - expressions.add(new TextureParameter(textureKey, texture, bindingCounter)); - materialLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = bindingCounter, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .shaderStages = Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, - }); - parameters.add(textureKey); - bindingCounter++; - - std::string samplerKey = "NormalSampler"; - SamplerCreateInfo samplerInfo = {}; - expressions.add(new SamplerParameter(samplerKey, graphics->createSampler(samplerInfo), bindingCounter)); - materialLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = bindingCounter, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER, - .shaderStages = Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, - }); - parameters.add(samplerKey); - bindingCounter++; - - std::string sampleKey = "NormalSample"; - expressions.add(new SampleExpression()); - expressions.back()->key = sampleKey; - expressions.back()->inputs["texture"].source = textureKey; - expressions.back()->inputs["sampler"].source = samplerKey; - expressions.back()->inputs["coords"].source = fmt::format("input.texCoords[{0}]", uvIndex); - - std::string normalExtract = "NormalExtract"; - expressions.add(new SwizzleExpression({ 0, 1, 2, -1 })); - expressions.back()->key = normalExtract; - expressions.back()->inputs["target"].source = sampleKey; - - std::string mulKey = "NormalMul"; - expressions.add(new MulExpression()); - expressions.back()->key = mulKey; - expressions.back()->inputs["lhs"].source = "2"; - expressions.back()->inputs["rhs"].source = normalExtract; - - std::string subKey = "NormalSub"; - expressions.add(new SubExpression()); - expressions.back()->key = subKey; - expressions.back()->inputs["lhs"].source = mulKey; - expressions.back()->inputs["rhs"].source = "float3(1,1,1)"; - - outputNormal = subKey; - } + addTextureParameter(KEY_AMBIENT_TEXTURE, aiTextureType_AMBIENT, i, outputAmbient); } - + + // Shininess + addScalarParameter(KEY_SHININESS, AI_MATKEY_SHININESS); + std::string outputShininess = KEY_SHININESS; + uint32 numShiny = material->GetTextureCount(aiTextureType_SHININESS); + for (uint32 i = 0; i < numShiny; ++i) + { + addTextureParameter(KEY_SHININESS_TEXTURE, aiTextureType_SHININESS, i, outputShininess, { 0, -1, -1, -1 }); + } + + // Roughness + addScalarParameter(KEY_ROUGHNESS, AI_MATKEY_ROUGHNESS_FACTOR); + std::string outputRoughness = KEY_ROUGHNESS; + uint32 numRoughness = material->GetTextureCount(aiTextureType_DIFFUSE_ROUGHNESS); + for (uint32 i = 0; i < numRoughness; ++i) + { + addTextureParameter(KEY_ROUGHNESS_TEXTURE, aiTextureType_DIFFUSE_ROUGHNESS, i, outputRoughness, { 0, -1, -1, -1 }); + } + + // Metallic + addScalarParameter(KEY_METALLIC, AI_MATKEY_METALLIC_FACTOR); + std::string outputMetallic = KEY_METALLIC; + uint32 numMetallic = material->GetTextureCount(aiTextureType_METALNESS); + for (uint32 i = 0; i < numMetallic; ++i) + { + addTextureParameter(KEY_METALLIC_TEXTURE, aiTextureType_METALNESS, i, outputMetallic, { 0, -1, -1, -1 }); + } + + // Ambient Occlusion + std::string outputAO = ""; + uint32 numAO = material->GetTextureCount(aiTextureType_AMBIENT_OCCLUSION); + for (uint32 i = 0; i < numAO; ++i) + { + addTextureParameter(KEY_AMBIENT_OCCLUSION_TEXTURE, aiTextureType_AMBIENT_OCCLUSION, i, outputAO, { 0, -1, -1, -1 }); + } + + MaterialNode brdf; - brdf.profile = "BlinnPhong"; brdf.variables["baseColor"] = outputDiffuse; - //brdf.variables["specular"] = outputSpecular; if (!outputNormal.empty()) { brdf.variables["normal"] = outputNormal; } + aiShadingMode mode; + material->Get(AI_MATKEY_SHADING_MODEL, mode); + switch (mode) { + case aiShadingMode_Blinn: + brdf.profile = "Phong"; + brdf.variables["specular"] = outputSpecular; + brdf.variables["ambient"] = outputAmbient; + brdf.variables["shininess"] = outputShininess; + break; + case aiShadingMode_Phong: + brdf.profile = "BlinnPhong"; + brdf.variables["specularColor"] = outputSpecular; + brdf.variables["ambient"] = outputAmbient; + break; + case aiShadingMode_Toon: + brdf.profile = "CelShading"; + break; + case aiShadingMode_CookTorrance: + brdf.profile = "CookTorrance"; + brdf.variables["roughness"] = outputRoughness; + brdf.variables["metallic"] = outputMetallic; + if (!outputAO.empty()) + { + brdf.variables["ambientOcclusion"] = outputAmbient; + } + break; + default: + throw std::logic_error("Todo"); + }; materialLayout->create(); - OMaterialAsset baseMat = new MaterialAsset(importPath, materialName); baseMat->material = new Material(graphics, std::move(materialLayout), diff --git a/src/Editor/Asset/TextureLoader.cpp b/src/Editor/Asset/TextureLoader.cpp index 2f99f72..e832ddd 100644 --- a/src/Editor/Asset/TextureLoader.cpp +++ b/src/Editor/Asset/TextureLoader.cpp @@ -51,100 +51,134 @@ PTextureAsset TextureLoader::getPlaceholderTexture() return placeholderAsset; } +#define KTX_ASSERT(x) { auto error = x; if(error != KTX_SUCCESS) { std::cout << ktxErrorString(error) << std::endl; abort(); } } + void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) { - int totalWidth = 0, totalHeight = 0, n = 0; - unsigned char* data = stbi_load(args.filePath.string().c_str(), &totalWidth, &totalHeight, &n, 4); - ktxTexture2* kTexture = nullptr; - ktxTextureCreateInfo createInfo = { - .vkFormat = VK_FORMAT_R8G8B8A8_UNORM, - .baseDepth = 1, - .numLevels = 1, - .numLayers = 1, - .isArray = false, - .generateMipmaps = false, - }; - - if (args.type == TextureImportType::TEXTURE_CUBEMAP) + // manually transcode ktx textures using toktx + if (args.filePath.extension().compare("ktx") != 0) { - uint32 faceWidth = totalWidth / 4; - // uint32 faceHeight = totalHeight / 3; - // Cube map - createInfo.baseWidth = totalWidth / 4; - createInfo.baseHeight = totalHeight / 3; - createInfo.numFaces = 6; - createInfo.numDimensions = 2; - - ktxTexture2_Create(&createInfo, - KTX_TEXTURE_CREATE_ALLOC_STORAGE, - &kTexture); - - auto loadCubeFace = [&kTexture, &faceWidth, &totalWidth, &data](int xPos, int yPos, int faceName) - { - std::vector vec(faceWidth * faceWidth * 4); - for (uint32 y = 0; y < faceWidth; ++y) - { - for (uint32 x = 0; x < faceWidth; ++x) - { - int imgX = x + (xPos * faceWidth); - int imgY = y + (yPos * faceWidth); - std::memcpy(&vec[(x + (faceWidth * y)) * 4], &data[(imgX + (totalWidth * imgY)) * 4], 4); - } - } - ktxTexture_SetImageFromMemory(ktxTexture(kTexture), - 0, 0, faceName, vec.data(), vec.size()); - }; - loadCubeFace(2, 1, 0); // +X - loadCubeFace(0, 1, 1); // -X - loadCubeFace(1, 0, 2); // +Y - loadCubeFace(1, 2, 3); // -Y - loadCubeFace(1, 1, 4); // +Z - loadCubeFace(3, 1, 5); // -Z - } - else - { - createInfo.baseWidth = totalWidth; - createInfo.baseHeight = totalHeight; - createInfo.numFaces = 1; - createInfo.numDimensions = 1 + (totalHeight > 1); - - ktxTexture2_Create(&createInfo, - KTX_TEXTURE_CREATE_ALLOC_STORAGE, - &kTexture); - - ktxTexture_SetImageFromMemory(ktxTexture(kTexture), - 0, 0, 0, data, totalWidth * totalHeight * 4 * sizeof(unsigned char)); + auto ktxFile = args.filePath; + ktxFile.replace_extension("ktx"); + std::stringstream ss; + ss << "toktx --encode etc1s " << ktxFile << " " << args.filePath; + system(ss.str().c_str()); + args.filePath = ktxFile; } - ktxBasisParams params2 = { - .structSize = sizeof(ktxBasisParams), - .uastc = false, - .threadCount = std::thread::hardware_concurrency(), - .compressionLevel = 0, - .qualityLevel = 1, - }; + ktxTexture2* ktxHandle; + KTX_ASSERT(ktxTexture_CreateFromNamedFile(args.filePath.string().c_str(), 0, (ktxTexture**) & ktxHandle)); - //ktx_error_code_e error = ktxTexture2_CompressBasisEx(kTexture, ¶ms2); - //assert(error == KTX_SUCCESS); - ktx_uint8_t* dest; - ktx_size_t size; - ktxTexture_WriteToMemory(ktxTexture(kTexture), &dest, &size); + //int totalWidth = 0, totalHeight = 0, n = 0; + //unsigned char* data = stbi_load(args.filePath.string().c_str(), &totalWidth, &totalHeight, &n, 4); + //ktxTexture2* kTexture = nullptr; + //VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; + //ktxTextureCreateInfo createInfo = { + // .vkFormat = (uint32)format, + // .baseDepth = 1, + // .numLevels = 1, + // .numLayers = 1, + // .isArray = false, + // .generateMipmaps = false, + //}; + // + //if (args.type == TextureImportType::TEXTURE_CUBEMAP) + //{ + // uint32 faceWidth = totalWidth / 4; + // // uint32 faceHeight = totalHeight / 3; + // // Cube map + // createInfo.baseWidth = totalWidth / 4; + // createInfo.baseHeight = totalHeight / 3; + // createInfo.numFaces = 6; + // createInfo.numDimensions = 2; - Array memory(size); - std::memcpy(memory.data(), dest, size); - free(dest); - - stbi_image_free(data); + // KTX_ASSERT(ktxTexture2_Create(&createInfo, + // KTX_TEXTURE_CREATE_ALLOC_STORAGE, + // &kTexture)); + + // auto loadCubeFace = [&kTexture, &faceWidth, &totalWidth, &data](int xPos, int yPos, int faceName) + // { + // std::vector vec(faceWidth * faceWidth * 4); + // for (uint32 y = 0; y < faceWidth; ++y) + // { + // for (uint32 x = 0; x < faceWidth; ++x) + // { + // int imgX = x + (xPos * faceWidth); + // int imgY = y + (yPos * faceWidth); + // std::memcpy(&vec[(x + (faceWidth * y)) * 4], &data[(imgX + (totalWidth * imgY)) * 4], 4); + // } + // } + // ktxTexture_SetImageFromMemory(ktxTexture(kTexture), + // 0, 0, faceName, vec.data(), vec.size()); + // }; + // loadCubeFace(2, 1, 0); // +X + // loadCubeFace(0, 1, 1); // -X + // loadCubeFace(1, 0, 2); // +Y + // loadCubeFace(1, 2, 3); // -Y + // loadCubeFace(1, 1, 4); // +Z + // loadCubeFace(3, 1, 5); // -Z + //} + //else + //{ + // createInfo.baseWidth = totalWidth; + // createInfo.baseHeight = totalHeight; + // createInfo.numFaces = 1; + // createInfo.numDimensions = 1 + (totalHeight > 1); + + // ktxTexture2_Create(&createInfo, + // KTX_TEXTURE_CREATE_ALLOC_STORAGE, + // &kTexture); + + // ktxTexture_SetImageFromMemory(ktxTexture(kTexture), + // 0, 0, 0, data, totalWidth * totalHeight * n * sizeof(unsigned char)); + //} + //ktxTexture_WriteToNamedFile(ktxTexture(kTexture), args.filePath.replace_extension(".ktx").string().c_str()); + + //ktxBasisParams basisParams = { + // .structSize = sizeof(ktxBasisParams), + // .uastc = true, + // .threadCount = std::thread::hardware_concurrency(), + // .normalMap = normalMap, + // .uastcFlags = KTX_PACK_UASTC_LEVEL_VERYSLOW, + // .uastcRDO = true, + // .uastcRDOQualityScalar = 1, + //}; + //KTX_ASSERT(ktxTexture2_CompressBasisEx(kTexture, &basisParams)); + //KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 3)); + + //char writer[100]; + //snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1"); + //ktxHashList_AddKVPair(&kTexture->kvDataHead, KTX_WRITER_KEY, + // (ktx_uint32_t)strlen(writer) + 1, + // writer); + + //uint8* texData; + //size_t texSize; + //KTX_ASSERT(ktxTexture_WriteToMemory(ktxTexture(kTexture), &texData, &texSize)); + // + //stbi_image_free(data); - ArchiveBuffer temp(graphics); - Serialization::save(temp, memory); - temp.rewind(); - textureAsset->load(temp); if (textureAsset->getName().empty()) { return; } - AssetRegistry::get().saveAsset(textureAsset, TextureAsset::IDENTIFIER, textureAsset->getFolderPath(), textureAsset->getName()); + std::string path = (std::filesystem::path(args.importPath) / textureAsset->getName()).string().append(".asset"); + auto assetStream = AssetRegistry::createWriteStream(std::move(path), std::ios::binary); + ArchiveBuffer buffer(graphics); + // write identifier + Serialization::save(buffer, TextureAsset::IDENTIFIER); + // write name + Serialization::save(buffer, textureAsset->getName()); + // write folder + Serialization::save(buffer, textureAsset->getFolderPath()); + // write asset data + Serialization::save(buffer, args.filePath.string()); + + buffer.writeToStream(assetStream); + + buffer.rewind(); + + AssetRegistry::get().loadAsset(buffer); } diff --git a/src/Editor/Asset/TextureLoader.h b/src/Editor/Asset/TextureLoader.h index 59253ca..42bcec3 100644 --- a/src/Editor/Asset/TextureLoader.h +++ b/src/Editor/Asset/TextureLoader.h @@ -12,6 +12,7 @@ DECLARE_NAME_REF(Gfx, Texture2D) enum class TextureImportType { TEXTURE_2D, + TEXTURE_NORMAL, TEXTURE_CUBEMAP, }; struct TextureImportArgs @@ -20,6 +21,7 @@ struct TextureImportArgs std::string importPath; TextureImportType type = TextureImportType::TEXTURE_2D; Gfx::SeImageUsageFlagBits usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT; + uint32 numChannels = 4; }; class TextureLoader { diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 7d58273..de733d1 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -57,15 +57,18 @@ int main() { }); AssetImporter::importMesh(MeshImportArgs{ .filePath = sourcePath / "import/models/cube.fbx", - }); + }); + //AssetImporter::importMesh(MeshImportArgs{ + // .filePath = sourcePath / "import/models/Arissa.fbx", + // }); AssetImporter::importMesh(MeshImportArgs{ .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.fbx", .importPath = "Whitechapel" }); - AssetImporter::importMesh(MeshImportArgs{ - .filePath = sourcePath / "import/models/Volvo S90/Volvo S90.fbx", - .importPath = "Volvo", - }); + //AssetImporter::importMesh(MeshImportArgs{ + // .filePath = sourcePath / "import/models/Volvo S90/Volvo S90.fbx", + // .importPath = "Volvo", + // }); WindowCreateInfo mainWindowInfo; mainWindowInfo.title = "SeeleEngine"; mainWindowInfo.width = 1920; diff --git a/src/Engine/Asset/TextureAsset.cpp b/src/Engine/Asset/TextureAsset.cpp index d82e5d3..5ba213a 100644 --- a/src/Engine/Asset/TextureAsset.cpp +++ b/src/Engine/Asset/TextureAsset.cpp @@ -7,7 +7,7 @@ using namespace Seele; -#define KTX_CHECK(x) { ktx_error_code_e err = x; assert(err == KTX_SUCCESS); } +#define KTX_ASSERT(x) { auto error = x; if(error != KTX_SUCCESS) { std::cout << ktxErrorString(error) << std::endl; abort(); } } TextureAsset::TextureAsset() { @@ -20,54 +20,58 @@ TextureAsset::TextureAsset(std::string_view folderPath, std::string_view name) TextureAsset::~TextureAsset() { - ktxTexture_Destroy(ktxTexture(ktxHandle)); } void TextureAsset::save(ArchiveBuffer& buffer) const { - char writer[100]; - snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1"); - ktxHashList_AddKVPair(&ktxHandle->kvDataHead, KTX_WRITER_KEY, - (ktx_uint32_t)strlen(writer) + 1, - writer); - - ktx_uint8_t* texData; - ktx_size_t texSize; - KTX_CHECK(ktxTexture_WriteToMemory(ktxTexture(ktxHandle), &texData, &texSize)); - - Array rawData(texSize); - std::memcpy(rawData.data(), texData, texSize); - Serialization::save(buffer, rawData); - free(texData); + //ktxBasisParams basisParams = { + // .structSize = sizeof(ktxBasisParams), + // .uastc = true, + // .threadCount = std::thread::hardware_concurrency(), + // .normalMap = normalMap, + // .uastcFlags = KTX_PACK_UASTC_LEVEL_VERYSLOW, + // .uastcRDO = true, + // .uastcRDOQualityScalar = 1, + //}; + //KTX_ASSERT(ktxTexture2_CompressBasisEx(ktxHandle, &basisParams)); + //KTX_ASSERT(ktxTexture2_DeflateZstd(ktxHandle, 20)); + //ktx_uint8_t* texData; + //ktx_size_t texSize; + //KTX_ASSERT(ktxTexture_WriteToMemory(ktxTexture(ktxHandle), &texData, &texSize)); + // + //Array rawData(texSize); + //std::memcpy(rawData.data(), texData, texSize); + //Serialization::save(buffer, rawData); + //free(texData); } void TextureAsset::load(ArchiveBuffer& buffer) { - Gfx::PGraphics graphics = buffer.getGraphics(); - Array rawData; - Serialization::load(buffer, rawData); - KTX_CHECK(ktxTexture_CreateFromMemory(rawData.data(), - rawData.size(), - KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, + std::string ktxPath; + Serialization::load(buffer, ktxPath); + ktxTexture2* ktxHandle; + + KTX_ASSERT(ktxTexture_CreateFromNamedFile(ktxPath.c_str(), + KTX_TEXTURE_CREATE_NO_FLAGS, (ktxTexture**)&ktxHandle)); - //ktx_error_code_e e = ktxTexture2_TranscodeBasis(ktxHandle, KTX_TTF_BC7_RGBA, 0); - //assert(e == ktx_error_code_e::KTX_SUCCESS); + KTX_ASSERT(ktxTexture2_TranscodeBasis(ktxHandle, KTX_TTF_BC7_RGBA, 0)); + Gfx::PGraphics graphics = buffer.getGraphics(); TextureCreateInfo createInfo = { - .sourceData = { - .size = ktxTexture_GetDataSize(ktxTexture(ktxHandle)), - .data = ktxTexture_GetData(ktxTexture(ktxHandle)), - .owner = Gfx::QueueType::TRANSFER, - }, - .format = (Gfx::SeFormat)ktxHandle->vkFormat, - .width = ktxHandle->baseWidth, - .height = ktxHandle->baseHeight, - .depth = ktxHandle->baseDepth, - .mipLevels = ktxHandle->numLevels, - .layers = ktxHandle->numFaces, - .elements = ktxHandle->numLayers, - .usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT, + .sourceData = { + .size = ktxTexture_GetDataSize(ktxTexture(ktxHandle)), + .data = ktxTexture_GetData(ktxTexture(ktxHandle)), + .owner = Gfx::QueueType::TRANSFER, + }, + .format = (Gfx::SeFormat)ktxHandle->vkFormat, + .width = ktxHandle->baseWidth, + .height = ktxHandle->baseHeight, + .depth = ktxHandle->baseDepth, + .mipLevels = ktxHandle->numLevels, + .layers = ktxHandle->numFaces, + .elements = ktxHandle->numLayers, + .usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT, }; if (ktxHandle->isCubemap) { @@ -81,7 +85,9 @@ void TextureAsset::load(ArchiveBuffer& buffer) { texture = graphics->createTexture2D(createInfo); } + texture->transferOwnership(Gfx::QueueType::GRAPHICS); + ktxTexture_Destroy(ktxTexture(ktxHandle)); } void TextureAsset::setTexture(Gfx::OTexture _texture) diff --git a/src/Engine/Asset/TextureAsset.h b/src/Engine/Asset/TextureAsset.h index 7c4dab3..e8b4a35 100644 --- a/src/Engine/Asset/TextureAsset.h +++ b/src/Engine/Asset/TextureAsset.h @@ -22,8 +22,8 @@ public: uint32 getWidth(); uint32 getHeight(); private: - struct ktxTexture2* ktxHandle; Gfx::OTexture texture; + bool normalMap; friend class TextureLoader; }; DEFINE_REF(TextureAsset) diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index 64f322e..f66a338 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -518,6 +518,7 @@ public: { std::uninitialized_move_n(begin(), arraySize, temp); } + deallocateArray(_data, allocated); _data = temp; } allocated = new_cap; diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp index 696d0a4..f0d5db8 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -28,6 +28,7 @@ void RenderPass::beginFrame(const Component::Camera& cam) { viewParams = { .viewMatrix = cam.getViewMatrix(), + .inverseViewMatrix = glm::inverse(cam.getViewMatrix()), .projectionMatrix = viewport->getProjectionMatrix(), .inverseProjection = glm::inverse(viewport->getProjectionMatrix()), .cameraPosition = Vector4(cam.getCameraPosition(), 1), diff --git a/src/Engine/Graphics/RenderPass/RenderPass.h b/src/Engine/Graphics/RenderPass/RenderPass.h index 672d904..ad382ea 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.h +++ b/src/Engine/Graphics/RenderPass/RenderPass.h @@ -30,6 +30,7 @@ protected: struct ViewParameter { Matrix4 viewMatrix; + Matrix4 inverseViewMatrix; Matrix4 projectionMatrix; Matrix4 inverseProjection; Vector4 cameraPosition; diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 453e9de..a37ad3d 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -38,9 +38,11 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform) MaterialInstanceData& matInstanceData = matData.instances[referencedInstance->getId()]; for (const auto& data : meshData[mesh->id]) { + Matrix4 transformMatrix = transform.toMatrix() * mesh->transform; matInstanceData.meshes.add(MeshInstanceData{ .instance = InstanceData { - .transformMatrix = mesh->transform * transform.toMatrix(), + .transformMatrix = transformMatrix, + .inverseTransformMatrix = glm::inverse(transformMatrix), }, .data = data, }); @@ -167,7 +169,7 @@ void VertexData::loadMesh(MeshId id, Array loadedIndices, Array primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3)); std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8)); meshlets.add(MeshletDescription{ - .bounding = m.boundingBox.toSphere(), + .bounding = m.boundingBox,//.toSphere(), .vertexCount = m.numVertices, .primitiveCount = m.numPrimitives, .vertexOffset = vertexOffset, @@ -176,7 +178,7 @@ void VertexData::loadMesh(MeshId id, Array loadedIndices, Array }); } meshData[id].add(MeshData{ - .bounding = meshAABB.toSphere(), + .bounding = meshAABB,//.toSphere(), .numMeshlets = numMeshlets, .meshletOffset = meshletOffset, .indicesOffset = (uint32)meshOffsets[id], @@ -185,16 +187,20 @@ void VertexData::loadMesh(MeshId id, Array loadedIndices, Array } meshData[id][0].firstIndex = indices.size(); meshData[id][0].numIndices = loadedIndices.size(); - indices.resize(indices.size() + loadedIndices.size()); - std::memcpy(indices.data() + meshData[id][0].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32)); - indexBuffer = graphics->createIndexBuffer(IndexBufferCreateInfo{ - .sourceData = { - .size = sizeof(uint32) * indices.size(), - .data = (uint8*)indices.data(), - }, - .indexType = Gfx::SE_INDEX_TYPE_UINT32, - .name = "IndexBuffer", - }); + if (!graphics->supportMeshShading()) + { + indices.resize(indices.size() + loadedIndices.size()); + std::memcpy(indices.data() + meshData[id][0].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32)); + indexBuffer = graphics->createIndexBuffer(IndexBufferCreateInfo{ + .sourceData = { + .size = sizeof(uint32) * indices.size(), + .data = (uint8*)indices.data(), + }, + .indexType = Gfx::SE_INDEX_TYPE_UINT32, + .name = "IndexBuffer", + }); + + } meshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { .size = sizeof(MeshletDescription) * meshlets.size(), @@ -273,7 +279,7 @@ void Seele::VertexData::init(Gfx::PGraphics _graphics) graphics = _graphics; verticesAllocated = NUM_DEFAULT_ELEMENTS; instanceDataLayout = graphics->createDescriptorLayout("pScene"); - instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding =0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,}); + instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,}); // meshData instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,}); diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index 8ee608c..9bb4432 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -29,10 +29,11 @@ public: struct InstanceData { Matrix4 transformMatrix; + Matrix4 inverseTransformMatrix; }; struct MeshData { - BoundingSphere bounding; + AABB bounding; uint32 numMeshlets = 0; uint32 meshletOffset = 0; uint32 firstIndex = 0; @@ -85,7 +86,7 @@ protected: VertexData(); struct MeshletDescription { - BoundingSphere bounding; + AABB bounding; uint32_t vertexCount; uint32_t primitiveCount; uint32_t vertexOffset; diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index 3a6998f..73315c6 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -123,6 +123,7 @@ void* Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) .sharingMode = VK_SHARING_MODE_EXCLUSIVE, }; VmaAllocationCreateInfo allocInfo = { + .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT, .usage = VMA_MEMORY_USAGE_AUTO, .requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, }; diff --git a/src/Engine/Graphics/Vulkan/Texture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp index ab747db..a471863 100644 --- a/src/Engine/Graphics/Vulkan/Texture.cpp +++ b/src/Engine/Graphics/Vulkan/Texture.cpp @@ -100,96 +100,89 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, .usage = VMA_MEMORY_USAGE_AUTO, }; VK_CHECK(vmaCreateImage(graphics->getAllocator(), &info, &allocInfo, &image, &allocation, nullptr)); - - const DataSource& sourceData = createInfo.sourceData; - if(sourceData.size > 0) - { - changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - void* data; - VkMemoryPropertyFlags memProps; - VkBuffer stagingBuffer = VK_NULL_HANDLE; - VmaAllocation stagingAlloc = VK_NULL_HANDLE; - vmaGetAllocationMemoryProperties(graphics->getAllocator(), allocation, &memProps); - if(memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) - { - vmaMapMemory(graphics->getAllocator(), allocation, &data); - } - else - { - VkBufferCreateInfo stagingInfo = { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .size = sourceData.size, - .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - }; - VmaAllocationCreateInfo alloc = { - .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, - .usage = VMA_MEMORY_USAGE_AUTO, - }; - VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &alloc, &stagingBuffer, &stagingAlloc, nullptr)); - vmaMapMemory(graphics->getAllocator(), stagingAlloc, &data); - } - std::memcpy(data, sourceData.data, sourceData.size); - vmaFlushAllocation(graphics->getAllocator(), stagingAlloc, 0, VK_WHOLE_SIZE); + } - PCommandPool commandPool = graphics->getQueueCommands(currentOwner); - VkBufferImageCopy region = { - .bufferOffset = 0, - .bufferRowLength = 0, - .bufferImageHeight = 0, - .imageSubresource = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel = 0, - .baseArrayLayer = 0, - .layerCount = arrayCount * layerCount, - }, - .imageOffset = { - .x = 0, - .y = 0, - .z = 0, - }, - .imageExtent = { - .width = width, - .height = height, - .depth = depth - }, - }; - - vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), - stagingBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - - // When loading a texture from a file, we will almost always use it as a texture map for fragment shaders - changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - if(stagingBuffer != VK_NULL_HANDLE) - { - vmaUnmapMemory(graphics->getAllocator(), stagingAlloc); - graphics->getDestructionManager()->queueBuffer(commandPool->getCommands(), stagingBuffer, stagingAlloc); - } - } - } - if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) + const DataSource& sourceData = createInfo.sourceData; + if (sourceData.size > 0) { - changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); - } - else if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) - { - changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); + VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + void* data; + VkMemoryPropertyFlags memProps; + VkBuffer stagingBuffer = VK_NULL_HANDLE; + VmaAllocation stagingAlloc = VK_NULL_HANDLE; + VkBufferCreateInfo stagingInfo = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .size = sourceData.size, + .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + }; + VmaAllocationCreateInfo alloc = { + .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT, + .usage = VMA_MEMORY_USAGE_AUTO, + }; + VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &alloc, &stagingBuffer, &stagingAlloc, nullptr)); + vmaMapMemory(graphics->getAllocator(), stagingAlloc, &data); + + std::memcpy(data, sourceData.data, sourceData.size); + vmaUnmapMemory(graphics->getAllocator(), stagingAlloc); + + PCommandPool commandPool = graphics->getQueueCommands(currentOwner); + VkBufferImageCopy region = { + .bufferOffset = 0, + .bufferRowLength = 0, + .bufferImageHeight = 0, + .imageSubresource = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = arrayCount * layerCount, + }, + .imageOffset = { + .x = 0, + .y = 0, + .z = 0, + }, + .imageExtent = { + .width = width, + .height = height, + .depth = depth + }, + }; + + vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), + stagingBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + + // When loading a texture from a file, we will almost always use it as a texture map for fragment shaders + changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + + graphics->getDestructionManager()->queueBuffer(commandPool->getCommands(), stagingBuffer, stagingAlloc); } else { - changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, - VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + if (usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) + { + changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); + } + else if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) + { + changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); + } + else + { + changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, + VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + } } VkImageViewCreateInfo viewInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, diff --git a/src/Engine/Graphics/slang-compile.cpp b/src/Engine/Graphics/slang-compile.cpp index c399dbc..9d86add 100644 --- a/src/Engine/Graphics/slang-compile.cpp +++ b/src/Engine/Graphics/slang-compile.cpp @@ -16,7 +16,7 @@ Slang::ComPtr Seele::generateShader(const ShaderCreateInfo& create } slang::SessionDesc sessionDesc; sessionDesc.flags = 0; - StaticArray option; + StaticArray option; option[0].name = slang::CompilerOptionName::IgnoreCapabilities; option[0].value = slang::CompilerOptionValue(); option[0].value.kind = slang::CompilerOptionValueKind::Int; @@ -25,10 +25,6 @@ Slang::ComPtr Seele::generateShader(const ShaderCreateInfo& create option[1].value = slang::CompilerOptionValue(); option[1].value.kind = slang::CompilerOptionValueKind::Int; option[1].value.intValue0 = 1; - option[2].name = slang::CompilerOptionName::DumpIntermediates; - option[2].value = slang::CompilerOptionValue(); - option[2].value.kind = slang::CompilerOptionValueKind::Int; - option[2].value.intValue0 = 1; sessionDesc.compilerOptionEntries = option.data(); sessionDesc.compilerOptionEntryCount = option.size(); sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR; diff --git a/src/Engine/Material/MaterialInstance.cpp b/src/Engine/Material/MaterialInstance.cpp index e184d87..99cd494 100644 --- a/src/Engine/Material/MaterialInstance.cpp +++ b/src/Engine/Material/MaterialInstance.cpp @@ -50,8 +50,6 @@ MaterialInstance::~MaterialInstance() void MaterialInstance::updateDescriptor() { - if(!dirty) - return; Gfx::PDescriptorLayout layout = baseMaterial->getMaterial()->getDescriptorLayout(); descriptor = layout->allocateDescriptorSet(); for (auto& param : parameters) diff --git a/src/Engine/Material/MaterialInstance.h b/src/Engine/Material/MaterialInstance.h index 3904c82..578ce6e 100644 --- a/src/Engine/Material/MaterialInstance.h +++ b/src/Engine/Material/MaterialInstance.h @@ -35,7 +35,6 @@ private: Gfx::PDescriptorSet descriptor; PMaterialAsset baseMaterial; uint64 id; - bool dirty = true; }; DEFINE_REF(MaterialInstance) } // namespace Seele \ No newline at end of file