From 4ee45c9c28d16e9afe8e92f40ef5b603bc145c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 12:41:32 +0200 Subject: [PATCH 01/18] putting shaders changes on a new branch to avoid merge nightmare --- lib/Ray/CMakeLists.txt | 2 +- lib/Ray/sources/Exceptions/RayError.cpp | 5 +++ lib/Ray/sources/Exceptions/RayError.hpp | 17 ++++++++ lib/Ray/sources/Shaders/Shaders.cpp | 49 ++++++++++++++++++++++ lib/Ray/sources/Shaders/Shaders.hpp | 55 +++++++++++++++++++++++++ lib/Ray/sources/Utils/Cache.hpp | 42 ++++++++++++++++++- 6 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 lib/Ray/sources/Shaders/Shaders.cpp create mode 100644 lib/Ray/sources/Shaders/Shaders.hpp diff --git a/lib/Ray/CMakeLists.txt b/lib/Ray/CMakeLists.txt index d713eb1e..9a55f6be 100644 --- a/lib/Ray/CMakeLists.txt +++ b/lib/Ray/CMakeLists.txt @@ -97,7 +97,7 @@ set(SRC sources/Model/ModelAnimations.cpp sources/Vector/Vector2.cpp sources/Vector/Vector3.cpp -) + sources/Shaders/Shaders.cpp sources/Shaders/Shaders.hpp) find_package(raylib QUIET) if (NOT raylib_FOUND) diff --git a/lib/Ray/sources/Exceptions/RayError.cpp b/lib/Ray/sources/Exceptions/RayError.cpp index bc2ba888..a4de1200 100644 --- a/lib/Ray/sources/Exceptions/RayError.cpp +++ b/lib/Ray/sources/Exceptions/RayError.cpp @@ -21,3 +21,8 @@ RAY::Exception::NotCompatibleError::NotCompatibleError(const std::string &expect RayError(expectionMessage) { } + +RAY::Exception::WrongInputError::WrongInputError(const std::string &what): + RayError(what) +{ +} diff --git a/lib/Ray/sources/Exceptions/RayError.hpp b/lib/Ray/sources/Exceptions/RayError.hpp index f700ac17..158640d6 100644 --- a/lib/Ray/sources/Exceptions/RayError.hpp +++ b/lib/Ray/sources/Exceptions/RayError.hpp @@ -59,6 +59,23 @@ namespace RAY::Exception { //! @brief A default assignment operator NotSupportedError &operator=(const NotSupportedError &) = default; }; + + + //! @brief exception used when an non-supported operation is done + class WrongInputError: public RayError { + public: + //! @brief Create a new exception instance + explicit WrongInputError(const std::string &what = "The input can't be proceed"); + + //! @brief A default destructor + ~WrongInputError() override = default; + + //! @brief An exception is copy constructable + WrongInputError(const WrongInputError &) = default; + + //! @brief A default assignment operator + WrongInputError &operator=(const WrongInputError &) = default; + }; } #endif /* !RAYERROR_HPP_ */ diff --git a/lib/Ray/sources/Shaders/Shaders.cpp b/lib/Ray/sources/Shaders/Shaders.cpp new file mode 100644 index 00000000..435b4f72 --- /dev/null +++ b/lib/Ray/sources/Shaders/Shaders.cpp @@ -0,0 +1,49 @@ +// +// Created by cbihan on 04/06/2021. +// + +#include "Shaders.hpp" + +#include +#include "Exceptions/RayError.hpp" + +namespace RAY +{ + Cache<::Shader> Shader::_shadersCache(LoadShader, UnloadShader); + + + Shader::Shader(const std::string &vertexFile, const std::string &fragmentFile) + : _vertexFile(vertexFile), + _fragmentFile(fragmentFile), + _rayLibShader(_shadersCache.fetch(vertexFile, fragmentFile)) + { + } + + const std::shared_ptr<::Shader> &Shader::getShaderPtr() const + { + return this->_rayLibShader; + } + + void Shader::setShaderUniformVar(const std::string &varName, float value) + { + if (this->_shaderIndexVars.find(varName) == this->_shaderIndexVars.end()) { + int varShaderIndex = GetShaderLocation(*this->_rayLibShader, varName.c_str()); + + if (varShaderIndex < 0) { + throw Exception::WrongInputError("The loaded shader doesn't have a variable called: " + varName); + } + this->_shaderIndexVars[varName] = varShaderIndex; + } + SetShaderValue(*this->_rayLibShader, this->_shaderIndexVars[varName], &value, SHADER_UNIFORM_FLOAT); + } + + void Shader::BeginUsingCustomShader(Shader &shader) + { + BeginShaderMode(*shader.getShaderPtr()); + } + + void Shader::EndUsingCustomShader() + { + EndShaderMode(); + } +} \ No newline at end of file diff --git a/lib/Ray/sources/Shaders/Shaders.hpp b/lib/Ray/sources/Shaders/Shaders.hpp new file mode 100644 index 00000000..529eea64 --- /dev/null +++ b/lib/Ray/sources/Shaders/Shaders.hpp @@ -0,0 +1,55 @@ +// +// Created by cbihan on 04/06/2021. +// + +#pragma once + +#include +#include +#include +#include +#include "Utils/Cache.hpp" + +namespace RAY +{ + class Shader + { + private: + //! @brief The vertex file of the shader + std::string _vertexFile; + //! @brief The fragment file of the shader + std::string _fragmentFile; + + //! @brief Raylib shader struct + std::shared_ptr<::Shader> _rayLibShader; + + //! @brief Fetch and cache the index of the shader variable on the first set of the var + std::map _shaderIndexVars = {}; + + static Cache<::Shader> _shadersCache; + public: + //INTERNAL: + const std::shared_ptr<::Shader> &getShaderPtr() const; + + public: + + //! @brief start using a custom shader when drawing + static void BeginUsingCustomShader(RAY::Shader &shader); + //! @brief stop using the custom shader + static void EndUsingCustomShader(); + + //! @brief The set var for float values + //! @note Throw if the var is not found + void setShaderUniformVar(const std::string &varName, float value); + + //! @brief ctor if no vertexfile in needed set it to nullptr + Shader(const std::string &vertexFile, const std::string &fragmentFile); + //! @brief Default copy ctor + Shader(const Shader &) = default; + //! @brief dtor + ~Shader() = default; + //! @brief Assignment operator + Shader &operator=(const Shader &) = default; + }; + +} \ No newline at end of file diff --git a/lib/Ray/sources/Utils/Cache.hpp b/lib/Ray/sources/Utils/Cache.hpp index 653933f5..8ecbde29 100644 --- a/lib/Ray/sources/Utils/Cache.hpp +++ b/lib/Ray/sources/Utils/Cache.hpp @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include "Exceptions/RayError.hpp" namespace RAY { //! @brief A templated class used to cache ressources, indexed with a string @@ -57,7 +59,7 @@ namespace RAY { class Cache<::ModelAnimation> { public: Cache(std::function<::ModelAnimation *(const char *, int *)> dataLoader, std::functiondataUnloader): - _dataLoader(dataLoader), _dataUnloader(dataUnloader) + _dataLoader(std::move(dataLoader)), _dataUnloader(std::move(dataUnloader)) {}; std::shared_ptr<::ModelAnimation> fetch(const std::string &path, int *counter) { @@ -83,4 +85,42 @@ namespace RAY { //! @brief map storing shared ptr of caches std::unordered_map> _cache; }; + + template<> + class Cache<::Shader> + { + public: + Cache(std::function<::Shader(const char *, const char *)> dataLoader, + std::function dataUnloader) : + _dataLoader(std::move(dataLoader)), _dataUnloader(std::move(dataUnloader)) + {}; + + std::shared_ptr<::Shader> fetch(const std::string &vertexFile, const std::string &fragmentFile) + { + const std::string index = vertexFile + fragmentFile; + + if (vertexFile.empty() && fragmentFile.empty()) { + throw RAY::Exception::WrongInputError(); + } + if (this->_cache.find(index) != this->_cache.end()) + return this->_cache[index]; + + this->_cache.emplace(index, std::shared_ptr<::Shader>( + new ::Shader( + this->_dataLoader(vertexFile.empty() ? nullptr : vertexFile.c_str(), fragmentFile.c_str())), + [this](::Shader *p) { + this->_dataUnloader(*p); + })); + return this->_cache[index]; + }; + private: + //! @brief function to call to load data + std::function<::Shader(const char *, const char *)> _dataLoader; + + //! @brief function to call when the ray data will be unloaded + std::function _dataUnloader; + + //! @brief map storing shared ptr of caches + std::unordered_map> _cache; + }; } From d738848eb000a80a4ca812587f98c5ba95d838fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 12:44:52 +0200 Subject: [PATCH 02/18] readding ShaderComponent.cpp/hpp --- CMakeLists.txt | 108 +++++++++--------- sources/Component/Shaders/ShaderComponent.cpp | 49 ++++++++ sources/Component/Shaders/ShaderComponent.hpp | 78 +++++++++++++ sources/Runner/Runner.cpp | 2 + 4 files changed, 183 insertions(+), 54 deletions(-) create mode 100644 sources/Component/Shaders/ShaderComponent.cpp create mode 100644 sources/Component/Shaders/ShaderComponent.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dfb4cd6f..6bcfed49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,60 +20,60 @@ if (EMSCRIPTEN) endif () set(SOURCES - sources/Models/GameState.hpp - sources/Runner/Runner.cpp - sources/Runner/Runner.hpp - sources/Map/Map.cpp - sources/Map/Map.hpp - sources/Component/Position/PositionComponent.cpp - sources/Component/Position/PositionComponent.hpp - sources/Component/Movable/MovableComponent.cpp - sources/Component/Movable/MovableComponent.hpp - sources/Component/Controllable/ControllableComponent.hpp - sources/Component/Controllable/ControllableComponent.cpp - sources/Component/Gamepad/GamepadComponent.cpp - sources/Component/Gamepad/GamepadComponent.hpp - sources/Component/Keyboard/KeyboardComponent.cpp - sources/Component/Keyboard/KeyboardComponent.hpp - sources/Component/Health/HealthComponent.cpp - sources/Component/Health/HealthComponent.hpp - sources/System/Movable/MovableSystem.hpp - sources/System/Movable/MovableSystem.cpp - sources/System/Controllable/ControllableSystem.cpp - sources/System/Controllable/ControllableSystem.hpp - sources/System/Gamepad/GamepadSystem.cpp - sources/System/Gamepad/GamepadSystem.hpp - sources/System/Health/HealthSystem.cpp - sources/System/Health/HealthSystem.hpp - sources/System/Keyboard/KeyboardSystem.cpp - sources/System/Keyboard/KeyboardSystem.hpp - sources/System/Movable/MovableSystem.cpp - sources/System/Movable/MovableSystem.hpp - sources/Models/Vector3.hpp - sources/Component/GridCentered/GridCenteredComponent.cpp - sources/Component/GridCentered/GridCenteredComponent.hpp - sources/System/GridCentered/GridCenteredSystem.cpp - sources/System/GridCentered/GridCenteredSystem.hpp - sources/Models/Vector2.hpp - sources/Component/Renderer/Drawable2DComponent.hpp - sources/Component/Renderer/Drawable3DComponent.hpp - sources/System/Renderer/RenderSystem.hpp - sources/System/Renderer/RenderSystem.cpp - sources/Component/Renderer/CameraComponent.cpp - sources/Component/Renderer/CameraComponent.hpp - sources/Component/Animation/AnimationsComponent.cpp - sources/Component/Animation/AnimationsComponent.hpp - sources/System/Animation/AnimationsSystem.cpp - sources/System/Animation/AnimationsSystem.hpp - sources/Component/Collision/CollisionComponent.cpp - sources/Component/Collision/CollisionComponent.hpp - sources/System/Collision/CollisionSystem.hpp - sources/System/Collision/CollisionSystem.cpp - sources/Component/Animator/AnimatorComponent.cpp - sources/Component/Animator/AnimatorComponent.hpp - sources/System/Animator/AnimatorSystem.cpp - sources/System/Animator/AnimatorSystem.hpp -) + sources/Models/GameState.hpp + sources/Runner/Runner.cpp + sources/Runner/Runner.hpp + sources/Map/Map.cpp + sources/Map/Map.hpp + sources/Component/Position/PositionComponent.cpp + sources/Component/Position/PositionComponent.hpp + sources/Component/Movable/MovableComponent.cpp + sources/Component/Movable/MovableComponent.hpp + sources/Component/Controllable/ControllableComponent.hpp + sources/Component/Controllable/ControllableComponent.cpp + sources/Component/Gamepad/GamepadComponent.cpp + sources/Component/Gamepad/GamepadComponent.hpp + sources/Component/Keyboard/KeyboardComponent.cpp + sources/Component/Keyboard/KeyboardComponent.hpp + sources/Component/Health/HealthComponent.cpp + sources/Component/Health/HealthComponent.hpp + sources/System/Movable/MovableSystem.hpp + sources/System/Movable/MovableSystem.cpp + sources/System/Controllable/ControllableSystem.cpp + sources/System/Controllable/ControllableSystem.hpp + sources/System/Gamepad/GamepadSystem.cpp + sources/System/Gamepad/GamepadSystem.hpp + sources/System/Health/HealthSystem.cpp + sources/System/Health/HealthSystem.hpp + sources/System/Keyboard/KeyboardSystem.cpp + sources/System/Keyboard/KeyboardSystem.hpp + sources/System/Movable/MovableSystem.cpp + sources/System/Movable/MovableSystem.hpp + sources/Models/Vector3.hpp + sources/Component/GridCentered/GridCenteredComponent.cpp + sources/Component/GridCentered/GridCenteredComponent.hpp + sources/System/GridCentered/GridCenteredSystem.cpp + sources/System/GridCentered/GridCenteredSystem.hpp + sources/Models/Vector2.hpp + sources/Component/Renderer/Drawable2DComponent.hpp + sources/Component/Renderer/Drawable3DComponent.hpp + sources/System/Renderer/RenderSystem.hpp + sources/System/Renderer/RenderSystem.cpp + sources/Component/Renderer/CameraComponent.cpp + sources/Component/Renderer/CameraComponent.hpp + sources/Component/Animation/AnimationsComponent.cpp + sources/Component/Animation/AnimationsComponent.hpp + sources/System/Animation/AnimationsSystem.cpp + sources/System/Animation/AnimationsSystem.hpp + sources/Component/Collision/CollisionComponent.cpp + sources/Component/Collision/CollisionComponent.hpp + sources/System/Collision/CollisionSystem.hpp + sources/System/Collision/CollisionSystem.cpp + sources/Component/Animator/AnimatorComponent.cpp + sources/Component/Animator/AnimatorComponent.hpp + sources/System/Animator/AnimatorSystem.cpp + sources/System/Animator/AnimatorSystem.hpp + sources/Component/Shaders/ShaderComponent.cpp sources/Component/Shaders/ShaderComponent.hpp) add_executable(bomberman sources/main.cpp ${SOURCES} diff --git a/sources/Component/Shaders/ShaderComponent.cpp b/sources/Component/Shaders/ShaderComponent.cpp new file mode 100644 index 00000000..a87068b6 --- /dev/null +++ b/sources/Component/Shaders/ShaderComponent.cpp @@ -0,0 +1,49 @@ +// +// Created by cbihan on 03/06/2021. +// + +#include "ShaderComponent.hpp" + +#include + +namespace BBM +{ + WAL::Component *ShaderComponent::clone(WAL::Entity &entity) const + { + return new ShaderComponent(*this); + } + + RAY::Shader &ShaderComponent::getShader() + { + return this->_shader; + } + + ShaderComponent::ShaderComponent(WAL::Entity &entity, const std::string &fragmentFilePath, const std::string &vertexFilePath) + : WAL::Component(entity), + _refEntity(entity), + _shader(vertexFilePath, fragmentFilePath), + _fragmentFilePath(fragmentFilePath), + _vertexFilePath(vertexFilePath) + { + } + + std::string ShaderComponent::getFragmentFilePath() const + { + return this->_fragmentFilePath; + } + + std::string ShaderComponent::getVertexFilePath() const + { + return this->_vertexFilePath; + } + + ShaderComponentModel::ShaderComponentModel(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath) + : ShaderComponent(entity, std::move(fragmentFilePath), std::move(vertexFilePath)) + { + } + + ShaderComponentDrawable::ShaderComponentDrawable(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath) + : ShaderComponent(entity, std::move(fragmentFilePath), std::move(vertexFilePath)) + { + } +} \ No newline at end of file diff --git a/sources/Component/Shaders/ShaderComponent.hpp b/sources/Component/Shaders/ShaderComponent.hpp new file mode 100644 index 00000000..c20a7e6c --- /dev/null +++ b/sources/Component/Shaders/ShaderComponent.hpp @@ -0,0 +1,78 @@ +// +// Created by cbihan on 03/06/2021. +// + +#pragma once + +#include +#include +#include +#include + +namespace BBM +{ + class ShaderComponent : public WAL::Component + { + private: + //! @brief efefefefez + WAL::Entity &_refEntity; + + //! @brief The shader to be applied + RAY::Shader _shader; + //! @brief The path to the fragment file + std::string _fragmentFilePath; + //! @brief The path to the vertex file + std::string _vertexFilePath; + public: + //! @brief getter for _shader + RAY::Shader &getShader(); + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief get the fragment file path + std::string getFragmentFilePath() const; + + + //! @brief get the fragment file path + std::string getVertexFilePath() const; + + //! @brief ctor + //! @note use empty string to omit a file + ShaderComponent(WAL::Entity &entity, const std::string& fragmentFilePath, const std::string& vertexFilePath = ""); + //! @brief Default copy ctor + ShaderComponent(const ShaderComponent &) = default; + //! @brief Default dtor + ~ShaderComponent() override = default; + //! @brief Default assignment operator + ShaderComponent &operator=(const ShaderComponent &) = delete; + }; + + class ShaderComponentModel : public ShaderComponent + { + public: + //! @brief ctor + //! @note use empty string to omit a file + ShaderComponentModel(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath = ""); + //! @brief Default copy ctor + ShaderComponentModel(const ShaderComponentModel &) = default; + //! @brief Default dtor + ~ShaderComponentModel() override = default; + //! @brief Default assignment operator + ShaderComponentModel &operator=(const ShaderComponentModel &) = delete; + }; + + class ShaderComponentDrawable : public ShaderComponent + { + public: + //! @brief ctor + //! @note use empty string to omit a file + ShaderComponentDrawable(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath = ""); + //! @brief Default copy ctor + ShaderComponentDrawable(const ShaderComponentDrawable &) = default; + //! @brief Default dtor + ~ShaderComponentDrawable() override = default; + //! @brief Default assignment operator + ShaderComponentDrawable &operator=(const ShaderComponentDrawable &) = delete; + }; +} \ No newline at end of file diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index ab953439..e6a0dc33 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -26,6 +26,7 @@ #include #include "Component/Animation/AnimationsComponent.hpp" #include "System/Animation/AnimationsSystem.hpp" +#include "Component/Shaders/ShaderComponent.hpp" #include "Map/Map.hpp" namespace RAY3D = RAY::Drawables::Drawables3D; @@ -69,6 +70,7 @@ namespace BBM .addComponent() .addComponent() .addComponent() + .addComponent("assets/shaders/glsl330/predator.fs") .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 3) .addComponent(1) .addComponent() From 8a729414f5a914513c316e58217610a252c94acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 12:46:09 +0200 Subject: [PATCH 03/18] adding shaders assets --- assets/shaders/basic_shader.fs | 33 ++ assets/shaders/basic_shader.vs | 218 +++++++++ assets/shaders/glsl100/base.fs | 23 + assets/shaders/glsl100/base.vs | 26 ++ assets/shaders/glsl100/base_lighting.vs | 59 +++ .../glsl100/base_lighting_instanced.vs | 62 +++ assets/shaders/glsl100/bloom.fs | 39 ++ assets/shaders/glsl100/blur.fs | 34 ++ assets/shaders/glsl100/color_mix.fs | 26 ++ assets/shaders/glsl100/cross_hatching.fs | 47 ++ assets/shaders/glsl100/cross_stitching.fs | 57 +++ assets/shaders/glsl100/cubes_panning.fs | 60 +++ assets/shaders/glsl100/depth.fs | 26 ++ assets/shaders/glsl100/distortion.fs | 54 +++ assets/shaders/glsl100/dream_vision.fs | 37 ++ assets/shaders/glsl100/eratosthenes.fs | 60 +++ assets/shaders/glsl100/fisheye.fs | 43 ++ assets/shaders/glsl100/fog.fs | 94 ++++ assets/shaders/glsl100/grayscale.fs | 25 + assets/shaders/glsl100/julia_set.fs | 83 ++++ assets/shaders/glsl100/lighting.fs | 81 ++++ assets/shaders/glsl100/mask.fs | 24 + assets/shaders/glsl100/palette_switch.fs | 41 ++ assets/shaders/glsl100/pixelizer.fs | 32 ++ assets/shaders/glsl100/posterization.fs | 29 ++ assets/shaders/glsl100/predator.fs | 31 ++ assets/shaders/glsl100/raymarching.fs | 429 +++++++++++++++++ assets/shaders/glsl100/reload.fs | 39 ++ assets/shaders/glsl100/scanlines.fs | 44 ++ assets/shaders/glsl100/sobel.fs | 40 ++ assets/shaders/glsl100/spotlight.fs | 77 ++++ assets/shaders/glsl100/swirl.fs | 46 ++ assets/shaders/glsl100/wave.fs | 36 ++ assets/shaders/glsl120/base.fs | 22 + assets/shaders/glsl120/base.vs | 26 ++ assets/shaders/glsl120/base_lighting.vs | 59 +++ assets/shaders/glsl120/bloom.fs | 37 ++ assets/shaders/glsl120/blur.fs | 32 ++ assets/shaders/glsl120/cross_hatching.fs | 45 ++ assets/shaders/glsl120/cross_stitching.fs | 55 +++ assets/shaders/glsl120/distortion.fs | 52 +++ assets/shaders/glsl120/dream_vision.fs | 35 ++ assets/shaders/glsl120/fisheye.fs | 41 ++ assets/shaders/glsl120/fog.fs | 92 ++++ assets/shaders/glsl120/grayscale.fs | 23 + assets/shaders/glsl120/palette_switch.fs | 27 ++ assets/shaders/glsl120/pixelizer.fs | 30 ++ assets/shaders/glsl120/posterization.fs | 27 ++ assets/shaders/glsl120/predator.fs | 29 ++ assets/shaders/glsl120/scanlines.fs | 42 ++ assets/shaders/glsl120/sobel.fs | 38 ++ assets/shaders/glsl120/swirl.fs | 44 ++ assets/shaders/glsl330/base.fs | 25 + assets/shaders/glsl330/base.vs | 26 ++ assets/shaders/glsl330/base_lighting.vs | 32 ++ .../glsl330/base_lighting_instanced.vs | 36 ++ assets/shaders/glsl330/bloom.fs | 40 ++ assets/shaders/glsl330/blur.fs | 35 ++ assets/shaders/glsl330/color_mix.fs | 27 ++ assets/shaders/glsl330/cross_hatching.fs | 49 ++ assets/shaders/glsl330/cross_stitching.fs | 60 +++ assets/shaders/glsl330/cubes_panning.fs | 61 +++ assets/shaders/glsl330/depth.fs | 27 ++ assets/shaders/glsl330/distortion.fs | 56 +++ assets/shaders/glsl330/dream_vision.fs | 34 ++ assets/shaders/glsl330/eratosthenes.fs | 59 +++ assets/shaders/glsl330/fisheye.fs | 40 ++ assets/shaders/glsl330/fog.fs | 95 ++++ assets/shaders/glsl330/grayscale.fs | 26 ++ assets/shaders/glsl330/julia_set.fs | 81 ++++ assets/shaders/glsl330/lighting.fs | 82 ++++ assets/shaders/glsl330/mask.fs | 22 + assets/shaders/glsl330/overdraw.fs | 26 ++ assets/shaders/glsl330/palette_switch.fs | 30 ++ assets/shaders/glsl330/pixelizer.fs | 33 ++ assets/shaders/glsl330/posterization.fs | 32 ++ assets/shaders/glsl330/predator.fs | 32 ++ assets/shaders/glsl330/raymarching.fs | 430 ++++++++++++++++++ assets/shaders/glsl330/reload.fs | 40 ++ assets/shaders/glsl330/scanlines.fs | 49 ++ assets/shaders/glsl330/sobel.fs | 41 ++ assets/shaders/glsl330/spotlight.fs | 65 +++ assets/shaders/glsl330/swirl.fs | 47 ++ assets/shaders/glsl330/wave.fs | 37 ++ 84 files changed, 4586 insertions(+) create mode 100644 assets/shaders/basic_shader.fs create mode 100644 assets/shaders/basic_shader.vs create mode 100644 assets/shaders/glsl100/base.fs create mode 100644 assets/shaders/glsl100/base.vs create mode 100644 assets/shaders/glsl100/base_lighting.vs create mode 100644 assets/shaders/glsl100/base_lighting_instanced.vs create mode 100644 assets/shaders/glsl100/bloom.fs create mode 100644 assets/shaders/glsl100/blur.fs create mode 100644 assets/shaders/glsl100/color_mix.fs create mode 100644 assets/shaders/glsl100/cross_hatching.fs create mode 100644 assets/shaders/glsl100/cross_stitching.fs create mode 100644 assets/shaders/glsl100/cubes_panning.fs create mode 100644 assets/shaders/glsl100/depth.fs create mode 100644 assets/shaders/glsl100/distortion.fs create mode 100644 assets/shaders/glsl100/dream_vision.fs create mode 100644 assets/shaders/glsl100/eratosthenes.fs create mode 100644 assets/shaders/glsl100/fisheye.fs create mode 100644 assets/shaders/glsl100/fog.fs create mode 100644 assets/shaders/glsl100/grayscale.fs create mode 100644 assets/shaders/glsl100/julia_set.fs create mode 100644 assets/shaders/glsl100/lighting.fs create mode 100644 assets/shaders/glsl100/mask.fs create mode 100644 assets/shaders/glsl100/palette_switch.fs create mode 100644 assets/shaders/glsl100/pixelizer.fs create mode 100644 assets/shaders/glsl100/posterization.fs create mode 100644 assets/shaders/glsl100/predator.fs create mode 100644 assets/shaders/glsl100/raymarching.fs create mode 100644 assets/shaders/glsl100/reload.fs create mode 100644 assets/shaders/glsl100/scanlines.fs create mode 100644 assets/shaders/glsl100/sobel.fs create mode 100644 assets/shaders/glsl100/spotlight.fs create mode 100644 assets/shaders/glsl100/swirl.fs create mode 100644 assets/shaders/glsl100/wave.fs create mode 100644 assets/shaders/glsl120/base.fs create mode 100644 assets/shaders/glsl120/base.vs create mode 100644 assets/shaders/glsl120/base_lighting.vs create mode 100644 assets/shaders/glsl120/bloom.fs create mode 100644 assets/shaders/glsl120/blur.fs create mode 100644 assets/shaders/glsl120/cross_hatching.fs create mode 100644 assets/shaders/glsl120/cross_stitching.fs create mode 100644 assets/shaders/glsl120/distortion.fs create mode 100644 assets/shaders/glsl120/dream_vision.fs create mode 100644 assets/shaders/glsl120/fisheye.fs create mode 100644 assets/shaders/glsl120/fog.fs create mode 100644 assets/shaders/glsl120/grayscale.fs create mode 100644 assets/shaders/glsl120/palette_switch.fs create mode 100644 assets/shaders/glsl120/pixelizer.fs create mode 100644 assets/shaders/glsl120/posterization.fs create mode 100644 assets/shaders/glsl120/predator.fs create mode 100644 assets/shaders/glsl120/scanlines.fs create mode 100644 assets/shaders/glsl120/sobel.fs create mode 100644 assets/shaders/glsl120/swirl.fs create mode 100644 assets/shaders/glsl330/base.fs create mode 100644 assets/shaders/glsl330/base.vs create mode 100644 assets/shaders/glsl330/base_lighting.vs create mode 100644 assets/shaders/glsl330/base_lighting_instanced.vs create mode 100644 assets/shaders/glsl330/bloom.fs create mode 100644 assets/shaders/glsl330/blur.fs create mode 100644 assets/shaders/glsl330/color_mix.fs create mode 100644 assets/shaders/glsl330/cross_hatching.fs create mode 100644 assets/shaders/glsl330/cross_stitching.fs create mode 100644 assets/shaders/glsl330/cubes_panning.fs create mode 100644 assets/shaders/glsl330/depth.fs create mode 100644 assets/shaders/glsl330/distortion.fs create mode 100644 assets/shaders/glsl330/dream_vision.fs create mode 100644 assets/shaders/glsl330/eratosthenes.fs create mode 100644 assets/shaders/glsl330/fisheye.fs create mode 100644 assets/shaders/glsl330/fog.fs create mode 100644 assets/shaders/glsl330/grayscale.fs create mode 100644 assets/shaders/glsl330/julia_set.fs create mode 100644 assets/shaders/glsl330/lighting.fs create mode 100644 assets/shaders/glsl330/mask.fs create mode 100644 assets/shaders/glsl330/overdraw.fs create mode 100644 assets/shaders/glsl330/palette_switch.fs create mode 100644 assets/shaders/glsl330/pixelizer.fs create mode 100644 assets/shaders/glsl330/posterization.fs create mode 100644 assets/shaders/glsl330/predator.fs create mode 100644 assets/shaders/glsl330/raymarching.fs create mode 100644 assets/shaders/glsl330/reload.fs create mode 100644 assets/shaders/glsl330/scanlines.fs create mode 100644 assets/shaders/glsl330/sobel.fs create mode 100644 assets/shaders/glsl330/spotlight.fs create mode 100644 assets/shaders/glsl330/swirl.fs create mode 100644 assets/shaders/glsl330/wave.fs diff --git a/assets/shaders/basic_shader.fs b/assets/shaders/basic_shader.fs new file mode 100644 index 00000000..241d07a7 --- /dev/null +++ b/assets/shaders/basic_shader.fs @@ -0,0 +1,33 @@ +#version 330 +precision highp float; +precision highp int; + +varying float noise; + +//uniform float brightness; + +float random( vec3 scale, float seed ) { + return fract( sin( dot( gl_FragCoord.xyz + seed, scale ) ) * 43758.5453 + seed ) ; +} + +vec3 mult(vec3 a, vec3 b){ + return vec3(a.r *b.r, a.g * b.g, a.b * b.b); +} + +void main() { + + brightness = 0.86080327; + // get a random offset + float offset = .01 * random( vec3( 12.9898, 78.233, 0151.7182 ), 0.0 ); + + // not quite depth, but how bright the sphere is (higher is dimmer) + float depth = 0.25; + + // lookup vertically in the texture, using noise and offset + // to get the right RGB colour + vec2 tPos = vec2( 0, ( brightness + depth ) * noise + offset ); + // vec4 color = texture2D( tExplosion, ( brightness - depth ) - tPos ); + vec3 color = mult(vec3(0, 1, 0), vec3( ( brightness - depth ) - tPos.y )); + gl_FragColor = vec4( color, 1.0 ); + +} diff --git a/assets/shaders/basic_shader.vs b/assets/shaders/basic_shader.vs new file mode 100644 index 00000000..6a7846d8 --- /dev/null +++ b/assets/shaders/basic_shader.vs @@ -0,0 +1,218 @@ +#version 330 +precision highp float; +precision highp int; + +//uniform mat4 modelMatrix; +uniform mat4 view; +uniform mat4 projection; +uniform mat4 viewMatrix; +//uniform mat3 matNormal; + +attribute vec3 vertexPosition; +attribute vec3 vertexNormal; +//attribute vec2 uv; +//attribute vec2 uv2; + +varying float noise; +uniform float time; +uniform float fireSpeed; +uniform float pulseHeight; +uniform float displacementHeight; +uniform float turbulenceDetail; + +// +// GLSL textureless classic 3D noise "cnoise", +// with an RSL-style periodic variant "pnoise". +// Author: Stefan Gustavson (stefan.gustavson@liu.se) +// Version: 2011-10-11 +// +// Many thanks to Ian McEwan of Ashima Arts for the +// ideas for permutation and gradient selection. +// +// Copyright (c) 2011 Stefan Gustavson. All rights reserved. +// Distributed under the MIT license. See LICENSE file. +// https://github.com/ashima/webgl-noise +// + +vec3 mod289(vec3 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 mod289(vec4 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 permute(vec4 x) { + return mod289(((x*34.0)+1.0)*x); +} + +vec4 taylorInvSqrt(vec4 r) { + return 1.79284291400159 - 0.85373472095314 * r; +} + +vec3 fade(vec3 t) { + return t*t*t*(t*(t*6.0-15.0)+10.0); +} + +// Classic Perlin noise +float cnoise(vec3 P) { + vec3 Pi0 = floor(P); // Integer part for indexing + vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1 + Pi0 = mod289(Pi0); + Pi1 = mod289(Pi1); + vec3 Pf0 = fract(P); // Fractional part for interpolation + vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 + vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec4 iy = vec4(Pi0.yy, Pi1.yy); + vec4 iz0 = Pi0.zzzz; + vec4 iz1 = Pi1.zzzz; + + vec4 ixy = permute(permute(ix) + iy); + vec4 ixy0 = permute(ixy + iz0); + vec4 ixy1 = permute(ixy + iz1); + + vec4 gx0 = ixy0 * (1.0 / 7.0); + vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5; + gx0 = fract(gx0); + vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); + vec4 sz0 = step(gz0, vec4(0.0)); + gx0 -= sz0 * (step(0.0, gx0) - 0.5); + gy0 -= sz0 * (step(0.0, gy0) - 0.5); + + vec4 gx1 = ixy1 * (1.0 / 7.0); + vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5; + gx1 = fract(gx1); + vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); + vec4 sz1 = step(gz1, vec4(0.0)); + gx1 -= sz1 * (step(0.0, gx1) - 0.5); + gy1 -= sz1 * (step(0.0, gy1) - 0.5); + + vec3 g000 = vec3(gx0.x,gy0.x,gz0.x); + vec3 g100 = vec3(gx0.y,gy0.y,gz0.y); + vec3 g010 = vec3(gx0.z,gy0.z,gz0.z); + vec3 g110 = vec3(gx0.w,gy0.w,gz0.w); + vec3 g001 = vec3(gx1.x,gy1.x,gz1.x); + vec3 g101 = vec3(gx1.y,gy1.y,gz1.y); + vec3 g011 = vec3(gx1.z,gy1.z,gz1.z); + vec3 g111 = vec3(gx1.w,gy1.w,gz1.w); + + vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + float n000 = dot(g000, Pf0); + float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); + float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); + float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); + float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); + float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); + float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); + float n111 = dot(g111, Pf1); + + vec3 fade_xyz = fade(Pf0); + vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); + vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); + float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return 2.2 * n_xyz; +} + +// Classic Perlin noise, periodic variant +float pnoise(vec3 P, vec3 rep) { + vec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period + vec3 Pi1 = mod(Pi0 + vec3(1.0), rep); // Integer part + 1, mod period + Pi0 = mod289(Pi0); + Pi1 = mod289(Pi1); + vec3 Pf0 = fract(P); // Fractional part for interpolation + vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 + vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec4 iy = vec4(Pi0.yy, Pi1.yy); + vec4 iz0 = Pi0.zzzz; + vec4 iz1 = Pi1.zzzz; + + vec4 ixy = permute(permute(ix) + iy); + vec4 ixy0 = permute(ixy + iz0); + vec4 ixy1 = permute(ixy + iz1); + + vec4 gx0 = ixy0 * (1.0 / 7.0); + vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5; + gx0 = fract(gx0); + vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); + vec4 sz0 = step(gz0, vec4(0.0)); + gx0 -= sz0 * (step(0.0, gx0) - 0.5); + gy0 -= sz0 * (step(0.0, gy0) - 0.5); + + vec4 gx1 = ixy1 * (1.0 / 7.0); + vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5; + gx1 = fract(gx1); + vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); + vec4 sz1 = step(gz1, vec4(0.0)); + gx1 -= sz1 * (step(0.0, gx1) - 0.5); + gy1 -= sz1 * (step(0.0, gy1) - 0.5); + + vec3 g000 = vec3(gx0.x,gy0.x,gz0.x); + vec3 g100 = vec3(gx0.y,gy0.y,gz0.y); + vec3 g010 = vec3(gx0.z,gy0.z,gz0.z); + vec3 g110 = vec3(gx0.w,gy0.w,gz0.w); + vec3 g001 = vec3(gx1.x,gy1.x,gz1.x); + vec3 g101 = vec3(gx1.y,gy1.y,gz1.y); + vec3 g011 = vec3(gx1.z,gy1.z,gz1.z); + vec3 g111 = vec3(gx1.w,gy1.w,gz1.w); + + vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + float n000 = dot(g000, Pf0); + float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); + float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); + float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); + float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); + float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); + float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); + float n111 = dot(g111, Pf1); + + vec3 fade_xyz = fade(Pf0); + vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); + vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); + float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return 2.2 * n_xyz; +} + +// Include the Ashima code here! + +float turbulence( vec3 p ) { + float t = -0.5; + for (float f = 1.0 ; f <= 10.0 ; f++ ){ + float power = pow( 2.0, f ); + t += abs( pnoise( vec3( power * p ), vec3( 10.0, 10.0, 10.0 ) ) / power ); + } + return t; +} + +void main() { + + noise = -1.1 * turbulence( turbulenceDetail * vertexNormal + ( time * fireSpeed ) ); + + float b = pulseHeight * pnoise( + 0.05 * vertexPosition + vec3( 1.0 * time ), vec3( 100.0 ) + ); + float displacement = ( 0.0 - displacementHeight ) * noise + b; + + vec3 newvertexPosition = vertexPosition + vertexNormal * displacement; + gl_vertexPosition = projection * view * vec4( newvertexPosition, 1.0 ); + +} \ No newline at end of file diff --git a/assets/shaders/glsl100/base.fs b/assets/shaders/glsl100/base.fs new file mode 100644 index 00000000..c1126423 --- /dev/null +++ b/assets/shaders/glsl100/base.fs @@ -0,0 +1,23 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord); + + // NOTE: Implement here your fragment shader code + + gl_FragColor = texelColor*colDiffuse; +} \ No newline at end of file diff --git a/assets/shaders/glsl100/base.vs b/assets/shaders/glsl100/base.vs new file mode 100644 index 00000000..4be76b9e --- /dev/null +++ b/assets/shaders/glsl100/base.vs @@ -0,0 +1,26 @@ +#version 100 + +// Input vertex attributes +attribute vec3 vertexPosition; +attribute vec2 vertexTexCoord; +attribute vec3 vertexNormal; +attribute vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; + +// Output vertex attributes (to fragment shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/base_lighting.vs b/assets/shaders/glsl100/base_lighting.vs new file mode 100644 index 00000000..5245c615 --- /dev/null +++ b/assets/shaders/glsl100/base_lighting.vs @@ -0,0 +1,59 @@ +#version 100 + +// Input vertex attributes +attribute vec3 vertexPosition; +attribute vec2 vertexTexCoord; +attribute vec3 vertexNormal; +attribute vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; +uniform mat4 matModel; + +// Output vertex attributes (to fragment shader) +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +// NOTE: Add here your custom variables + +// https://github.com/glslify/glsl-inverse +mat3 inverse(mat3 m) +{ + float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2]; + float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2]; + float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2]; + + float b01 = a22*a11 - a12*a21; + float b11 = -a22*a10 + a12*a20; + float b21 = a21*a10 - a11*a20; + + float det = a00*b01 + a01*b11 + a02*b21; + + return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11), + b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10), + b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det; +} + +// https://github.com/glslify/glsl-transpose +mat3 transpose(mat3 m) +{ + return mat3(m[0][0], m[1][0], m[2][0], + m[0][1], m[1][1], m[2][1], + m[0][2], m[1][2], m[2][2]); +} + +void main() +{ + // Send vertex attributes to fragment shader + fragPosition = vec3(matModel*vec4(vertexPosition, 1.0)); + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + mat3 normalMatrix = transpose(inverse(mat3(matModel))); + fragNormal = normalize(normalMatrix*vertexNormal); + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +} diff --git a/assets/shaders/glsl100/base_lighting_instanced.vs b/assets/shaders/glsl100/base_lighting_instanced.vs new file mode 100644 index 00000000..c8e25607 --- /dev/null +++ b/assets/shaders/glsl100/base_lighting_instanced.vs @@ -0,0 +1,62 @@ +#version 100 + +// Input vertex attributes +attribute vec3 vertexPosition; +attribute vec2 vertexTexCoord; +attribute vec3 vertexNormal; +attribute vec4 vertexColor; + +attribute mat4 instance; + +// Input uniform values +uniform mat4 mvp; + +// Output vertex attributes (to fragment shader) +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +// NOTE: Add here your custom variables + +// https://github.com/glslify/glsl-inverse +mat3 inverse(mat3 m) +{ + float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2]; + float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2]; + float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2]; + + float b01 = a22*a11 - a12*a21; + float b11 = -a22*a10 + a12*a20; + float b21 = a21*a10 - a11*a20; + + float det = a00*b01 + a01*b11 + a02*b21; + + return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11), + b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10), + b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det; +} + +// https://github.com/glslify/glsl-transpose +mat3 transpose(mat3 m) +{ + return mat3(m[0][0], m[1][0], m[2][0], + m[0][1], m[1][1], m[2][1], + m[0][2], m[1][2], m[2][2]); +} + +void main() +{ + // Send vertex attributes to fragment shader + fragPosition = vec3(instance*vec4(vertexPosition, 1.0)); + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + mat3 normalMatrix = transpose(inverse(mat3(instance))); + fragNormal = normalize(normalMatrix*vertexNormal); + + mat4 mvpi = mvp*instance; + + // Calculate final vertex position + gl_Position = mvpi*vec4(vertexPosition, 1.0); +} diff --git a/assets/shaders/glsl100/bloom.fs b/assets/shaders/glsl100/bloom.fs new file mode 100644 index 00000000..673e0116 --- /dev/null +++ b/assets/shaders/glsl100/bloom.fs @@ -0,0 +1,39 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +const vec2 size = vec2(800, 450); // render size +const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance +const float quality = 2.5; // lower = smaller glow, better quality + +void main() +{ + vec4 sum = vec4(0); + vec2 sizeFactor = vec2(1)/size*quality; + + // Texel color fetching from texture sampler + vec4 source = texture2D(texture0, fragTexCoord); + + const int range = 2; // should be = (samples - 1)/2; + + for (int x = -range; x <= range; x++) + { + for (int y = -range; y <= range; y++) + { + sum += texture2D(texture0, fragTexCoord + vec2(x, y)*sizeFactor); + } + } + + // Calculate final fragment color + gl_FragColor = ((sum/(samples*samples)) + source)*colDiffuse; +} \ No newline at end of file diff --git a/assets/shaders/glsl100/blur.fs b/assets/shaders/glsl100/blur.fs new file mode 100644 index 00000000..96f780e1 --- /dev/null +++ b/assets/shaders/glsl100/blur.fs @@ -0,0 +1,34 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +// NOTE: Render size values must be passed from code +const float renderWidth = 800.0; +const float renderHeight = 450.0; + +vec3 offset = vec3(0.0, 1.3846153846, 3.2307692308); +vec3 weight = vec3(0.2270270270, 0.3162162162, 0.0702702703); + +void main() +{ + // Texel color fetching from texture sampler + vec3 tc = texture2D(texture0, fragTexCoord).rgb*weight.x; + + tc += texture2D(texture0, fragTexCoord + vec2(offset.y)/renderWidth, 0.0).rgb*weight.y; + tc += texture2D(texture0, fragTexCoord - vec2(offset.y)/renderWidth, 0.0).rgb*weight.y; + + tc += texture2D(texture0, fragTexCoord + vec2(offset.z)/renderWidth, 0.0).rgb*weight.z; + tc += texture2D(texture0, fragTexCoord - vec2(offset.z)/renderWidth, 0.0).rgb*weight.z; + + gl_FragColor = vec4(tc, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/color_mix.fs b/assets/shaders/glsl100/color_mix.fs new file mode 100644 index 00000000..c5c0cb70 --- /dev/null +++ b/assets/shaders/glsl100/color_mix.fs @@ -0,0 +1,26 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform sampler2D texture1; +uniform vec4 colDiffuse; + +uniform float divider; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor0 = texture2D(texture0, fragTexCoord); + vec4 texelColor1 = texture2D(texture1, fragTexCoord); + + float x = fract(fragTexCoord.s); + float final = smoothstep(divider - 0.1, divider + 0.1, x); + + gl_FragColor = mix(texelColor0, texelColor1, final); +} diff --git a/assets/shaders/glsl100/cross_hatching.fs b/assets/shaders/glsl100/cross_hatching.fs new file mode 100644 index 00000000..7d63b0a5 --- /dev/null +++ b/assets/shaders/glsl100/cross_hatching.fs @@ -0,0 +1,47 @@ +# version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +float hatchOffsetY = 5.0; +float lumThreshold01 = 0.9; +float lumThreshold02 = 0.7; +float lumThreshold03 = 0.5; +float lumThreshold04 = 0.3; + +void main() +{ + vec3 tc = vec3(1.0, 1.0, 1.0); + float lum = length(texture2D(texture0, fragTexCoord).rgb); + + if (lum < lumThreshold01) + { + if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + if (lum < lumThreshold02) + { + if (mod(gl_FragCoord .x - gl_FragCoord .y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + if (lum < lumThreshold03) + { + if (mod(gl_FragCoord .x + gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + if (lum < lumThreshold04) + { + if (mod(gl_FragCoord .x - gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + gl_FragColor = vec4(tc, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/cross_stitching.fs b/assets/shaders/glsl100/cross_stitching.fs new file mode 100644 index 00000000..de6d4f40 --- /dev/null +++ b/assets/shaders/glsl100/cross_stitching.fs @@ -0,0 +1,57 @@ +# version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +// NOTE: Render size values must be passed from code +const float renderWidth = 800.0; +const float renderHeight = 450.0; + +float stitchingSize = 6.0; +int invert = 0; + +vec4 PostFX(sampler2D tex, vec2 uv) +{ + vec4 c = vec4(0.0); + float size = stitchingSize; + vec2 cPos = uv * vec2(renderWidth, renderHeight); + vec2 tlPos = floor(cPos / vec2(size, size)); + tlPos *= size; + + int remX = int(mod(cPos.x, size)); + int remY = int(mod(cPos.y, size)); + + if (remX == 0 && remY == 0) tlPos = cPos; + + vec2 blPos = tlPos; + blPos.y += (size - 1.0); + + if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y))))) + { + if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0); + else c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; + } + else + { + if (invert == 1) c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; + else c = vec4(0.0, 0.0, 0.0, 1.0); + } + + return c; +} + +void main() +{ + vec3 tc = PostFX(texture0, fragTexCoord).rgb; + + gl_FragColor = vec4(tc, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/cubes_panning.fs b/assets/shaders/glsl100/cubes_panning.fs new file mode 100644 index 00000000..108f0579 --- /dev/null +++ b/assets/shaders/glsl100/cubes_panning.fs @@ -0,0 +1,60 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Custom variables +const float PI = 3.14159265358979323846; +uniform float uTime; + +float divisions = 5.0; +float angle = 0.0; + +vec2 VectorRotateTime(vec2 v, float speed) +{ + float time = uTime*speed; + float localTime = fract(time); // The time domain this works on is 1 sec. + + if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0; + else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4.0*sin(2.0*PI*localTime - PI/2.0); + else if ((localTime >= 0.50) && (localTime < 0.75)) angle = PI*0.25; + else if ((localTime >= 0.75) && (localTime < 1.00)) angle = PI/4.0*sin(2.0*PI*localTime); + + // Rotate vector by angle + v -= 0.5; + v = mat2(cos(angle), -sin(angle), sin(angle), cos(angle))*v; + v += 0.5; + + return v; +} + +float Rectangle(in vec2 st, in float size, in float fill) +{ + float roundSize = 0.5 - size/2.0; + float left = step(roundSize, st.x); + float top = step(roundSize, st.y); + float bottom = step(roundSize, 1.0 - st.y); + float right = step(roundSize, 1.0 - st.x); + + return (left*bottom*right*top)*fill; +} + +void main() +{ + vec2 fragPos = fragTexCoord; + fragPos.xy += uTime/9.0; + + fragPos *= divisions; + vec2 ipos = floor(fragPos); // Get the integer coords + vec2 fpos = fract(fragPos); // Get the fractional coords + + fpos = VectorRotateTime(fpos, 0.2); + + float alpha = Rectangle(fpos, 0.216, 1.0); + vec3 color = vec3(0.3, 0.3, 0.3); + + gl_FragColor = vec4(color, alpha); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/depth.fs b/assets/shaders/glsl100/depth.fs new file mode 100644 index 00000000..f6a14eb2 --- /dev/null +++ b/assets/shaders/glsl100/depth.fs @@ -0,0 +1,26 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; // Depth texture +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +void main() +{ + float zNear = 0.01; // camera z near + float zFar = 10.0; // camera z far + float z = texture2D(texture0, fragTexCoord).x; + + // Linearize depth value + float depth = (2.0*zNear)/(zFar + zNear - z*(zFar - zNear)); + + // Calculate final fragment color + gl_FragColor = vec4(depth, depth, depth, 1.0f); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/distortion.fs b/assets/shaders/glsl100/distortion.fs new file mode 100644 index 00000000..50116ce0 --- /dev/null +++ b/assets/shaders/glsl100/distortion.fs @@ -0,0 +1,54 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; + +// Input uniform values +uniform sampler2D texture0; + +// NOTE: Default parameters for Oculus Rift DK2 device +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftScreenCenter = vec2(0.25, 0.5); +const vec2 RightScreenCenter = vec2(0.75, 0.5); +const vec2 Scale = vec2(0.25, 0.45); +const vec2 ScaleIn = vec2(4.0, 2.5); +const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0); +const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); + +void main() +{ + // The following two variables need to be set per eye + vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter; + + // Scales input texture coordinates for distortion: vec2 HmdWarp(vec2 fragTexCoord, vec2 LensCenter) + vec2 theta = (fragTexCoord - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 theta1 = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + //vec2 tc = LensCenter + Scale*theta1; + + // Detect whether blue texture coordinates are out of range since these will scaled out the furthest + vec2 thetaBlue = theta1*(ChromaAbParam.z + ChromaAbParam.w*rSq); + vec2 tcBlue = LensCenter + Scale*thetaBlue; + + if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tcBlue))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + // Do blue texture lookup + float blue = texture2D(texture0, tcBlue).b; + + // Do green lookup (no scaling) + vec2 tcGreen = LensCenter + Scale*theta1; + float green = texture2D(texture0, tcGreen).g; + + // Do red scale and lookup + vec2 thetaRed = theta1*(ChromaAbParam.x + ChromaAbParam.y*rSq); + vec2 tcRed = LensCenter + Scale*thetaRed; + float red = texture2D(texture0, tcRed).r; + + gl_FragColor = vec4(red, green, blue, 1.0); + } +} diff --git a/assets/shaders/glsl100/dream_vision.fs b/assets/shaders/glsl100/dream_vision.fs new file mode 100644 index 00000000..7014b592 --- /dev/null +++ b/assets/shaders/glsl100/dream_vision.fs @@ -0,0 +1,37 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +void main() +{ + vec4 color = texture2D(texture0, fragTexCoord); + + color += texture2D(texture0, fragTexCoord + 0.001); + color += texture2D(texture0, fragTexCoord + 0.003); + color += texture2D(texture0, fragTexCoord + 0.005); + color += texture2D(texture0, fragTexCoord + 0.007); + color += texture2D(texture0, fragTexCoord + 0.009); + color += texture2D(texture0, fragTexCoord + 0.011); + + color += texture2D(texture0, fragTexCoord - 0.001); + color += texture2D(texture0, fragTexCoord - 0.003); + color += texture2D(texture0, fragTexCoord - 0.005); + color += texture2D(texture0, fragTexCoord - 0.007); + color += texture2D(texture0, fragTexCoord - 0.009); + color += texture2D(texture0, fragTexCoord - 0.011); + + color.rgb = vec3((color.r + color.g + color.b)/3.0); + color = color/9.5; + + gl_FragColor = color; +} \ No newline at end of file diff --git a/assets/shaders/glsl100/eratosthenes.fs b/assets/shaders/glsl100/eratosthenes.fs new file mode 100644 index 00000000..ba6de891 --- /dev/null +++ b/assets/shaders/glsl100/eratosthenes.fs @@ -0,0 +1,60 @@ +#version 100 + +precision mediump float; + +/************************************************************************************* + + The Sieve of Eratosthenes -- a simple shader by ProfJski + An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes + + The screen is divided into a square grid of boxes, each representing an integer value. + Each integer is tested to see if it is a prime number. Primes are colored white. + Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer. + + You can change the scale variable to make a larger or smaller grid. + Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers. + + WARNING: If you make scale too large, your GPU may bog down! + +***************************************************************************************/ + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Make a nice spectrum of colors based on counter and maxSize +vec4 Colorizer(float counter, float maxSize) +{ + float red = 0.0, green = 0.0, blue = 0.0; + float normsize = counter/maxSize; + + red = smoothstep(0.3, 0.7, normsize); + green = sin(3.14159*normsize); + blue = 1.0 - smoothstep(0.0, 0.4, normsize); + + return vec4(0.8*red, 0.8*green, 0.8*blue, 1.0); +} + +void main() +{ + vec4 color = vec4(1.0); + float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid. + float value = scale*floor(fragTexCoord.y*scale) + floor(fragTexCoord.x*scale); // Group pixels into boxes representing integer values + int valuei = int(value); + + //if ((valuei == 0) || (valuei == 1) || (valuei == 2)) gl_FragColor = vec4(1.0); + //else + { + //for (int i = 2; (i < int(max(2.0, sqrt(value) + 1.0))); i++) + // NOTE: On GLSL 100 for loops are restricted and loop condition must be a constant + // Tested on RPI, it seems loops are limited around 60 iteractions + for (int i = 2; i < 48; i++) + { + if ((value - float(i)*floor(value/float(i))) <= 0.0) + { + gl_FragColor = Colorizer(float(i), scale); + //break; // Uncomment to color by the largest factor instead + } + } + } +} diff --git a/assets/shaders/glsl100/fisheye.fs b/assets/shaders/glsl100/fisheye.fs new file mode 100644 index 00000000..8beb3d4a --- /dev/null +++ b/assets/shaders/glsl100/fisheye.fs @@ -0,0 +1,43 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +const float PI = 3.1415926535; + +void main() +{ + float aperture = 178.0; + float apertureHalf = 0.5 * aperture * (PI / 180.0); + float maxFactor = sin(apertureHalf); + + vec2 uv = vec2(0.0); + vec2 xy = 2.0 * fragTexCoord.xy - 1.0; + float d = length(xy); + + if (d < (2.0 - maxFactor)) + { + d = length(xy * maxFactor); + float z = sqrt(1.0 - d * d); + float r = atan(d, z) / PI; + float phi = atan(xy.y, xy.x); + + uv.x = r * cos(phi) + 0.5; + uv.y = r * sin(phi) + 0.5; + } + else + { + uv = fragTexCoord.xy; + } + + gl_FragColor = texture2D(texture0, uv); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/fog.fs b/assets/shaders/glsl100/fog.fs new file mode 100644 index 00000000..eeb2150f --- /dev/null +++ b/assets/shaders/glsl100/fog.fs @@ -0,0 +1,94 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +#define MAX_LIGHTS 4 +#define LIGHT_DIRECTIONAL 0 +#define LIGHT_POINT 1 + +struct MaterialProperty { + vec3 color; + int useSampler; + sampler2D sampler; +}; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 target; + vec4 color; +}; + +// Input lighting values +uniform Light lights[MAX_LIGHTS]; +uniform vec4 ambient; +uniform vec3 viewPos; +uniform float fogDensity; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord); + vec3 lightDot = vec3(0.0); + vec3 normal = normalize(fragNormal); + vec3 viewD = normalize(viewPos - fragPosition); + vec3 specular = vec3(0.0); + + // NOTE: Implement here your fragment shader code + + for (int i = 0; i < MAX_LIGHTS; i++) + { + if (lights[i].enabled == 1) + { + vec3 light = vec3(0.0); + + if (lights[i].type == LIGHT_DIRECTIONAL) light = -normalize(lights[i].target - lights[i].position); + if (lights[i].type == LIGHT_POINT) light = normalize(lights[i].position - fragPosition); + + float NdotL = max(dot(normal, light), 0.0); + lightDot += lights[i].color.rgb*NdotL; + + float specCo = 0.0; + if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(light), normal))), 16.0); // Shine: 16.0 + specular += specCo; + } + } + + vec4 finalColor = (texelColor*((colDiffuse + vec4(specular,1))*vec4(lightDot, 1.0))); + finalColor += texelColor*(ambient/10.0); + + // Gamma correction + finalColor = pow(finalColor, vec4(1.0/2.2)); + + // Fog calculation + float dist = length(viewPos - fragPosition); + + // these could be parameters... + const vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0); + //const float fogDensity = 0.16; + + // Exponential fog + float fogFactor = 1.0/exp((dist*fogDensity)*(dist*fogDensity)); + + // Linear fog (less nice) + //const float fogStart = 2.0; + //const float fogEnd = 10.0; + //float fogFactor = (fogEnd - dist)/(fogEnd - fogStart); + + fogFactor = clamp(fogFactor, 0.0, 1.0); + + gl_FragColor = mix(fogColor, finalColor, fogFactor); +} diff --git a/assets/shaders/glsl100/grayscale.fs b/assets/shaders/glsl100/grayscale.fs new file mode 100644 index 00000000..15174ea5 --- /dev/null +++ b/assets/shaders/glsl100/grayscale.fs @@ -0,0 +1,25 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord)*colDiffuse*fragColor; + + // Convert texel color to grayscale using NTSC conversion weights + float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); + + // Calculate final fragment color + gl_FragColor = vec4(gray, gray, gray, texelColor.a); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/julia_set.fs b/assets/shaders/glsl100/julia_set.fs new file mode 100644 index 00000000..bce25db1 --- /dev/null +++ b/assets/shaders/glsl100/julia_set.fs @@ -0,0 +1,83 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +uniform vec2 screenDims; // Dimensions of the screen +uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c +uniform vec2 offset; // Offset of the scale. +uniform float zoom; // Zoom of the scale. + +// NOTE: Maximum number of shader for-loop iterations depend on GPU, +// for example, on RasperryPi for this examply only supports up to 60 +const int MAX_ITERATIONS = 48; // Max iterations to do + +// Square a complex number +vec2 ComplexSquare(vec2 z) +{ + return vec2( + z.x * z.x - z.y * z.y, + z.x * z.y * 2.0 + ); +} + +// Convert Hue Saturation Value (HSV) color into RGB +vec3 Hsv2rgb(vec3 c) +{ + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +void main() +{ + /********************************************************************************************** + Julia sets use a function z^2 + c, where c is a constant. + This function is iterated until the nature of the point is determined. + + If the magnitude of the number becomes greater than 2, then from that point onward + the number will get bigger and bigger, and will never get smaller (tends towards infinity). + 2^2 = 4, 4^2 = 8 and so on. + So at 2 we stop iterating. + + If the number is below 2, we keep iterating. + But when do we stop iterating if the number is always below 2 (it converges)? + That is what MAX_ITERATIONS is for. + Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can + then map to a color. + + We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared. + And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power). + *************************************************************************************************/ + + // The pixel coordinates are scaled so they are on the mandelbrot scale + // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom + vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom); + + int iter = 0; + for (int iterations = 0; iterations < 60; iterations++) + { + z = ComplexSquare(z) + c; // Iterate function + if (dot(z, z) > 4.0) break; + + iter = iterations; + } + + // Another few iterations decreases errors in the smoothing calculation. + // See http://linas.org/art-gallery/escape/escape.html for more information. + z = ComplexSquare(z) + c; + z = ComplexSquare(z) + c; + + // This last part smooths the color (again see link above). + float smoothVal = float(iter) + 1.0 - (log(log(length(z)))/log(2.0)); + + // Normalize the value so it is between 0 and 1. + float norm = smoothVal/float(MAX_ITERATIONS); + + // If in set, color black. 0.999 allows for some float accuracy error. + if (norm > 0.999) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + else gl_FragColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0); +} diff --git a/assets/shaders/glsl100/lighting.fs b/assets/shaders/glsl100/lighting.fs new file mode 100644 index 00000000..5e4ff64c --- /dev/null +++ b/assets/shaders/glsl100/lighting.fs @@ -0,0 +1,81 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +#define MAX_LIGHTS 4 +#define LIGHT_DIRECTIONAL 0 +#define LIGHT_POINT 1 + +struct MaterialProperty { + vec3 color; + int useSampler; + sampler2D sampler; +}; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 target; + vec4 color; +}; + +// Input lighting values +uniform Light lights[MAX_LIGHTS]; +uniform vec4 ambient; +uniform vec3 viewPos; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord); + vec3 lightDot = vec3(0.0); + vec3 normal = normalize(fragNormal); + vec3 viewD = normalize(viewPos - fragPosition); + vec3 specular = vec3(0.0); + + // NOTE: Implement here your fragment shader code + + for (int i = 0; i < MAX_LIGHTS; i++) + { + if (lights[i].enabled == 1) + { + vec3 light = vec3(0.0); + + if (lights[i].type == LIGHT_DIRECTIONAL) + { + light = -normalize(lights[i].target - lights[i].position); + } + + if (lights[i].type == LIGHT_POINT) + { + light = normalize(lights[i].position - fragPosition); + } + + float NdotL = max(dot(normal, light), 0.0); + lightDot += lights[i].color.rgb*NdotL; + + float specCo = 0.0; + if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(light), normal))), 16.0); // 16 refers to shine + specular += specCo; + } + } + + vec4 finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0))); + finalColor += texelColor*(ambient/10.0); + + // Gamma correction + gl_FragColor = pow(finalColor, vec4(1.0/2.2)); +} diff --git a/assets/shaders/glsl100/mask.fs b/assets/shaders/glsl100/mask.fs new file mode 100644 index 00000000..20710620 --- /dev/null +++ b/assets/shaders/glsl100/mask.fs @@ -0,0 +1,24 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform sampler2D mask; +uniform vec4 colDiffuse; +uniform int frame; + +// NOTE: Add here your custom variables + +void main() +{ + vec4 maskColour = texture2D(mask, fragTexCoord + vec2(sin(-float(frame)/150.0)/10.0, cos(-float(frame)/170.0)/10.0)); + if (maskColour.r < 0.25) discard; + vec4 texelColor = texture2D(texture0, fragTexCoord + vec2(sin(float(frame)/90.0)/8.0, cos(float(frame)/60.0)/8.0)); + + gl_FragColor = texelColor*maskColour; +} diff --git a/assets/shaders/glsl100/palette_switch.fs b/assets/shaders/glsl100/palette_switch.fs new file mode 100644 index 00000000..e5b038d6 --- /dev/null +++ b/assets/shaders/glsl100/palette_switch.fs @@ -0,0 +1,41 @@ +#version 100 + +precision mediump float; + +const int colors = 8; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform ivec3 palette[colors]; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord)*fragColor; + + // Convert the (normalized) texel color RED component (GB would work, too) + // to the palette index by scaling up from [0, 1] to [0, 255]. + int index = int(texelColor.r*255.0); + + ivec3 color = ivec3(0); + + // NOTE: On GLSL 100 we are not allowed to index a uniform array by a variable value, + // a constantmust be used, so this logic... + if (index == 0) color = palette[0]; + else if (index == 1) color = palette[1]; + else if (index == 2) color = palette[2]; + else if (index == 3) color = palette[3]; + else if (index == 4) color = palette[4]; + else if (index == 5) color = palette[5]; + else if (index == 6) color = palette[6]; + else if (index == 7) color = palette[7]; + + // Calculate final fragment color. Note that the palette color components + // are defined in the range [0, 255] and need to be normalized to [0, 1] + // for OpenGL to work. + gl_FragColor = vec4(float(color.x)/255.0, float(color.y)/255.0, float(color.z)/255.0, texelColor.a); +} diff --git a/assets/shaders/glsl100/pixelizer.fs b/assets/shaders/glsl100/pixelizer.fs new file mode 100644 index 00000000..44fb0ca2 --- /dev/null +++ b/assets/shaders/glsl100/pixelizer.fs @@ -0,0 +1,32 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +// NOTE: Render size values must be passed from code +const float renderWidth = 800.0; +const float renderHeight = 450.0; + +float pixelWidth = 5.0; +float pixelHeight = 5.0; + +void main() +{ + float dx = pixelWidth*(1.0/renderWidth); + float dy = pixelHeight*(1.0/renderHeight); + + vec2 coord = vec2(dx*floor(fragTexCoord.x/dx), dy*floor(fragTexCoord.y/dy)); + + vec3 tc = texture2D(texture0, coord).rgb; + + gl_FragColor = vec4(tc, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/posterization.fs b/assets/shaders/glsl100/posterization.fs new file mode 100644 index 00000000..a7942c82 --- /dev/null +++ b/assets/shaders/glsl100/posterization.fs @@ -0,0 +1,29 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +float gamma = 0.6; +float numColors = 8.0; + +void main() +{ + vec3 color = texture2D(texture0, fragTexCoord.xy).rgb; + + color = pow(color, vec3(gamma, gamma, gamma)); + color = color*numColors; + color = floor(color); + color = color/numColors; + color = pow(color, vec3(1.0/gamma)); + + gl_FragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/predator.fs b/assets/shaders/glsl100/predator.fs new file mode 100644 index 00000000..37dc0bdf --- /dev/null +++ b/assets/shaders/glsl100/predator.fs @@ -0,0 +1,31 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +void main() +{ + vec3 color = texture2D(texture0, fragTexCoord).rgb; + vec3 colors[3]; + colors[0] = vec3(0.0, 0.0, 1.0); + colors[1] = vec3(1.0, 1.0, 0.0); + colors[2] = vec3(1.0, 0.0, 0.0); + + float lum = (color.r + color.g + color.b)/3.0; + + vec3 tc = vec3(0.0, 0.0, 0.0); + + if (lum < 0.5) tc = mix(colors[0], colors[1], lum/0.5); + else tc = mix(colors[1], colors[2], (lum - 0.5)/0.5); + + gl_FragColor = vec4(tc, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/raymarching.fs b/assets/shaders/glsl100/raymarching.fs new file mode 100644 index 00000000..7535086b --- /dev/null +++ b/assets/shaders/glsl100/raymarching.fs @@ -0,0 +1,429 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +uniform vec3 viewEye; +uniform vec3 viewCenter; +uniform float runTime; +uniform vec2 resolution; + +// The MIT License +// Copyright © 2013 Inigo Quilez +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// A list of useful distance function to simple primitives, and an example on how to +// do some interesting boolean operations, repetition and displacement. +// +// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm + +#define AA 1 // make this 1 is your machine is too slow + +//------------------------------------------------------------------ + +float sdPlane( vec3 p ) +{ + return p.y; +} + +float sdSphere( vec3 p, float s ) +{ + return length(p)-s; +} + +float sdBox( vec3 p, vec3 b ) +{ + vec3 d = abs(p) - b; + return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); +} + +float sdEllipsoid( in vec3 p, in vec3 r ) +{ + return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z); +} + +float udRoundBox( vec3 p, vec3 b, float r ) +{ + return length(max(abs(p)-b,0.0))-r; +} + +float sdTorus( vec3 p, vec2 t ) +{ + return length( vec2(length(p.xz)-t.x,p.y) )-t.y; +} + +float sdHexPrism( vec3 p, vec2 h ) +{ + vec3 q = abs(p); +#if 0 + return max(q.z-h.y,max((q.x*0.866025+q.y*0.5),q.y)-h.x); +#else + float d1 = q.z-h.y; + float d2 = max((q.x*0.866025+q.y*0.5),q.y)-h.x; + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +#endif +} + +float sdCapsule( vec3 p, vec3 a, vec3 b, float r ) +{ + vec3 pa = p-a, ba = b-a; + float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); + return length( pa - ba*h ) - r; +} + +float sdEquilateralTriangle( in vec2 p ) +{ + const float k = sqrt(3.0); + p.x = abs(p.x) - 1.0; + p.y = p.y + 1.0/k; + if( p.x + k*p.y > 0.0 ) p = vec2( p.x - k*p.y, -k*p.x - p.y )/2.0; + p.x += 2.0 - 2.0*clamp( (p.x+2.0)/2.0, 0.0, 1.0 ); + return -length(p)*sign(p.y); +} + +float sdTriPrism( vec3 p, vec2 h ) +{ + vec3 q = abs(p); + float d1 = q.z-h.y; +#if 1 + // distance bound + float d2 = max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5; +#else + // correct distance + h.x *= 0.866025; + float d2 = sdEquilateralTriangle(p.xy/h.x)*h.x; +#endif + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +} + +float sdCylinder( vec3 p, vec2 h ) +{ + vec2 d = abs(vec2(length(p.xz),p.y)) - h; + return min(max(d.x,d.y),0.0) + length(max(d,0.0)); +} + +float sdCone( in vec3 p, in vec3 c ) +{ + vec2 q = vec2( length(p.xz), p.y ); + float d1 = -q.y-c.z; + float d2 = max( dot(q,c.xy), q.y); + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +} + +float sdConeSection( in vec3 p, in float h, in float r1, in float r2 ) +{ + float d1 = -p.y - h; + float q = p.y - h; + float si = 0.5*(r1-r2)/h; + float d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q ); + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +} + +float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height } +{ + // Tetrahedron = Octahedron - Cube + float box = sdBox( p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z) ); + + float d = 0.0; + d = max( d, abs( dot(p, vec3( -h.x, h.y, 0 )) )); + d = max( d, abs( dot(p, vec3( h.x, h.y, 0 )) )); + d = max( d, abs( dot(p, vec3( 0, h.y, h.x )) )); + d = max( d, abs( dot(p, vec3( 0, h.y,-h.x )) )); + float octa = d - h.z; + return max(-box,octa); // Subtraction + } + +float length2( vec2 p ) +{ + return sqrt( p.x*p.x + p.y*p.y ); +} + +float length6( vec2 p ) +{ + p = p*p*p; p = p*p; + return pow( p.x + p.y, 1.0/6.0 ); +} + +float length8( vec2 p ) +{ + p = p*p; p = p*p; p = p*p; + return pow( p.x + p.y, 1.0/8.0 ); +} + +float sdTorus82( vec3 p, vec2 t ) +{ + vec2 q = vec2(length2(p.xz)-t.x,p.y); + return length8(q)-t.y; +} + +float sdTorus88( vec3 p, vec2 t ) +{ + vec2 q = vec2(length8(p.xz)-t.x,p.y); + return length8(q)-t.y; +} + +float sdCylinder6( vec3 p, vec2 h ) +{ + return max( length6(p.xz)-h.x, abs(p.y)-h.y ); +} + +//------------------------------------------------------------------ + +float opS( float d1, float d2 ) +{ + return max(-d2,d1); +} + +vec2 opU( vec2 d1, vec2 d2 ) +{ + return (d1.x0.0 ) tmax = min( tmax, tp1 ); + float tp2 = (1.6-ro.y)/rd.y; if( tp2>0.0 ) { if( ro.y>1.6 ) tmin = max( tmin, tp2 ); + else tmax = min( tmax, tp2 ); } +#endif + + float t = tmin; + float m = -1.0; + for( int i=0; i<64; i++ ) + { + float precis = 0.0005*t; + vec2 res = map( ro+rd*t ); + if( res.xtmax ) break; + t += res.x; + m = res.y; + } + + if( t>tmax ) m=-1.0; + return vec2( t, m ); +} + + +float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax ) +{ + float res = 1.0; + float t = mint; + for( int i=0; i<16; i++ ) + { + float h = map( ro + rd*t ).x; + res = min( res, 8.0*h/t ); + t += clamp( h, 0.02, 0.10 ); + if( h<0.001 || t>tmax ) break; + } + return clamp( res, 0.0, 1.0 ); +} + +vec3 calcNormal( in vec3 pos ) +{ + vec2 e = vec2(1.0,-1.0)*0.5773*0.0005; + return normalize( e.xyy*map( pos + e.xyy ).x + + e.yyx*map( pos + e.yyx ).x + + e.yxy*map( pos + e.yxy ).x + + e.xxx*map( pos + e.xxx ).x ); + /* + vec3 eps = vec3( 0.0005, 0.0, 0.0 ); + vec3 nor = vec3( + map(pos+eps.xyy).x - map(pos-eps.xyy).x, + map(pos+eps.yxy).x - map(pos-eps.yxy).x, + map(pos+eps.yyx).x - map(pos-eps.yyx).x ); + return normalize(nor); + */ +} + +float calcAO( in vec3 pos, in vec3 nor ) +{ + float occ = 0.0; + float sca = 1.0; + for( int i=0; i<5; i++ ) + { + float hr = 0.01 + 0.12*float(i)/4.0; + vec3 aopos = nor * hr + pos; + float dd = map( aopos ).x; + occ += -(dd-hr)*sca; + sca *= 0.95; + } + return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ); +} + +// http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm +float checkersGradBox( in vec2 p ) +{ + // filter kernel + vec2 w = fwidth(p) + 0.001; + // analytical integral (box filter) + vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w; + // xor pattern + return 0.5 - 0.5*i.x*i.y; +} + +vec3 render( in vec3 ro, in vec3 rd ) +{ + vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8; + vec2 res = castRay(ro,rd); + float t = res.x; + float m = res.y; + if( m>-0.5 ) + { + vec3 pos = ro + t*rd; + vec3 nor = calcNormal( pos ); + vec3 ref = reflect( rd, nor ); + + // material + col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) ); + if( m<1.5 ) + { + + float f = checkersGradBox( 5.0*pos.xz ); + col = 0.3 + f*vec3(0.1); + } + + // lighting + float occ = calcAO( pos, nor ); + vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) ); + vec3 hal = normalize( lig-rd ); + float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 ); + float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); + float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); + float dom = smoothstep( -0.1, 0.1, ref.y ); + float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 ); + + dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); + dom *= calcSoftshadow( pos, ref, 0.02, 2.5 ); + + float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)* + dif * + (0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 )); + + vec3 lin = vec3(0.0); + lin += 1.30*dif*vec3(1.00,0.80,0.55); + lin += 0.40*amb*vec3(0.40,0.60,1.00)*occ; + lin += 0.50*dom*vec3(0.40,0.60,1.00)*occ; + lin += 0.50*bac*vec3(0.25,0.25,0.25)*occ; + lin += 0.25*fre*vec3(1.00,1.00,1.00)*occ; + col = col*lin; + col += 10.00*spe*vec3(1.00,0.90,0.70); + + col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) ); + } + + return vec3( clamp(col,0.0,1.0) ); +} + +mat3 setCamera( in vec3 ro, in vec3 ta, float cr ) +{ + vec3 cw = normalize(ta-ro); + vec3 cp = vec3(sin(cr), cos(cr),0.0); + vec3 cu = normalize( cross(cw,cp) ); + vec3 cv = normalize( cross(cu,cw) ); + return mat3( cu, cv, cw ); +} + +void main() +{ + vec3 tot = vec3(0.0); +#if AA>1 + for( int m=0; m1 + } + tot /= float(AA*AA); +#endif + + gl_FragColor = vec4( tot, 1.0 ); +} diff --git a/assets/shaders/glsl100/reload.fs b/assets/shaders/glsl100/reload.fs new file mode 100644 index 00000000..eda00ae3 --- /dev/null +++ b/assets/shaders/glsl100/reload.fs @@ -0,0 +1,39 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; // Texture coordinates (sampler2D) +varying vec4 fragColor; // Tint color + +// Uniform inputs +uniform vec2 resolution; // Viewport resolution (in pixels) +uniform vec2 mouse; // Mouse pixel xy coordinates +uniform float time; // Total run time (in secods) + +// Draw circle +vec4 DrawCircle(vec2 fragCoord, vec2 position, float radius, vec3 color) +{ + float d = length(position - fragCoord) - radius; + float t = clamp(d, 0.0, 1.0); + return vec4(color, 1.0 - t); +} + +void main() +{ + vec2 fragCoord = gl_FragCoord.xy; + vec2 position = vec2(mouse.x, resolution.y - mouse.y); + float radius = 40.0; + + // Draw background layer + vec4 colorA = vec4(0.2,0.2,0.8, 1.0); + vec4 colorB = vec4(1.0,0.7,0.2, 1.0); + vec4 layer1 = mix(colorA, colorB, abs(sin(time*0.1))); + + // Draw circle layer + vec3 color = vec3(0.9, 0.16, 0.21); + vec4 layer2 = DrawCircle(fragCoord, position, radius, color); + + // Blend the two layers + gl_FragColor = mix(layer1, layer2, layer2.a); +} diff --git a/assets/shaders/glsl100/scanlines.fs b/assets/shaders/glsl100/scanlines.fs new file mode 100644 index 00000000..ce649e1a --- /dev/null +++ b/assets/shaders/glsl100/scanlines.fs @@ -0,0 +1,44 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +float offset = 0.0; +float frequency = 450.0/3.0; + +uniform float time; + +void main() +{ +/* + // Scanlines method 1 + float tval = 0; //time + vec2 uv = 0.5 + (fragTexCoord - 0.5)*(0.9 + 0.01*sin(0.5*tval)); + + vec4 color = texture2D(texture0, fragTexCoord); + + color = clamp(color*0.5 + 0.5*color*color*1.2, 0.0, 1.0); + color *= 0.5 + 0.5*16.0*uv.x*uv.y*(1.0 - uv.x)*(1.0 - uv.y); + color *= vec4(0.8, 1.0, 0.7, 1); + color *= 0.9 + 0.1*sin(10.0*tval + uv.y*1000.0); + color *= 0.97 + 0.03*sin(110.0*tval); + + fragColor = color; +*/ + // Scanlines method 2 + float globalPos = (fragTexCoord.y + offset) * frequency; + float wavePos = cos((fract(globalPos) - 0.5)*3.14); + + vec4 color = texture2D(texture0, fragTexCoord); + + gl_FragColor = mix(vec4(0.0, 0.3, 0.0, 0.0), color, wavePos); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/sobel.fs b/assets/shaders/glsl100/sobel.fs new file mode 100644 index 00000000..3e5c22dd --- /dev/null +++ b/assets/shaders/glsl100/sobel.fs @@ -0,0 +1,40 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables +vec2 resolution = vec2(800.0, 450.0); + +void main() +{ + float x = 1.0/resolution.x; + float y = 1.0/resolution.y; + + vec4 horizEdge = vec4(0.0); + horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; + horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0; + horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; + horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; + horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0; + horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; + + vec4 vertEdge = vec4(0.0); + vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; + vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0; + vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; + vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; + vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0; + vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; + + vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb)); + + gl_FragColor = vec4(edge, texture2D(texture0, fragTexCoord).a); +} \ No newline at end of file diff --git a/assets/shaders/glsl100/spotlight.fs b/assets/shaders/glsl100/spotlight.fs new file mode 100644 index 00000000..c8d83038 --- /dev/null +++ b/assets/shaders/glsl100/spotlight.fs @@ -0,0 +1,77 @@ +#version 100 + +precision mediump float; + +#define MAX_SPOTS 3 + +struct Spot { + vec2 pos; // window coords of spot + float inner; // inner fully transparent centre radius + float radius; // alpha fades out to this radius +}; + +uniform Spot spots[MAX_SPOTS]; // Spotlight positions array +uniform float screenWidth; // Width of the screen + +void main() +{ + float alpha = 1.0; + + // Get the position of the current fragment (screen coordinates!) + vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y); + + // Find out which spotlight is nearest + float d = 65000.0; // some high value + int fi = -1; // found index + + for (int i = 0; i < MAX_SPOTS; i++) + { + for (int j = 0; j < MAX_SPOTS; j++) + { + float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius; + + if (d > dj) + { + d = dj; + fi = i; + } + } + } + + // d now equals distance to nearest spot... + // allowing for the different radii of all spotlights + if (fi == 0) + { + if (d > spots[0].radius) alpha = 1.0; + else + { + if (d < spots[0].inner) alpha = 0.0; + else alpha = (d - spots[0].inner)/(spots[0].radius - spots[0].inner); + } + } + else if (fi == 1) + { + if (d > spots[1].radius) alpha = 1.0; + else + { + if (d < spots[1].inner) alpha = 0.0; + else alpha = (d - spots[1].inner)/(spots[1].radius - spots[1].inner); + } + } + else if (fi == 2) + { + if (d > spots[2].radius) alpha = 1.0; + else + { + if (d < spots[2].inner) alpha = 0.0; + else alpha = (d - spots[2].inner)/(spots[2].radius - spots[2].inner); + } + } + + // Right hand side of screen is dimly lit, + // could make the threshold value user definable + if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9; + + // could make the black out colour user definable... + gl_FragColor = vec4(0, 0, 0, alpha); +} diff --git a/assets/shaders/glsl100/swirl.fs b/assets/shaders/glsl100/swirl.fs new file mode 100644 index 00000000..7807b807 --- /dev/null +++ b/assets/shaders/glsl100/swirl.fs @@ -0,0 +1,46 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +// NOTE: Render size values should be passed from code +const float renderWidth = 800.0; +const float renderHeight = 450.0; + +float radius = 250.0; +float angle = 0.8; + +uniform vec2 center; + +void main() +{ + vec2 texSize = vec2(renderWidth, renderHeight); + vec2 tc = fragTexCoord*texSize; + tc -= center; + + float dist = length(tc); + + if (dist < radius) + { + float percent = (radius - dist)/radius; + float theta = percent*percent*angle*8.0; + float s = sin(theta); + float c = cos(theta); + + tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c))); + } + + tc += center; + vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;; + + gl_FragColor = vec4(color.rgb, 1.0);; +} diff --git a/assets/shaders/glsl100/wave.fs b/assets/shaders/glsl100/wave.fs new file mode 100644 index 00000000..50c4e02f --- /dev/null +++ b/assets/shaders/glsl100/wave.fs @@ -0,0 +1,36 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +uniform float secondes; + +uniform vec2 size; + +uniform float freqX; +uniform float freqY; +uniform float ampX; +uniform float ampY; +uniform float speedX; +uniform float speedY; + +void main() { + float pixelWidth = 1.0 / size.x; + float pixelHeight = 1.0 / size.y; + float aspect = pixelHeight / pixelWidth; + float boxLeft = 0.0; + float boxTop = 0.0; + + vec2 p = fragTexCoord; + p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth; + p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight; + + gl_FragColor = texture2D(texture0, p)*colDiffuse*fragColor; +} diff --git a/assets/shaders/glsl120/base.fs b/assets/shaders/glsl120/base.fs new file mode 100644 index 00000000..18799f95 --- /dev/null +++ b/assets/shaders/glsl120/base.fs @@ -0,0 +1,22 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables +uniform vec2 resolution = vec2(800, 450); + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord); + + // NOTE: Implement here your fragment shader code + + gl_FragColor = texelColor*colDiffuse; +} \ No newline at end of file diff --git a/assets/shaders/glsl120/base.vs b/assets/shaders/glsl120/base.vs new file mode 100644 index 00000000..674153d8 --- /dev/null +++ b/assets/shaders/glsl120/base.vs @@ -0,0 +1,26 @@ +#version 120 + +// Input vertex attributes +attribute vec3 vertexPosition; +attribute vec2 vertexTexCoord; +attribute vec3 vertexNormal; +attribute vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; + +// Output vertex attributes (to fragment shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl120/base_lighting.vs b/assets/shaders/glsl120/base_lighting.vs new file mode 100644 index 00000000..678c60e9 --- /dev/null +++ b/assets/shaders/glsl120/base_lighting.vs @@ -0,0 +1,59 @@ +#version 120 + +// Input vertex attributes +attribute vec3 vertexPosition; +attribute vec2 vertexTexCoord; +attribute vec3 vertexNormal; +attribute vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; +uniform mat4 matModel; + +// Output vertex attributes (to fragment shader) +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +// NOTE: Add here your custom variables + +// https://github.com/glslify/glsl-inverse +mat3 inverse(mat3 m) +{ + float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2]; + float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2]; + float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2]; + + float b01 = a22*a11 - a12*a21; + float b11 = -a22*a10 + a12*a20; + float b21 = a21*a10 - a11*a20; + + float det = a00*b01 + a01*b11 + a02*b21; + + return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11), + b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10), + b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det; +} + +// https://github.com/glslify/glsl-transpose +mat3 transpose(mat3 m) +{ + return mat3(m[0][0], m[1][0], m[2][0], + m[0][1], m[1][1], m[2][1], + m[0][2], m[1][2], m[2][2]); +} + +void main() +{ + // Send vertex attributes to fragment shader + fragPosition = vec3(matModel*vec4(vertexPosition, 1.0)); + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + mat3 normalMatrix = transpose(inverse(mat3(matModel))); + fragNormal = normalize(normalMatrix*vertexNormal); + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +} diff --git a/assets/shaders/glsl120/bloom.fs b/assets/shaders/glsl120/bloom.fs new file mode 100644 index 00000000..f97c18ed --- /dev/null +++ b/assets/shaders/glsl120/bloom.fs @@ -0,0 +1,37 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +const vec2 size = vec2(800, 450); // render size +const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance +const float quality = 2.5; // lower = smaller glow, better quality + +void main() +{ + vec4 sum = vec4(0); + vec2 sizeFactor = vec2(1)/size*quality; + + // Texel color fetching from texture sampler + vec4 source = texture2D(texture0, fragTexCoord); + + const int range = 2; // should be = (samples - 1)/2; + + for (int x = -range; x <= range; x++) + { + for (int y = -range; y <= range; y++) + { + sum += texture2D(texture0, fragTexCoord + vec2(x, y)*sizeFactor); + } + } + + // Calculate final fragment color + gl_FragColor = ((sum/(samples*samples)) + source)*colDiffuse; +} \ No newline at end of file diff --git a/assets/shaders/glsl120/blur.fs b/assets/shaders/glsl120/blur.fs new file mode 100644 index 00000000..99cddfc9 --- /dev/null +++ b/assets/shaders/glsl120/blur.fs @@ -0,0 +1,32 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +// NOTE: Render size values must be passed from code +const float renderWidth = 800.0; +const float renderHeight = 450.0; + +vec3 offset = vec3(0.0, 1.3846153846, 3.2307692308); +vec3 weight = vec3(0.2270270270, 0.3162162162, 0.0702702703); + +void main() +{ + // Texel color fetching from texture sampler + vec3 tc = texture2D(texture0, fragTexCoord).rgb*weight.x; + + tc += texture2D(texture0, fragTexCoord + vec2(offset.y)/renderWidth, 0.0).rgb*weight.y; + tc += texture2D(texture0, fragTexCoord - vec2(offset.y)/renderWidth, 0.0).rgb*weight.y; + + tc += texture2D(texture0, fragTexCoord + vec2(offset.z)/renderWidth, 0.0).rgb*weight.z; + tc += texture2D(texture0, fragTexCoord - vec2(offset.z)/renderWidth, 0.0).rgb*weight.z; + + gl_FragColor = vec4(tc, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl120/cross_hatching.fs b/assets/shaders/glsl120/cross_hatching.fs new file mode 100644 index 00000000..46514120 --- /dev/null +++ b/assets/shaders/glsl120/cross_hatching.fs @@ -0,0 +1,45 @@ +# version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +float hatchOffsetY = 5.0; +float lumThreshold01 = 0.9; +float lumThreshold02 = 0.7; +float lumThreshold03 = 0.5; +float lumThreshold04 = 0.3; + +void main() +{ + vec3 tc = vec3(1.0, 1.0, 1.0); + float lum = length(texture2D(texture0, fragTexCoord).rgb); + + if (lum < lumThreshold01) + { + if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + if (lum < lumThreshold02) + { + if (mod(gl_FragCoord .x - gl_FragCoord .y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + if (lum < lumThreshold03) + { + if (mod(gl_FragCoord .x + gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + if (lum < lumThreshold04) + { + if (mod(gl_FragCoord .x - gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + gl_FragColor = vec4(tc, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl120/cross_stitching.fs b/assets/shaders/glsl120/cross_stitching.fs new file mode 100644 index 00000000..dee4617e --- /dev/null +++ b/assets/shaders/glsl120/cross_stitching.fs @@ -0,0 +1,55 @@ +# version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +// NOTE: Render size values must be passed from code +const float renderWidth = 800.0; +const float renderHeight = 450.0; + +float stitchingSize = 6.0; +int invert = 0; + +vec4 PostFX(sampler2D tex, vec2 uv) +{ + vec4 c = vec4(0.0); + float size = stitchingSize; + vec2 cPos = uv * vec2(renderWidth, renderHeight); + vec2 tlPos = floor(cPos / vec2(size, size)); + tlPos *= size; + + int remX = int(mod(cPos.x, size)); + int remY = int(mod(cPos.y, size)); + + if (remX == 0 && remY == 0) tlPos = cPos; + + vec2 blPos = tlPos; + blPos.y += (size - 1.0); + + if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y))))) + { + if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0); + else c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; + } + else + { + if (invert == 1) c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; + else c = vec4(0.0, 0.0, 0.0, 1.0); + } + + return c; +} + +void main() +{ + vec3 tc = PostFX(texture0, fragTexCoord).rgb; + + gl_FragColor = vec4(tc, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl120/distortion.fs b/assets/shaders/glsl120/distortion.fs new file mode 100644 index 00000000..f9d7f1e5 --- /dev/null +++ b/assets/shaders/glsl120/distortion.fs @@ -0,0 +1,52 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; + +// Input uniform values +uniform sampler2D texture0; + +// NOTE: Default parameters for Oculus Rift DK2 device +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftScreenCenter = vec2(0.25, 0.5); +const vec2 RightScreenCenter = vec2(0.75, 0.5); +const vec2 Scale = vec2(0.25, 0.45); +const vec2 ScaleIn = vec2(4.0, 2.5); +const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0); +const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); + +void main() +{ + // The following two variables need to be set per eye + vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter; + + // Scales input texture coordinates for distortion: vec2 HmdWarp(vec2 fragTexCoord, vec2 LensCenter) + vec2 theta = (fragTexCoord - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 theta1 = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + //vec2 tc = LensCenter + Scale*theta1; + + // Detect whether blue texture coordinates are out of range since these will scaled out the furthest + vec2 thetaBlue = theta1*(ChromaAbParam.z + ChromaAbParam.w*rSq); + vec2 tcBlue = LensCenter + Scale*thetaBlue; + + if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tcBlue))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + // Do blue texture lookup + float blue = texture2D(texture0, tcBlue).b; + + // Do green lookup (no scaling) + vec2 tcGreen = LensCenter + Scale*theta1; + float green = texture2D(texture0, tcGreen).g; + + // Do red scale and lookup + vec2 thetaRed = theta1*(ChromaAbParam.x + ChromaAbParam.y*rSq); + vec2 tcRed = LensCenter + Scale*thetaRed; + float red = texture2D(texture0, tcRed).r; + + gl_FragColor = vec4(red, green, blue, 1.0); + } +} diff --git a/assets/shaders/glsl120/dream_vision.fs b/assets/shaders/glsl120/dream_vision.fs new file mode 100644 index 00000000..cb97b2bd --- /dev/null +++ b/assets/shaders/glsl120/dream_vision.fs @@ -0,0 +1,35 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +void main() +{ + vec4 color = texture2D(texture0, fragTexCoord); + + color += texture2D(texture0, fragTexCoord + 0.001); + color += texture2D(texture0, fragTexCoord + 0.003); + color += texture2D(texture0, fragTexCoord + 0.005); + color += texture2D(texture0, fragTexCoord + 0.007); + color += texture2D(texture0, fragTexCoord + 0.009); + color += texture2D(texture0, fragTexCoord + 0.011); + + color += texture2D(texture0, fragTexCoord - 0.001); + color += texture2D(texture0, fragTexCoord - 0.003); + color += texture2D(texture0, fragTexCoord - 0.005); + color += texture2D(texture0, fragTexCoord - 0.007); + color += texture2D(texture0, fragTexCoord - 0.009); + color += texture2D(texture0, fragTexCoord - 0.011); + + color.rgb = vec3((color.r + color.g + color.b)/3.0); + color = color/9.5; + + gl_FragColor = color; +} \ No newline at end of file diff --git a/assets/shaders/glsl120/fisheye.fs b/assets/shaders/glsl120/fisheye.fs new file mode 100644 index 00000000..6f376ba3 --- /dev/null +++ b/assets/shaders/glsl120/fisheye.fs @@ -0,0 +1,41 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +const float PI = 3.1415926535; + +void main() +{ + float aperture = 178.0; + float apertureHalf = 0.5 * aperture * (PI / 180.0); + float maxFactor = sin(apertureHalf); + + vec2 uv = vec2(0.0); + vec2 xy = 2.0 * fragTexCoord.xy - 1.0; + float d = length(xy); + + if (d < (2.0 - maxFactor)) + { + d = length(xy * maxFactor); + float z = sqrt(1.0 - d * d); + float r = atan(d, z) / PI; + float phi = atan(xy.y, xy.x); + + uv.x = r * cos(phi) + 0.5; + uv.y = r * sin(phi) + 0.5; + } + else + { + uv = fragTexCoord.xy; + } + + gl_FragColor = texture2D(texture0, uv); +} \ No newline at end of file diff --git a/assets/shaders/glsl120/fog.fs b/assets/shaders/glsl120/fog.fs new file mode 100644 index 00000000..fcd6ef95 --- /dev/null +++ b/assets/shaders/glsl120/fog.fs @@ -0,0 +1,92 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +#define MAX_LIGHTS 4 +#define LIGHT_DIRECTIONAL 0 +#define LIGHT_POINT 1 + +struct MaterialProperty { + vec3 color; + int useSampler; + sampler2D sampler; +}; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 target; + vec4 color; +}; + +// Input lighting values +uniform Light lights[MAX_LIGHTS]; +uniform vec4 ambient; +uniform vec3 viewPos; +uniform float fogDensity; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord); + vec3 lightDot = vec3(0.0); + vec3 normal = normalize(fragNormal); + vec3 viewD = normalize(viewPos - fragPosition); + vec3 specular = vec3(0.0); + + // NOTE: Implement here your fragment shader code + + for (int i = 0; i < MAX_LIGHTS; i++) + { + if (lights[i].enabled == 1) + { + vec3 light = vec3(0.0); + + if (lights[i].type == LIGHT_DIRECTIONAL) light = -normalize(lights[i].target - lights[i].position); + if (lights[i].type == LIGHT_POINT) light = normalize(lights[i].position - fragPosition); + + float NdotL = max(dot(normal, light), 0.0); + lightDot += lights[i].color.rgb*NdotL; + + float specCo = 0.0; + if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(light), normal))), 16.0); // Shine: 16.0 + specular += specCo; + } + } + + vec4 finalColor = (texelColor*((colDiffuse + vec4(specular,1))*vec4(lightDot, 1.0))); + finalColor += texelColor*(ambient/10.0); + + // Gamma correction + finalColor = pow(finalColor, vec4(1.0/2.2)); + + // Fog calculation + float dist = length(viewPos - fragPosition); + + // these could be parameters... + const vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0); + //const float fogDensity = 0.16; + + // Exponential fog + float fogFactor = 1.0/exp((dist*fogDensity)*(dist*fogDensity)); + + // Linear fog (less nice) + //const float fogStart = 2.0; + //const float fogEnd = 10.0; + //float fogFactor = (fogEnd - dist)/(fogEnd - fogStart); + + fogFactor = clamp(fogFactor, 0.0, 1.0); + + gl_FragColor = mix(fogColor, finalColor, fogFactor); +} diff --git a/assets/shaders/glsl120/grayscale.fs b/assets/shaders/glsl120/grayscale.fs new file mode 100644 index 00000000..4de60d22 --- /dev/null +++ b/assets/shaders/glsl120/grayscale.fs @@ -0,0 +1,23 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord)*colDiffuse*fragColor; + + // Convert texel color to grayscale using NTSC conversion weights + float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); + + // Calculate final fragment color + gl_FragColor = vec4(gray, gray, gray, texelColor.a); +} \ No newline at end of file diff --git a/assets/shaders/glsl120/palette_switch.fs b/assets/shaders/glsl120/palette_switch.fs new file mode 100644 index 00000000..ab3f79c7 --- /dev/null +++ b/assets/shaders/glsl120/palette_switch.fs @@ -0,0 +1,27 @@ +#version 120 + +const int colors = 8; + +// Input fragment attributes (from fragment shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform ivec3 palette[colors]; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord) * fragColor; + + // Convert the (normalized) texel color RED component (GB would work, too) + // to the palette index by scaling up from [0, 1] to [0, 255]. + int index = int(texelColor.r * 255.0); + ivec3 color = palette[index]; + + // Calculate final fragment color. Note that the palette color components + // are defined in the range [0, 255] and need to be normalized to [0, 1] + // for OpenGL to work. + gl_FragColor = vec4(color / 255.0, texelColor.a); +} diff --git a/assets/shaders/glsl120/pixelizer.fs b/assets/shaders/glsl120/pixelizer.fs new file mode 100644 index 00000000..6f741faf --- /dev/null +++ b/assets/shaders/glsl120/pixelizer.fs @@ -0,0 +1,30 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +// NOTE: Render size values must be passed from code +const float renderWidth = 800.0; +const float renderHeight = 450.0; + +float pixelWidth = 5.0; +float pixelHeight = 5.0; + +void main() +{ + float dx = pixelWidth*(1.0/renderWidth); + float dy = pixelHeight*(1.0/renderHeight); + + vec2 coord = vec2(dx*floor(fragTexCoord.x/dx), dy*floor(fragTexCoord.y/dy)); + + vec3 tc = texture2D(texture0, coord).rgb; + + gl_FragColor = vec4(tc, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl120/posterization.fs b/assets/shaders/glsl120/posterization.fs new file mode 100644 index 00000000..475b93a1 --- /dev/null +++ b/assets/shaders/glsl120/posterization.fs @@ -0,0 +1,27 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +float gamma = 0.6; +float numColors = 8.0; + +void main() +{ + vec3 color = texture2D(texture0, fragTexCoord.xy).rgb; + + color = pow(color, vec3(gamma, gamma, gamma)); + color = color*numColors; + color = floor(color); + color = color/numColors; + color = pow(color, vec3(1.0/gamma)); + + gl_FragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl120/predator.fs b/assets/shaders/glsl120/predator.fs new file mode 100644 index 00000000..2999cc8d --- /dev/null +++ b/assets/shaders/glsl120/predator.fs @@ -0,0 +1,29 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +void main() +{ + vec3 color = texture2D(texture0, fragTexCoord).rgb; + vec3 colors[3]; + colors[0] = vec3(0.0, 0.0, 1.0); + colors[1] = vec3(1.0, 1.0, 0.0); + colors[2] = vec3(1.0, 0.0, 0.0); + + float lum = (color.r + color.g + color.b)/3.0; + + vec3 tc = vec3(0.0, 0.0, 0.0); + + if (lum < 0.5) tc = mix(colors[0], colors[1], lum/0.5); + else tc = mix(colors[1], colors[2], (lum - 0.5)/0.5); + + gl_FragColor = vec4(tc, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl120/scanlines.fs b/assets/shaders/glsl120/scanlines.fs new file mode 100644 index 00000000..929c79eb --- /dev/null +++ b/assets/shaders/glsl120/scanlines.fs @@ -0,0 +1,42 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +float offset = 0.0; +float frequency = 450.0/3.0; + +uniform float time; + +void main() +{ +/* + // Scanlines method 1 + float tval = 0; //time + vec2 uv = 0.5 + (fragTexCoord - 0.5)*(0.9 + 0.01*sin(0.5*tval)); + + vec4 color = texture2D(texture0, fragTexCoord); + + color = clamp(color*0.5 + 0.5*color*color*1.2, 0.0, 1.0); + color *= 0.5 + 0.5*16.0*uv.x*uv.y*(1.0 - uv.x)*(1.0 - uv.y); + color *= vec4(0.8, 1.0, 0.7, 1); + color *= 0.9 + 0.1*sin(10.0*tval + uv.y*1000.0); + color *= 0.97 + 0.03*sin(110.0*tval); + + fragColor = color; +*/ + // Scanlines method 2 + float globalPos = (fragTexCoord.y + offset) * frequency; + float wavePos = cos((fract(globalPos) - 0.5)*3.14); + + vec4 color = texture2D(texture0, fragTexCoord); + + gl_FragColor = mix(vec4(0.0, 0.3, 0.0, 0.0), color, wavePos); +} \ No newline at end of file diff --git a/assets/shaders/glsl120/sobel.fs b/assets/shaders/glsl120/sobel.fs new file mode 100644 index 00000000..73e72703 --- /dev/null +++ b/assets/shaders/glsl120/sobel.fs @@ -0,0 +1,38 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables +vec2 resolution = vec2(800.0, 450.0); + +void main() +{ + float x = 1.0/resolution.x; + float y = 1.0/resolution.y; + + vec4 horizEdge = vec4(0.0); + horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; + horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0; + horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; + horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; + horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0; + horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; + + vec4 vertEdge = vec4(0.0); + vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; + vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0; + vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; + vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; + vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0; + vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; + + vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb)); + + gl_FragColor = vec4(edge, texture2D(texture0, fragTexCoord).a); +} \ No newline at end of file diff --git a/assets/shaders/glsl120/swirl.fs b/assets/shaders/glsl120/swirl.fs new file mode 100644 index 00000000..0618e013 --- /dev/null +++ b/assets/shaders/glsl120/swirl.fs @@ -0,0 +1,44 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +// NOTE: Render size values should be passed from code +const float renderWidth = 800; +const float renderHeight = 450; + +float radius = 250.0; +float angle = 0.8; + +uniform vec2 center; + +void main() +{ + vec2 texSize = vec2(renderWidth, renderHeight); + vec2 tc = fragTexCoord*texSize; + tc -= center; + + float dist = length(tc); + + if (dist < radius) + { + float percent = (radius - dist)/radius; + float theta = percent*percent*angle*8.0; + float s = sin(theta); + float c = cos(theta); + + tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c))); + } + + tc += center; + vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;; + + gl_FragColor = vec4(color.rgb, 1.0);; +} \ No newline at end of file diff --git a/assets/shaders/glsl330/base.fs b/assets/shaders/glsl330/base.fs new file mode 100644 index 00000000..f1418df1 --- /dev/null +++ b/assets/shaders/glsl330/base.fs @@ -0,0 +1,25 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); + + // NOTE: Implement here your fragment shader code + + finalColor = texelColor*colDiffuse; +} + diff --git a/assets/shaders/glsl330/base.vs b/assets/shaders/glsl330/base.vs new file mode 100644 index 00000000..f3099e82 --- /dev/null +++ b/assets/shaders/glsl330/base.vs @@ -0,0 +1,26 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; + +// Output vertex attributes (to fragment shader) +out vec2 fragTexCoord; +out vec4 fragColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/base_lighting.vs b/assets/shaders/glsl330/base_lighting.vs new file mode 100644 index 00000000..f8ec45f1 --- /dev/null +++ b/assets/shaders/glsl330/base_lighting.vs @@ -0,0 +1,32 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; +uniform mat4 matModel; +uniform mat4 matNormal; + +// Output vertex attributes (to fragment shader) +out vec3 fragPosition; +out vec2 fragTexCoord; +out vec4 fragColor; +out vec3 fragNormal; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragPosition = vec3(matModel*vec4(vertexPosition, 1.0)); + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0))); + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +} diff --git a/assets/shaders/glsl330/base_lighting_instanced.vs b/assets/shaders/glsl330/base_lighting_instanced.vs new file mode 100644 index 00000000..d198efe1 --- /dev/null +++ b/assets/shaders/glsl330/base_lighting_instanced.vs @@ -0,0 +1,36 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +in mat4 instanceTransform; + +// Input uniform values +uniform mat4 mvp; +uniform mat4 matNormal; + +// Output vertex attributes (to fragment shader) +out vec3 fragPosition; +out vec2 fragTexCoord; +out vec4 fragColor; +out vec3 fragNormal; + +// NOTE: Add here your custom variables + +void main() +{ + // Compute MVP for current instance + mat4 mvpi = mvp*instanceTransform; + + // Send vertex attributes to fragment shader + fragPosition = vec3(mvpi*vec4(vertexPosition, 1.0)); + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0))); + + // Calculate final vertex position + gl_Position = mvpi*vec4(vertexPosition, 1.0); +} diff --git a/assets/shaders/glsl330/bloom.fs b/assets/shaders/glsl330/bloom.fs new file mode 100644 index 00000000..549cde8f --- /dev/null +++ b/assets/shaders/glsl330/bloom.fs @@ -0,0 +1,40 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +const vec2 size = vec2(800, 450); // render size +const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance +const float quality = 2.5; // lower = smaller glow, better quality + +void main() +{ + vec4 sum = vec4(0); + vec2 sizeFactor = vec2(1)/size*quality; + + // Texel color fetching from texture sampler + vec4 source = texture(texture0, fragTexCoord); + + const int range = 2; // should be = (samples - 1)/2; + + for (int x = -range; x <= range; x++) + { + for (int y = -range; y <= range; y++) + { + sum += texture(texture0, fragTexCoord + vec2(x, y)*sizeFactor); + } + } + + // Calculate final fragment color + finalColor = ((sum/(samples*samples)) + source)*colDiffuse; +} \ No newline at end of file diff --git a/assets/shaders/glsl330/blur.fs b/assets/shaders/glsl330/blur.fs new file mode 100644 index 00000000..e4df406d --- /dev/null +++ b/assets/shaders/glsl330/blur.fs @@ -0,0 +1,35 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +// NOTE: Render size values must be passed from code +const float renderWidth = 800; +const float renderHeight = 450; + +float offset[3] = float[](0.0, 1.3846153846, 3.2307692308); +float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703); + +void main() +{ + // Texel color fetching from texture sampler + vec3 texelColor = texture(texture0, fragTexCoord).rgb*weight[0]; + + for (int i = 1; i < 3; i++) + { + texelColor += texture(texture0, fragTexCoord + vec2(offset[i])/renderWidth, 0.0).rgb*weight[i]; + texelColor += texture(texture0, fragTexCoord - vec2(offset[i])/renderWidth, 0.0).rgb*weight[i]; + } + + finalColor = vec4(texelColor, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/color_mix.fs b/assets/shaders/glsl330/color_mix.fs new file mode 100644 index 00000000..761b3464 --- /dev/null +++ b/assets/shaders/glsl330/color_mix.fs @@ -0,0 +1,27 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec3 vertexPos; +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform sampler2D texture1; +uniform vec4 colDiffuse; + +uniform float divider = 0.5; + +out vec4 finalColor; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor0 = texture(texture0, fragTexCoord); + vec4 texelColor1 = texture(texture1, fragTexCoord); + + float x = fract(fragTexCoord.s); + float final = smoothstep(divider - 0.1, divider + 0.1, x); + + finalColor = mix(texelColor0, texelColor1, final); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/cross_hatching.fs b/assets/shaders/glsl330/cross_hatching.fs new file mode 100644 index 00000000..ffa5a41a --- /dev/null +++ b/assets/shaders/glsl330/cross_hatching.fs @@ -0,0 +1,49 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +float hatchOffsetY = 5.0; +float lumThreshold01 = 0.9; +float lumThreshold02 = 0.7; +float lumThreshold03 = 0.5; +float lumThreshold04 = 0.3; + +void main() +{ + vec3 tc = vec3(1.0, 1.0, 1.0); + float lum = length(texture(texture0, fragTexCoord).rgb); + float a = texture(texture0, fragTexCoord).a; + + if (lum < lumThreshold01) + { + if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + if (lum < lumThreshold02) + { + if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + if (lum < lumThreshold03) + { + if (mod(gl_FragCoord.x + gl_FragCoord.y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + if (lum < lumThreshold04) + { + if (mod(gl_FragCoord.x - gl_FragCoord.y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + } + + finalColor = vec4(tc, a); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/cross_stitching.fs b/assets/shaders/glsl330/cross_stitching.fs new file mode 100644 index 00000000..a50e085d --- /dev/null +++ b/assets/shaders/glsl330/cross_stitching.fs @@ -0,0 +1,60 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +// NOTE: Render size values must be passed from code +const float renderWidth = 800.0; +const float renderHeight = 450.0; + +float stitchingSize = 6.0; + +uniform int invert = 0; + +vec4 PostFX(sampler2D tex, vec2 uv) +{ + vec4 c = vec4(0.0); + float size = stitchingSize; + vec2 cPos = uv * vec2(renderWidth, renderHeight); + vec2 tlPos = floor(cPos / vec2(size, size)); + tlPos *= size; + + int remX = int(mod(cPos.x, size)); + int remY = int(mod(cPos.y, size)); + + if (remX == 0 && remY == 0) tlPos = cPos; + + vec2 blPos = tlPos; + blPos.y += (size - 1.0); + + if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y))))) + { + if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0); + else c = texture(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; + } + else + { + if (invert == 1) c = texture(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; + else c = vec4(0.0, 0.0, 0.0, 1.0); + } + + return c; +} + +void main() +{ + vec3 tc = PostFX(texture0, fragTexCoord).rgb; + float a = texture(texture0, fragTexCoord).a; + + finalColor = vec4(tc, a); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/cubes_panning.fs b/assets/shaders/glsl330/cubes_panning.fs new file mode 100644 index 00000000..c92418a4 --- /dev/null +++ b/assets/shaders/glsl330/cubes_panning.fs @@ -0,0 +1,61 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Output fragment color +out vec4 finalColor; + +// Custom variables +#define PI 3.14159265358979323846 +uniform float uTime = 0.0; + +float divisions = 5.0; +float angle = 0.0; + +vec2 VectorRotateTime(vec2 v, float speed) +{ + float time = uTime*speed; + float localTime = fract(time); // The time domain this works on is 1 sec. + + if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0; + else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4*sin(2*PI*localTime - PI/2); + else if ((localTime >= 0.50) && (localTime < 0.75)) angle = PI*0.25; + else if ((localTime >= 0.75) && (localTime < 1.00)) angle = PI/4*sin(2*PI*localTime); + + // Rotate vector by angle + v -= 0.5; + v = mat2(cos(angle), -sin(angle), sin(angle), cos(angle))*v; + v += 0.5; + + return v; +} + +float Rectangle(in vec2 st, in float size, in float fill) +{ + float roundSize = 0.5 - size/2.0; + float left = step(roundSize, st.x); + float top = step(roundSize, st.y); + float bottom = step(roundSize, 1.0 - st.y); + float right = step(roundSize, 1.0 - st.x); + + return (left*bottom*right*top)*fill; +} + +void main() +{ + vec2 fragPos = fragTexCoord; + fragPos.xy += uTime/9.0; + + fragPos *= divisions; + vec2 ipos = floor(fragPos); // Get the integer coords + vec2 fpos = fract(fragPos); // Get the fractional coords + + fpos = VectorRotateTime(fpos, 0.2); + + float alpha = Rectangle(fpos, 0.216, 1.0); + vec3 color = vec3(0.3, 0.3, 0.3); + + finalColor = vec4(color, alpha); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/depth.fs b/assets/shaders/glsl330/depth.fs new file mode 100644 index 00000000..2422f390 --- /dev/null +++ b/assets/shaders/glsl330/depth.fs @@ -0,0 +1,27 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; // Depth texture +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +void main() +{ + float zNear = 0.01; // camera z near + float zFar = 10.0; // camera z far + float z = texture(texture0, fragTexCoord).x; + + // Linearize depth value + float depth = (2.0*zNear)/(zFar + zNear - z*(zFar - zNear)); + + // Calculate final fragment color + finalColor = vec4(depth, depth, depth, 1.0f); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/distortion.fs b/assets/shaders/glsl330/distortion.fs new file mode 100644 index 00000000..cb4be8fc --- /dev/null +++ b/assets/shaders/glsl330/distortion.fs @@ -0,0 +1,56 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; + +// Input uniform values +uniform sampler2D texture0; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Default parameters for Oculus Rift DK2 device +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftScreenCenter = vec2(0.25, 0.5); +const vec2 RightScreenCenter = vec2(0.75, 0.5); +const vec2 Scale = vec2(0.25, 0.45); +const vec2 ScaleIn = vec2(4.0, 2.5); +const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0); +const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); + +void main() +{ + // The following two variables need to be set per eye + vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter; + + // Scales input texture coordinates for distortion: vec2 HmdWarp(vec2 fragTexCoord, vec2 LensCenter) + vec2 theta = (fragTexCoord - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 theta1 = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + //vec2 tc = LensCenter + Scale*theta1; + + // Detect whether blue texture coordinates are out of range since these will scaled out the furthest + vec2 thetaBlue = theta1*(ChromaAbParam.z + ChromaAbParam.w*rSq); + vec2 tcBlue = LensCenter + Scale*thetaBlue; + + if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tcBlue))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + // Do blue texture lookup + float blue = texture(texture0, tcBlue).b; + + // Do green lookup (no scaling) + vec2 tcGreen = LensCenter + Scale*theta1; + float green = texture(texture0, tcGreen).g; + + // Do red scale and lookup + vec2 thetaRed = theta1*(ChromaAbParam.x + ChromaAbParam.y*rSq); + vec2 tcRed = LensCenter + Scale*thetaRed; + float red = texture(texture0, tcRed).r; + + finalColor = vec4(red, green, blue, 1.0); + } +} + diff --git a/assets/shaders/glsl330/dream_vision.fs b/assets/shaders/glsl330/dream_vision.fs new file mode 100644 index 00000000..31d3fd2f --- /dev/null +++ b/assets/shaders/glsl330/dream_vision.fs @@ -0,0 +1,34 @@ +#version 330 + +in vec2 fragTexCoord; + +out vec4 fragColor; + +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +void main() +{ + vec4 color = texture(texture0, fragTexCoord); + + color += texture(texture0, fragTexCoord + 0.001); + color += texture(texture0, fragTexCoord + 0.003); + color += texture(texture0, fragTexCoord + 0.005); + color += texture(texture0, fragTexCoord + 0.007); + color += texture(texture0, fragTexCoord + 0.009); + color += texture(texture0, fragTexCoord + 0.011); + + color += texture(texture0, fragTexCoord - 0.001); + color += texture(texture0, fragTexCoord - 0.003); + color += texture(texture0, fragTexCoord - 0.005); + color += texture(texture0, fragTexCoord - 0.007); + color += texture(texture0, fragTexCoord - 0.009); + color += texture(texture0, fragTexCoord - 0.011); + + color.rgb = vec3((color.r + color.g + color.b)/3.0); + color = color/9.5; + + fragColor = color; +} \ No newline at end of file diff --git a/assets/shaders/glsl330/eratosthenes.fs b/assets/shaders/glsl330/eratosthenes.fs new file mode 100644 index 00000000..14711222 --- /dev/null +++ b/assets/shaders/glsl330/eratosthenes.fs @@ -0,0 +1,59 @@ +#version 330 + +/************************************************************************************* + + The Sieve of Eratosthenes -- a simple shader by ProfJski + An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes + + The screen is divided into a square grid of boxes, each representing an integer value. + Each integer is tested to see if it is a prime number. Primes are colored white. + Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer. + + You can change the scale variable to make a larger or smaller grid. + Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers. + + WARNING: If you make scale too large, your GPU may bog down! + +***************************************************************************************/ + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Output fragment color +out vec4 finalColor; + +// Make a nice spectrum of colors based on counter and maxSize +vec4 Colorizer(float counter, float maxSize) +{ + float red = 0.0, green = 0.0, blue = 0.0; + float normsize = counter/maxSize; + + red = smoothstep(0.3, 0.7, normsize); + green = sin(3.14159*normsize); + blue = 1.0 - smoothstep(0.0, 0.4, normsize); + + return vec4(0.8*red, 0.8*green, 0.8*blue, 1.0); +} + +void main() +{ + vec4 color = vec4(1.0); + float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid. + int value = int(scale*floor(fragTexCoord.y*scale)+floor(fragTexCoord.x*scale)); // Group pixels into boxes representing integer values + + if ((value == 0) || (value == 1) || (value == 2)) finalColor = vec4(1.0); + else + { + for (int i = 2; (i < max(2, sqrt(value) + 1)); i++) + { + if ((value - i*floor(float(value)/float(i))) == 0) + { + color = Colorizer(float(i), scale); + //break; // Uncomment to color by the largest factor instead + } + } + + finalColor = color; + } +} diff --git a/assets/shaders/glsl330/fisheye.fs b/assets/shaders/glsl330/fisheye.fs new file mode 100644 index 00000000..e85d7c9d --- /dev/null +++ b/assets/shaders/glsl330/fisheye.fs @@ -0,0 +1,40 @@ +#version 330 + +in vec2 fragTexCoord; + +out vec4 fragColor; + +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// NOTE: Add here your custom variables + +const float PI = 3.1415926535; + +void main() +{ + float aperture = 178.0; + float apertureHalf = 0.5 * aperture * (PI / 180.0); + float maxFactor = sin(apertureHalf); + + vec2 uv = vec2(0); + vec2 xy = 2.0 * fragTexCoord.xy - 1.0; + float d = length(xy); + + if (d < (2.0 - maxFactor)) + { + d = length(xy * maxFactor); + float z = sqrt(1.0 - d * d); + float r = atan(d, z) / PI; + float phi = atan(xy.y, xy.x); + + uv.x = r * cos(phi) + 0.5; + uv.y = r * sin(phi) + 0.5; + } + else + { + uv = fragTexCoord.xy; + } + + fragColor = texture(texture0, uv); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/fog.fs b/assets/shaders/glsl330/fog.fs new file mode 100644 index 00000000..2160f31b --- /dev/null +++ b/assets/shaders/glsl330/fog.fs @@ -0,0 +1,95 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; +in vec3 fragPosition; +in vec3 fragNormal; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +#define MAX_LIGHTS 4 +#define LIGHT_DIRECTIONAL 0 +#define LIGHT_POINT 1 + +struct MaterialProperty { + vec3 color; + int useSampler; + sampler2D sampler; +}; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 target; + vec4 color; +}; + +// Input lighting values +uniform Light lights[MAX_LIGHTS]; +uniform vec4 ambient; +uniform vec3 viewPos; +uniform float fogDensity; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); + vec3 lightDot = vec3(0.0); + vec3 normal = normalize(fragNormal); + vec3 viewD = normalize(viewPos - fragPosition); + vec3 specular = vec3(0.0); + + // NOTE: Implement here your fragment shader code + + for (int i = 0; i < MAX_LIGHTS; i++) + { + if (lights[i].enabled == 1) + { + vec3 light = vec3(0.0); + + if (lights[i].type == LIGHT_DIRECTIONAL) light = -normalize(lights[i].target - lights[i].position); + if (lights[i].type == LIGHT_POINT) light = normalize(lights[i].position - fragPosition); + + float NdotL = max(dot(normal, light), 0.0); + lightDot += lights[i].color.rgb*NdotL; + + float specCo = 0.0; + if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(light), normal))), 16.0); // Shine: 16.0 + specular += specCo; + } + } + + finalColor = (texelColor*((colDiffuse + vec4(specular,1))*vec4(lightDot, 1.0))); + finalColor += texelColor*(ambient/10.0); + + // Gamma correction + finalColor = pow(finalColor, vec4(1.0/2.2)); + + // Fog calculation + float dist = length(viewPos - fragPosition); + + // these could be parameters... + const vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0); + //const float fogDensity = 0.16; + + // Exponential fog + float fogFactor = 1.0/exp((dist*fogDensity)*(dist*fogDensity)); + + // Linear fog (less nice) + //const float fogStart = 2.0; + //const float fogEnd = 10.0; + //float fogFactor = (fogEnd - dist)/(fogEnd - fogStart); + + fogFactor = clamp(fogFactor, 0.0, 1.0); + + finalColor = mix(fogColor, finalColor, fogFactor); +} diff --git a/assets/shaders/glsl330/grayscale.fs b/assets/shaders/glsl330/grayscale.fs new file mode 100644 index 00000000..5b3e11be --- /dev/null +++ b/assets/shaders/glsl330/grayscale.fs @@ -0,0 +1,26 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord)*colDiffuse*fragColor; + + // Convert texel color to grayscale using NTSC conversion weights + float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); + + // Calculate final fragment color + finalColor = vec4(gray, gray, gray, texelColor.a); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/julia_set.fs b/assets/shaders/glsl330/julia_set.fs new file mode 100644 index 00000000..f68367ea --- /dev/null +++ b/assets/shaders/glsl330/julia_set.fs @@ -0,0 +1,81 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Output fragment color +out vec4 finalColor; + +uniform vec2 screenDims; // Dimensions of the screen +uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c +uniform vec2 offset; // Offset of the scale. +uniform float zoom; // Zoom of the scale. + +const int MAX_ITERATIONS = 255; // Max iterations to do. + +// Square a complex number +vec2 ComplexSquare(vec2 z) +{ + return vec2( + z.x * z.x - z.y * z.y, + z.x * z.y * 2.0 + ); +} + +// Convert Hue Saturation Value (HSV) color into RGB +vec3 Hsv2rgb(vec3 c) +{ + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +void main() +{ + /********************************************************************************************** + Julia sets use a function z^2 + c, where c is a constant. + This function is iterated until the nature of the point is determined. + + If the magnitude of the number becomes greater than 2, then from that point onward + the number will get bigger and bigger, and will never get smaller (tends towards infinity). + 2^2 = 4, 4^2 = 8 and so on. + So at 2 we stop iterating. + + If the number is below 2, we keep iterating. + But when do we stop iterating if the number is always below 2 (it converges)? + That is what MAX_ITERATIONS is for. + Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can + then map to a color. + + We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared. + And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power). + *************************************************************************************************/ + + // The pixel coordinates are scaled so they are on the mandelbrot scale + // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom + vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom); + + int iterations = 0; + for (iterations = 0; iterations < MAX_ITERATIONS; iterations++) + { + z = ComplexSquare(z) + c; // Iterate function + + if (dot(z, z) > 4.0) break; + } + + // Another few iterations decreases errors in the smoothing calculation. + // See http://linas.org/art-gallery/escape/escape.html for more information. + z = ComplexSquare(z) + c; + z = ComplexSquare(z) + c; + + // This last part smooths the color (again see link above). + float smoothVal = float(iterations) + 1.0 - (log(log(length(z)))/log(2.0)); + + // Normalize the value so it is between 0 and 1. + float norm = smoothVal/float(MAX_ITERATIONS); + + // If in set, color black. 0.999 allows for some float accuracy error. + if (norm > 0.999) finalColor = vec4(0.0, 0.0, 0.0, 1.0); + else finalColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0); +} diff --git a/assets/shaders/glsl330/lighting.fs b/assets/shaders/glsl330/lighting.fs new file mode 100644 index 00000000..6877c1c7 --- /dev/null +++ b/assets/shaders/glsl330/lighting.fs @@ -0,0 +1,82 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec3 fragPosition; +in vec2 fragTexCoord; +in vec4 fragColor; +in vec3 fragNormal; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +#define MAX_LIGHTS 4 +#define LIGHT_DIRECTIONAL 0 +#define LIGHT_POINT 1 + +struct MaterialProperty { + vec3 color; + int useSampler; + sampler2D sampler; +}; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 target; + vec4 color; +}; + +// Input lighting values +uniform Light lights[MAX_LIGHTS]; +uniform vec4 ambient; +uniform vec3 viewPos; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); + vec3 lightDot = vec3(0.0); + vec3 normal = normalize(fragNormal); + vec3 viewD = normalize(viewPos - fragPosition); + vec3 specular = vec3(0.0); + + // NOTE: Implement here your fragment shader code + + for (int i = 0; i < MAX_LIGHTS; i++) + { + if (lights[i].enabled == 1) + { + vec3 light = vec3(0.0); + + if (lights[i].type == LIGHT_DIRECTIONAL) + { + light = -normalize(lights[i].target - lights[i].position); + } + + if (lights[i].type == LIGHT_POINT) + { + light = normalize(lights[i].position - fragPosition); + } + + float NdotL = max(dot(normal, light), 0.0); + lightDot += lights[i].color.rgb*NdotL; + + float specCo = 0.0; + if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(light), normal))), 16.0); // 16 refers to shine + specular += specCo; + } + } + + finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0))); + finalColor += texelColor*(ambient/10.0)*colDiffuse; + + // Gamma correction + finalColor = pow(finalColor, vec4(1.0/2.2)); +} diff --git a/assets/shaders/glsl330/mask.fs b/assets/shaders/glsl330/mask.fs new file mode 100644 index 00000000..a93bed07 --- /dev/null +++ b/assets/shaders/glsl330/mask.fs @@ -0,0 +1,22 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform sampler2D mask; +uniform int frame; + +// Output fragment color +out vec4 finalColor; + +void main() +{ + vec4 maskColour = texture(mask, fragTexCoord + vec2(sin(-frame/150.0)/10.0, cos(-frame/170.0)/10.0)); + if (maskColour.r < 0.25) discard; + vec4 texelColor = texture(texture0, fragTexCoord + vec2(sin(frame/90.0)/8.0, cos(frame/60.0)/8.0)); + + finalColor = texelColor*maskColour; +} diff --git a/assets/shaders/glsl330/overdraw.fs b/assets/shaders/glsl330/overdraw.fs new file mode 100644 index 00000000..435217c3 --- /dev/null +++ b/assets/shaders/glsl330/overdraw.fs @@ -0,0 +1,26 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +void main() +{ + // To show overdraw, we just render all the fragments + // with a solid color and some transparency + + // NOTE: This is not a postpro render, + // it will only render all screen texture in a plain color + + finalColor = vec4(1.0, 0.0, 0.0, 0.2); +} + diff --git a/assets/shaders/glsl330/palette_switch.fs b/assets/shaders/glsl330/palette_switch.fs new file mode 100644 index 00000000..7c8a488c --- /dev/null +++ b/assets/shaders/glsl330/palette_switch.fs @@ -0,0 +1,30 @@ +#version 330 + +const int colors = 8; + +// Input fragment attributes (from fragment shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform ivec3 palette[colors]; + +// Output fragment color +out vec4 finalColor; + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord)*fragColor; + + // Convert the (normalized) texel color RED component (GB would work, too) + // to the palette index by scaling up from [0, 1] to [0, 255]. + int index = int(texelColor.r*255.0); + ivec3 color = palette[index]; + + // Calculate final fragment color. Note that the palette color components + // are defined in the range [0, 255] and need to be normalized to [0, 1] + // for OpenGL to work. + finalColor = vec4(color/255.0, texelColor.a); +} diff --git a/assets/shaders/glsl330/pixelizer.fs b/assets/shaders/glsl330/pixelizer.fs new file mode 100644 index 00000000..6a386c20 --- /dev/null +++ b/assets/shaders/glsl330/pixelizer.fs @@ -0,0 +1,33 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +// NOTE: Render size values must be passed from code +const float renderWidth = 800; +const float renderHeight = 450; + +uniform float pixelWidth = 5.0; +uniform float pixelHeight = 5.0; + +void main() +{ + float dx = pixelWidth*(1.0/renderWidth); + float dy = pixelHeight*(1.0/renderHeight); + + vec2 coord = vec2(dx*floor(fragTexCoord.x/dx), dy*floor(fragTexCoord.y/dy)); + + vec4 tc = texture(texture0, coord).rgba; + + finalColor = tc; +} \ No newline at end of file diff --git a/assets/shaders/glsl330/posterization.fs b/assets/shaders/glsl330/posterization.fs new file mode 100644 index 00000000..94197b01 --- /dev/null +++ b/assets/shaders/glsl330/posterization.fs @@ -0,0 +1,32 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +float gamma = 0.6; +float numColors = 8.0; + +void main() +{ + // Texel color fetching from texture sampler + vec3 texelColor = texture(texture0, fragTexCoord.xy).rgb; + float a = texture(texture0, fragTexCoord.xy).a; + + texelColor = pow(texelColor, vec3(gamma, gamma, gamma)); + texelColor = texelColor*numColors; + texelColor = floor(texelColor); + texelColor = texelColor/numColors; + texelColor = pow(texelColor, vec3(1.0/gamma)); + + finalColor = vec4(texelColor, a); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/predator.fs b/assets/shaders/glsl330/predator.fs new file mode 100644 index 00000000..fb983996 --- /dev/null +++ b/assets/shaders/glsl330/predator.fs @@ -0,0 +1,32 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord).rgba; + vec3 colors[3]; + colors[0] = vec3(0.0, 0.0, 1.0); + colors[1] = vec3(1.0, 1.0, 0.0); + colors[2] = vec3(1.0, 0.0, 0.0); + + float lum = (texelColor.r + texelColor.g + texelColor.b)/3.0; + + int ix = (lum < 0.5)? 0:1; + + vec3 tc = mix(colors[ix], colors[ix + 1], (lum - float(ix)*0.5)/0.5); + + finalColor = vec4(tc, texelColor.a); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/raymarching.fs b/assets/shaders/glsl330/raymarching.fs new file mode 100644 index 00000000..5b0caa65 --- /dev/null +++ b/assets/shaders/glsl330/raymarching.fs @@ -0,0 +1,430 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Output fragment color +out vec4 finalColor; + +uniform vec3 viewEye; +uniform vec3 viewCenter; +uniform float runTime; +uniform vec2 resolution; + +// The MIT License +// Copyright © 2013 Inigo Quilez +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// A list of useful distance function to simple primitives, and an example on how to +// do some interesting boolean operations, repetition and displacement. +// +// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm + +#define AA 1 // make this 1 is your machine is too slow + +//------------------------------------------------------------------ + +float sdPlane( vec3 p ) +{ + return p.y; +} + +float sdSphere( vec3 p, float s ) +{ + return length(p)-s; +} + +float sdBox( vec3 p, vec3 b ) +{ + vec3 d = abs(p) - b; + return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); +} + +float sdEllipsoid( in vec3 p, in vec3 r ) +{ + return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z); +} + +float udRoundBox( vec3 p, vec3 b, float r ) +{ + return length(max(abs(p)-b,0.0))-r; +} + +float sdTorus( vec3 p, vec2 t ) +{ + return length( vec2(length(p.xz)-t.x,p.y) )-t.y; +} + +float sdHexPrism( vec3 p, vec2 h ) +{ + vec3 q = abs(p); +#if 0 + return max(q.z-h.y,max((q.x*0.866025+q.y*0.5),q.y)-h.x); +#else + float d1 = q.z-h.y; + float d2 = max((q.x*0.866025+q.y*0.5),q.y)-h.x; + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +#endif +} + +float sdCapsule( vec3 p, vec3 a, vec3 b, float r ) +{ + vec3 pa = p-a, ba = b-a; + float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); + return length( pa - ba*h ) - r; +} + +float sdEquilateralTriangle( in vec2 p ) +{ + const float k = sqrt(3.0); + p.x = abs(p.x) - 1.0; + p.y = p.y + 1.0/k; + if( p.x + k*p.y > 0.0 ) p = vec2( p.x - k*p.y, -k*p.x - p.y )/2.0; + p.x += 2.0 - 2.0*clamp( (p.x+2.0)/2.0, 0.0, 1.0 ); + return -length(p)*sign(p.y); +} + +float sdTriPrism( vec3 p, vec2 h ) +{ + vec3 q = abs(p); + float d1 = q.z-h.y; +#if 1 + // distance bound + float d2 = max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5; +#else + // correct distance + h.x *= 0.866025; + float d2 = sdEquilateralTriangle(p.xy/h.x)*h.x; +#endif + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +} + +float sdCylinder( vec3 p, vec2 h ) +{ + vec2 d = abs(vec2(length(p.xz),p.y)) - h; + return min(max(d.x,d.y),0.0) + length(max(d,0.0)); +} + +float sdCone( in vec3 p, in vec3 c ) +{ + vec2 q = vec2( length(p.xz), p.y ); + float d1 = -q.y-c.z; + float d2 = max( dot(q,c.xy), q.y); + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +} + +float sdConeSection( in vec3 p, in float h, in float r1, in float r2 ) +{ + float d1 = -p.y - h; + float q = p.y - h; + float si = 0.5*(r1-r2)/h; + float d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q ); + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +} + +float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height } +{ + // Tetrahedron = Octahedron - Cube + float box = sdBox( p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z) ); + + float d = 0.0; + d = max( d, abs( dot(p, vec3( -h.x, h.y, 0 )) )); + d = max( d, abs( dot(p, vec3( h.x, h.y, 0 )) )); + d = max( d, abs( dot(p, vec3( 0, h.y, h.x )) )); + d = max( d, abs( dot(p, vec3( 0, h.y,-h.x )) )); + float octa = d - h.z; + return max(-box,octa); // Subtraction + } + +float length2( vec2 p ) +{ + return sqrt( p.x*p.x + p.y*p.y ); +} + +float length6( vec2 p ) +{ + p = p*p*p; p = p*p; + return pow( p.x + p.y, 1.0/6.0 ); +} + +float length8( vec2 p ) +{ + p = p*p; p = p*p; p = p*p; + return pow( p.x + p.y, 1.0/8.0 ); +} + +float sdTorus82( vec3 p, vec2 t ) +{ + vec2 q = vec2(length2(p.xz)-t.x,p.y); + return length8(q)-t.y; +} + +float sdTorus88( vec3 p, vec2 t ) +{ + vec2 q = vec2(length8(p.xz)-t.x,p.y); + return length8(q)-t.y; +} + +float sdCylinder6( vec3 p, vec2 h ) +{ + return max( length6(p.xz)-h.x, abs(p.y)-h.y ); +} + +//------------------------------------------------------------------ + +float opS( float d1, float d2 ) +{ + return max(-d2,d1); +} + +vec2 opU( vec2 d1, vec2 d2 ) +{ + return (d1.x0.0 ) tmax = min( tmax, tp1 ); + float tp2 = (1.6-ro.y)/rd.y; if( tp2>0.0 ) { if( ro.y>1.6 ) tmin = max( tmin, tp2 ); + else tmax = min( tmax, tp2 ); } +#endif + + float t = tmin; + float m = -1.0; + for( int i=0; i<64; i++ ) + { + float precis = 0.0005*t; + vec2 res = map( ro+rd*t ); + if( res.xtmax ) break; + t += res.x; + m = res.y; + } + + if( t>tmax ) m=-1.0; + return vec2( t, m ); +} + + +float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax ) +{ + float res = 1.0; + float t = mint; + for( int i=0; i<16; i++ ) + { + float h = map( ro + rd*t ).x; + res = min( res, 8.0*h/t ); + t += clamp( h, 0.02, 0.10 ); + if( h<0.001 || t>tmax ) break; + } + return clamp( res, 0.0, 1.0 ); +} + +vec3 calcNormal( in vec3 pos ) +{ + vec2 e = vec2(1.0,-1.0)*0.5773*0.0005; + return normalize( e.xyy*map( pos + e.xyy ).x + + e.yyx*map( pos + e.yyx ).x + + e.yxy*map( pos + e.yxy ).x + + e.xxx*map( pos + e.xxx ).x ); + /* + vec3 eps = vec3( 0.0005, 0.0, 0.0 ); + vec3 nor = vec3( + map(pos+eps.xyy).x - map(pos-eps.xyy).x, + map(pos+eps.yxy).x - map(pos-eps.yxy).x, + map(pos+eps.yyx).x - map(pos-eps.yyx).x ); + return normalize(nor); + */ +} + +float calcAO( in vec3 pos, in vec3 nor ) +{ + float occ = 0.0; + float sca = 1.0; + for( int i=0; i<5; i++ ) + { + float hr = 0.01 + 0.12*float(i)/4.0; + vec3 aopos = nor * hr + pos; + float dd = map( aopos ).x; + occ += -(dd-hr)*sca; + sca *= 0.95; + } + return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ); +} + +// http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm +float checkersGradBox( in vec2 p ) +{ + // filter kernel + vec2 w = fwidth(p) + 0.001; + // analytical integral (box filter) + vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w; + // xor pattern + return 0.5 - 0.5*i.x*i.y; +} + +vec3 render( in vec3 ro, in vec3 rd ) +{ + vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8; + vec2 res = castRay(ro,rd); + float t = res.x; + float m = res.y; + if( m>-0.5 ) + { + vec3 pos = ro + t*rd; + vec3 nor = calcNormal( pos ); + vec3 ref = reflect( rd, nor ); + + // material + col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) ); + if( m<1.5 ) + { + + float f = checkersGradBox( 5.0*pos.xz ); + col = 0.3 + f*vec3(0.1); + } + + // lighting + float occ = calcAO( pos, nor ); + vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) ); + vec3 hal = normalize( lig-rd ); + float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 ); + float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); + float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); + float dom = smoothstep( -0.1, 0.1, ref.y ); + float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 ); + + dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); + dom *= calcSoftshadow( pos, ref, 0.02, 2.5 ); + + float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)* + dif * + (0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 )); + + vec3 lin = vec3(0.0); + lin += 1.30*dif*vec3(1.00,0.80,0.55); + lin += 0.40*amb*vec3(0.40,0.60,1.00)*occ; + lin += 0.50*dom*vec3(0.40,0.60,1.00)*occ; + lin += 0.50*bac*vec3(0.25,0.25,0.25)*occ; + lin += 0.25*fre*vec3(1.00,1.00,1.00)*occ; + col = col*lin; + col += 10.00*spe*vec3(1.00,0.90,0.70); + + col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) ); + } + + return vec3( clamp(col,0.0,1.0) ); +} + +mat3 setCamera( in vec3 ro, in vec3 ta, float cr ) +{ + vec3 cw = normalize(ta-ro); + vec3 cp = vec3(sin(cr), cos(cr),0.0); + vec3 cu = normalize( cross(cw,cp) ); + vec3 cv = normalize( cross(cu,cw) ); + return mat3( cu, cv, cw ); +} + +void main() +{ + vec3 tot = vec3(0.0); +#if AA>1 + for( int m=0; m1 + } + tot /= float(AA*AA); +#endif + + finalColor = vec4( tot, 1.0 ); +} diff --git a/assets/shaders/glsl330/reload.fs b/assets/shaders/glsl330/reload.fs new file mode 100644 index 00000000..21ce18e0 --- /dev/null +++ b/assets/shaders/glsl330/reload.fs @@ -0,0 +1,40 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; // Texture coordinates (sampler2D) +in vec4 fragColor; // Tint color + +// Output fragment color +out vec4 finalColor; // Output fragment color + +// Uniform inputs +uniform vec2 resolution; // Viewport resolution (in pixels) +uniform vec2 mouse; // Mouse pixel xy coordinates +uniform float time; // Total run time (in secods) + +// Draw circle +vec4 DrawCircle(vec2 fragCoord, vec2 position, float radius, vec3 color) +{ + float d = length(position - fragCoord) - radius; + float t = clamp(d, 0.0, 1.0); + return vec4(color, 1.0 - t); +} + +void main() +{ + vec2 fragCoord = gl_FragCoord.xy; + vec2 position = vec2(mouse.x, resolution.y - mouse.y); + float radius = 40.0; + + // Draw background layer + vec4 colorA = vec4(0.2,0.2,0.8, 1.0); + vec4 colorB = vec4(1.0,0.7,0.2, 1.0); + vec4 layer1 = mix(colorA, colorB, abs(sin(time*0.1))); + + // Draw circle layer + vec3 color = vec3(0.9, 0.16, 0.21); + vec4 layer2 = DrawCircle(fragCoord, position, radius, color); + + // Blend the two layers + finalColor = mix(layer1, layer2, layer2.a); +} diff --git a/assets/shaders/glsl330/scanlines.fs b/assets/shaders/glsl330/scanlines.fs new file mode 100644 index 00000000..22dc9cd5 --- /dev/null +++ b/assets/shaders/glsl330/scanlines.fs @@ -0,0 +1,49 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +// NOTE: Render size values must be passed from code +const float renderWidth = 800; +const float renderHeight = 450; +float offset = 0.0; + +uniform float time; + +void main() +{ + float frequency = renderHeight/3.0; +/* + // Scanlines method 1 + float tval = 0; //time + vec2 uv = 0.5 + (fragTexCoord - 0.5)*(0.9 + 0.01*sin(0.5*tval)); + + vec4 color = texture(texture0, fragTexCoord); + + color = clamp(color*0.5 + 0.5*color*color*1.2, 0.0, 1.0); + color *= 0.5 + 0.5*16.0*uv.x*uv.y*(1.0 - uv.x)*(1.0 - uv.y); + color *= vec4(0.8, 1.0, 0.7, 1); + color *= 0.9 + 0.1*sin(10.0*tval + uv.y*1000.0); + color *= 0.97 + 0.03*sin(110.0*tval); + + fragColor = color; +*/ + // Scanlines method 2 + float globalPos = (fragTexCoord.y + offset) * frequency; + float wavePos = cos((fract(globalPos) - 0.5)*3.14); + + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); + + finalColor = mix(vec4(0.0, 0.3, 0.0, 0.0), texelColor, wavePos); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/sobel.fs b/assets/shaders/glsl330/sobel.fs new file mode 100644 index 00000000..60fe56e4 --- /dev/null +++ b/assets/shaders/glsl330/sobel.fs @@ -0,0 +1,41 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables +uniform vec2 resolution = vec2(800 * 2, 450 * 2); + +void main() +{ + float x = 1.0/resolution.x; + float y = 1.0/resolution.y; + + vec4 horizEdge = vec4(0.0); + horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; + horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0; + horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; + horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; + horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0; + horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; + + vec4 vertEdge = vec4(0.0); + vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; + vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0; + vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; + vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; + vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0; + vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; + + vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb)); + + finalColor = vec4(edge, texture2D(texture0, fragTexCoord).a); +} \ No newline at end of file diff --git a/assets/shaders/glsl330/spotlight.fs b/assets/shaders/glsl330/spotlight.fs new file mode 100644 index 00000000..c573be8f --- /dev/null +++ b/assets/shaders/glsl330/spotlight.fs @@ -0,0 +1,65 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +#define MAX_SPOTS 3 + +struct Spot { + vec2 pos; // window coords of spot + float inner; // inner fully transparent centre radius + float radius; // alpha fades out to this radius +}; + +uniform Spot spots[MAX_SPOTS]; // Spotlight positions array +uniform float screenWidth; // Width of the screen + +void main() +{ + float alpha = 1.0; + + // Get the position of the current fragment (screen coordinates!) + vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y); + + // Find out which spotlight is nearest + float d = 65000; // some high value + int fi = -1; // found index + + for (int i = 0; i < MAX_SPOTS; i++) + { + for (int j = 0; j < MAX_SPOTS; j++) + { + float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius; + + if (d > dj) + { + d = dj; + fi = i; + } + } + } + + // d now equals distance to nearest spot... + // allowing for the different radii of all spotlights + if (fi != -1) + { + if (d > spots[fi].radius) alpha = 1.0; + else + { + if (d < spots[fi].inner) alpha = 0.0; + else alpha = (d - spots[fi].inner) / (spots[fi].radius - spots[fi].inner); + } + } + + // Right hand side of screen is dimly lit, + // could make the threshold value user definable + if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9; + + finalColor = vec4(0, 0, 0, alpha); +} diff --git a/assets/shaders/glsl330/swirl.fs b/assets/shaders/glsl330/swirl.fs new file mode 100644 index 00000000..4741e597 --- /dev/null +++ b/assets/shaders/glsl330/swirl.fs @@ -0,0 +1,47 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +// NOTE: Render size values should be passed from code +const float renderWidth = 800; +const float renderHeight = 450; + +float radius = 250.0; +float angle = 0.8; + +uniform vec2 center = vec2(200.0, 200.0); + +void main() +{ + vec2 texSize = vec2(renderWidth, renderHeight); + vec2 tc = fragTexCoord*texSize; + tc -= center; + + float dist = length(tc); + + if (dist < radius) + { + float percent = (radius - dist)/radius; + float theta = percent*percent*angle*8.0; + float s = sin(theta); + float c = cos(theta); + + tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c))); + } + + tc += center; + vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;; + + finalColor = vec4(color.rgb, 1.0);; +} \ No newline at end of file diff --git a/assets/shaders/glsl330/wave.fs b/assets/shaders/glsl330/wave.fs new file mode 100644 index 00000000..43efee23 --- /dev/null +++ b/assets/shaders/glsl330/wave.fs @@ -0,0 +1,37 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +uniform float secondes; + +uniform vec2 size; + +uniform float freqX; +uniform float freqY; +uniform float ampX; +uniform float ampY; +uniform float speedX; +uniform float speedY; + +void main() { + float pixelWidth = 1.0 / size.x; + float pixelHeight = 1.0 / size.y; + float aspect = pixelHeight / pixelWidth; + float boxLeft = 0.0; + float boxTop = 0.0; + + vec2 p = fragTexCoord; + p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth; + p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight; + + finalColor = texture(texture0, p)*colDiffuse*fragColor; +} From 7bff82a5c9f6f80d1b041af75c953273e48d73a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 15:52:12 +0200 Subject: [PATCH 04/18] shaders are working for models --- lib/Ray/sources/Model/Model.cpp | 11 +++++++++++ lib/Ray/sources/Model/Model.hpp | 9 +++++++++ sources/Runner/Runner.cpp | 17 +++++++++-------- sources/System/Renderer/RenderSystem.cpp | 19 +++++++++++++++++++ 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/lib/Ray/sources/Model/Model.cpp b/lib/Ray/sources/Model/Model.cpp index aab5fdc6..e99c151d 100644 --- a/lib/Ray/sources/Model/Model.cpp +++ b/lib/Ray/sources/Model/Model.cpp @@ -106,4 +106,15 @@ namespace RAY::Drawables::Drawables3D { { DrawModelEx(*this->_model, this->_position, this->_rotationAxis, this->_rotationAngle, this->_scale, this->_color); } + + void Model::setShader(const RAY::Shader &shader) + { + this->_originalShader = this->_model->materials[0].shader; + this->_model->materials[0].shader = *shader.getShaderPtr(); + } + + void Model::resetShader() + { + this->_model->materials[0].shader = this->_originalShader; + } } \ No newline at end of file diff --git a/lib/Ray/sources/Model/Model.hpp b/lib/Ray/sources/Model/Model.hpp index 7a7e3fdf..943385b8 100644 --- a/lib/Ray/sources/Model/Model.hpp +++ b/lib/Ray/sources/Model/Model.hpp @@ -11,6 +11,7 @@ #include "Drawables/Texture.hpp" #include "Drawables/ADrawable3D.hpp" #include "Model/ModelAnimation.hpp" +#include "Shaders/Shaders.hpp" #include #include #include @@ -77,6 +78,12 @@ namespace RAY::Drawables::Drawables3D { //! @return Scale const RAY::Vector3 & getScale(void); + //! @brief Set a shader on the model + void setShader(const RAY::Shader &shader); + + //! @brief Set the original shader (used to disable a shader) + void resetShader(); + void drawOn(RAY::Window &) override; private: @@ -90,6 +97,8 @@ namespace RAY::Drawables::Drawables3D { float _rotationAngle; //! @brief Scale of the shape RAY::Vector3 _scale; + //! @brief The original shaderId used to disable a shader effect + ::Shader _originalShader = {}; static RAY::Cache<::Model> _modelsCache; diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index e6a0dc33..79b112d3 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -70,7 +70,7 @@ namespace BBM .addComponent() .addComponent() .addComponent() - .addComponent("assets/shaders/glsl330/predator.fs") + .addComponent("assets/shaders/glsl330/grayscale.fs") .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 3) .addComponent(1) .addComponent() @@ -81,14 +81,15 @@ namespace BBM scene->addEntity("camera") .addComponent(8, 20, 7) .addComponent(Vector3f(8, 0, 8)); -// scene->addEntity("cube") -// .addComponent(5, 0, 5) -// .addComponent(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED) -// .addComponent() -// .addComponent() -// .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 3); + scene->addEntity("cube") + .addComponent(5, 0, 5) + .addComponent("assets/shaders/glsl330/grayscale.fs") + .addComponent(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED) + .addComponent() + .addComponent() + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 3); std::srand(std::time(nullptr)); - MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); + //MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); return scene; } diff --git a/sources/System/Renderer/RenderSystem.cpp b/sources/System/Renderer/RenderSystem.cpp index cdabb452..5ebfe531 100644 --- a/sources/System/Renderer/RenderSystem.cpp +++ b/sources/System/Renderer/RenderSystem.cpp @@ -8,7 +8,9 @@ #include "Component/Renderer/CameraComponent.hpp" #include "Component/Position/PositionComponent.hpp" #include "Component/Renderer/Drawable2DComponent.hpp" +#include #include "Drawables/ADrawable3D.hpp" +#include "Component/Shaders/ShaderComponent.hpp" namespace BBM { @@ -29,8 +31,25 @@ namespace BBM this->_window.useCamera(this->_camera); for (auto &[_, pos, drawable] : this->_wal.scene->view()) { + auto *modelShader = _.tryGetComponent(); + auto *shader = _.tryGetComponent(); + + if (modelShader) { + auto &model = dynamic_cast(*drawable.drawable); + model.setShader(modelShader->getShader()); + } + if (shader) { + RAY::Shader::BeginUsingCustomShader(shader->getShader()); + } drawable.drawable->setPosition(pos.position); drawable.drawable->drawOn(this->_window); + if (modelShader) { + auto &model = dynamic_cast(*drawable.drawable); + model.resetShader(); + } + if (shader) { + RAY::Shader::EndUsingCustomShader(); + } } this->_window.unuseCamera(); From 3e9037ed92d2a031a2d04e574d54a4b8b6db2568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Tue, 8 Jun 2021 16:10:20 +0200 Subject: [PATCH 05/18] renaming shaderDrawable to shaderDrawable 2d --- sources/Component/Shaders/ShaderComponent.cpp | 2 +- sources/Component/Shaders/ShaderComponent.hpp | 10 ++++----- sources/Runner/Runner.cpp | 16 ++++++++------ sources/System/Renderer/RenderSystem.cpp | 21 ++++++++++--------- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/sources/Component/Shaders/ShaderComponent.cpp b/sources/Component/Shaders/ShaderComponent.cpp index a87068b6..1b28a5bd 100644 --- a/sources/Component/Shaders/ShaderComponent.cpp +++ b/sources/Component/Shaders/ShaderComponent.cpp @@ -42,7 +42,7 @@ namespace BBM { } - ShaderComponentDrawable::ShaderComponentDrawable(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath) + ShaderComponentDrawable2D::ShaderComponentDrawable2D(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath) : ShaderComponent(entity, std::move(fragmentFilePath), std::move(vertexFilePath)) { } diff --git a/sources/Component/Shaders/ShaderComponent.hpp b/sources/Component/Shaders/ShaderComponent.hpp index c20a7e6c..4b541d0c 100644 --- a/sources/Component/Shaders/ShaderComponent.hpp +++ b/sources/Component/Shaders/ShaderComponent.hpp @@ -62,17 +62,17 @@ namespace BBM ShaderComponentModel &operator=(const ShaderComponentModel &) = delete; }; - class ShaderComponentDrawable : public ShaderComponent + class ShaderComponentDrawable2D : public ShaderComponent { public: //! @brief ctor //! @note use empty string to omit a file - ShaderComponentDrawable(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath = ""); + ShaderComponentDrawable2D(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath = ""); //! @brief Default copy ctor - ShaderComponentDrawable(const ShaderComponentDrawable &) = default; + ShaderComponentDrawable2D(const ShaderComponentDrawable2D &) = default; //! @brief Default dtor - ~ShaderComponentDrawable() override = default; + ~ShaderComponentDrawable2D() override = default; //! @brief Default assignment operator - ShaderComponentDrawable &operator=(const ShaderComponentDrawable &) = delete; + ShaderComponentDrawable2D &operator=(const ShaderComponentDrawable2D &) = delete; }; } \ No newline at end of file diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 79b112d3..6be5b05d 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -8,6 +8,7 @@ #include "System/Renderer/RenderSystem.hpp" #include #include +#include #include #include #include @@ -24,12 +25,14 @@ #include #include #include +#include #include "Component/Animation/AnimationsComponent.hpp" #include "System/Animation/AnimationsSystem.hpp" #include "Component/Shaders/ShaderComponent.hpp" #include "Map/Map.hpp" namespace RAY3D = RAY::Drawables::Drawables3D; +namespace RAY2D = RAY::Drawables::Drawables2D; namespace BBM { @@ -70,7 +73,7 @@ namespace BBM .addComponent() .addComponent() .addComponent() - .addComponent("assets/shaders/glsl330/grayscale.fs") + .addComponent("assets/shaders/glsl330/predator.fs") .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 3) .addComponent(1) .addComponent() @@ -81,15 +84,16 @@ namespace BBM scene->addEntity("camera") .addComponent(8, 20, 7) .addComponent(Vector3f(8, 0, 8)); - scene->addEntity("cube") + /*scene->addEntity("cube") .addComponent(5, 0, 5) - .addComponent("assets/shaders/glsl330/grayscale.fs") - .addComponent(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED) + .addComponent("assets/shaders/glsl330/grayscale.fs") + //.addComponent(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED) + .addComponent(BBM::Vector2f{200,200}, BBM::Vector2f{200, 200}, RED) .addComponent() .addComponent() - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 3); + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, 3); */ std::srand(std::time(nullptr)); - //MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); + MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); return scene; } diff --git a/sources/System/Renderer/RenderSystem.cpp b/sources/System/Renderer/RenderSystem.cpp index 5ebfe531..3796f2c3 100644 --- a/sources/System/Renderer/RenderSystem.cpp +++ b/sources/System/Renderer/RenderSystem.cpp @@ -30,33 +30,34 @@ namespace BBM this->_window.clear(); this->_window.useCamera(this->_camera); - for (auto &[_, pos, drawable] : this->_wal.scene->view()) { - auto *modelShader = _.tryGetComponent(); - auto *shader = _.tryGetComponent(); + for (auto &[entity, pos, drawable] : this->_wal.scene->view()) { + auto *modelShader = entity.tryGetComponent(); if (modelShader) { auto &model = dynamic_cast(*drawable.drawable); model.setShader(modelShader->getShader()); } - if (shader) { - RAY::Shader::BeginUsingCustomShader(shader->getShader()); - } drawable.drawable->setPosition(pos.position); drawable.drawable->drawOn(this->_window); if (modelShader) { auto &model = dynamic_cast(*drawable.drawable); model.resetShader(); } - if (shader) { - RAY::Shader::EndUsingCustomShader(); - } } this->_window.unuseCamera(); // TODO sort entities based on the Z axis - for (auto &[_, pos, drawable] : this->_wal.scene->view()) { + for (auto &[entity, pos, drawable] : this->_wal.scene->view()) { + auto *shader = entity.tryGetComponent(); + + if (shader) { + RAY::Shader::BeginUsingCustomShader(shader->getShader()); + } drawable.drawable->setPosition(Vector2f(pos.position.x, pos.position.y)); drawable.drawable->drawOn(this->_window); + if (shader) { + RAY::Shader::EndUsingCustomShader(); + } } if (this->_debugMode) this->_window.drawFPS(Vector2f()); From c69c87e910fa448df4330a649b83bc2e6f297915 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 8 Jun 2021 17:52:52 +0200 Subject: [PATCH 06/18] Trying things --- sources/Models/Vector3.hpp | 5 +++ .../System/BombHolder/BombHolderSystem.cpp | 36 +++++++++++++------ .../System/BombHolder/BombHolderSystem.hpp | 3 ++ tests/CollisionTest.cpp | 6 ++++ 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/sources/Models/Vector3.hpp b/sources/Models/Vector3.hpp index d4ba7337..a2266e07 100644 --- a/sources/Models/Vector3.hpp +++ b/sources/Models/Vector3.hpp @@ -168,6 +168,11 @@ namespace BBM return (point * this) / std::pow(this->magnitude(), 2) * this; } + Vector3 round() const requires(std::is_floating_point_v) + { + return Vector3(std::round(this->x), std::round(this->y), std::round(this->z)); + } + operator RAY::Vector3() const requires(std::is_same_v) { return RAY::Vector3(this->x, this->y, this->z); diff --git a/sources/System/BombHolder/BombHolderSystem.cpp b/sources/System/BombHolder/BombHolderSystem.cpp index 2d46b3b8..10c21960 100644 --- a/sources/System/BombHolder/BombHolderSystem.cpp +++ b/sources/System/BombHolder/BombHolderSystem.cpp @@ -7,6 +7,8 @@ #include "Component/Renderer/Drawable3DComponent.hpp" #include "BombHolderSystem.hpp" #include "Component/Health/HealthComponent.hpp" +#include +#include using namespace std::chrono_literals; namespace RAY3D = RAY::Drawables::Drawables3D; @@ -14,29 +16,41 @@ namespace RAY3D = RAY::Drawables::Drawables3D; namespace BBM { std::chrono::nanoseconds BombHolderSystem::explosionTimer = 3s; - float BombHolderSystem::explosionRadius = 3; BombHolderSystem::BombHolderSystem(WAL::Wal &wal) : System(wal) {} - void BombHolderSystem::_bombExplosion(WAL::Entity &bomb, WAL::Wal &wal) + void BombHolderSystem::_dispatchExplosion(Vector3f position, WAL::Wal &wal, int count) { - bomb.scheduleDeletion(); - auto &bombPosition = bomb.getComponent(); - wal.getSystem().dispatchEvent([&bombPosition](WAL::Entity &entity){ + if (count <= 0) + return; + std::cout << position << " count: " << count << std::endl; + // TODO use it in a global context with a find and so on. + wal.getSystem().dispatchEvent([position, &wal, count](WAL::Entity &entity) { auto *health = entity.tryGetComponent(); auto *pos = entity.tryGetComponent(); - if (!health || !pos) - return; - if (pos->position.distance(bombPosition.position) > BombHolderSystem::explosionRadius) - return; - // TODO do a raycast here to only remove health to entities that are not behind others. - health->takeDmg(1); + if (health && pos && pos->position.round() == position) { + std::cout << pos->position << std::endl; + health->takeDmg(1); + } + else { + _dispatchExplosion(position + Vector3f(1, 0, 0), wal, count - 1); + _dispatchExplosion(position + Vector3f(-1, 0, 0), wal, count - 1); + _dispatchExplosion(position + Vector3f(0, 0, 1), wal, count - 1); + _dispatchExplosion(position + Vector3f(0, 0, -1), wal, count - 1); + } }); } + void BombHolderSystem::_bombExplosion(WAL::Entity &bomb, WAL::Wal &wal) + { + bomb.scheduleDeletion(); + auto position = bomb.getComponent().position.round(); + _dispatchExplosion(position, wal, 2); + } + void BombHolderSystem::_spawnBomb(Vector3f position) { this->_wal.scene->scheduleNewEntity("Bomb") diff --git a/sources/System/BombHolder/BombHolderSystem.hpp b/sources/System/BombHolder/BombHolderSystem.hpp index fd3d4e78..105f9139 100644 --- a/sources/System/BombHolder/BombHolderSystem.hpp +++ b/sources/System/BombHolder/BombHolderSystem.hpp @@ -20,6 +20,9 @@ namespace BBM //! @brief Spawn a bomb at the specified position. void _spawnBomb(Vector3f position); + //! @brief Spawn a bomb at the specified position. + static void _dispatchExplosion(Vector3f position, WAL::Wal &, int count); + //! @brief The method triggered when the bomb explode. static void _bombExplosion(WAL::Entity &bomb, WAL::Wal &); public: diff --git a/tests/CollisionTest.cpp b/tests/CollisionTest.cpp index 394b1ccc..51c7200c 100644 --- a/tests/CollisionTest.cpp +++ b/tests/CollisionTest.cpp @@ -94,4 +94,10 @@ TEST_CASE("Collsion test with movable", "[Component][System]") REQUIRE(entity.getComponent().position.x == 0.0); REQUIRE(entity.getComponent().position.y == 0.0); REQUIRE(entity.getComponent().position.z == 0.0); +} + +TEST_CASE("Vector round", "[Vector]") +{ + Vector3f v(1.3, 1.5, 1.7); + REQUIRE(v.round() == Vector3f(1, 2, 2)); } \ No newline at end of file From 8f92e7a3372651314bffdc13135e86b7d5679e26 Mon Sep 17 00:00:00 2001 From: Askou Date: Wed, 9 Jun 2021 10:28:28 +0200 Subject: [PATCH 07/18] replace stairs by bumper and add assets for it --- assets/map/bumper.png | Bin 2739 -> 26301 bytes sources/Map/Map.cpp | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/map/bumper.png b/assets/map/bumper.png index a86b67f2fdd6f701f1b353ad512b3b3b7386c135..63632844a4d7fbee363388dbf6af8090188d29f7 100644 GIT binary patch literal 26301 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

9yJ72F91@7NU3e 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 Ef=c^C2><{9 literal 2739 zcma);X*3l28^?b$%-FJ|W|XdMqs7!@EDa_Z8Cx=ntXaa4Z5TU=8IzPH$}WsG*HWV_ z$#zjHBF378iW`kBp$1v5`|khl{$G5b=bYy}=X_s0-*cW%>_w7+u%M(M06^HtkZ88s z>Hmr!zFS|Ob?O2D;_IQSd(p$i1%PAsgYM&vd35&Q(#Clb<&W2hJvA(FE|3v)KEAgm z7Kvq4x>YY8dEsLhybm=ZcpAyL?X!Nm|98HwD9G-Tsiu?JTcvM z0GH1)3T>x0H!WpSolkyOoDlcHRc%x)6;NA_^6mf2?0Q3cZ=8xkq}BYxrAv&9dMMZ*P>?Ad+Nh z8FEZ@W%8?!r#y8U9+;i%Ggj zGp6fl&-^C&>sNu*FN2Io&}DpW8RmHE=m}QPsLwm6XM~y;Zws{#=NORftvZqm`YM9+8zttc@XVgvC#b zx{=!7j|?sjyd@xZ-2njrC=mNMCcHpqHy-~rQcZD{oxz za~W^K+|y`@-xF!3M?NGq4V#bY8`y@Z9tB;wG=Its%eD%(@{A;+baE#i{`pqF-*w9J z6W@|CkKV>@744quH+%NuUT?ockhI^0_}>2O*~DUz{9q0^kbdobC-*soUs=n^vCz^t zInE($w5|8?)1Av3&6pXtzr9w*@$crKh=Y zr~#Mu7W=XBkiCFx?q~CsF@3{&ic?>dMtB*@Hg#??rLWih68{~hqwc3?&ANDFgDwBW z@!NJ5n_A}5)#1&Q?xM35c>%=X6Q%6WMs@SnXO`v8P`l8Z*D;fI8u|5WjlG>E`l! zpr&p?ZvY?1pO1sRCXq-2cTZFiU0a^B&a%G|L%v&NWGn0OELa% zi1NAmO_kR$vQ(fxR3=*Pg2>~_)xOTjl94>4eeV7|(z7E)cKV6(nq!Tsy;3FbkJ3tB z_1vA#sNJnA&NIcWdnvT|oHl?uy{ZFrKXYJyp z%33bZ8XYW-8w@&VVd-*&%PHRLKN?!->HOXTQyjNF1#VGb}#8^3ZymVT+&CH;irAbu-oaa z19(0$1dl8~%E9jZVKN16U@F*bwxJN*J4}HTYPKfS0*4r+j7jRaef@>%rdam-XQ?D~ zw|OWa1o@-T!0vvNWGLL1^40m9myld~-U@Hc=};3nT^HC2(X{`Y_9+P^UC5IEI;#dO zx#zF3XURF8dCzsOB9Qn=0KKsN8GG%QsyL|HG^&Uc zK31AMJA-fm0$3k?E$=I3xQ;U<@xHlkxUGw0Cmb9e^;XP#sJD1gX}zu5%L$egpnN97 zG2E1pjt<>mw3ZKlkYJ3RJ-B))$mP5^dBB$bwdYeO7*W|sJFRFyG$=QbwMm2)CMzUA zhkO{L=~-`wzmQ0Z^U=Fv-y38g*$bmS=-t( z?I6~YM?NOXjJBYmBkGJ3JG#;0{g?!MOq!t^x1*F=hW4*85BSjE(Sp$R-Tj6u5aIv^ z?)oNj7z--uTmwwFm(+GRV@OM$LyGWHw*xCPWFI<@_Te3Es+!#1dCiQQkKG`IAt%tqxz(GfQcC-yxFMh`ZdXRYnBDt1A0?y#WhYlWLBsb7?id3w+AQEC9 z+aJ{PMr}1533nEGQM&cHy&CuoQHi{<7_-2oEs*EGe27!vQnEWRk4 z^h(Z2Lb}Ib;-r$2FQ^)A5|qfl*rr^ajo*Dl(QACo=52Rt;`uN#f%B}o+iI7^_<^BE z4y*i0w$*84u@SaWL5`(VZB$@5he#zCBpGP`$xNrTjT=@-DkFJAU;+bAu(gb#FHo!MC!vm!2&lr_x%MEJTEVp`CI0R7 z^-9`E8-@AuZ zKJMTGL{i#r6&`MOGi|9&@R1Z+5q%i4aCUBQYIY$@?rnPcVPNf^d;@{78Z^!n^zn!6 lg35nV!2ibz|GVW$*b=f7upO1vL}c$e03$sTk#+7W;~xMg(OUoj diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 5e8a9a2e..5bf045a5 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -75,7 +75,7 @@ namespace BBM .addComponent(Vector3f((width + 1) / 2, 0, -1)) .addComponent( WAL::Callback(), - &MapGenerator::wallCollide, 0.25, .75) + &MapGenerator::wallCollide, Vector3f(-(width + 1) / 2 , 0.25, 0.25), Vector3f(width + 1, 2, 0.75)) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); @@ -83,7 +83,7 @@ namespace BBM .addComponent(Vector3f((width + 1) / 2, 0, height + 1)) .addComponent( WAL::Callback(), - &MapGenerator::wallCollide, 0.25, .75) + &MapGenerator::wallCollide, Vector3f(-(width + 1) / 2 , 0.25, 0.25), Vector3f(width + 1, 2, 0.75)) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); @@ -91,7 +91,7 @@ namespace BBM .addComponent(Vector3f(width + 1, 0, height / 2)) .addComponent( WAL::Callback(), - &MapGenerator::wallCollide, 0.25, .75) + &MapGenerator::wallCollide, Vector3f(0.25, 0.25, -(height + 1) / 2 ), Vector3f(0.75, 2, height + 1)) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); @@ -99,7 +99,7 @@ namespace BBM .addComponent(Vector3f(-1, 0, height / 2)) .addComponent( WAL::Callback(), - &MapGenerator::wallCollide, 0.25, .75) + &MapGenerator::wallCollide, Vector3f(0.25, 0.25, -(height + 1) / 2 ), Vector3f(0.75, 2, height + 1)) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); @@ -273,10 +273,10 @@ namespace BBM map[std::make_tuple(i, 1, 0)] = map[std::make_tuple(i, 0, 0)]; map[std::make_tuple(i, 0, 0)] = UPPERFLOOR; } - map[std::make_tuple(0, 0, height - 1)] = STAIRS; - map[std::make_tuple(0, 0, 1)] = STAIRS; - map[std::make_tuple(width, 0, height - 1)] = STAIRS; - map[std::make_tuple(width, 0, 1)] = STAIRS; + map[std::make_tuple(0, -1, height - 1)] = BUMPER; + map[std::make_tuple(0, -1, 1)] = BUMPER; + map[std::make_tuple(width, -1, height - 1)] = BUMPER; + map[std::make_tuple(width, -1, 1)] = BUMPER; map[std::make_tuple(width / 2, -1, height - 1)] = BUMPER; map[std::make_tuple(width / 2, -1, 1)] = BUMPER; } @@ -289,10 +289,10 @@ namespace BBM map[std::make_tuple(i, 0, j)] = UPPERFLOOR; } } - map[std::make_tuple(width / 2 - width / 8, 0, height / 2 + height / 4 + 1)] = STAIRS; - map[std::make_tuple(width / 2 + width / 8, 0, height / 2 - height / 4 - 1)] = STAIRS; - map[std::make_tuple(width / 2 - width / 4 - 1, 0, height / 2 - height / 8)] = STAIRS; - map[std::make_tuple(width / 2 + width / 4 + 1, 0, height / 2 + height / 8)] = STAIRS; + map[std::make_tuple(width / 2 - width / 8, -1, height / 2 + height / 4 + 1)] = BUMPER; + map[std::make_tuple(width / 2 + width / 8, -1, height / 2 - height / 4 - 1)] = BUMPER; + map[std::make_tuple(width / 2 - width / 4 - 1, -1, height / 2 - height / 8)] = BUMPER; + map[std::make_tuple(width / 2 + width / 4 + 1, -1, height / 2 + height / 8)] = BUMPER; } return map; } From 6f24139e2909196b719aa3dcb47c0a5f5e2a883f Mon Sep 17 00:00:00 2001 From: Askou Date: Wed, 9 Jun 2021 10:45:14 +0200 Subject: [PATCH 08/18] remove stairs --- sources/Map/Map.cpp | 12 ------------ sources/Map/Map.hpp | 7 ------- 2 files changed, 19 deletions(-) diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 5bf045a5..98020d17 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -129,7 +129,6 @@ namespace BBM {HOLE, &createHole}, {FLOOR, &createFloor}, {BUMPER, &createBumper}, - {STAIRS, &createStairs}, {UPPERFLOOR, &createUpperFloor}, }; @@ -231,17 +230,6 @@ namespace BBM }); */ } - void MapGenerator::createStairs(Vector3f coords, std::shared_ptr scene) - { - static const std::string stairsObj = stairsPath + objExtension; - static const std::string stairsPng = stairsPath + imageExtension; - - scene->addEntity("Stairs Block") - .addComponent(coords) - //.addComponent(1) - .addComponent(stairsObj, std::make_pair(MAP_DIFFUSE, stairsPng)); - } - bool MapGenerator::isCloseToBlockType(std::map, BlockType> map, int x, int y, int z, BlockType blockType) { diff --git a/sources/Map/Map.hpp b/sources/Map/Map.hpp index 4a961cbc..f99fd550 100644 --- a/sources/Map/Map.hpp +++ b/sources/Map/Map.hpp @@ -37,7 +37,6 @@ namespace BBM UPPERFLOOR, FLOOR, BUMPER, - STAIRS, SPAWNER, UNBREAKABLE }; @@ -109,12 +108,6 @@ namespace BBM //! @brief Create upper floor of the map static void createUpperFloor(Vector3f coords, std::shared_ptr scene); - - //! @param coords coords of the element - //! @param scene Scene where the map is instanced - //! @brief Create stair of the map - static void createStairs(Vector3f coords, std::shared_ptr scene); - //! @param map Map to load with block declared inside //! @param width Width of the map //! @param height Height of the map From b6b2b5ffc9eca6c1fde23eb54d7dbbbe28784e1e Mon Sep 17 00:00:00 2001 From: Askou Date: Wed, 9 Jun 2021 10:57:55 +0200 Subject: [PATCH 09/18] fix useless if that called STAIRS enum --- sources/Map/Map.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 98020d17..8e43f8ef 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -299,8 +299,6 @@ namespace BBM { for (int i = 0; i < width + 1; i++) for (int j = 0; j < height; j++) { - if (map[std::make_tuple(i, 0, j)] == BREAKABLE && isCloseToBlockType(map, i, 0, j, STAIRS)) - map[std::make_tuple(i, 0, j)] = NOTHING; if (map[std::make_tuple(i, 0, j)] == BREAKABLE && map[std::make_tuple(i, -1, j)] == BUMPER) map[std::make_tuple(i, 0, j)] = NOTHING; } From 70524fa935f69c0917e3300ab0d81214affbbff3 Mon Sep 17 00:00:00 2001 From: "arthur.jamet" Date: Wed, 9 Jun 2021 11:14:53 +0200 Subject: [PATCH 10/18] cache system add lonely functionnality --- lib/Ray/sources/Audio/Music.cpp | 4 ++-- lib/Ray/sources/Audio/Music.hpp | 3 ++- lib/Ray/sources/Audio/Sound.cpp | 4 ++-- lib/Ray/sources/Audio/Sound.hpp | 3 ++- lib/Ray/sources/Drawables/Image.cpp | 4 ++-- lib/Ray/sources/Drawables/Image.hpp | 3 ++- lib/Ray/sources/Drawables/Texture.cpp | 4 ++-- lib/Ray/sources/Drawables/Texture.hpp | 3 ++- lib/Ray/sources/Font.cpp | 4 ++-- lib/Ray/sources/Font.hpp | 3 ++- lib/Ray/sources/Model/Model.cpp | 4 ++-- lib/Ray/sources/Model/Model.hpp | 3 ++- lib/Ray/sources/Utils/Cache.hpp | 31 +++++++++++++++++++-------- 13 files changed, 46 insertions(+), 27 deletions(-) diff --git a/lib/Ray/sources/Audio/Music.cpp b/lib/Ray/sources/Audio/Music.cpp index db3dae78..670ba2f8 100644 --- a/lib/Ray/sources/Audio/Music.cpp +++ b/lib/Ray/sources/Audio/Music.cpp @@ -10,8 +10,8 @@ RAY::Cache<::Music> RAY::Audio::Music::_musicsCache(LoadMusicStream, UnloadMusicStream); -RAY::Audio::Music::Music(const std::string &path): - _music(this->_musicsCache.fetch(path.c_str())) +RAY::Audio::Music::Music(const std::string &path, bool lonely): + _music(this->_musicsCache.fetch(path, lonely)) { } diff --git a/lib/Ray/sources/Audio/Music.hpp b/lib/Ray/sources/Audio/Music.hpp index c28e8089..2c35bfcd 100644 --- a/lib/Ray/sources/Audio/Music.hpp +++ b/lib/Ray/sources/Audio/Music.hpp @@ -19,7 +19,8 @@ namespace RAY::Audio public: //! @brief Load Music stream from file - Music(const std::string &path); + //! @param lonely: should be set to true if the entity's loaded data must be independant from others + Music(const std::string &path, bool lonely = false); //! @brief Default destructor ~Music() = default; diff --git a/lib/Ray/sources/Audio/Sound.cpp b/lib/Ray/sources/Audio/Sound.cpp index da8df7ba..de1002bc 100644 --- a/lib/Ray/sources/Audio/Sound.cpp +++ b/lib/Ray/sources/Audio/Sound.cpp @@ -9,8 +9,8 @@ RAY::Cache<::Sound> RAY::Audio::Sound::_soundsCache(LoadSound, UnloadSound); -RAY::Audio::Sound::Sound(const std::string &path): - _sound(_soundsCache.fetch(path.c_str())) +RAY::Audio::Sound::Sound(const std::string &path, bool lonely): + _sound(_soundsCache.fetch(path, lonely)) { } diff --git a/lib/Ray/sources/Audio/Sound.hpp b/lib/Ray/sources/Audio/Sound.hpp index 00ba3ddc..0f7a7ff5 100644 --- a/lib/Ray/sources/Audio/Sound.hpp +++ b/lib/Ray/sources/Audio/Sound.hpp @@ -20,7 +20,8 @@ namespace RAY::Audio public: //! @brief Load Sound stream from file - Sound(const std::string &path); + //! @param lonely: should be set to true if the entity's loaded data must be independant from others + Sound(const std::string &path, bool lonely = false); //! @brief Default destructor ~Sound() = default; diff --git a/lib/Ray/sources/Drawables/Image.cpp b/lib/Ray/sources/Drawables/Image.cpp index 9676bc95..685aa376 100644 --- a/lib/Ray/sources/Drawables/Image.cpp +++ b/lib/Ray/sources/Drawables/Image.cpp @@ -12,9 +12,9 @@ namespace RAY { Cache<::Image> Image::_imagesCache(LoadImage, UnloadImage); - Image::Image(const std::string &filename): + Image::Image(const std::string &filename, bool lonely): Rectangle(Vector2(0, 0), Vector2(0, 0), WHITE), - _image(_imagesCache.fetch(filename)) + _image(_imagesCache.fetch(filename, lonely)) { this->_dimensions = Vector2(this->_image->width, this->_image->height); } diff --git a/lib/Ray/sources/Drawables/Image.hpp b/lib/Ray/sources/Drawables/Image.hpp index 840be518..911f1a96 100644 --- a/lib/Ray/sources/Drawables/Image.hpp +++ b/lib/Ray/sources/Drawables/Image.hpp @@ -21,7 +21,8 @@ namespace RAY public: //! @brief Create an image, loading a file //! @param filename: path to file to load - Image(const std::string &filename); + //! @param lonely: should be set to true if the entity's loaded data must be independant from others + Image(const std::string &filename, bool lonely = false); //! @brief A default copy constructor Image(const Image &image) = default; diff --git a/lib/Ray/sources/Drawables/Texture.cpp b/lib/Ray/sources/Drawables/Texture.cpp index befe8579..821a743d 100644 --- a/lib/Ray/sources/Drawables/Texture.cpp +++ b/lib/Ray/sources/Drawables/Texture.cpp @@ -11,8 +11,8 @@ namespace RAY { Cache<::Texture> Texture::_texturesCache(LoadTexture, UnloadTexture); - Texture::Texture(const std::string &filename): - _texture(_texturesCache.fetch(filename)), + Texture::Texture(const std::string &filename, bool lonely): + _texture(_texturesCache.fetch(filename, lonely)), _resourcePath(filename) { } diff --git a/lib/Ray/sources/Drawables/Texture.hpp b/lib/Ray/sources/Drawables/Texture.hpp index 6fb2be66..2952b58d 100644 --- a/lib/Ray/sources/Drawables/Texture.hpp +++ b/lib/Ray/sources/Drawables/Texture.hpp @@ -19,7 +19,8 @@ namespace RAY public: //! @brief Create an texture, loading a file //! @param filename: path to file to load - Texture(const std::string &filename); + //! @param lonely: should be set to true if the entity's loaded data must be independant from others + Texture(const std::string &filename, bool lonely = false); //! @brief A texture is copy constructable Texture(const Texture &) = default; diff --git a/lib/Ray/sources/Font.cpp b/lib/Ray/sources/Font.cpp index c4288463..89bf9517 100644 --- a/lib/Ray/sources/Font.cpp +++ b/lib/Ray/sources/Font.cpp @@ -9,8 +9,8 @@ RAY::Cache<::Font> RAY::Font::_fontsCache(LoadFont, UnloadFont); -RAY::Font::Font(const std::string &filename): - _font(_fontsCache.fetch(filename)) +RAY::Font::Font(const std::string &filename, bool lonely): + _font(_fontsCache.fetch(filename, lonely)) { } diff --git a/lib/Ray/sources/Font.hpp b/lib/Ray/sources/Font.hpp index a403dcb3..1aaeb173 100644 --- a/lib/Ray/sources/Font.hpp +++ b/lib/Ray/sources/Font.hpp @@ -19,7 +19,8 @@ namespace RAY public: //! @brief Create an font, loading a file //! @param filename: path to file to load - Font(const std::string &filename); + //! @param lonely: should be set to true if the entity's loaded data must be independant from others + Font(const std::string &filename, bool lonely = false); //! @brief A default copy constructor Font(const Font &) = default; diff --git a/lib/Ray/sources/Model/Model.cpp b/lib/Ray/sources/Model/Model.cpp index aab5fdc6..77951483 100644 --- a/lib/Ray/sources/Model/Model.cpp +++ b/lib/Ray/sources/Model/Model.cpp @@ -19,9 +19,9 @@ namespace RAY::Drawables::Drawables3D { const RAY::Vector3 &scale, const RAY::Vector3 &position, const RAY::Vector3 &rotationAxis, - float rotationAngle) + float rotationAngle, bool lonely) : ADrawable3D(position, WHITE), - _model(_modelsCache.fetch(filename)), + _model(_modelsCache.fetch(filename, lonely)), _rotationAxis(rotationAxis), _rotationAngle(rotationAngle), _scale(scale) diff --git a/lib/Ray/sources/Model/Model.hpp b/lib/Ray/sources/Model/Model.hpp index 7a7e3fdf..40c9a9dd 100644 --- a/lib/Ray/sources/Model/Model.hpp +++ b/lib/Ray/sources/Model/Model.hpp @@ -25,12 +25,13 @@ namespace RAY::Drawables::Drawables3D { //! @brief Create an model, loading a file //! @param filePath: path to file to load + //! @param lonely: should be set to true if the entity's loaded data must be independant from others Model(const std::string &filePath, std::optional> texture = std::nullopt, const RAY::Vector3 &scale = RAY::Vector3(1, 1, 1), const RAY::Vector3 &position = {0, 0, 0}, const RAY::Vector3 &rotationAxis = RAY::Vector3(0, 1, 0), - float rotationAngle = 0); + float rotationAngle = 0, bool lonely = false); //! @brief Create an model, loading a file //! @param mesh: mesh to load diff --git a/lib/Ray/sources/Utils/Cache.hpp b/lib/Ray/sources/Utils/Cache.hpp index 653933f5..c0e370d1 100644 --- a/lib/Ray/sources/Utils/Cache.hpp +++ b/lib/Ray/sources/Utils/Cache.hpp @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include namespace RAY { //! @brief A templated class used to cache ressources, indexed with a string @@ -31,16 +34,26 @@ namespace RAY { Cache &operator=(const Cache &) = default; //! @param path path of the file + //! @param lonely: should be set to true if the loaded data must be held by no other active entites //! @return a newly loaded ressource if it hasn't be previously loaded, or one from cache - std::shared_ptrfetch(const std::string &path) + std::shared_ptrfetch(const std::string &path, bool lonely = false) { - if (this->_cache.find(path) == this->_cache.end()) - this->_cache.emplace(path, std::shared_ptr( - new T(this->_dataLoader(path.c_str())), [this](T *p) { - this->_dataUnloader(*p); - delete p; - })); - return _cache[path]; + if (!this->_cache.contains(path)) + this->_cache.emplace(path, std::vector>()); + std::vector> &matchingDataVector = this->_cache.at(path); + + for (std::shared_ptr &i: matchingDataVector) { + if (!lonely) + return i; + if (lonely && i.use_count() == 1) + return i; + } + matchingDataVector.emplace_back(std::shared_ptr( + new T(this->_dataLoader(path.c_str())), [this](T *p) { + this->_dataUnloader(*p); + delete p; + })); + return matchingDataVector.back(); }; private: //! @brief function to call to load data @@ -50,7 +63,7 @@ namespace RAY { std::function _dataUnloader; //! @brief map storing shared ptr of caches - std::unordered_map> _cache; + std::unordered_map>> _cache; }; template<> From a6b4f1717a7d8842ffc2e9835fc22a41536aa0a4 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Wed, 9 Jun 2021 12:10:19 +0200 Subject: [PATCH 11/18] Finishing exploson radius --- CMakeLists.txt | 1 + sources/Component/Tag/TagComponent.hpp | 54 +++++++++++++++++++ sources/Map/Map.cpp | 8 +++ sources/Runner/Runner.cpp | 2 + .../System/BombHolder/BombHolderSystem.cpp | 33 ++++++------ sources/System/Event/EventSystem.cpp | 8 +++ sources/System/Event/EventSystem.hpp | 7 ++- 7 files changed, 94 insertions(+), 19 deletions(-) create mode 100644 sources/Component/Tag/TagComponent.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 588f5096..0583a352 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,6 +81,7 @@ set(SOURCES sources/Component/Animator/AnimatorComponent.hpp sources/System/Animator/AnimatorSystem.cpp sources/System/Animator/AnimatorSystem.hpp + sources/Component/Tag/TagComponent.hpp ) add_executable(bomberman sources/main.cpp diff --git a/sources/Component/Tag/TagComponent.hpp b/sources/Component/Tag/TagComponent.hpp new file mode 100644 index 00000000..00fa27d5 --- /dev/null +++ b/sources/Component/Tag/TagComponent.hpp @@ -0,0 +1,54 @@ +// +// Created by Zoe Roux on 6/9/21. +// + +#pragma once + +#include +#include + +namespace BBM +{ + template + struct StringLiteral + { + public: + char value[I]; + + //! @brief Implicitly convert an array of char to a string literal. + constexpr StringLiteral(const char (&str)[I]) // NOLINT(google-explicit-constructor) + : value() + { + std::copy_n(str, I, value); + } + //! @brief A string literal is copy constructable. + constexpr StringLiteral(const StringLiteral &) = default; + //! @brief A default destructor + constexpr ~StringLiteral() = default; + //! @brief A string literal is assignable. + constexpr StringLiteral &operator=(const StringLiteral &) = default; + }; + + template + class TagComponent : public WAL::Component + { + public: + Component *clone(WAL::Entity &entity) const override + { + return new TagComponent(entity); + } + + //! @brief Create a new empty tag component. + explicit TagComponent(WAL::Entity &entity) + : WAL::Component(entity) + {} + //! @brief A default copy constructor. + TagComponent(const TagComponent &) = default; + //! @brief A default destructor + ~TagComponent() override = default; + //! @brief A tag component is not assignable. + TagComponent &operator=(const TagComponent &) = delete; + }; + + constexpr const char Blowable[] = "Blowable"; +} diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 754e080f..90e187f8 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -6,6 +6,7 @@ #include #include "Map.hpp" #include +#include namespace RAY3D = RAY::Drawables::Drawables3D; @@ -58,6 +59,7 @@ namespace BBM if (!(i % 2) && !(j % 2)) { scene->addEntity("Unbreakable Wall") .addComponent(i, 0, j) + .addComponent>() .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePng)); } @@ -72,24 +74,28 @@ namespace BBM scene->addEntity("Bottom Wall") .addComponent(Vector3f((width + 1) / 2, 0, -1)) + .addComponent>() .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Upper Wall") .addComponent(Vector3f((width + 1) / 2, 0, height + 1)) + .addComponent>() .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Left Wall") .addComponent(Vector3f(width + 1, 0, height / 2)) + .addComponent>() .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); scene->addEntity("Right Wall") .addComponent(Vector3f(-1, 0, height / 2)) + .addComponent>() .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), @@ -141,6 +147,7 @@ namespace BBM .addComponent(coords) .addComponent(1, &MapGenerator::wallDestroyed) .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent>() .addComponent(breakableObj, std::make_pair(MAP_DIFFUSE, breakablePng)); } @@ -173,6 +180,7 @@ namespace BBM scene->addEntity("Unbreakable Block") .addComponent(coords) + .addComponent>() .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(UnbreakableObj, std::make_pair(MAP_DIFFUSE, UnbreakablePng)); diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 57494e5e..c88c9194 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "Component/Animation/AnimationsComponent.hpp" #include "System/Animation/AnimationsSystem.hpp" #include "Map/Map.hpp" @@ -77,6 +78,7 @@ namespace BBM .addComponent() .addComponent() .addComponent() + .addComponent>() .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 3) .addComponent(1) .addComponent() diff --git a/sources/System/BombHolder/BombHolderSystem.cpp b/sources/System/BombHolder/BombHolderSystem.cpp index 10c21960..e9ff4ab5 100644 --- a/sources/System/BombHolder/BombHolderSystem.cpp +++ b/sources/System/BombHolder/BombHolderSystem.cpp @@ -8,7 +8,8 @@ #include "BombHolderSystem.hpp" #include "Component/Health/HealthComponent.hpp" #include -#include +#include "Component/Collision/CollisionComponent.hpp" +#include "Component/Tag/TagComponent.hpp" using namespace std::chrono_literals; namespace RAY3D = RAY::Drawables::Drawables3D; @@ -25,22 +26,18 @@ namespace BBM { if (count <= 0) return; - std::cout << position << " count: " << count << std::endl; - // TODO use it in a global context with a find and so on. - wal.getSystem().dispatchEvent([position, &wal, count](WAL::Entity &entity) { - auto *health = entity.tryGetComponent(); - auto *pos = entity.tryGetComponent(); - - if (health && pos && pos->position.round() == position) { - std::cout << pos->position << std::endl; - health->takeDmg(1); - } - else { - _dispatchExplosion(position + Vector3f(1, 0, 0), wal, count - 1); - _dispatchExplosion(position + Vector3f(-1, 0, 0), wal, count - 1); - _dispatchExplosion(position + Vector3f(0, 0, 1), wal, count - 1); - _dispatchExplosion(position + Vector3f(0, 0, -1), wal, count - 1); + wal.getSystem().dispatchEvent([position, count](WAL::Wal &wal) { + for (auto &[entity, pos, _] : wal.scene->view>()) { + if (pos.position.round() == position) { + if (auto *health = entity.tryGetComponent()) + health->takeDmg(1); + return; + } } + _dispatchExplosion(position + Vector3f(1, 0, 0), wal, count - 1); + _dispatchExplosion(position + Vector3f(-1, 0, 0), wal, count - 1); + _dispatchExplosion(position + Vector3f(0, 0, 1), wal, count - 1); + _dispatchExplosion(position + Vector3f(0, 0, -1), wal, count - 1); }); } @@ -48,13 +45,13 @@ namespace BBM { bomb.scheduleDeletion(); auto position = bomb.getComponent().position.round(); - _dispatchExplosion(position, wal, 2); + _dispatchExplosion(position, wal, 3); } void BombHolderSystem::_spawnBomb(Vector3f position) { this->_wal.scene->scheduleNewEntity("Bomb") - .addComponent(position) + .addComponent(position.round()) .addComponent(BombHolderSystem::explosionTimer, &BombHolderSystem::_bombExplosion) .addComponent("assets/bombs/bomb.obj", std::make_pair(MAP_DIFFUSE, "assets/bombs/bomb_normal.png")); diff --git a/sources/System/Event/EventSystem.cpp b/sources/System/Event/EventSystem.cpp index af20674f..da683dec 100644 --- a/sources/System/Event/EventSystem.cpp +++ b/sources/System/Event/EventSystem.cpp @@ -15,6 +15,11 @@ namespace BBM this->_events.emplace_back(event); } + void EventSystem::dispatchEvent(const std::function &event) + { + this->_globalEvents.emplace_back(event); + } + void EventSystem::onUpdate(WAL::ViewEntity<> &entity, std::chrono::nanoseconds) { for (auto &event : this->_events) @@ -23,6 +28,9 @@ namespace BBM void EventSystem::onSelfUpdate() { + for (auto &event : this->_globalEvents) + event(this->_wal); this->_events.clear(); + this->_globalEvents.clear(); } } \ No newline at end of file diff --git a/sources/System/Event/EventSystem.hpp b/sources/System/Event/EventSystem.hpp index 0a4c205f..bcdb14c0 100644 --- a/sources/System/Event/EventSystem.hpp +++ b/sources/System/Event/EventSystem.hpp @@ -14,11 +14,16 @@ namespace BBM { private: //! @brief The list of events that occurred in the last update. - std::vector> _events; + std::list> _events; + //! @brief The list of events that occurred in the last update. + std::list> _globalEvents; public: //! @brief Inform the system that a new event has occurred and it should run the given method on every entities. void dispatchEvent(const std::function& event); + //! @brief Inform the system that a new event has occurred and it should run the given method on every entities. + void dispatchEvent(const std::function& event); + //! @inherit void onUpdate(WAL::ViewEntity<> &entity, std::chrono::nanoseconds dtime) override; //! @inherit From 0174d121f1f7e4383033883953fadb09db5b3923 Mon Sep 17 00:00:00 2001 From: "arthur.jamet" Date: Wed, 9 Jun 2021 12:25:21 +0200 Subject: [PATCH 12/18] cache system test --- CMakeLists.txt | 1 + lib/Ray/sources/Utils/Cache.hpp | 15 +++++---- tests/CacheTest.cpp | 57 +++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 tests/CacheTest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 48dcf444..93c17008 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,6 +92,7 @@ target_link_libraries(bomberman PUBLIC wal ray) add_executable(unit_tests EXCLUDE_FROM_ALL ${SOURCES} + tests/CacheTest.cpp tests/EntityTests.cpp tests/MainTest.cpp tests/EngineTests.cpp diff --git a/lib/Ray/sources/Utils/Cache.hpp b/lib/Ray/sources/Utils/Cache.hpp index c0e370d1..cea5dd71 100644 --- a/lib/Ray/sources/Utils/Cache.hpp +++ b/lib/Ray/sources/Utils/Cache.hpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace RAY { //! @brief A templated class used to cache ressources, indexed with a string @@ -42,13 +43,15 @@ namespace RAY { this->_cache.emplace(path, std::vector>()); std::vector> &matchingDataVector = this->_cache.at(path); - for (std::shared_ptr &i: matchingDataVector) { - if (!lonely) - return i; - if (lonely && i.use_count() == 1) - return i; + if (matchingDataVector.size()) { + for (std::shared_ptr &i: matchingDataVector) { + if (!lonely) + return i; + if (lonely && i.use_count() == 1) + return i; + } } - matchingDataVector.emplace_back(std::shared_ptr( + matchingDataVector.push_back(std::shared_ptr( new T(this->_dataLoader(path.c_str())), [this](T *p) { this->_dataUnloader(*p); delete p; diff --git a/tests/CacheTest.cpp b/tests/CacheTest.cpp new file mode 100644 index 00000000..7e30cd99 --- /dev/null +++ b/tests/CacheTest.cpp @@ -0,0 +1,57 @@ + +#include + +#define private public +#include +#include