Skip to content

Commit

Permalink
Fixes for GLES and emscripten
Browse files Browse the repository at this point in the history
  • Loading branch information
wivlaro committed Dec 19, 2024
1 parent 6658ec9 commit 6f3d997
Show file tree
Hide file tree
Showing 18 changed files with 132 additions and 79 deletions.
65 changes: 33 additions & 32 deletions shaders/GameShader.frag
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
uniform highp vec3 light;
uniform vec3 ambientColor = vec3(0.25, 0.25, 0.25);
uniform vec3 lightColor = vec3(1.0, 1.0, 1.0);
uniform float shininess = 80.0;
uniform mediump vec3 ambientColor;
uniform mediump vec3 lightColor;
uniform mediump float shininess;

uniform sampler2D lightmapTexture;
uniform sampler2DArrayShadow shadowmapTexture;
uniform sampler2D diffuseTexture;
uniform vec3 specularColor = vec3(1.0, 1.0, 1.0);
uniform highp sampler2D lightmapTexture;
uniform highp sampler2DArrayShadow shadowmapTexture;
uniform highp sampler2D diffuseTexture;
uniform mediump vec3 specularColor;

in mediump vec3 transformedNormal;
in highp vec3 cameraDirection;
Expand All @@ -15,32 +15,32 @@ in mediump vec2 interpolatedTextureCoords;

#ifdef ENABLE_SHADOWMAP_LEVELS
in highp vec3 shadowCoord[ENABLE_SHADOWMAP_LEVELS];
uniform float shadowDepthSplits[ENABLE_SHADOWMAP_LEVELS];
uniform highp float shadowDepthSplits[ENABLE_SHADOWMAP_LEVELS];
#endif

out lowp vec4 color;
in highp vec3 worldPos;
uniform highp mat4 modelMatrix;

in vec3 worldPos;

uniform mat4 modelMatrix;
layout(location = 0) out lowp vec4 color;
layout(location = 1) out highp uint fragmentObjectId;


#ifdef ENABLE_SHADOWMAP_LEVELS
float computeShadowAtLevel(vec3 levelShadowCoord, int shadowLevel, vec3 normal, vec3 lightDir) {
float baseBias = 0.0010 + shadowLevel * 0.001;
float slopeScaledBias = baseBias * max(1.0 - dot(normal, lightDir), 0.0); // Slope-scaled bias
float dZdx = dFdx(levelShadowCoord.z);
float dZdy = dFdy(levelShadowCoord.z);
float depthOffset = max(abs(dZdx), abs(dZdy)) * baseBias;
highp float computeShadowAtLevel(mediump vec3 levelShadowCoord, int shadowLevel, mediump vec3 normal, mediump vec3 lightDir) {
highp float baseBias = 0.0010 + float(shadowLevel) * 0.001;
highp float slopeScaledBias = baseBias * max(1.0 - dot(normal, lightDir), 0.0); // Slope-scaled bias
highp float dZdx = dFdx(levelShadowCoord.z);
highp float dZdy = dFdy(levelShadowCoord.z);
highp float depthOffset = max(abs(dZdx), abs(dZdy)) * baseBias;

float bias = depthOffset + slopeScaledBias;
highp float bias = depthOffset + slopeScaledBias;

#ifdef SHADOWMAP_PCF
vec2 texelSize = vec2(1.0) / textureSize(shadowmapTexture, 0).xy;
float shadow = 0.0;
mediump vec2 texelSize = vec2(1.0) / vec2(textureSize(shadowmapTexture, 0).xy);
highp float shadow = 0.0;
for (int x = -1; x <= 1; ++x) {
for (int y = -1; y <= 1; ++y) {
vec2 offset = vec2(x, y) * texelSize;
mediump vec2 offset = vec2(x, y) * texelSize;
shadow += texture(shadowmapTexture, vec4(levelShadowCoord.xy + offset, shadowLevel, clamp(levelShadowCoord.z - bias, 0.0, 1.0)));
}
}
Expand All @@ -50,12 +50,12 @@ float computeShadowAtLevel(vec3 levelShadowCoord, int shadowLevel, vec3 normal,
return texture(shadowmapTexture, vec4(levelShadowCoord.xy, shadowLevel, levelShadowCoord.z - bias));
#endif
}
float computeShadow(vec3 normalizedTransformedNormal) {
mediump float computeShadow(mediump vec3 normalizedTransformedNormal) {
lowp float intensity = dot(normalizedTransformedNormal, light);
if (intensity > 0) {
if (intensity > 0.0) {
for (int shadowLevel = 0; shadowLevel < ENABLE_SHADOWMAP_LEVELS; shadowLevel++) {
vec3 levelShadowCoord = shadowCoord[shadowLevel];
bool inRange = levelShadowCoord.x > 0 && levelShadowCoord.y > 0 && levelShadowCoord.x < 1 && levelShadowCoord.y < 1 && levelShadowCoord.z > 0 && levelShadowCoord.z < 1;
mediump vec3 levelShadowCoord = shadowCoord[shadowLevel];
bool inRange = levelShadowCoord.x > 0.0 && levelShadowCoord.y > 0.0 && levelShadowCoord.x < 1.0 && levelShadowCoord.y < 1.0 && levelShadowCoord.z > 0.0 && levelShadowCoord.z < 1.0;
if (inRange) {
return computeShadowAtLevel(levelShadowCoord, shadowLevel, normalizedTransformedNormal, light);
}
Expand All @@ -68,26 +68,27 @@ float computeShadow(vec3 normalizedTransformedNormal) {
void main() {
lowp vec3 diffuseColor = texture(diffuseTexture, interpolatedTextureCoords).xyz;

vec3 ambient = ambientColor;
mediump vec3 ambient = ambientColor;

mediump vec3 normalizedTransformedNormal = normalize(transformedNormal);

// color.rgb = ambient * diffuseColor * lightColor * intensity;
ambient *= diffuseColor.rgb;

vec3 diffuse = max(dot(normalizedTransformedNormal, normalize(light)), 0.0) * diffuseColor.rgb * lightColor;
mediump vec3 diffuse = max(dot(normalizedTransformedNormal, normalize(light)), 0.0) * diffuseColor.rgb * lightColor;

vec3 viewDir = normalize(cameraDirection); // Direction to the camera
vec3 reflectDir = reflect(-light, normalizedTransformedNormal); // Reflect light around the normal
vec3 specular = pow(max(dot(viewDir, reflectDir), 0.0), shininess) * 0.5 * lightColor;
mediump vec3 viewDir = normalize(cameraDirection); // Direction to the camera
mediump vec3 reflectDir = reflect(-light, normalizedTransformedNormal); // Reflect light around the normal
mediump vec3 specular = pow(max(dot(viewDir, reflectDir), 0.0), shininess) * 0.5 * lightColor;

vec3 finalColor = ambient + diffuse + specular;
mediump vec3 finalColor = ambient + diffuse + specular;

#ifdef ENABLE_SHADOWMAP_LEVELS
// Adjust shadow darkness as needed
finalColor *= mix(0.5, 1.0, computeShadow(normalizedTransformedNormal));
#endif

fragmentObjectId = 0U;
color = vec4(finalColor, 1.0); // Output final color with alpha

// color.rgb = vec3(0.5) + normalRaw * 0.5;
Expand Down
5 changes: 2 additions & 3 deletions shaders/GameShader.vert
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

uniform highp mat4 transformationMatrix;
uniform highp mat4 projectionMatrix;
uniform mediump mat3 normalMatrix;
Expand All @@ -21,7 +20,7 @@ out highp vec3 shadowCoord[ENABLE_SHADOWMAP_LEVELS];
#endif

#ifdef ENABLE_MAX_ANIMATION_BONES
uniform int perVertexJointCount;
uniform uint perVertexJointCount;
uniform mat4 jointMatrices[ENABLE_MAX_ANIMATION_BONES];

layout(location = 6) in mediump uvec4 jointIds;
Expand All @@ -40,7 +39,7 @@ void main() {

vec3 modelNormal = normal;
#ifdef ENABLE_MAX_ANIMATION_BONES
if (perVertexJointCount > 0) {
if (perVertexJointCount > 0u) {
mat4 skinMatrix = getSkinMatrix();
position4 = skinMatrix * position4;
modelNormal = mat3(skinMatrix) * normal;
Expand Down
2 changes: 1 addition & 1 deletion shaders/ShadowCaster.frag
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
out float fragmentdepth;
out highp float fragmentdepth;

void main() {
fragmentdepth = gl_FragCoord.z;
Expand Down
4 changes: 2 additions & 2 deletions shaders/ShadowCaster.vert
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ uniform highp mat4 transformationMatrix;
in highp vec4 position;

#ifdef ENABLE_MAX_ANIMATION_BONES
uniform int perVertexJointCount;
uniform uint perVertexJointCount;
uniform mat4 jointMatrices[ENABLE_MAX_ANIMATION_BONES];

layout(location = 6) in mediump uvec4 jointIds;
Expand All @@ -21,7 +21,7 @@ void main()
vec4 modelPosition = position;

#ifdef ENABLE_MAX_ANIMATION_BONES
if (perVertexJointCount > 0) {
if (perVertexJointCount > 0u) {
modelPosition = getSkinMatrix() * modelPosition;
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/Animator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ namespace MagnumGame {
Animator::Animation::Animation(const Containers::StringView& animationName, const AnimatorAsset &asset, std::map<int, BoneObject *>& boneMap) {
auto& animationData = asset._animations.at(animationName);

Debug{} << "Instancing anim" << animationName;
// Debug{} << "Instancing anim" << animationName;
for (UnsignedInt trackIndex = 0; trackIndex != animationData.trackCount(); ++trackIndex) {

auto animatedObjectId = animationData.trackTarget(trackIndex);
Expand Down
11 changes: 4 additions & 7 deletions src/AnimatorAsset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,7 @@ namespace MagnumGame {
for (auto attrId = 0U; attrId < meshData->attributeCount(); attrId++) {
auto attrName = meshData->attributeName(attrId);

Debug{} << "\tAttribute" << attrId << ":" << attrName
<< "format=" << meshData->attributeFormat(attrId)
<< " offset=" << meshData->attributeOffset(attrId)
<< " stride=" << meshData->attributeStride(attrId)
<< " arraySize=" << meshData->attributeArraySize(attrId)
<< " morphTargetId=" << meshData->attributeMorphTargetId(attrId);
// Debug{} << "\tAttribute" << attrId << ":" << attrName << "format=" << meshData->attributeFormat(attrId) << " offset=" << meshData->attributeOffset(attrId) << " stride=" << meshData->attributeStride(attrId) << " arraySize=" << meshData->attributeArraySize(attrId) << " morphTargetId=" << meshData->attributeMorphTargetId(attrId);
}

[[maybe_unused]]
Expand Down Expand Up @@ -160,9 +155,11 @@ namespace MagnumGame {
processMeshes(-1, _rootSkinMeshNode, 0);

if (importer.animationCount() > 0) {
Debug debug{};
debug << "Animations:" << importer.animationCount();
for (UnsignedInt animationIndex = 0; animationIndex != importer.animationCount(); ++animationIndex) {
auto animationName = importer.animationName(animationIndex);
Debug{} << "Animation" << animationIndex << animationName;
debug << animationName;
auto animationData = importer.animation(animationIndex);
_animations.insert(std::pair{animationName, std::move(*animationData)});
}
Expand Down
14 changes: 14 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,20 @@ if (CORRADE_TARGET_EMSCRIPTEN)
emscripten_embed_file(MagnumGameApp ../font/Roboto-Regular.ttf /font/Roboto-Regular.ttf)
emscripten_embed_file(MagnumGameApp ../models/characters/ /models/characters/)
emscripten_embed_file(MagnumGameApp ../models/levels/ /models/levels/)
emscripten_embed_file(MagnumGameApp ../shaders/ /shaders/)

# add_custom_command(
# OUTPUT generated_dummy_embeds
# COMMAND ${CMAKE_COMMAND} -E touch generated_dummy_embeds
# DEPENDS ../shaders/*.vert ../shaders/*.frag ../models/characters/* ../models/levels/* ../font/Roboto-Regular.ttf
# )
#
# add_custom_target(dummy_embed_target DEPENDS generated_dummy_embeds)
# add_file_dependencies()
file(GLOB EMBEDDED_FILES ../shaders/*.vert ../shaders/*.frag ../models/characters/* ../models/levels/* ../font/Roboto-Regular.ttf)
set_property(SOURCE MagnumGameApp APPEND PROPERTY OBJECT_DEPENDS ${EMBEDDED_FILES})



target_link_libraries(MagnumGameApp PRIVATE
MagnumPlugins::StbImageImporter
Expand Down
8 changes: 4 additions & 4 deletions src/GameAssets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,10 @@ namespace MagnumGame {
for (auto materialId = 0U; materialId < importer.materialCount(); materialId++) {
auto material = importer.material(materialId);
Debug{} << "\tMaterial" << materialId << importer.materialName(materialId) << material->types();
for (auto attributeId = 0U; attributeId < material->attributeCount(); attributeId++) {
Debug{} << "\t\tattribute" << attributeId << material->attributeName(attributeId) << material->
attributeType(attributeId) << material->attributeDataFlags();
}
// for (auto attributeId = 0U; attributeId < material->attributeCount(); attributeId++) {
// Debug{} << "\t\tattribute" << attributeId << material->attributeName(attributeId) << material->
// attributeType(attributeId) << material->attributeDataFlags();
// }

GL::Texture2D *texture = nullptr;
if (auto textureId = material->findAttribute<UnsignedInt>(Trade::MaterialAttribute::DiffuseTexture)) {
Expand Down
19 changes: 9 additions & 10 deletions src/GameShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,15 @@ GameShader::GameShader(const std::string& vertFilename, const std::string& fragF
setUniform(uniformLocation("diffuseTexture"), DiffuseTextureLayer);
setUniform(uniformLocation("shadowmapTexture"), ShadowmapTextureLayer);

Debug debug{};
debug << "\nSHADER " << vertFilename << " & " << fragFilename << "\nAttribute locations:\n\tposition=" << Position::Location << "\n\tnormal=" << Normal::Location << "\n\ttexcoords=" << TextureCoordinates::Location ;
debug << "\n\tbound: position = " << glGetAttribLocation(id(), "position") ;
debug << "\n\tbound: textureCoords = " << glGetAttribLocation(id(), "textureCoordinates") ;
debug << "\n\tbound: normal = " << glGetAttribLocation(id(), "normal") ;
debug << "\n\tbound: particlePosition = " << glGetAttribLocation(id(), "particlePosition") ;
debug << "\n\tbound: shadowmapTexture = " << uniformLocation("shadowmapTexture") ;
debug << "\n\tbound: diffuseTexture = " << uniformLocation("diffuseTexture") ;
debug << "\n\tbound: lightmapTexture = " << uniformLocation("lightmapTexture") ;
debug << "\n\tshininess = " << shininessUniform ;
Debug{} << "\nSHADER " << vertFilename << " & " << fragFilename << "Attributes:"
<< "position=" << Position::Location << glGetAttribLocation(id(), "position")
<< "normal=" << Normal::Location << glGetAttribLocation(id(), "normal")
<< "texcoords=" << TextureCoordinates::Location << glGetAttribLocation(id(), "textureCoordinates")
<< "Uniforms:"
<< "shadowmapTexture=" << uniformLocation("shadowmapTexture")
<< "diffuseTexture=" << uniformLocation("diffuseTexture")
<< "lightmapTexture=" << uniformLocation("lightmapTexture")
<< "shininess=" << shininessUniform ;
}

void GameShader::addDefine(const std::string &name, const std::string &value) {
Expand Down
2 changes: 1 addition & 1 deletion src/GameShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class GameShader : public GL::AbstractShaderProgram
}


GameShader& setPerVertexJointCount(int jointCount) {
GameShader& setPerVertexJointCount(UnsignedInt jointCount) {
setUniform(perVertexJointCountUniform, jointCount);
return *this;
}
Expand Down
10 changes: 10 additions & 0 deletions src/GameState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,30 +200,40 @@ namespace MagnumGame {
}

_shadowLight->render(_shadowCasterDrawables);
CHECK_GL_ERROR();

GL::Renderer::flush();
CHECK_GL_ERROR();

Containers::Array<Matrix4> shadowMatrices(NoInit, _shadowLight->getNumLayers());
for (auto layerIndex = 0u; layerIndex < _shadowLight->getNumLayers(); layerIndex++) {
shadowMatrices[layerIndex] = _shadowLight->getLayerMatrix(layerIndex);
}
auto setupShaderForShadows = [&](GameShader* shader) {
shader->setShadowmapTexture(_shadowLight->getShadowmapTextureArray());
CHECK_GL_ERROR();
shader->setShadowmapMatrices(shadowMatrices);
CHECK_GL_ERROR();
auto& shadowCutPlanes = _shadowLight->getCutPlanes();
shader->setShadowCutPlanes({shadowCutPlanes.data(), shadowCutPlanes.size()});
CHECK_GL_ERROR();
shader->setLightVector(_cameraController->getCameraMatrix().rotationScaling() * _shadowLight->transformation()[2].xyz());
// shader->setShadowmapMatrix(shadowLight->camera().projectionMatrix() * shadowLight->camera().cameraMatrix());
CHECK_GL_ERROR();
};
setupShaderForShadows(&_assets.getTexturedShader());
setupShaderForShadows(&_assets.getAnimatedTexturedShader());
}

void GameState::drawOpaque() {
_cameraController->draw(_opaqueDrawables);
CHECK_GL_ERROR();
}

void GameState::drawTransparent() {
//Might want to sort the drawables along the camera Z axis
_cameraController->draw(_transparentDrawables);
CHECK_GL_ERROR();
}

void GameState::setupPlayer() {
Expand Down
14 changes: 7 additions & 7 deletions src/MagnumGameApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include <Magnum/MeshTools/Compile.h>
#include <Magnum/MeshTools/Transform.h>
#include <Magnum/SceneGraph/Camera.h>
#include <Magnum/Shaders/PhongGL.h>
#include <Magnum/Trade/AbstractImporter.h>
#include <Magnum/Trade/TextureData.h>
#include <Magnum/Text/AbstractFont.h>
Expand Down Expand Up @@ -77,8 +76,8 @@ namespace MagnumGame {
_framebuffer.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, _color)
.attachRenderbuffer(GL::Framebuffer::ColorAttachment{1}, _objectId)
.attachRenderbuffer(GL::Framebuffer::BufferAttachment::Depth, _depth)
.mapForDraw({{Shaders::PhongGL::ColorOutput, GL::Framebuffer::ColorAttachment{0}},
{Shaders::PhongGL::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}}});
.mapForDraw({{Shaders::GenericGL3D::ColorOutput, GL::Framebuffer::ColorAttachment{0}},
{Shaders::GenericGL3D::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}}});

CHECK_GL_ERROR();

Expand Down Expand Up @@ -157,15 +156,16 @@ namespace MagnumGame {
_gameState->drawShadowBuffer();

//Object picking support
_framebuffer.mapForDraw({{Shaders::PhongGL::ColorOutput, GL::Framebuffer::ColorAttachment{0}},
{Shaders::PhongGL::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}}});
_framebuffer.mapForDraw({{Shaders::GenericGL3D::ColorOutput, GL::Framebuffer::ColorAttachment{0}},
{Shaders::GenericGL3D::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}}});
// _framebuffer.mapForDraw({{Shaders::GenericGL3D::ColorOutput, GL::Framebuffer::ColorAttachment{0}}});
GL::Renderer::enable(GL::Renderer::Feature::Blending);
GL::Renderer::setBlendFunction(GL::Renderer::BlendFunction::SourceAlpha, GL::Renderer::BlendFunction::OneMinusSourceAlpha);

_gameState->drawOpaque();

_framebuffer.mapForDraw({{Shaders::PhongGL::ColorOutput, GL::Framebuffer::ColorAttachment{0}},
{Shaders::PhongGL::ObjectIdOutput, GL::Framebuffer::DrawAttachment::None}});
_framebuffer.mapForDraw({{Shaders::GenericGL3D::ColorOutput, GL::Framebuffer::ColorAttachment{0}},
{Shaders::GenericGL3D::ObjectIdOutput, GL::Framebuffer::DrawAttachment::None}});

_gameState->drawTransparent();

Expand Down
22 changes: 17 additions & 5 deletions src/MagnumGameCommon.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
#pragma once

#include <Magnum/GL/Renderer.h>
#include <Magnum/SceneGraph/MatrixTransformation3D.h>
using namespace Magnum;
using namespace Magnum::Math::Literals;

inline void CheckGLError(const char* file, const int line) {
static int maxLoggable = 100;
if (maxLoggable < 0) return;
GL::Renderer::Error err;
while ((err = GL::Renderer::error()) != GL::Renderer::Error::NoError) {
Error{} << file << ":" << line << "Error: " << err;
if (maxLoggable-- == 0) {
Error{} << "Logging no more errors from CheckGLError";
break;
}
}
}

#define STR(s) #s
#define XSTR(x) STR(x)
#define CHECK_GL_ERROR() { GL::Renderer::Error err; while ((err = GL::Renderer::error()) != GL::Renderer::Error::NoError) { Error() << (__FILE__ ":" STR(__LINE__)) << "Error: " << err; } }
#define CHECK_GL_ERROR() CheckGLError(__FILE__, __LINE__)

#define DISALLOW_COPY(TypeName) TypeName(const TypeName&) = delete; TypeName& operator=(const TypeName&) = delete;

using namespace Magnum;
using namespace Magnum::Math::Literals;

namespace MagnumGame {

Expand Down
Loading

0 comments on commit 6f3d997

Please sign in to comment.