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:
parent
6dc9475419
commit
f95fd2efc2
16 changed files with 94 additions and 20 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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.
|
@ -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.
49
renderer/shaders/skinned.vert
Normal file
49
renderer/shaders/skinned.vert
Normal 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;
|
||||
}
|
BIN
renderer/shaders/skinned.vert.spv
Normal file
BIN
renderer/shaders/skinned.vert.spv
Normal file
Binary file not shown.
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue