Added shadow maps
This commit is contained in:
1 parent
a47306533e
commit
d8795ec076
15 files changed
+880
-6
No files matched your search
+226
-4
@@ -249,7 +249,11 @@ void Character::draw(Renderer& renderer) {
|
||||
}
|
||||
|
||||
void Character::prepareGpuSkinningVBOs(AnimationData& anim) {
|
||||
if (anim.gpuSkinningPrepared) return;
|
||||
if (anim.gpuSkinningPrepared)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
anim.model.PrepareGpuSkinningData();
|
||||
|
||||
@@ -284,13 +288,18 @@ void Character::prepareGpuSkinningVBOs(AnimationData& anim) {
|
||||
void Character::drawGpuSkinning(Renderer& renderer) {
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end() || !texture) return;
|
||||
if (it == animations.end() || !texture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& anim = it->second;
|
||||
prepareGpuSkinningVBOs(anim);
|
||||
|
||||
if (anim.skinningMatrices.empty()) return;
|
||||
|
||||
if (anim.skinningMatrices.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
static const std::string skinningShaderName = "skinning";
|
||||
static const std::string boneMatricesUniform = "uBoneMatrices[0]";
|
||||
|
||||
@@ -354,4 +363,217 @@ void Character::drawGpuSkinning(Renderer& renderer) {
|
||||
renderer.shaderManager.PopShader();
|
||||
}
|
||||
|
||||
// ==================== Shadow depth pass ====================
|
||||
|
||||
void Character::drawShadowDepth(Renderer& renderer) {
|
||||
if (useGpuSkinning) {
|
||||
drawShadowDepthGpuSkinning(renderer);
|
||||
} else {
|
||||
drawShadowDepthCpu(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
void Character::drawShadowDepthCpu(Renderer& renderer) {
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end()) return;
|
||||
|
||||
// The caller has already pushed the shadow_depth shader and the
|
||||
// light's projection + view onto the renderer stacks.
|
||||
renderer.PushMatrix();
|
||||
renderer.TranslateMatrix({ position.x(), position.y(), position.z() });
|
||||
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-facingAngle, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
renderer.ScaleMatrix(modelScale);
|
||||
renderer.RotateMatrix(modelCorrectionRotation.toRotationMatrix());
|
||||
|
||||
auto& anim = it->second;
|
||||
anim.modelMutable.AssignFrom(anim.model.mesh);
|
||||
anim.modelMutable.RefreshVBO();
|
||||
renderer.DrawVertexRenderStruct(anim.modelMutable);
|
||||
|
||||
renderer.PopMatrix();
|
||||
}
|
||||
|
||||
void Character::drawShadowDepthGpuSkinning(Renderer& renderer) {
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end()) return;
|
||||
|
||||
auto& anim = it->second;
|
||||
prepareGpuSkinningVBOs(anim);
|
||||
if (anim.skinningMatrices.empty()) return;
|
||||
|
||||
static const std::string shadowSkinningShader = "shadow_depth_skinning";
|
||||
static const std::string boneMatricesUniform = "uBoneMatrices[0]";
|
||||
|
||||
// Switch to the skinning depth shader (caller has the static depth shader active).
|
||||
renderer.shaderManager.PushShader(shadowSkinningShader);
|
||||
|
||||
renderer.PushMatrix();
|
||||
renderer.TranslateMatrix({ position.x(), position.y(), position.z() });
|
||||
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-facingAngle, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
renderer.ScaleMatrix(modelScale);
|
||||
renderer.RotateMatrix(modelCorrectionRotation.toRotationMatrix());
|
||||
|
||||
renderer.RenderUniformMatrix4fvArray(boneMatricesUniform,
|
||||
static_cast<int>(anim.skinningMatrices.size()), false,
|
||||
anim.skinningMatrices[0].data());
|
||||
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifndef __ANDROID__
|
||||
if (anim.bindPoseMutable.vao) {
|
||||
glBindVertexArray(anim.bindPoseMutable.vao->getBuffer());
|
||||
renderer.shaderManager.EnableVertexAttribArrays();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.positionVBO->getBuffer());
|
||||
renderer.VertexAttribPointer3fv("vPosition", 0, NULL);
|
||||
|
||||
if (anim.bindPoseMutable.texCoordVBO) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.texCoordVBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("vTexCoord", 0, NULL);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneIndices0", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneIndices1", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneWeights0", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneWeights1", 0, NULL);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(anim.bindPoseMutable.data.PositionData.size()));
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.shaderManager.PopShader();
|
||||
}
|
||||
|
||||
// ==================== Main pass with shadows ====================
|
||||
|
||||
void Character::drawWithShadow(Renderer& renderer, const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const Eigen::Vector3f& lightDirCamera) {
|
||||
if (useGpuSkinning) {
|
||||
drawGpuSkinningWithShadow(renderer, lightFromCamera, shadowMapTex, lightDirCamera);
|
||||
} else {
|
||||
drawCpuWithShadow(renderer, lightFromCamera, shadowMapTex, lightDirCamera);
|
||||
}
|
||||
}
|
||||
|
||||
void Character::drawCpuWithShadow(Renderer& renderer, const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const Eigen::Vector3f& lightDirCamera) {
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end() || !texture) return;
|
||||
|
||||
static const std::string shadowShader = "default_shadow";
|
||||
|
||||
renderer.shaderManager.PushShader(shadowShader);
|
||||
renderer.RenderUniform1i(textureUniformName, 0);
|
||||
renderer.RenderUniform1i("uShadowMap", 1);
|
||||
renderer.RenderUniformMatrix4fv("uLightFromCamera", false, lightFromCamera.data());
|
||||
renderer.RenderUniform3fv("uLightDir", lightDirCamera.data());
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, shadowMapTex);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
||||
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
||||
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
|
||||
|
||||
renderer.PushMatrix();
|
||||
renderer.TranslateMatrix({ position.x(), position.y(), position.z() });
|
||||
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-facingAngle, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
renderer.ScaleMatrix(modelScale);
|
||||
renderer.RotateMatrix(modelCorrectionRotation.toRotationMatrix());
|
||||
|
||||
auto& anim = it->second;
|
||||
anim.modelMutable.AssignFrom(anim.model.mesh);
|
||||
anim.modelMutable.RefreshVBO();
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(anim.modelMutable);
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
renderer.shaderManager.PopShader();
|
||||
}
|
||||
|
||||
void Character::drawGpuSkinningWithShadow(Renderer& renderer, const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const Eigen::Vector3f& lightDirCamera) {
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end() || !texture) return;
|
||||
|
||||
auto& anim = it->second;
|
||||
prepareGpuSkinningVBOs(anim);
|
||||
if (anim.skinningMatrices.empty()) return;
|
||||
|
||||
static const std::string skinningShadowShader = "skinning_shadow";
|
||||
static const std::string boneMatricesUniform = "uBoneMatrices[0]";
|
||||
|
||||
renderer.shaderManager.PushShader(skinningShadowShader);
|
||||
renderer.RenderUniform1i(textureUniformName, 0);
|
||||
renderer.RenderUniform1i("uShadowMap", 1);
|
||||
renderer.RenderUniformMatrix4fv("uLightFromCamera", false, lightFromCamera.data());
|
||||
renderer.RenderUniform3fv("uLightDir", lightDirCamera.data());
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, shadowMapTex);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
||||
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
||||
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
|
||||
|
||||
renderer.PushMatrix();
|
||||
renderer.TranslateMatrix({ position.x(), position.y(), position.z() });
|
||||
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-facingAngle, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
renderer.ScaleMatrix(modelScale);
|
||||
renderer.RotateMatrix(modelCorrectionRotation.toRotationMatrix());
|
||||
|
||||
renderer.RenderUniformMatrix4fvArray(boneMatricesUniform,
|
||||
static_cast<int>(anim.skinningMatrices.size()), false,
|
||||
anim.skinningMatrices[0].data());
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifndef __ANDROID__
|
||||
if (anim.bindPoseMutable.vao) {
|
||||
glBindVertexArray(anim.bindPoseMutable.vao->getBuffer());
|
||||
renderer.shaderManager.EnableVertexAttribArrays();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.positionVBO->getBuffer());
|
||||
renderer.VertexAttribPointer3fv("vPosition", 0, NULL);
|
||||
|
||||
if (anim.bindPoseMutable.texCoordVBO) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.texCoordVBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("vTexCoord", 0, NULL);
|
||||
}
|
||||
|
||||
// Bind normals for diffuse lighting (skinning_shadow shader skins them)
|
||||
if (anim.bindPoseMutable.normalVBO) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.normalVBO->getBuffer());
|
||||
renderer.VertexAttribPointer3fv("vNormal", 0, NULL);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneIndices0", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneIndices1", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneWeights0", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneWeights1", 0, NULL);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(anim.bindPoseMutable.data.PositionData.size()));
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
renderer.shaderManager.PopShader();
|
||||
}
|
||||
|
||||
} // namespace ZL
|
||||
Reference in new issue
Block a user