1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-23 20:47:45 +00:00

Add a dedicated skinned shader

This is to prevent trying to use bone transforms on terrain.
This commit is contained in:
Joshua Goins 2024-02-02 14:37:58 -05:00
parent 6dc9475419
commit f95fd2efc2
16 changed files with 94 additions and 20 deletions

View file

@ -339,6 +339,7 @@ void GearView::updatePart()
gearAddition.bodyId = physis_get_race_code(fallbackRace, fallbackSubrace, currentGender);
mdlPart->addModel(mdl,
true,
glm::vec3(),
sanitizeMdlPath(mdlPath),
materials,
@ -390,7 +391,7 @@ void GearView::updatePart()
}
}
mdlPart->addModel(mdl, glm::vec3(), sanitizeMdlPath(mdlPath), materials, currentLod);
mdlPart->addModel(mdl, true, glm::vec3(), sanitizeMdlPath(mdlPath), materials, currentLod);
}
}
@ -413,7 +414,7 @@ void GearView::updatePart()
}
}
mdlPart->addModel(mdl, glm::vec3(), sanitizeMdlPath(mdlPath), materials, currentLod);
mdlPart->addModel(mdl, true, glm::vec3(), sanitizeMdlPath(mdlPath), materials, currentLod);
}
}
@ -436,7 +437,7 @@ void GearView::updatePart()
}
}
mdlPart->addModel(mdl, glm::vec3(), sanitizeMdlPath(mdlPath), materials, currentLod);
mdlPart->addModel(mdl, true, glm::vec3(), sanitizeMdlPath(mdlPath), materials, currentLod);
}
}
@ -453,7 +454,7 @@ void GearView::updatePart()
if (cache.fileExists(QLatin1String(skinmtrl_path.c_str()))) {
auto mat = physis_material_parse(cache.lookupFile(QLatin1String(skinmtrl_path.c_str())));
mdlPart->addModel(mdl, glm::vec3(), sanitizeMdlPath(mdlPath), {mat}, currentLod);
mdlPart->addModel(mdl, true, glm::vec3(), sanitizeMdlPath(mdlPath), {mat}, currentLod);
}
}
}

View file

@ -38,7 +38,12 @@ void MapView::addTerrain(QString basePath, physis_Terrain terrain)
auto plateMdlFile = physis_gamedata_extract_file(data, mdlPathStd.c_str());
auto plateMdl = physis_mdl_parse(plateMdlFile);
mdlPart->addModel(plateMdl, glm::vec3(terrain.plates[i].position[0], 0.0f, terrain.plates[i].position[1]), QStringLiteral("terapart%1").arg(i), {}, 0);
mdlPart->addModel(plateMdl,
false,
glm::vec3(terrain.plates[i].position[0], 0.0f, terrain.plates[i].position[1]),
QStringLiteral("terapart%1").arg(i),
{},
0);
}
}

View file

@ -58,7 +58,7 @@ void MainWindow::setupFileMenu(QMenu *menu)
auto buffer = physis_read_file(fileName.toStdString().c_str());
part->addModel(physis_mdl_parse(buffer), glm::vec3(), QStringLiteral("mdl"), {}, 0);
part->addModel(physis_mdl_parse(buffer), false, glm::vec3(), QStringLiteral("mdl"), {}, 0);
});
}

View file

@ -72,6 +72,7 @@ void MDLPart::clear()
}
void MDLPart::addModel(physis_MDL mdl,
bool skinned,
glm::vec3 position,
const QString &name,
std::vector<physis_Material> materials,
@ -86,6 +87,7 @@ void MDLPart::addModel(physis_MDL mdl,
model.from_body_id = fromBodyId;
model.to_body_id = toBodyId;
model.position = position;
model.skinned = skinned;
std::transform(materials.begin(), materials.end(), std::back_inserter(model.materials), [this](const physis_Material &mat) {
return createMaterial(mat);

View file

@ -53,6 +53,7 @@ public Q_SLOTS:
/// Adds a new MDL with a list of materials used.
void addModel(physis_MDL mdl,
bool skinned,
glm::vec3 position,
const QString &name,
std::vector<physis_Material> materials,

View file

@ -16,7 +16,8 @@ qt_add_resources(renderer
shaders/imgui.frag.spv
shaders/imgui.vert.spv
shaders/mesh.frag.spv
shaders/mesh.vert.spv)
shaders/mesh.vert.spv
shaders/skinned.vert.spv)
target_include_directories(renderer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(renderer
PUBLIC

View file

@ -47,6 +47,7 @@ struct RenderModel {
std::array<glm::mat4, 128> boneData;
std::vector<RenderMaterial> materials;
glm::vec3 position;
bool skinned = false;
uint16_t from_body_id = 101;
uint16_t to_body_id = 101;
@ -109,6 +110,7 @@ public:
std::map<uint64_t, VkDescriptorSet> cachedDescriptors;
VkPipeline pipeline;
VkPipeline skinnedPipeline;
VkPipelineLayout pipelineLayout;
std::tuple<VkBuffer, VkDeviceMemory> createBuffer(size_t size, VkBufferUsageFlags usageFlags);

View file

@ -3,6 +3,7 @@
# SPDX-License-Identifier: CC0-1.0
glslc mesh.vert -o mesh.vert.spv &&
glslc skinned.vert -o skinned.vert.spv &&
glslc mesh.frag -o mesh.frag.spv &&
glslc imgui.vert -o imgui.vert.spv &&
glslc imgui.frag -o imgui.frag.spv

View file

@ -23,7 +23,12 @@ layout(std430, push_constant) uniform PushConstant {
void main() {
const vec3 lightPos = vec3(3);
vec3 diffuse = texture(diffuseTexture, inUV).rgb;
vec3 diffuse;
if (textureSize(diffuseTexture, 0).x == 1) {
diffuse = vec3(1);
} else {
diffuse = texture(diffuseTexture, inUV).rgb;
}
if(type == 1) {
const float skinInfluence = texture(specularTexture, inUV).r;
vec3 skinColor = vec3(250 / 255.0, 199 / 255.0, 166 / 255.0);

Binary file not shown.

View file

@ -32,15 +32,8 @@ layout(std430, binding = 2) buffer readonly BoneInformation {
};
void main() {
mat4 BoneTransform = bones[boneOffset + inBoneIds[0]] * inBoneWeights[0];
BoneTransform += bones[boneOffset + inBoneIds[1]] * inBoneWeights[1];
BoneTransform += bones[boneOffset + inBoneIds[2]] * inBoneWeights[2];
BoneTransform += bones[boneOffset + inBoneIds[3]] * inBoneWeights[3];
BoneTransform = model * BoneTransform;
vec4 bPos = BoneTransform * vec4(inPosition, 1.0);
vec4 bNor = BoneTransform * vec4(inNormal, 0.0);
vec4 bPos = model * vec4(inPosition, 1.0);
vec4 bNor = vec4(inNormal, 0.0);
gl_Position = vp * bPos;
outNormal = bNor.xyz;

Binary file not shown.

View file

@ -0,0 +1,49 @@
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: CC0-1.0
#version 450
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec2 inUV0;
layout(location = 2) in vec2 inUV1;
layout(location = 3) in vec3 inNormal;
layout(location = 4) in vec4 inBiTangent;
layout(location = 5) in vec4 inColor;
layout(location = 6) in vec4 inBoneWeights;
layout(location = 7) in uvec4 inBoneIds;
layout(location = 0) out vec3 outNormal;
layout(location = 1) out vec3 outFragPos;
layout(location = 2) out vec2 outUV;
layout(binding = 3) uniform sampler2D diffuseTexture;
layout(binding = 4) uniform sampler2D normalTexture;
layout(binding = 5) uniform sampler2D specularTexture;
layout(binding = 6) uniform sampler2D multiTexture;
layout(std430, push_constant) uniform PushConstant {
mat4 vp, model;
int boneOffset;
int type;
};
layout(std430, binding = 2) buffer readonly BoneInformation {
mat4 bones[128];
};
void main() {
mat4 BoneTransform = bones[boneOffset + inBoneIds[0]] * inBoneWeights[0];
BoneTransform += bones[boneOffset + inBoneIds[1]] * inBoneWeights[1];
BoneTransform += bones[boneOffset + inBoneIds[2]] * inBoneWeights[2];
BoneTransform += bones[boneOffset + inBoneIds[3]] * inBoneWeights[3];
BoneTransform = model * BoneTransform;
vec4 bPos = BoneTransform * vec4(inPosition, 1.0);
vec4 bNor = BoneTransform * vec4(inNormal, 0.0);
gl_Position = vp * bPos;
outNormal = bNor.xyz;
outFragPos = vec3(model * vec4(inPosition, 1.0));
outUV = inUV0;
}

Binary file not shown.

View file

@ -472,9 +472,13 @@ void Renderer::render(const std::vector<RenderModel> &models)
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
for (auto model : models) {
if (model.skinned) {
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, skinnedPipeline);
} else {
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
}
// copy bone data
{
const size_t bufferSize = sizeof(glm::mat4) * 128;
@ -731,6 +735,12 @@ void Renderer::initPipeline()
vertexShaderStageInfo.module = loadShaderFromDisk(":/shaders/mesh.vert.spv");
vertexShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo skinnedVertexShaderStageInfo = {};
skinnedVertexShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
skinnedVertexShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
skinnedVertexShaderStageInfo.module = loadShaderFromDisk(":/shaders/skinned.vert.spv");
skinnedVertexShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo fragmentShaderStageInfo = {};
fragmentShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
fragmentShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
@ -867,6 +877,10 @@ void Renderer::initPipeline()
createInfo.renderPass = renderPass;
vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &createInfo, nullptr, &pipeline);
shaderStages[0] = skinnedVertexShaderStageInfo;
vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &createInfo, nullptr, &skinnedPipeline);
}
VkShaderModule Renderer::createShaderModule(const uint32_t *code, const int length)

View file

@ -89,7 +89,7 @@ void MainWindow::refreshParts(const QString &path)
partHolder->addTab(exdWidget, QStringLiteral("Note"));
} else if (info.completeSuffix() == QStringLiteral("mdl")) {
auto mdlWidget = new MDLPart(data, fileCache);
mdlWidget->addModel(physis_mdl_parse(file), glm::vec3(), QStringLiteral("mdl"), {}, 0);
mdlWidget->addModel(physis_mdl_parse(file), false, glm::vec3(), QStringLiteral("mdl"), {}, 0);
partHolder->addTab(mdlWidget, QStringLiteral("Model"));
} else if (info.completeSuffix() == QStringLiteral("tex") || info.completeSuffix() == QStringLiteral("atex")) {
auto texWidget = new TexPart(data);