Skip to content

Commit

Permalink
Fixed the shadows and enabled PCF
Browse files Browse the repository at this point in the history
  • Loading branch information
wivlaro committed Dec 18, 2024
1 parent 7922afe commit 90d3e0a
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 81 deletions.
74 changes: 33 additions & 41 deletions shaders/GameShader.frag
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,21 @@ in mediump vec3 transformedNormal;
in highp vec3 cameraDirection;

in mediump vec2 interpolatedTextureCoords;

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

out lowp vec4 color;

in vec3 worldPos;

uniform mat4 modelMatrix;

in highp vec3 normalRaw;



float computeShadow(vec3 levelShadowCoord, int shadowLevel, vec3 normal, vec3 lightDir) {
#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);
Expand All @@ -35,72 +36,63 @@ float computeShadow(vec3 levelShadowCoord, int shadowLevel, vec3 normal, vec3 li
float bias = depthOffset + slopeScaledBias;

#ifdef SHADOWMAP_PCF
{
vec2 texelSize = vec2(1.0) / textureSize(shadowmapTexture, 0).xy;
float shadow = 0.0;
for (int x = -1; x <= 1; ++x) {
for (int y = -1; y <= 1; ++y) {
vec2 offset = vec2(x, y) * texelSize;
shadow += texture(shadowmapTexture, vec4(levelShadowCoord.xy + offset, shadowLevel, clamp(levelShadowCoord.z - bias, 0.0, 1.0)));
}
vec2 texelSize = vec2(1.0) / textureSize(shadowmapTexture, 0).xy;
float shadow = 0.0;
for (int x = -1; x <= 1; ++x) {
for (int y = -1; y <= 1; ++y) {
vec2 offset = vec2(x, y) * texelSize;
shadow += texture(shadowmapTexture, vec4(levelShadowCoord.xy + offset, shadowLevel, clamp(levelShadowCoord.z - bias, 0.0, 1.0)));
}
return shadow / 9.0; // Average PCF samples
}
return shadow / 9.0; // Average PCF samples
#else
// return texture(shadowmapTexture, vec4(levelShadowCoord.xy, shadowLevel, clamp(levelShadowCoord.z - bias, 0.0, 1.0)));
return texture(shadowmapTexture, vec4(levelShadowCoord.xy, shadowLevel, levelShadowCoord.z - bias));
#endif
}
float computeShadow(vec3 normalizedTransformedNormal) {
lowp float intensity = dot(normalizedTransformedNormal, light);
if (intensity > 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;
if (inRange) {
return computeShadowAtLevel(levelShadowCoord, shadowLevel, normalizedTransformedNormal, light);
}
}
}
return 0.0;
}
#endif

void main() {
lowp vec3 diffuseColor = texture(diffuseTexture, interpolatedTextureCoords).xyz;

/* Ambient color */
vec3 ambient = ambientColor;

mediump vec3 normalizedTransformedNormal = normalize(transformedNormal);

float shadow = 0.0;
lowp float intensity = dot(normalizedTransformedNormal, light);
int shadowLevel = 0;
if (intensity <= 0) {
shadow = 0.0f;
intensity = 0.0f;
}
else {
for (; 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;
if (inRange) {
float bias = 0.0015;
// float bias = 0.0015 * max(1.0 - dot(normalizedTransformedNormal, light), 0.0);
shadow = computeShadow(levelShadowCoord, shadowLevel, normalizedTransformedNormal, light);
// shadow = texture(shadowmapTexture, vec4(levelShadowCoord.xy, shadowLevel, levelShadowCoord.z-bias));
break;
}
}
}
// color.rgb = ambient * diffuseColor * lightColor * intensity;
ambient *= diffuseColor.rgb;

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;
vec3 specular = vec3(0);
vec3 shadowFactor = mix(vec3(0.5), vec3(1.0), shadow); // Adjust shadow darkness as needed
vec3 specular = pow(max(dot(viewDir, reflectDir), 0.0), shininess) * 0.5 * lightColor;

vec3 finalColor = ambient + diffuse + specular;

vec3 finalColor = shadowFactor * (ambient + diffuse + specular);
// finalColor = vec3(shadowFactor.x, 0.5, 0.5);
#ifdef ENABLE_SHADOWMAP_LEVELS
// Adjust shadow darkness as needed
finalColor *= mix(0.5, 1.0, computeShadow(normalizedTransformedNormal));
#endif

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

// color.rgb = vec3(0.5) + normalRaw * 0.5;
// color.rgb = diffuseColor;

// color.rgb = vec3(intensity);
// color.rgb = vec3(interpolatedTextureCoords, 0.0);
// color.rgb = ((0.1 + vec3(intensity * shadow)) * diffuseColor);

// color.rgb = diffuseColor * (inRange ? clamp(shadowCoord[shadowLevel],0,1) : vec3(0.1,0.1,0.1));
Expand Down
9 changes: 6 additions & 3 deletions shaders/GameShader.vert
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ uniform mat4 modelMatrix;

layout(location = 0) in highp vec3 position;
layout(location = 1) in mediump vec2 textureCoordinates;
layout(location = 2) in highp vec3 normal;
layout(location = 5) in highp vec3 normal;

out mediump vec2 interpolatedTextureCoords;
out mediump vec3 transformedNormal;
out highp vec3 lightDirection;
out highp vec3 cameraDirection;

//out highp vec3 normalRaw;

#ifdef ENABLE_SHADOWMAP_LEVELS
uniform highp mat4 shadowmapMatrix[ENABLE_SHADOWMAP_LEVELS];
out highp vec3 shadowCoord[ENABLE_SHADOWMAP_LEVELS];
Expand Down Expand Up @@ -54,13 +56,14 @@ void main() {

cameraDirection = -transformedPosition;

#ifdef ENABLE_SHADOWMAP_LEVELS
for (int i = 0; i < shadowmapMatrix.length(); i++) {
// float castReceiveOffsetBias = 0.10 + i * 0.001;
// shadowCoord[i] = (shadowmapMatrix[i] * (worldPos4 + vec4(transformedNormal * castReceiveOffsetBias,0))).xyz;
shadowCoord[i] = (shadowmapMatrix[i] * worldPos4).xyz;
}
#endif

gl_Position = projectionMatrix*transformedPosition4;

interpolatedTextureCoords = textureCoordinates;
// normalRaw = normal;
}
4 changes: 2 additions & 2 deletions src/CameraController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <Magnum/SceneGraph/Scene.h>

namespace MagnumGame {
CameraController::CameraController(Scene3D &scene, float near, float far)
CameraController::CameraController(Scene3D &scene, Range1D zPlanes)
: _cameraObject(scene.addChild<Object3D>(nullptr))
, _camera(_cameraObject.addFeature<SceneGraph::Camera3D>())
, _targetObject{}
Expand All @@ -17,7 +17,7 @@ namespace MagnumGame {
.translate(Vector3::zAxis(30.0f))
.rotateX(-90.0_degf);
_camera.setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend)
.setProjectionMatrix(Matrix4::perspectiveProjection(30.0_degf, 1.0f, near, far))
.setProjectionMatrix(Matrix4::perspectiveProjection(30.0_degf, 1.0f, zPlanes.min(), zPlanes.max()))
.setViewport(GL::defaultFramebuffer.viewport().size());
}

Expand Down
2 changes: 1 addition & 1 deletion src/CameraController.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace MagnumGame {
class CameraController {
public:
explicit CameraController(Scene3D &camera, float near, float far);
explicit CameraController(Scene3D &camera, Range1D zPlanes);

void setupTargetFromCurrent(Object3D &target);

Expand Down
13 changes: 3 additions & 10 deletions src/GameAssets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,29 +51,22 @@ namespace MagnumGame {
_fontsDir = *findDirectory("font");
_shadersDir = *findDirectory("shaders");

const int maxAnimationBones = 16;

_shadowCasterShader.emplace(
Utility::Path::join(_shadersDir, "ShadowCaster.vert"),
Utility::Path::join(_shadersDir, "ShadowCaster.frag"), 0);

_animatedShadowCasterShader.emplace(
Utility::Path::join(_shadersDir, "ShadowCaster.vert"),
Utility::Path::join(_shadersDir, "ShadowCaster.frag"), maxAnimationBones);
Utility::Path::join(_shadersDir, "ShadowCaster.frag"), MaxAnimationBones);

_texturedShader.emplace(
Utility::Path::join(_shadersDir, "GameShader.vert"),
Utility::Path::join(_shadersDir, "GameShader.frag"), 0);
Utility::Path::join(_shadersDir, "GameShader.frag"), 0, ShadowMapLevels, ShadowPercentageCloserFiltering);

_animatedTexturedShader.emplace(
Utility::Path::join(_shadersDir, "GameShader.vert"),
Utility::Path::join(_shadersDir, "GameShader.frag"), maxAnimationBones);
// _animatedTexturedShader.emplace(Shaders::PhongGL::Configuration{}
// .setJointCount(16, 4)
// .setFlags(Shaders::PhongGL::Flag::DiffuseTexture | Shaders::PhongGL::Flag::ObjectId | Shaders::PhongGL::Flag::DynamicPerVertexJointCount));
Utility::Path::join(_shadersDir, "GameShader.frag"), MaxAnimationBones, ShadowMapLevels, ShadowPercentageCloserFiltering);
_animatedTexturedShader->setAmbientColor(0x111111_rgbf);
// .setSpecularColor(0x33000000_rgbaf)
// .setLightPositions({{10.0f, 15.0f, 5.0f, 0.0f}});

_vertexColorShader.emplace();

Expand Down
9 changes: 7 additions & 2 deletions src/GameAssets.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ namespace MagnumGame {

class GameAssets {
public:
static constexpr int ShadowMapLevels = 2;
static constexpr bool ShadowPercentageCloserFiltering = true;
static constexpr int MaxAnimationBones = 16;
static constexpr Vector2i ShadowMapResolution = {1024, 1024};

explicit GameAssets(Trade::AbstractImporter& );
~GameAssets();

Expand Down Expand Up @@ -56,8 +61,8 @@ namespace MagnumGame {


void loadModel(Trade::AbstractImporter &gltfImporter, Trade::SceneData &sceneData,
Containers::StringView objectName, GL::Mesh *outMesh, Matrix4x4 *outTransform,
std::shared_ptr<GL::Texture2D> *outTexture, btConvexHullShape *outConvexHullShape);
Containers::StringView objectName, GL::Mesh *outMesh, Matrix4x4 *outTransform,
std::shared_ptr<GL::Texture2D> *outTexture, btConvexHullShape *outConvexHullShape);
};
}

Expand Down
10 changes: 8 additions & 2 deletions src/GameShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ namespace MagnumGame {

using namespace Magnum::GL;

GameShader::GameShader(const std::string& vertFilename, const std::string& fragFilename, int maxAnimationBones)
GameShader::GameShader(const std::string& vertFilename, const std::string& fragFilename, int maxAnimationBones, int shadowMapLevels, bool shadowPcf)
{
CHECK_GL_ERROR();
addDefine("ENABLE_SHADOWMAP_LEVELS","4");
if (shadowMapLevels > 0) {
addDefine("ENABLE_SHADOWMAP_LEVELS",std::to_string(shadowMapLevels));
}
if (maxAnimationBones > 0) {
addDefine("ENABLE_MAX_ANIMATION_BONES",std::to_string(maxAnimationBones));
}
if (shadowPcf) {
addDefine("SHADOWMAP_PCF", "1");
}

CHECK_GL_ERROR();
using namespace Magnum;
Expand Down Expand Up @@ -102,6 +107,7 @@ GameShader::GameShader(const std::string& vertFilename, const std::string& fragF
debug << "\n\tbound: shadowmapTexture = " << uniformLocation("shadowmapTexture") ;
debug << "\n\tbound: diffuseTexture = " << uniformLocation("diffuseTexture") ;
debug << "\n\tbound: lightmapTexture = " << uniformLocation("lightmapTexture") ;
debug << "\n\tshininess = " << shininessUniform ;
}

void GameShader::addDefine(const std::string &name, const std::string &value) {
Expand Down
4 changes: 3 additions & 1 deletion src/GameShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ class GameShader : public GL::AbstractShaderProgram
typedef Shaders::GenericGL3D::JointIds JointIds;
typedef Shaders::GenericGL3D::Weights Weights;

explicit GameShader(const std::string& vertFilename, const std::string& fragFilename, int maxAnimationBones);
explicit GameShader(const std::string& vertFilename, const std::string& fragFilename, int maxAnimationBones, int shadowMapLevels, bool shadowPcf);

~GameShader() override = default;

void addDefine(const std::string& name, const std::string& value);


enum: Int {
DiffuseTextureLayer = 0,
ShadowmapTextureLayer = 1
Expand Down Expand Up @@ -77,6 +78,7 @@ class GameShader : public GL::AbstractShaderProgram
setUniform(lightVectorUniform, f);
return *this;
}
auto& setShininess(float shininess) { setUniform(shininessUniform, shininess); return *this; }

GameShader& setLightColor(const Vector3& f) {
setUniform(lightColorUniform, f);
Expand Down
13 changes: 6 additions & 7 deletions src/GameState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ namespace MagnumGame {
_debugDraw.setMode(BulletIntegration::DebugDraw::Mode::DrawWireframe);
_bWorld.setDebugDrawer(&_debugDraw);

Float near = 0.1f, far = 128.0f;
_cameraController.emplace(_scene, near, far);
Range1D zPlanes{0.1f, 128.0f};
_cameraController.emplace(_scene, zPlanes);

_debugResourceManager.set(DebugRendererGroup, DebugTools::ObjectRendererOptions{}.setSize(1.f));

_shadowLight.emplace(_scene, 4, near, far);
_shadowLight.emplace(_scene, zPlanes, GameAssets::ShadowMapLevels, GameAssets::ShadowMapResolution);

}

Expand Down Expand Up @@ -234,10 +234,9 @@ namespace MagnumGame {
&_animatorDrawables, &_opaqueDrawables);

for (auto& meshDrawable : animator->meshDrawables()) {
auto& skinMeshObject3D = dynamic_cast<Object3D &>(meshDrawable.get().object());
skinMeshObject3D.addFeature<ShadowCasterDrawable>(_assets.getAnimatedShadowCasterShader(), _shadowCasterDrawables)
.setMesh(&meshDrawable.get().getMesh())
.setSkinMeshDrawable(meshDrawable.get().getSkinMeshDrawable());
meshDrawable->getObject3D().addFeature<ShadowCasterDrawable>(_assets.getAnimatedShadowCasterShader(), _shadowCasterDrawables)
.setMesh(&meshDrawable.get().getMesh())
.setSkinMeshDrawable(meshDrawable.get().getSkinMeshDrawable());
}

animationOffset.setTransformation(Matrix4::translation({0, -0.4f, 0}));
Expand Down
6 changes: 4 additions & 2 deletions src/ShadowLight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ namespace MagnumGame {

using namespace Magnum::GL;

ShadowLight::ShadowLight(Object3D& parent, int numShadowLevels, Float zNear, Float zFar)
ShadowLight::ShadowLight(Object3D& parent, Range1D zPlanes, int numShadowLevels, Vector2i shadowMapSize)
: Object3D(&parent)
, _numLayers(numShadowLevels)
, _camera(addFeature<SceneGraph::Camera3D>())
{
Range2Di viewport = {{0, 0}, {1024, 1024}};
Range2Di viewport = {{0, 0}, shadowMapSize};
_shadowTexture.emplace();
_shadowTexture->setLabel("Shadow texture");
// shadowTexture.setStorage(1, Magnum::TextureFormat::DepthComponent, shadowFramebuffer.viewport().size());
Expand All @@ -52,6 +52,8 @@ ShadowLight::ShadowLight(Object3D& parent, int numShadowLevels, Float zNear, Flo
Debug() << "Framebuffer status: read=" << shadowFramebuffer.checkStatus(FramebufferTarget::Read) << " draw=" << shadowFramebuffer.checkStatus(FramebufferTarget::Draw);
}

auto zNear = zPlanes.min();
auto zFar = zPlanes.max();
_cutPlanes = {};
arrayReserve(_cutPlanes, _numLayers);
//props http://stackoverflow.com/a/33465663
Expand Down
2 changes: 1 addition & 1 deletion src/ShadowLight.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace MagnumGame {
class ShadowLight : public Object3D
{
public:
ShadowLight(Object3D& parent, int numShadowLevels, Float near, Float far);
ShadowLight(Object3D& parent, Range1D zPlanes, int numShadowLevels, Vector2i shadowMapSize);
~ShadowLight() override;

void setTarget(Vector3 lightDirection, Vector3 screenDirection, const Matrix4& inverseModelViewProjection);
Expand Down
Loading

0 comments on commit 90d3e0a

Please sign in to comment.