mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Add player character shadow casting in shadow pass
This commit is contained in:
parent
3d63c32b7f
commit
54eac50c4d
3 changed files with 103 additions and 2 deletions
|
|
@ -57,6 +57,7 @@ public:
|
|||
void update(float deltaTime);
|
||||
|
||||
void render(const Camera& camera, const glm::mat4& view, const glm::mat4& projection);
|
||||
void renderShadow(GLuint shadowShaderProgram);
|
||||
|
||||
void setInstancePosition(uint32_t instanceId, const glm::vec3& position);
|
||||
void setInstanceRotation(uint32_t instanceId, const glm::vec3& rotation);
|
||||
|
|
|
|||
|
|
@ -1151,6 +1151,86 @@ void CharacterRenderer::render(const Camera& camera, const glm::mat4& view, cons
|
|||
glEnable(GL_CULL_FACE); // Restore culling for other renderers
|
||||
}
|
||||
|
||||
void CharacterRenderer::renderShadow(GLuint shadowShaderProgram) {
|
||||
if (instances.empty() || shadowShaderProgram == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
GLint modelLoc = glGetUniformLocation(shadowShaderProgram, "uModel");
|
||||
GLint useTexLoc = glGetUniformLocation(shadowShaderProgram, "uUseTexture");
|
||||
GLint texLoc = glGetUniformLocation(shadowShaderProgram, "uTexture");
|
||||
GLint alphaTestLoc = glGetUniformLocation(shadowShaderProgram, "uAlphaTest");
|
||||
GLint opacityLoc = glGetUniformLocation(shadowShaderProgram, "uShadowOpacity");
|
||||
GLint useBonesLoc = glGetUniformLocation(shadowShaderProgram, "uUseBones");
|
||||
if (modelLoc < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (useTexLoc >= 0) glUniform1i(useTexLoc, 0);
|
||||
if (alphaTestLoc >= 0) glUniform1i(alphaTestLoc, 0);
|
||||
if (opacityLoc >= 0) glUniform1f(opacityLoc, 1.0f);
|
||||
if (useBonesLoc >= 0) glUniform1i(useBonesLoc, 0);
|
||||
if (texLoc >= 0) glUniform1i(texLoc, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
for (const auto& [_, instance] : instances) {
|
||||
auto modelIt = models.find(instance.modelId);
|
||||
if (modelIt == models.end()) continue;
|
||||
const auto& gpuModel = modelIt->second;
|
||||
|
||||
glm::mat4 modelMat = instance.hasOverrideModelMatrix
|
||||
? instance.overrideModelMatrix
|
||||
: getModelMatrix(instance);
|
||||
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, &modelMat[0][0]);
|
||||
|
||||
bool useBones = !instance.boneMatrices.empty();
|
||||
if (useBonesLoc >= 0) glUniform1i(useBonesLoc, useBones ? 1 : 0);
|
||||
if (useBones) {
|
||||
int numBones = std::min(static_cast<int>(instance.boneMatrices.size()), MAX_BONES);
|
||||
GLint bonesLoc = glGetUniformLocation(shadowShaderProgram, "uBones[0]");
|
||||
if (bonesLoc >= 0) {
|
||||
glUniformMatrix4fv(bonesLoc, numBones, GL_FALSE, &instance.boneMatrices[0][0][0]);
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray(gpuModel.vao);
|
||||
|
||||
if (!gpuModel.data.batches.empty()) {
|
||||
for (const auto& batch : gpuModel.data.batches) {
|
||||
GLuint texId = whiteTexture;
|
||||
if (batch.textureIndex < gpuModel.data.textureLookup.size()) {
|
||||
uint16_t lookupIdx = gpuModel.data.textureLookup[batch.textureIndex];
|
||||
if (lookupIdx < gpuModel.textureIds.size()) {
|
||||
texId = gpuModel.textureIds[lookupIdx];
|
||||
}
|
||||
}
|
||||
|
||||
bool useTexture = (texId != 0 && texId != whiteTexture);
|
||||
if (useTexLoc >= 0) glUniform1i(useTexLoc, useTexture ? 1 : 0);
|
||||
if (alphaTestLoc >= 0) glUniform1i(alphaTestLoc, useTexture ? 1 : 0);
|
||||
if (opacityLoc >= 0) glUniform1f(opacityLoc, 1.0f);
|
||||
if (useTexture) {
|
||||
glBindTexture(GL_TEXTURE_2D, texId);
|
||||
}
|
||||
|
||||
glDrawElements(GL_TRIANGLES,
|
||||
batch.indexCount,
|
||||
GL_UNSIGNED_SHORT,
|
||||
(void*)(batch.indexStart * sizeof(uint16_t)));
|
||||
}
|
||||
} else {
|
||||
if (useTexLoc >= 0) glUniform1i(useTexLoc, 0);
|
||||
if (alphaTestLoc >= 0) glUniform1i(alphaTestLoc, 0);
|
||||
glDrawElements(GL_TRIANGLES,
|
||||
static_cast<GLsizei>(gpuModel.data.indices.size()),
|
||||
GL_UNSIGNED_SHORT,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
glm::mat4 CharacterRenderer::getModelMatrix(const CharacterInstance& instance) const {
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
|
||||
|
|
|
|||
|
|
@ -1524,11 +1524,24 @@ uint32_t Renderer::compileShadowShader() {
|
|||
uniform mat4 uLightSpaceMatrix;
|
||||
uniform mat4 uModel;
|
||||
layout(location = 0) in vec3 aPos;
|
||||
layout(location = 4) in vec2 aTexCoord;
|
||||
layout(location = 2) in vec2 aTexCoord;
|
||||
layout(location = 3) in vec4 aBoneWeights;
|
||||
layout(location = 4) in vec4 aBoneIndicesF;
|
||||
uniform bool uUseBones;
|
||||
uniform mat4 uBones[200];
|
||||
out vec2 vTexCoord;
|
||||
void main() {
|
||||
vec3 pos = aPos;
|
||||
if (uUseBones) {
|
||||
ivec4 bi = ivec4(aBoneIndicesF);
|
||||
mat4 boneTransform = uBones[bi.x] * aBoneWeights.x
|
||||
+ uBones[bi.y] * aBoneWeights.y
|
||||
+ uBones[bi.z] * aBoneWeights.z
|
||||
+ uBones[bi.w] * aBoneWeights.w;
|
||||
pos = vec3(boneTransform * vec4(aPos, 1.0));
|
||||
}
|
||||
vTexCoord = aTexCoord;
|
||||
gl_Position = uLightSpaceMatrix * uModel * vec4(aPos, 1.0);
|
||||
gl_Position = uLightSpaceMatrix * uModel * vec4(pos, 1.0);
|
||||
}
|
||||
)";
|
||||
const char* fragSrc = R"(
|
||||
|
|
@ -1690,9 +1703,11 @@ void Renderer::renderShadowPass() {
|
|||
GLint texLoc = glGetUniformLocation(shadowShaderProgram, "uTexture");
|
||||
GLint alphaTestLoc = glGetUniformLocation(shadowShaderProgram, "uAlphaTest");
|
||||
GLint opacityLoc = glGetUniformLocation(shadowShaderProgram, "uShadowOpacity");
|
||||
GLint useBonesLoc = glGetUniformLocation(shadowShaderProgram, "uUseBones");
|
||||
if (useTexLoc >= 0) glUniform1i(useTexLoc, 0);
|
||||
if (alphaTestLoc >= 0) glUniform1i(alphaTestLoc, 0);
|
||||
if (opacityLoc >= 0) glUniform1f(opacityLoc, 1.0f);
|
||||
if (useBonesLoc >= 0) glUniform1i(useBonesLoc, 0);
|
||||
if (texLoc >= 0) glUniform1i(texLoc, 0);
|
||||
|
||||
// Render terrain into shadow map
|
||||
|
|
@ -1732,6 +1747,11 @@ void Renderer::renderShadowPass() {
|
|||
m2Renderer->renderShadow(shadowShaderProgram);
|
||||
}
|
||||
|
||||
// Render characters into shadow map
|
||||
if (characterRenderer) {
|
||||
characterRenderer->renderShadow(shadowShaderProgram);
|
||||
}
|
||||
|
||||
// Restore state
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glCullFace(GL_BACK);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue