├── CMakeLists.txt ├── Camera.cpp ├── Camera.h ├── Chunk.cpp ├── Chunk.h ├── Core.cpp ├── Core.h ├── CubeMapRenderer.cpp ├── CubeMapRenderer.h ├── DeferredRenderer.cpp ├── DeferredRenderer.h ├── Dependencies ├── DependenciesMath.h └── DependenciesRendering.h ├── FirstPassLighting.cpp ├── FirstPassLighting.h ├── Framebuffer.cpp ├── Framebuffer.h ├── Frustum.cpp ├── Frustum.h ├── GL ├── glad.c └── glad.h ├── Images ├── Open7Days.png └── Up-To-Date-Screenshot.png ├── IndirectDiffuse.cpp ├── IndirectDiffuse.h ├── IndirectSpecular.cpp ├── IndirectSpecular.h ├── LICENSE ├── LightCombiner.cpp ├── LightCombiner.h ├── Materials.cpp ├── Materials.h ├── Mesh.cpp ├── Mesh.h ├── Models ├── WaterPlane.mtl └── WaterPlane.obj ├── Pipeline.cpp ├── Pipeline.h ├── README.md ├── Shader.cpp ├── Shader.h ├── Shaders ├── CubeMapDeferred │ ├── frag.glsl │ └── vert.glsl ├── CubeMapIndirectDiffuse │ ├── frag.glsl │ └── vert.glsl ├── CubeMapPostProcess │ ├── frag.glsl │ └── vert.glsl ├── CustomDeferred │ ├── frag.glsl │ └── vert.glsl ├── Deferred │ ├── frag.glsl │ └── vert.glsl ├── DeferredShadow │ ├── frag.glsl │ └── vert.glsl ├── DeferredUnwrapper │ ├── frag.glsl │ └── vert.glsl ├── EquirectangularToCubeMapShader │ ├── frag.glsl │ └── vert.glsl ├── FirstPassLighting │ ├── frag.glsl │ └── vert.glsl ├── IndirectDiffuse │ ├── frag.glsl │ └── vert.glsl ├── IndirectDiffusePacker │ ├── frag.glsl │ └── vert.glsl ├── IndirectDiffuseSpatial │ ├── frag.glsl │ └── vert.glsl ├── IndirectSpecular │ ├── frag.glsl │ └── vert.glsl ├── LightCombiner │ ├── frag.glsl │ └── vert.glsl ├── ShadowGaussian │ ├── frag.glsl │ └── vert.glsl ├── Voxelizer │ ├── frag.glsl │ ├── geom.glsl │ └── vert.glsl └── WaterDeferred │ ├── frag.glsl │ └── vert.glsl ├── Shadows.cpp ├── Shadows.h ├── Texture.cpp ├── Texture.h ├── Voxelizer.cpp ├── Voxelizer.h ├── WaterRenderer.cpp ├── WaterRenderer.h ├── Window.cpp ├── Window.h ├── main.cpp └── noise.h /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8.2) 2 | project(Open7Days) 3 | set(CMAKE_CXX_STANDARD 17) 4 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 5 | 6 | find_package(SFML COMPONENTS graphics REQUIRED) 7 | find_package(glm REQUIRED) 8 | find_package(assimp REQUIRED) 9 | 10 | add_executable(7days 11 | ./WaterRenderer.cpp 12 | ./Framebuffer.cpp 13 | ./Core.cpp 14 | ./IndirectDiffuse.cpp 15 | ./Materials.cpp 16 | ./Window.cpp 17 | ./Texture.cpp 18 | ./Voxelizer.cpp 19 | ./Mesh.cpp 20 | ./Frustum.cpp 21 | ./Pipeline.cpp 22 | ./CubeMapRenderer.cpp 23 | ./Shadows.cpp 24 | ./main.cpp 25 | ./IndirectSpecular.cpp 26 | ./FirstPassLighting.cpp 27 | ./Chunk.cpp 28 | ./Camera.cpp 29 | ./LightCombiner.cpp 30 | ./Shader.cpp 31 | ./DeferredRenderer.cpp 32 | ./GL/glad.c) 33 | 34 | target_link_libraries(7days PRIVATE sfml-graphics ${ASSIMP_LIBRARIES} ${CMAKE_DL_LIBS}) 35 | -------------------------------------------------------------------------------- /Camera.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UglySwedishFish/Open7Days/107b924974ac017d9797689365ddcb232b60c3b3/Camera.cpp -------------------------------------------------------------------------------- /Camera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core.h" 4 | #include "Window.h" 5 | #include "Frustum.h" 6 | 7 | namespace Open7Days { 8 | struct Camera { 9 | Matrix4f Project, View, PrevView; 10 | Vector3f Position, Rotation, PreviousPosition; 11 | Frustum CameraFrustum; 12 | float Height, MaxJumpSpeed, GravityAcceleration, MaxGravitySpeed; 13 | bool ShadowCamera; 14 | inline Camera(float fov, float znear, float zfar, Vector3f pos, Vector3f rot, Window & screen) : 15 | Project(glm::perspective(glm::radians(fov), float(screen.GetResolution().x) / float(screen.GetResolution().y), znear, zfar)), 16 | Position(pos), 17 | Rotation(rot), 18 | View(Open7Days::Core::ViewMatrix(pos, rot)), 19 | ShadowCamera(false) 20 | {} 21 | inline Camera() : 22 | Project(Matrix4f(0.)), 23 | View(Matrix4f(0.)), 24 | PrevView(Matrix4f(0.)), 25 | Position(Vector3f(0.)), 26 | Rotation(Vector3f(0.)), 27 | ShadowCamera(false) { 28 | 29 | } 30 | inline void SetPosition(Vector3f Position) { 31 | this->Position = Position; 32 | PrevView = View; 33 | View = Open7Days::Core::ViewMatrix(Position, Rotation); 34 | } 35 | inline void SetRotation(Vector3f Rotation) { 36 | this->Rotation = Rotation; 37 | PrevView = View; 38 | View = Open7Days::Core::ViewMatrix(Position, Rotation); 39 | } 40 | inline void Move(Vector3f PositionAddon) { 41 | PrevView = View; 42 | View = Open7Days::Core::ViewMatrix(Position + PositionAddon, Rotation); 43 | } 44 | inline void Rotate(Vector3f RotationAddon) { 45 | PrevView = View; 46 | View = Open7Days::Core::ViewMatrix(Position, Rotation + RotationAddon); 47 | } 48 | 49 | void UpdateFrustum() { 50 | 51 | CameraFrustum.Update(Project * View); 52 | } 53 | 54 | 55 | }; 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Chunk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core.h" 4 | #include "Framebuffer.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "Camera.h" 12 | #include "Shader.h" 13 | #include "Materials.h" 14 | #include 15 | #include 16 | 17 | #define CHUNKSIZE 16 18 | #define CHUNKHEIGHT 256 19 | 20 | //TODO: this should absolutely be a setting 21 | #define RENDER_DISTANCE 6 22 | 23 | namespace Open7Days { 24 | 25 | namespace Rendering { 26 | 27 | inline std::tuple ExtractFrom(std::uint16_t Block) { 28 | return std::make_tuple(Block & 0xFF, Block >> 8); 29 | } 30 | 31 | inline std::uint16_t ExtractTo(std::uint16_t State, std::uint16_t Type) { 32 | return ((Type << 8) & 0xFF) | (State & 0xFF); 33 | } 34 | 35 | 36 | 37 | struct Chunk { 38 | std::int64_t X, Y; 39 | std::vector Vertices, Normals; 40 | Matrix4f Model; 41 | 42 | std::vector BlockMaterials; 43 | std::vector BlockWeights; 44 | 45 | GLuint VAO, VBOs[3]; 46 | 47 | Chunk(std::int64_t X = 0, std::int64_t Y = 0) : 48 | X(X), Y(Y),BlockWeights(std::vector((CHUNKSIZE+1)*(CHUNKHEIGHT+1)*(CHUNKSIZE+1))), BlockMaterials(std::vector((CHUNKSIZE + 1) * (CHUNKHEIGHT + 1) * (CHUNKSIZE + 1))), Vertices{}, Normals{}, VAO(0), VBOs{ 0,0,0 } { 49 | Model = Core::ModelMatrix(Vector3f(-X * CHUNKSIZE, 0.0, -Y * CHUNKSIZE), Vector3f(0.)); 50 | } 51 | 52 | void Generate(Materials::MaterialList& Materials); 53 | 54 | void UpdateMesh(Materials::MaterialList* Materials); 55 | 56 | void Draw(Matrix4f View, Matrix4f Project, Shader& Shader); 57 | 58 | //destructor, important 59 | ~Chunk(); 60 | 61 | 62 | }; 63 | 64 | struct ChunkContainer { 65 | 66 | std::vector DrawChunks; //for faster iteration 67 | std::map> ChunkContainer; 68 | 69 | 70 | struct ChunkLocation { 71 | std::int64_t X, Y; 72 | 73 | ChunkLocation(std::int64_t X, std::int64_t Y): X(X), Y(Y) { 74 | } 75 | 76 | bool operator<(ChunkLocation& a) { 77 | //empty for now, will be used for sorting later 78 | } 79 | }; 80 | 81 | std::list ChunksToBeGenerated; 82 | 83 | void GenerateChunks(Camera& Camera, Materials::MaterialList* Materials); 84 | void RenderChunks(Matrix4f View, Matrix4f Project, Shader & Shader, int RenderDistanceOverload = -1, Vector2f Position = Vector2f(0.), Frustum * ViewFrustum = nullptr); 85 | 86 | 87 | }; 88 | 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /Core.cpp: -------------------------------------------------------------------------------- 1 | #include "Core.h" 2 | #include 3 | 4 | template 5 | T Open7Days::Core::Interpolate(T A, T B, T X) { 6 | T FT = X * static_cast(3.1415); 7 | } 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Matrix4f Open7Days::Core::ViewMatrix(Vector3f Position, Vector3f Rotation) { 16 | Matrix4f Temp = glm::rotate(Matrix4f(1.0f), glm::radians(Rotation.x), { 1, 0, 0 }); 17 | Temp = glm::rotate(Temp, glm::radians(Rotation.y), { 0, 1, 0 }); 18 | Temp = glm::rotate(Temp, glm::radians(Rotation.z), { 0, 0, 1 }); 19 | 20 | Temp = glm::translate(Temp, Vector3f(-Position.x, -Position.y, -Position.z)); 21 | 22 | return Temp; 23 | } 24 | 25 | Matrix4f Open7Days::Core::ModelMatrix(Vector3f Position, Vector3f Rotation) { 26 | Matrix4f Temp = glm::translate(Matrix4f(1.0f), Vector3f(-Position.x, -Position.y, -Position.z)); 27 | Temp = glm::rotate(Temp, glm::radians(Rotation.x), { 1, 0, 0 }); 28 | Temp = glm::rotate(Temp, glm::radians(Rotation.y), { 0, 1, 0 }); 29 | Temp = glm::rotate(Temp, glm::radians(Rotation.z), { 0, 0, 1 }); 30 | 31 | return Temp; 32 | } 33 | 34 | Matrix4f Open7Days::Core::ShadowOrthoMatrix(float edge, float znear, float zfar) { 35 | return glm::ortho(-edge, edge, -edge, edge, znear, zfar); 36 | } 37 | 38 | const Vector2f TAA8X[8] = { 39 | Vector2f(-7.0f, 1.0f) / 8.0f, 40 | Vector2f(-5.0f, -5.0f) / 8.0f, 41 | Vector2f(-1.0f, -3.0f) / 8.0f, 42 | Vector2f(3.0f, -7.0f) / 8.0f, 43 | Vector2f(5.0f, -1.0f) / 8.0f, 44 | Vector2f(7.0f, 7.0f) / 8.0f, 45 | Vector2f(1.0f, 3.0f) / 8.0f, 46 | Vector2f(-3.0f, 5.0f) / 8.0f }; 47 | 48 | const Vector2f TAA4X[4] = { 49 | Vector2f(-7.0f, 1.0f) / 8.0f, 50 | Vector2f(-1.0f, -3.0f) / 8.0f, 51 | Vector2f(5.0f, -1.0f) / 8.0f, 52 | Vector2f(1.0f, 3.0f) / 8.0f }; 53 | 54 | 55 | Vector2f TAA2X[] = { 56 | Vector2f(-0.25f, -0.25f), 57 | Vector2f(0.25f, 0.25f) 58 | }; 59 | 60 | Matrix4f Open7Days::Core::JitterMatrix(int Sample, Vector2i Resolution, TAAQuality Quality) { 61 | Vector2f Jitter = TAA4X[Sample % 4]; 62 | Vector2f TexelSize = 1.0f / Vector2f(Resolution); 63 | return glm::translate(Matrix4f(), glm::vec3(2.0 * Jitter.x * TexelSize.x, 2.0 * Jitter.y * TexelSize.y, 0.0f)); 64 | } 65 | -------------------------------------------------------------------------------- /Core.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Dependencies/DependenciesMath.h" 3 | #include "Window.h" 4 | constexpr double PI = 3.14159265; 5 | #define Open7Days_DEBUG 6 | 7 | namespace Open7Days { 8 | namespace Core { 9 | template 10 | inline T mix(T A, T B, float Mix) { 11 | return A * static_cast(Mix) + B * static_cast(1.0 - Mix); 12 | } 13 | 14 | 15 | 16 | struct BoundingBox { 17 | Vector3f Min, Max; 18 | inline Vector3f Center() { return (Min + Max) / 2.f; } 19 | inline Vector3f Size() { 20 | return Max - Min; 21 | } 22 | inline int LongestAxis() { 23 | Vector3f Length = Size(); 24 | return Length.x > Length.y && Length.x > Length.z ? 0 : Length.y > Length.z ? 1 : 2; 25 | } 26 | inline float Area() { 27 | return (Size().x*Size().y + Size().x*Size().z + Size().y * Size().z) * 2.; 28 | } 29 | inline void ResizeToFit(BoundingBox Box) { 30 | Max = glm::max(Max, Box.Max); 31 | Min = glm::min(Min, Box.Min); 32 | } 33 | inline void ResizeToFit(Vector3f Point) { 34 | Max = glm::max(Max, Point); 35 | Min = glm::min(Min, Point); 36 | } 37 | 38 | BoundingBox(Vector3f Min = Vector3f(100000.), Vector3f Max = Vector3f(-100000.)) : Min(Min), Max(Max) {} 39 | 40 | }; 41 | template 42 | T min3(T a, T b, T c) { 43 | return std::min(a, std::min(b, c)); 44 | } 45 | template 46 | T max3(T a, T b, T c) { 47 | return std::max(a, std::max(b, c)); 48 | } 49 | template 50 | T min4(T a, T b, T c, T d) { 51 | return std::min(std::min(a, b), std::min(c, d)); 52 | } 53 | template 54 | T max4(T a, T b, T c, T d) { 55 | return std::max(std::max(a, b), std::max(c, d)); 56 | } 57 | 58 | 59 | 60 | template 61 | T Interpolate(T A, T B, T X); 62 | template 63 | void Move_2DXY(V & Pos, T Speed, T Rotation, T FrameTime) { 64 | Pos.x -= cos(Rotation*T(PI / 180.))*Speed*FrameTime; 65 | Pos.y -= sin(Rotation*T(PI / 180.))*Speed*FrameTime; 66 | 67 | } 68 | template 69 | void Move_2DXZ(V & Pos, T Speed, T Rotation, T FrameTime) { 70 | Pos.x -= cos(Rotation*T(PI / 180.))*Speed*FrameTime; 71 | Pos.z -= sin(Rotation*T(PI / 180.))*Speed*FrameTime; 72 | } 73 | template 74 | void Move_3D(V & Pos, T Speed, T RotationX, T RotationY, T FrameTime, bool Forward = false) { 75 | 76 | float HMultiplier = Forward ? -cos(RotationX*(PI / 180.)) : cos(RotationX*(PI / 180.)); 77 | 78 | Pos.x -= (cos(RotationY*(PI / 180.)) * HMultiplier)*Speed*FrameTime; 79 | Pos.y += sin(RotationX*(PI / 180.))*Speed*FrameTime; 80 | Pos.z -= (sin(RotationY*(PI / 180.)) * HMultiplier)*Speed*FrameTime; 81 | } 82 | template 83 | bool inRange(T value, T min, T max) { //is a value in a certain range 84 | return value > min && value < max; 85 | } 86 | 87 | template 88 | inline void HandleInput(T & Camera, F MovementSpeed, F MouseSense, Window & Window, bool Rotation, bool Position) { 89 | if (Position) { 90 | 91 | if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { 92 | Move_2DXZ(Camera.Position, MovementSpeed, static_cast(Camera.Rotation.y - 180.0), static_cast(Window.GetFrameTime())); 93 | //Window.FrameCount = 0; 94 | } 95 | else if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { 96 | Move_2DXZ(Camera.Position, MovementSpeed, static_cast(Camera.Rotation.y), static_cast(Window.GetFrameTime())); 97 | //Window.FrameCount = 0; 98 | } 99 | if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { 100 | Move_3D(Camera.Position, MovementSpeed, static_cast(Camera.Rotation.x), static_cast(Camera.Rotation.y - 90.0), static_cast(Window.GetFrameTime())); 101 | //Window.FrameCount = 0; 102 | } 103 | else if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { 104 | Move_3D(Camera.Position, MovementSpeed, static_cast(Camera.Rotation.x + 180.0), static_cast(Camera.Rotation.y + 90.0), static_cast(Window.GetFrameTime()), true); 105 | //Window.FrameCount = 0; 106 | } 107 | } 108 | if (Rotation) { 109 | float RelativeMouseX = sf::Mouse::getPosition(*Window.GetRawWindow()).x - Window.GetResolution().x / 2; 110 | float RelativeMouseY = sf::Mouse::getPosition(*Window.GetRawWindow()).y - Window.GetResolution().y / 2; 111 | 112 | 113 | sf::Mouse::setPosition(sf::Vector2i(Window.GetResolution().x / 2, Window.GetResolution().y / 2), *Window.GetRawWindow()); 114 | 115 | Vector2f PreviousCameraRotation = Vector2f(Camera.Rotation.x, Camera.Rotation.y); 116 | 117 | Vector3f TempRotation = Camera.Rotation; 118 | 119 | Camera.Rotation.y += RelativeMouseX * MouseSense; 120 | Camera.Rotation.x += static_cast(RelativeMouseY*MouseSense); 121 | 122 | Camera.Rotation.y = Camera.Rotation.y > 360.0 ? Camera.Rotation.y - 360.0 : Camera.Rotation.y < 0.0 ? Camera.Rotation.y + 360.0 : Camera.Rotation.y; 123 | 124 | 125 | 126 | 127 | } 128 | 129 | //Window.FrameCountOpposite++; 130 | 131 | //if (Window.FrameCount != 0) 132 | // Window.FrameCountOpposite = 0; 133 | } 134 | 135 | Matrix4f ViewMatrix(Vector3f Position, Vector3f Rotation); 136 | Matrix4f ModelMatrix(Vector3f Position, Vector3f Rotation); 137 | Matrix4f ShadowOrthoMatrix(float edge, float znear, float zfar); 138 | template 139 | const T Lerp(T A, T B, T F) { 140 | return A + F * (B - A); 141 | } 142 | 143 | enum class TAAQuality : int { 144 | TAA2X, TAA8X, TAA4X 145 | }; 146 | 147 | Matrix4f JitterMatrix(int Sample, Vector2i Resolution, TAAQuality Quality); 148 | 149 | 150 | 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /CubeMapRenderer.cpp: -------------------------------------------------------------------------------- 1 | #include "CubeMapRenderer.h" 2 | 3 | namespace Open7Days { 4 | 5 | namespace Rendering { 6 | void CubeMapRenderer::PrepareCubeMapRenderer() 7 | { 8 | CubeDeferred = Shader("Shaders/CubeMapDeferred"); 9 | CubeLighting = Shader("Shaders/CubeMapPostProcess"); 10 | 11 | RawDeferred = CubeMultiPassFrameBufferObject(Vector2i(CUBEMAPRESOLUTION), 2, { GL_RGB16F, GL_RGBA32F }, true); 12 | Lighting = CubeFrameBufferObject(Vector2i(CUBEMAPRESOLUTION), GL_RGBA16F, false); 13 | 14 | ViewFrustum = new Frustum(); 15 | 16 | CubeLighting.Bind(); 17 | 18 | CubeLighting.SetUniform("Normal", 0); 19 | CubeLighting.SetUniform("WorldPosition", 1); 20 | CubeLighting.SetUniform("Textures", 2); 21 | 22 | CubeLighting.UnBind(); 23 | 24 | } 25 | void CubeMapRenderer::RenderToCubeMap(Window& Window, Camera& Camera, DeferredRenderer& Deferred, ShadowMapper& Shadows, ChunkContainer& Chunks) { 26 | 27 | RawDeferred.Bind(); 28 | 29 | CubeDeferred.Bind(); 30 | 31 | for (int i = 0; i < 6; i++) { 32 | 33 | Matrix4f ViewMatrix = glm::translate(CubeViews[i], -Camera.Position); 34 | 35 | ViewFrustum->Update(CubeProjection * ViewMatrix); 36 | 37 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 38 | GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, RawDeferred.DepthTexture, 0); 39 | for (int _i = 0; _i < RawDeferred.Texture.size(); _i++) 40 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + _i, 41 | GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, RawDeferred.Texture[_i], 0); 42 | 43 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 44 | 45 | Chunks.RenderChunks(ViewMatrix, CubeProjection, CubeDeferred, -1, Vector2f(0.), ViewFrustum); 46 | 47 | } 48 | 49 | CubeDeferred.UnBind(); 50 | 51 | RawDeferred.UnBind(Window); 52 | 53 | CubeLighting.Bind(); 54 | 55 | Lighting.Bind(); 56 | 57 | for (int i = 0; i < 6; i++) { 58 | 59 | //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 60 | // GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, Lighting.DepthTexture, 0); 61 | 62 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , 63 | GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, Lighting.Texture, 0); 64 | 65 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 66 | 67 | 68 | glActiveTexture(GL_TEXTURE0); 69 | glBindTexture(GL_TEXTURE_CUBE_MAP, RawDeferred.Texture[0]); 70 | 71 | glActiveTexture(GL_TEXTURE1); 72 | glBindTexture(GL_TEXTURE_CUBE_MAP, RawDeferred.Texture[1]); 73 | 74 | glActiveTexture(GL_TEXTURE2); 75 | glBindTexture(GL_TEXTURE_2D_ARRAY, Deferred.Materials->TextureMaterials); 76 | 77 | Shadows.BindAndSetUniforms(CubeLighting, 3); 78 | 79 | CubeLighting.SetUniform("IdentityMatrix", CubeProjection * CubeViews[i]); 80 | 81 | DrawPostProcessCube(); 82 | 83 | } 84 | 85 | Lighting.UnBind(Window); 86 | 87 | CubeLighting.UnBind(); 88 | 89 | } 90 | } 91 | 92 | } -------------------------------------------------------------------------------- /CubeMapRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Shadows.h" 4 | #include "DeferredRenderer.h" 5 | #include "Texture.h" 6 | 7 | namespace Open7Days { 8 | 9 | namespace Rendering { 10 | 11 | #define CUBEMAPRESOLUTION 128 12 | 13 | 14 | struct CubeMapRenderer { 15 | 16 | CubeMultiPassFrameBufferObject RawDeferred; 17 | CubeFrameBufferObject Lighting; 18 | Shader CubeLighting, CubeDeferred; 19 | Frustum* ViewFrustum; 20 | 21 | void PrepareCubeMapRenderer(); 22 | void RenderToCubeMap(Window& Window, Camera& Camera, DeferredRenderer& Deferred, ShadowMapper& Shadows, ChunkContainer& Chunks); 23 | 24 | 25 | 26 | 27 | }; 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /DeferredRenderer.cpp: -------------------------------------------------------------------------------- 1 | #include "DeferredRenderer.h" 2 | 3 | namespace Open7Days { 4 | namespace Rendering { 5 | void DeferredRenderer::PrepareDeferredRendering(Window & Window, Camera & Camera) { 6 | DeferredRawBuffer = FrameBufferObject(Window.GetResolution(), GL_RGBA32F); 7 | DeferredUnwrappedBuffer = MultiPassFrameBufferObject(Window.GetResolution(), 3, { GL_RGBA8, GL_RGBA16F, GL_RGB32F }, false); 8 | 9 | DeferredRaw = Shader("Shaders/Deferred"); 10 | DeferredUnwrappedShader = Shader("Shaders/DeferredUnwrapper"); 11 | 12 | DeferredUnwrappedShader.Bind(); 13 | 14 | DeferredUnwrappedShader.SetUniform("DeferredNormal", 0); 15 | DeferredUnwrappedShader.SetUniform("DeferredDepth", 1); 16 | DeferredUnwrappedShader.SetUniform("Textures", 2); 17 | 18 | DeferredUnwrappedShader.UnBind(); 19 | 20 | Materials = new Materials::MaterialList(); 21 | Materials->Load(); 22 | 23 | 24 | } 25 | void DeferredRenderer::RenderToDeffered(Window & Window, Camera & Camera, ChunkContainer& Chunks) { 26 | 27 | DeferredRawBuffer.Bind(); 28 | 29 | DeferredRaw.Bind(); 30 | 31 | Chunks.RenderChunks(Camera.View, Camera.Project, DeferredRaw, -1, Vector2f(0.0), &Camera.CameraFrustum); 32 | 33 | DeferredRaw.UnBind(); 34 | 35 | DeferredRawBuffer.UnBind(Window); 36 | 37 | DeferredRawBuffer.BindImage(0); 38 | 39 | DeferredRawBuffer.BindDepthImage(1); 40 | 41 | glActiveTexture(GL_TEXTURE2); 42 | glBindTexture(GL_TEXTURE_2D_ARRAY, Materials->TextureMaterials); 43 | 44 | 45 | DeferredUnwrappedBuffer.Bind(); 46 | 47 | DeferredUnwrappedShader.Bind(); 48 | 49 | DeferredUnwrappedShader.SetUniform("InverseView", glm::inverse(Camera.View)); 50 | DeferredUnwrappedShader.SetUniform("InverseProjection", glm::inverse(Camera.Project)); 51 | 52 | DrawPostProcessQuad(); 53 | 54 | DeferredUnwrappedShader.UnBind(); 55 | 56 | DeferredUnwrappedBuffer.UnBind(Window); 57 | 58 | 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /DeferredRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //renders + unwraps the required terrain 4 | 5 | #include "Shader.h" 6 | #include "Framebuffer.h" 7 | #include "Camera.h" 8 | #include "Chunk.h" 9 | #include "Materials.h" 10 | 11 | 12 | namespace Open7Days { 13 | namespace Rendering { 14 | 15 | struct DeferredRenderer { 16 | FrameBufferObject DeferredRawBuffer; 17 | MultiPassFrameBufferObject DeferredUnwrappedBuffer; 18 | 19 | Shader DeferredUnwrappedShader, DeferredRaw; 20 | 21 | Materials::MaterialList *Materials; 22 | 23 | void PrepareDeferredRendering(Window & Window, Camera & Camera); 24 | void RenderToDeffered(Window & Window, Camera & Camera, ChunkContainer & Chunks); 25 | 26 | }; 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Dependencies/DependenciesMath.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | //dependencies for mathematics, strictly to simplify other files 3 | 4 | #define GLM_SWIZZLE 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | //some variable definitions 13 | 14 | 15 | 16 | using Vector2f = glm::vec2; 17 | using Vector2i = glm::ivec2; 18 | using Vector2u = glm::uvec2; 19 | using Vector2d = glm::dvec2; 20 | 21 | using Vector3f = glm::vec3; 22 | using Vector3i = glm::ivec3; 23 | using Vector3u = glm::uvec3; 24 | using Vector3d = glm::dvec3; 25 | 26 | using Vector4f = glm::vec4; 27 | using Vector4i = glm::ivec4; 28 | using Vector4u = glm::uvec4; 29 | using Vector4d = glm::dvec4; 30 | 31 | using Matrix2f = glm::mat2; 32 | using Matrix2d = glm::dmat2; 33 | 34 | using Matrix3f = glm::mat3; 35 | using Matrix3d = glm::dmat3; 36 | 37 | using Matrix4f = glm::mat4; 38 | using Matrix4d = glm::dmat4; 39 | 40 | static const Vector3f PointPositions[12] = { 41 | Vector3f(0.5,0.0,0.0), 42 | Vector3f(1.0,0.0,0.5), 43 | Vector3f(0.5,0.0,1.0), 44 | Vector3f(0.0,0.0,0.5), 45 | Vector3f(0.5,1.0,0.0), 46 | Vector3f(1.0,1.0,0.5), 47 | Vector3f(0.5,1.0,1.0), 48 | Vector3f(0.0,1.0,0.5), 49 | Vector3f(0.0,0.5,0.0), 50 | Vector3f(1.0,0.5,0.0), 51 | Vector3f(1.0,0.5,1.0), 52 | Vector3f(0.0,0.5,1.0) 53 | }; 54 | 55 | static const Vector3u BlockPointPositions[8] = { 56 | Vector3i(0,0,0), 57 | Vector3i(1,0,0), 58 | Vector3i(1,0,1), 59 | Vector3i(0,0,1), 60 | Vector3i(0,1,0), 61 | Vector3i(1,1,0), 62 | Vector3i(1,1,1), 63 | Vector3i(0,1,1) 64 | }; 65 | 66 | static const int cornerIndexAFromEdge[12] = { 67 | 0, 68 | 1, 69 | 2, 70 | 3, 71 | 4, 72 | 5, 73 | 6, 74 | 7, 75 | 0, 76 | 1, 77 | 2, 78 | 3 79 | }; 80 | 81 | static const int cornerIndexBFromEdge[12] = { 82 | 1, 83 | 2, 84 | 3, 85 | 0, 86 | 5, 87 | 6, 88 | 7, 89 | 4, 90 | 4, 91 | 5, 92 | 6, 93 | 7 94 | }; 95 | 96 | static const int triangulation[256][15] = { 97 | {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 98 | { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 99 | { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 100 | { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 101 | { 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 102 | { 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 103 | { 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 104 | { 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1}, 105 | { 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 106 | { 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 107 | { 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 108 | { 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1}, 109 | { 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 110 | { 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1}, 111 | { 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1}, 112 | { 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 113 | { 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 114 | { 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 115 | { 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 116 | { 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1}, 117 | { 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 118 | { 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1}, 119 | { 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1}, 120 | { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1}, 121 | { 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 122 | { 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1}, 123 | { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1}, 124 | { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1}, 125 | { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1}, 126 | { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1}, 127 | { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1}, 128 | { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1}, 129 | { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 130 | { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 131 | { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 132 | { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1}, 133 | { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 134 | { 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1}, 135 | { 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1}, 136 | { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1}, 137 | { 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 138 | { 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1}, 139 | { 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1}, 140 | { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1}, 141 | { 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1}, 142 | { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1}, 143 | { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1}, 144 | { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1}, 145 | { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 146 | { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1}, 147 | { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1}, 148 | { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 149 | { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1}, 150 | { 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1}, 151 | { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1}, 152 | { 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1}, 153 | { 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1}, 154 | { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1}, 155 | { 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1}, 156 | { 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1}, 157 | { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1}, 158 | { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0}, 159 | { 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0}, 160 | { 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 161 | { 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 162 | { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 163 | { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 164 | { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1}, 165 | { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 166 | { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1}, 167 | { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1}, 168 | { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1}, 169 | { 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 170 | { 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1}, 171 | { 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1}, 172 | { 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1}, 173 | { 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1}, 174 | { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1}, 175 | { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1}, 176 | { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1}, 177 | { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 178 | { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1}, 179 | { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1}, 180 | { 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1}, 181 | { 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1}, 182 | { 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1}, 183 | { 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1}, 184 | { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9}, 185 | { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1}, 186 | { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1}, 187 | { 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1}, 188 | { 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6}, 189 | { 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1}, 190 | { 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11}, 191 | { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7}, 192 | { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1}, 193 | { 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 194 | { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1}, 195 | { 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1}, 196 | { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1}, 197 | { 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1}, 198 | { 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1}, 199 | { 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 200 | { 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1}, 201 | { 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1}, 202 | { 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1}, 203 | { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1}, 204 | { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1}, 205 | { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1}, 206 | { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1}, 207 | { 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1}, 208 | { 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 209 | { 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1}, 210 | { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1}, 211 | { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1}, 212 | { 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1}, 213 | { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1}, 214 | { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9}, 215 | { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1}, 216 | { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 217 | { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1}, 218 | { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7}, 219 | { 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11}, 220 | { 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1}, 221 | { 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6}, 222 | { 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 223 | { 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1}, 224 | { 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 225 | { 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 226 | { 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 227 | { 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 228 | { 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1}, 229 | { 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 230 | { 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1}, 231 | { 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1}, 232 | { 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1}, 233 | { 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 234 | { 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1}, 235 | { 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1}, 236 | { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1}, 237 | { 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1}, 238 | { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1}, 239 | { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1}, 240 | { 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1}, 241 | { 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 242 | { 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1}, 243 | { 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1}, 244 | { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1}, 245 | { 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1}, 246 | { 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1}, 247 | { 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1}, 248 | { 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3}, 249 | { 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1}, 250 | { 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 251 | { 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1}, 252 | { 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1}, 253 | { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1}, 254 | { 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1}, 255 | { 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3}, 256 | { 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 257 | { 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 258 | { 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1}, 259 | { 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1}, 260 | { 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1}, 261 | { 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1}, 262 | { 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1}, 263 | { 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1}, 264 | { 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6}, 265 | { 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1}, 266 | { 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1}, 267 | { 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1}, 268 | { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8}, 269 | { 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1}, 270 | { 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4}, 271 | { 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10}, 272 | { 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1}, 273 | { 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1}, 274 | { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1}, 275 | { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1}, 276 | { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1}, 277 | { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1}, 278 | { 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10}, 279 | { 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5}, 280 | { 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1}, 281 | { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1}, 282 | { 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1}, 283 | { 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8}, 284 | { 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 285 | { 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6}, 286 | { 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1}, 287 | { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 288 | { 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 289 | { 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 290 | { 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1}, 291 | { 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1}, 292 | { 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1}, 293 | { 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1}, 294 | { 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1}, 295 | { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1}, 296 | { 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2}, 297 | { 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1}, 298 | { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1}, 299 | { 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1}, 300 | { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2}, 301 | { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 302 | { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1}, 303 | { 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1}, 304 | { 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 305 | { 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1}, 306 | { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1}, 307 | { 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1}, 308 | { 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4}, 309 | { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1}, 310 | { 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11}, 311 | { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5}, 312 | { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 313 | { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1}, 314 | { 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1}, 315 | { 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9}, 316 | { 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1}, 317 | { 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1}, 318 | { 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 319 | { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1}, 320 | { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 321 | { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1}, 322 | { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1}, 323 | { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1}, 324 | { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4}, 325 | { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1}, 326 | { 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3}, 327 | { 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1}, 328 | { 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1}, 329 | { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1}, 330 | { 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7}, 331 | { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10}, 332 | { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 333 | { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1}, 334 | { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1}, 335 | { 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 336 | { 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 337 | { 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 338 | { 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1}, 339 | { 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1}, 340 | { 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 341 | { 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1}, 342 | { 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1}, 343 | { 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 344 | { 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 345 | { 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1}, 346 | { 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 347 | { 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1}, 348 | { 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 349 | { 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 350 | { 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 351 | { 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, 352 | {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} 353 | }; 354 | -------------------------------------------------------------------------------- /Dependencies/DependenciesRendering.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../GL/glad.h" 3 | #include 4 | -------------------------------------------------------------------------------- /FirstPassLighting.cpp: -------------------------------------------------------------------------------- 1 | #include "FirstPassLighting.h" 2 | 3 | namespace Open7Days { 4 | namespace Rendering { 5 | void FirstPassLighting::Prepare(Window& Window) { 6 | 7 | FirstPassLightingBuffer = MultiPassFrameBufferObject(Window.GetResolution(), 2, { GL_RGB16F, GL_RGB16F }, false); 8 | FirstPassLightingShader = Shader("Shaders/FirstPassLighting"); 9 | 10 | FirstPassLightingShader.Bind(); 11 | 12 | FirstPassLightingShader.SetUniform("ViewPosition", 0); 13 | FirstPassLightingShader.SetUniform("Normal", 1); 14 | FirstPassLightingShader.SetUniform("BlueNoise", 2); 15 | FirstPassLightingShader.SetUniform("IndirectDiffuse", 3); 16 | FirstPassLightingShader.SetUniform("Depth", 4); 17 | FirstPassLightingShader.SetUniform("WaterDepth", 5); 18 | FirstPassLightingShader.SetUniform("WaterNormal", 6); 19 | FirstPassLightingShader.SetUniform("WaterNormalMap", 7); 20 | 21 | FirstPassLightingShader.UnBind(); 22 | 23 | BlueNoise = LoadTextureGL("Textures/BlueNoise.png"); 24 | 25 | 26 | 27 | } 28 | void FirstPassLighting::ReloadShader() { 29 | FirstPassLightingShader.Reload("Shaders/FirstPassLighting"); 30 | 31 | FirstPassLightingShader.Bind(); 32 | 33 | FirstPassLightingShader.SetUniform("ViewPosition", 0); 34 | FirstPassLightingShader.SetUniform("Normal", 1); 35 | FirstPassLightingShader.SetUniform("BlueNoise", 2); 36 | FirstPassLightingShader.SetUniform("IndirectDiffuse", 3); 37 | FirstPassLightingShader.SetUniform("Depth", 4); 38 | FirstPassLightingShader.SetUniform("WaterDepth", 5); 39 | FirstPassLightingShader.SetUniform("WaterNormal", 6); 40 | FirstPassLightingShader.SetUniform("WaterNormalMap", 7); 41 | 42 | 43 | FirstPassLightingShader.UnBind(); 44 | } 45 | void FirstPassLighting::RenderFirstLightingPass(Window& Window, Camera& Camera, DeferredRenderer &Deferred, ShadowMapper &Shadows, IndirectDiffuseLighting& Diffuse, CubeMapRenderer& CubeMap, WaterRenderer& Water) { 46 | 47 | FirstPassLightingBuffer.Bind(); 48 | 49 | FirstPassLightingShader.Bind(); 50 | 51 | FirstPassLightingShader.SetUniform("InverseView", glm::inverse(Camera.View)); 52 | FirstPassLightingShader.SetUniform("InverseProject", glm::inverse(Camera.Project)); 53 | 54 | FirstPassLightingShader.SetUniform("CameraPosition", Camera.Position); 55 | FirstPassLightingShader.SetUniform("Time", Window.GetTimeOpened()); 56 | 57 | Deferred.DeferredUnwrappedBuffer.BindImage(1, 1); 58 | Deferred.DeferredUnwrappedBuffer.BindImage(2, 0); 59 | BlueNoise.Bind(2); 60 | Diffuse.IndirectDiffusePongBuffer.BindImage(3); 61 | Deferred.DeferredRawBuffer.BindDepthImage(4); 62 | Water.WaterBuffer.BindDepthImage(5); 63 | Water.WaterBuffer.BindImage(6); 64 | glActiveTexture(GL_TEXTURE7); 65 | glBindTexture(GL_TEXTURE_2D_ARRAY, Water.WaterNormalTexture); 66 | 67 | //CubeMap.RawDeferred; 68 | 69 | Shadows.BindAndSetUniforms(FirstPassLightingShader, 8); 70 | 71 | DrawPostProcessQuad(); 72 | 73 | FirstPassLightingShader.UnBind(); 74 | 75 | FirstPassLightingBuffer.UnBind(Window); 76 | 77 | 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /FirstPassLighting.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IndirectDiffuse.h" 4 | #include "CubeMapRenderer.h" 5 | #include "WaterRenderer.h" 6 | 7 | namespace Open7Days { 8 | namespace Rendering { 9 | 10 | struct FirstPassLighting { 11 | 12 | Shader FirstPassLightingShader; 13 | MultiPassFrameBufferObject FirstPassLightingBuffer; 14 | TextureGL BlueNoise; 15 | 16 | 17 | 18 | void Prepare(Window &Window); 19 | void ReloadShader(); 20 | void RenderFirstLightingPass(Window& Window, Camera& Camera, DeferredRenderer &Deferred, ShadowMapper &Shadows, IndirectDiffuseLighting & Diffuse, CubeMapRenderer & CubeMap, WaterRenderer & Water); 21 | 22 | 23 | 24 | }; 25 | 26 | 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Framebuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma once 3 | #include "Dependencies/DependenciesRendering.h" 4 | #include "Dependencies/DependenciesMath.h" 5 | #include "Window.h" 6 | 7 | namespace Open7Days { 8 | namespace Rendering { 9 | struct FrameBufferObject { 10 | GLuint FrameBuffer, ColorBuffer, DepthBuffer; 11 | glm::ivec2 Resolution; 12 | bool GenerateMip; 13 | FrameBufferObject(glm::ivec2 Resolution, int Format = GL_RGB32F, bool HasDepth = true, bool generatemip = false); 14 | FrameBufferObject(); 15 | void Bind(); 16 | void BindImage(int Target) { glActiveTexture(GL_TEXTURE0 + Target); glBindTexture(GL_TEXTURE_2D, ColorBuffer); } 17 | void BindDepthImage(int Target) { glActiveTexture(GL_TEXTURE0 + Target); glBindTexture(GL_TEXTURE_2D, DepthBuffer); } 18 | void UnBind(Window Window); 19 | 20 | }; 21 | 22 | class FrameBufferObjectPreviousData { //also stores the previous data! 23 | bool Buffer; 24 | public: 25 | FrameBufferObject Buffers[2]; 26 | 27 | 28 | FrameBufferObjectPreviousData(Vector2i Resolution, int Format = GL_RGB32F, bool HasDepth = true, bool generatemip = false); 29 | FrameBufferObjectPreviousData() : Buffers{ FrameBufferObject(),FrameBufferObject() }, Buffer(0) {} 30 | 31 | FrameBufferObject& GetCurrent() { 32 | return Buffers[Buffer]; 33 | } 34 | 35 | 36 | void Bind(bool Swap = true); 37 | void BindImage(int Target); 38 | void BindDepthImage(int Target); 39 | 40 | void BindImagePrevious(int Target); 41 | void BindDepthImagePrevious(int Target); 42 | 43 | void UnBind(Window& Window); 44 | void Swap(); 45 | 46 | }; 47 | 48 | struct MultiPassFrameBufferObject { 49 | GLuint FrameBuffer, DepthBuffer; 50 | std::vector ColorBuffers; 51 | glm::ivec2 Resolution; 52 | bool GenerateMip; 53 | MultiPassFrameBufferObject(glm::ivec2 Resolution, int stages, std::vector Formats, bool HasDepth = true, bool generatemip = false); 54 | MultiPassFrameBufferObject(); 55 | void Bind(); 56 | void BindImage(int Target, int TargetImage) { glActiveTexture(GL_TEXTURE0 + TargetImage); glBindTexture(GL_TEXTURE_2D, ColorBuffers[Target]); } 57 | void BindDepthImage(int Target) { glActiveTexture(GL_TEXTURE0 + Target); glBindTexture(GL_TEXTURE_2D, DepthBuffer); } 58 | void UnBind(Window Window); 59 | }; 60 | 61 | struct CubeMultiPassFrameBufferObject { 62 | unsigned int DepthTexture, DepthBuffer, FrameBuffer; 63 | std::vector Texture; 64 | Vector2i Resolution; 65 | inline CubeMultiPassFrameBufferObject() : 66 | DepthTexture(0), 67 | DepthBuffer(0), 68 | Texture{}, 69 | FrameBuffer(0), 70 | Resolution(0){ 71 | 72 | } 73 | 74 | void Bind(); 75 | void UnBind(Window Window); 76 | CubeMultiPassFrameBufferObject(Vector2i Resolution, int Targets, std::vector Formats, bool HasDepth); 77 | }; 78 | struct CubeFrameBufferObject { 79 | unsigned int DepthTexture, DepthBuffer, FrameBuffer, Texture; 80 | Vector2i Resolution; 81 | inline CubeFrameBufferObject() : 82 | DepthTexture(0), 83 | DepthBuffer(0), 84 | Texture{}, 85 | FrameBuffer(0), 86 | Resolution(0){ 87 | 88 | } 89 | 90 | void Bind(); 91 | void UnBind(Window Window); 92 | CubeFrameBufferObject(Vector2i Resolution, int Format, bool HasDepth); 93 | }; 94 | 95 | 96 | void PreparePostProcess(); 97 | void DrawPostProcessQuad(); 98 | void DrawPostProcessCube(); 99 | void DrawWaterQuad(); 100 | 101 | } 102 | 103 | } 104 | 105 | -------------------------------------------------------------------------------- /Frustum.cpp: -------------------------------------------------------------------------------- 1 | #include "Frustum.h" 2 | 3 | 4 | //https://github.com/Hopson97/MineCraft-One-Week-Challenge/blob/a17cb344ebd61f0349f375a247d559e607d0dc06/Source/Maths/Frustum.cpp 5 | void Open7Days::Frustum::Update(Matrix4f Matrix) { 6 | 7 | Planes[FrustumPlanes::Left].Normal.x = Matrix[0][3] + Matrix[0][0]; 8 | Planes[FrustumPlanes::Left].Normal.y = Matrix[1][3] + Matrix[1][0]; 9 | Planes[FrustumPlanes::Left].Normal.z = Matrix[2][3] + Matrix[2][0]; 10 | Planes[FrustumPlanes::Left].DistToOrig = Matrix[3][3] + Matrix[3][0]; 11 | 12 | // right 13 | Planes[FrustumPlanes::Right].Normal.x = Matrix[0][3] - Matrix[0][0]; 14 | Planes[FrustumPlanes::Right].Normal.y = Matrix[1][3] - Matrix[1][0]; 15 | Planes[FrustumPlanes::Right].Normal.z = Matrix[2][3] - Matrix[2][0]; 16 | Planes[FrustumPlanes::Right].DistToOrig = Matrix[3][3] - Matrix[3][0]; 17 | 18 | // bottom 19 | Planes[FrustumPlanes::Bottom].Normal.x = Matrix[0][3] + Matrix[0][1]; 20 | Planes[FrustumPlanes::Bottom].Normal.y = Matrix[1][3] + Matrix[1][1]; 21 | Planes[FrustumPlanes::Bottom].Normal.z = Matrix[2][3] + Matrix[2][1]; 22 | Planes[FrustumPlanes::Bottom].DistToOrig = Matrix[3][3] + Matrix[3][1]; 23 | 24 | // top 25 | Planes[FrustumPlanes::Top].Normal.x = Matrix[0][3] - Matrix[0][1]; 26 | Planes[FrustumPlanes::Top].Normal.y = Matrix[1][3] - Matrix[1][1]; 27 | Planes[FrustumPlanes::Top].Normal.z = Matrix[2][3] - Matrix[2][1]; 28 | Planes[FrustumPlanes::Top].DistToOrig = Matrix[3][3] - Matrix[3][1]; 29 | 30 | // near 31 | Planes[FrustumPlanes::Near].Normal.x = Matrix[0][3] + Matrix[0][2]; 32 | Planes[FrustumPlanes::Near].Normal.y = Matrix[1][3] + Matrix[1][2]; 33 | Planes[FrustumPlanes::Near].Normal.z = Matrix[2][3] + Matrix[2][2]; 34 | Planes[FrustumPlanes::Near].DistToOrig = Matrix[3][3] + Matrix[3][2]; 35 | 36 | // far 37 | Planes[FrustumPlanes::Far].Normal.x = Matrix[0][3] - Matrix[0][2]; 38 | Planes[FrustumPlanes::Far].Normal.y = Matrix[1][3] - Matrix[1][2]; 39 | Planes[FrustumPlanes::Far].Normal.z = Matrix[2][3] - Matrix[2][2]; 40 | Planes[FrustumPlanes::Far].DistToOrig = Matrix[3][3] - Matrix[3][2]; 41 | 42 | for (auto& plane : Planes) 43 | { 44 | float length = glm::length(plane.Normal); 45 | plane.Normal /= length; 46 | plane.DistToOrig /= length; 47 | } 48 | 49 | 50 | } 51 | 52 | bool Open7Days::Frustum::InFrustum(FrustumAABB Box) { 53 | bool result = true; 54 | for (auto& plane : Planes) 55 | { 56 | if (plane.DistanceToPoint(Box.GetMaxPointFromNormal(plane.Normal)) < 0) 57 | { 58 | return false; 59 | } 60 | else if (plane.DistanceToPoint(Box.GetMinPointFromNormal(plane.Normal)) < 0) 61 | { 62 | result = true; 63 | } 64 | } 65 | return result; 66 | 67 | } 68 | -------------------------------------------------------------------------------- /Frustum.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Dependencies/DependenciesMath.h" 4 | 5 | //Frustum, for frustum culling 6 | //uses a geometric aproach 7 | //based on http://www.lighthouse3d.com/tutorials/view-frustum-culling/ 8 | 9 | namespace Open7Days { 10 | 11 | enum FrustumPlanes { 12 | Top, Bottom, Left, 13 | Right, Near, Far 14 | }; 15 | 16 | struct FrustumAABB { 17 | Vector3f Min, Max; 18 | 19 | FrustumAABB(Vector3f Min, Vector3f Max) : Min(Min), Max(Max) {} 20 | 21 | Vector3f GetMinPointFromNormal(Vector3f Normal) { 22 | 23 | Vector3f Result = Max; 24 | 25 | for (int i = 0; i < 3; i++) 26 | if (Normal[i] >= 0) 27 | Result[i] = Min[i]; 28 | 29 | return Result; 30 | 31 | } 32 | 33 | Vector3f GetMaxPointFromNormal(Vector3f Normal) { 34 | 35 | Vector3f Result = Min; 36 | 37 | for (int i = 0; i < 3; i++) 38 | if (Normal[i] >= 0) 39 | Result[i] = Max[i]; 40 | 41 | return Result; 42 | 43 | 44 | } 45 | 46 | }; 47 | 48 | struct FrustumPlane { 49 | 50 | float DistToOrig; 51 | Vector3f Normal; 52 | 53 | FrustumPlane(float DistToOrig = 0.0, Vector3f Normal = Vector3f(0.)): 54 | DistToOrig(DistToOrig), Normal(Normal) {} 55 | 56 | float DistanceToPoint(Vector3f Point) { 57 | return glm::dot(Normal, Point) + DistToOrig; 58 | } 59 | 60 | }; 61 | 62 | struct Frustum { 63 | 64 | FrustumPlane Planes[6] = { FrustumPlane(),FrustumPlane(),FrustumPlane(),FrustumPlane(),FrustumPlane(),FrustumPlane() }; 65 | 66 | void Update(Matrix4f Matrix); 67 | bool InFrustum(FrustumAABB Box); 68 | 69 | }; 70 | } 71 | -------------------------------------------------------------------------------- /Images/Open7Days.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UglySwedishFish/Open7Days/107b924974ac017d9797689365ddcb232b60c3b3/Images/Open7Days.png -------------------------------------------------------------------------------- /Images/Up-To-Date-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UglySwedishFish/Open7Days/107b924974ac017d9797689365ddcb232b60c3b3/Images/Up-To-Date-Screenshot.png -------------------------------------------------------------------------------- /IndirectDiffuse.cpp: -------------------------------------------------------------------------------- 1 | #include "IndirectDiffuse.h" 2 | 3 | namespace Open7Days { 4 | namespace Rendering { 5 | 6 | 7 | 8 | void IndirectDiffuseLighting::PrepareIndirectDiffuseLighting(Window &Window) { 9 | 10 | //IndirectDiffusePongBuffer = MultiPassFrameBufferObject(Window.GetResolution() / 2, 3, { GL_RGB32F, GL_RGB16F, GL_RGB16F }); //useful for linear interpolation of the final image 11 | 12 | IndirectDiffuseBuffer = FrameBufferObject(Window.GetResolution() / 4, GL_RGBA32F, false); 13 | IndirectDiffusePongBuffer = FrameBufferObject(Window.GetResolution() / 4, GL_RGBA32F,false); 14 | IndirectDiffusePingBuffer = FrameBufferObject(Window.GetResolution() / 4, GL_RGBA32F, false); 15 | IndirectDiffuseTemporalBuffer = FrameBufferObjectPreviousData(Window.GetResolution() / 4, GL_RGBA32F, false); 16 | 17 | IndirectDiffuseShader = Shader("Shaders/IndirectDiffuse"); 18 | IndirectDiffuseSpatialShader = Shader("Shaders/IndirectDiffuseSpatial"); 19 | IndirectDiffusePacker = Shader("Shaders/IndirectDiffusePacker"); 20 | 21 | IndirectDiffuseShader.Bind(); 22 | 23 | IndirectDiffuseShader.SetUniform("ViewPosition", 0); 24 | IndirectDiffuseShader.SetUniform("Normal", 1); 25 | IndirectDiffuseShader.SetUniform("BlueNoise", 2); 26 | IndirectDiffuseShader.SetUniform("Depth", 3); 27 | IndirectDiffuseShader.SetUniform("Previous", 4); 28 | IndirectDiffuseShader.SetUniform("Sky", 5); 29 | IndirectDiffuseShader.SetUniform("Resolution", Window.GetResolution() / 4); 30 | 31 | IndirectDiffuseShader.UnBind(); 32 | 33 | IndirectDiffuseSpatialShader.Bind(); 34 | 35 | IndirectDiffuseSpatialShader.SetUniform("TexelSize", 1.0f / Vector2f(Window.GetResolution() / 4)); 36 | IndirectDiffuseSpatialShader.SetUniform("PackedData", 0); 37 | 38 | IndirectDiffuseSpatialShader.UnBind(); 39 | 40 | BlueNoise = LoadTextureGL("Textures/BlueNoise.png"); 41 | 42 | } 43 | 44 | void IndirectDiffuseLighting::RenderIndirectDiffuseLighting(Window &Window, Camera &Camera, DeferredRenderer & Deferred, ShadowMapper & Shadows, Voxelizer & Voxels, TextureCubeMap& Sky) { 45 | 46 | IndirectDiffuseTemporalBuffer.Bind(); 47 | 48 | IndirectDiffuseShader.Bind(); 49 | 50 | IndirectDiffuseShader.SetUniform("InverseView", glm::inverse(Camera.View)); 51 | IndirectDiffuseShader.SetUniform("PreviousCombined", Camera.Project * Camera.PrevView); 52 | 53 | IndirectDiffuseShader.SetUniform("CameraPosition", Camera.Position); 54 | IndirectDiffuseShader.SetUniform("First", First); 55 | IndirectDiffuseShader.SetUniform("Frame", Window.GetFrameCount()%10); 56 | 57 | Deferred.DeferredUnwrappedBuffer.BindImage(1, 1); 58 | Deferred.DeferredUnwrappedBuffer.BindImage(2, 0); 59 | BlueNoise.Bind(2); 60 | Deferred.DeferredRawBuffer.BindDepthImage(3); 61 | IndirectDiffuseTemporalBuffer.BindImagePrevious(4); 62 | Sky.Bind(5); 63 | 64 | Shadows.BindAndSetUniforms(IndirectDiffuseShader, 6); 65 | Voxels.SetUniforms(IndirectDiffuseShader, 9); 66 | 67 | DrawPostProcessQuad(); 68 | 69 | IndirectDiffuseShader.UnBind(); 70 | 71 | IndirectDiffuseTemporalBuffer.UnBind(Window); 72 | 73 | IndirectDiffuseSpatialShader.Bind(); 74 | 75 | IndirectDiffuseSpatialShader.SetUniform("InverseProject", glm::inverse(Camera.Project)); 76 | IndirectDiffuseSpatialShader.SetUniform("InverseView", glm::inverse(Matrix3f(Camera.View))); 77 | 78 | 79 | 80 | for (int i = 0; i < 2; i++) { 81 | IndirectDiffuseSpatialShader.SetUniform("Size", BlurSize[i]); 82 | 83 | if (i == 0) 84 | IndirectDiffuseTemporalBuffer.BindImage(0); 85 | else 86 | IndirectDiffusePongBuffer.BindImage(0); 87 | 88 | IndirectDiffusePingBuffer.Bind(); 89 | 90 | IndirectDiffuseSpatialShader.SetUniform("Vertical", false); 91 | 92 | DrawPostProcessQuad(); 93 | 94 | IndirectDiffusePingBuffer.UnBind(Window); 95 | 96 | IndirectDiffusePingBuffer.BindImage(0); 97 | 98 | IndirectDiffusePongBuffer.Bind(); 99 | 100 | IndirectDiffuseSpatialShader.SetUniform("Vertical", true); 101 | 102 | DrawPostProcessQuad(); 103 | 104 | IndirectDiffusePongBuffer.UnBind(Window); 105 | 106 | 107 | } 108 | 109 | IndirectDiffuseSpatialShader.UnBind(); 110 | 111 | First = false; 112 | 113 | 114 | } 115 | 116 | void IndirectDiffuseLighting::Reload(Window & Window) 117 | { 118 | 119 | First = true; 120 | 121 | IndirectDiffuseShader.Reload("Shaders/IndirectDiffuse"); 122 | IndirectDiffuseSpatialShader.Reload("Shaders/IndirectDiffuseSpatial"); 123 | 124 | IndirectDiffuseShader.Bind(); 125 | 126 | IndirectDiffuseShader.SetUniform("ViewPosition", 0); 127 | IndirectDiffuseShader.SetUniform("Normal", 1); 128 | IndirectDiffuseShader.SetUniform("BlueNoise", 2); 129 | IndirectDiffuseShader.SetUniform("Depth", 3); 130 | IndirectDiffuseShader.SetUniform("Previous", 4); 131 | IndirectDiffuseShader.SetUniform("Sky", 5); 132 | IndirectDiffuseShader.SetUniform("Resolution", Window.GetResolution() / 4); 133 | 134 | IndirectDiffuseShader.UnBind(); 135 | 136 | IndirectDiffuseSpatialShader.Bind(); 137 | 138 | IndirectDiffuseSpatialShader.SetUniform("TexelSize", 1.0f / Vector2f(Window.GetResolution() / 4)); 139 | IndirectDiffuseSpatialShader.SetUniform("PackedData", 0); 140 | 141 | IndirectDiffuseSpatialShader.UnBind(); 142 | 143 | } 144 | 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /IndirectDiffuse.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Shadows.h" 4 | #include "DeferredRenderer.h" 5 | #include "Voxelizer.h" 6 | 7 | namespace Open7Days { 8 | namespace Rendering { 9 | 10 | int const BlurSize[3] = { 1,3,9 }; 11 | 12 | struct IndirectDiffuseLighting { 13 | 14 | Shader IndirectDiffuseShader, IndirectDiffuseSpatialShader, IndirectDiffusePacker; 15 | 16 | FrameBufferObject IndirectDiffuseBuffer, IndirectDiffusePongBuffer, IndirectDiffusePingBuffer; //pong! 17 | FrameBufferObjectPreviousData IndirectDiffuseTemporalBuffer; 18 | 19 | TextureGL BlueNoise; 20 | 21 | bool First = true; 22 | 23 | void PrepareIndirectDiffuseLighting(Window & Window); 24 | void RenderIndirectDiffuseLighting(Window & Window, Camera& Camera,DeferredRenderer &Deferred,ShadowMapper &Shadows, Voxelizer &Voxels, TextureCubeMap& Sky); 25 | void Reload(Window & Window); 26 | }; 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /IndirectSpecular.cpp: -------------------------------------------------------------------------------- 1 | #include "IndirectSpecular.h" 2 | 3 | namespace Open7Days { 4 | namespace Rendering { 5 | 6 | 7 | 8 | void IndirectSpecularLighting::PrepareIndirectSpecularLighting(Window& Window) { 9 | IndirectSpecularBuffer = FrameBufferObjectPreviousData(Window.GetResolution(), GL_RGBA16F,false); 10 | 11 | IndirectSpecularShader = Shader("Shaders/IndirectSpecular"); 12 | 13 | IndirectSpecularShader.Bind(); 14 | 15 | IndirectSpecularShader.SetUniform("ViewPosition", 0); 16 | IndirectSpecularShader.SetUniform("Normal", 1); 17 | IndirectSpecularShader.SetUniform("FirstPassDiffuse", 2); 18 | IndirectSpecularShader.SetUniform("Test", 3); 19 | IndirectSpecularShader.SetUniform("CubeMapWorldPosition", 4); 20 | IndirectSpecularShader.SetUniform("Previous", 5); 21 | IndirectSpecularShader.SetUniform("Albedo", 6); 22 | IndirectSpecularShader.SetUniform("Sky", 7); 23 | IndirectSpecularShader.SetUniform("Depth", 8); 24 | IndirectSpecularShader.SetUniform("WaterDepth", 9); 25 | IndirectSpecularShader.SetUniform("WaterNormal", 10); 26 | 27 | IndirectSpecularShader.UnBind(); 28 | 29 | 30 | } 31 | 32 | void IndirectSpecularLighting::RenderIndirectSpecularLighting(Window& Window, Camera& Camera, DeferredRenderer& Deferred, CubeMapRenderer& CubeMap, FirstPassLighting& FirstPassLighting, WaterRenderer& Water, ShadowMapper& Shadows,TextureCubeMap& Sky) { 33 | 34 | IndirectSpecularBuffer.Bind(); 35 | 36 | IndirectSpecularShader.Bind(); 37 | 38 | IndirectSpecularShader.SetUniform("PreviousCombined", Camera.Project * Camera.PrevView); 39 | IndirectSpecularShader.SetUniform("InverseView", glm::inverse(Camera.View)); 40 | IndirectSpecularShader.SetUniform("View", Camera.View); 41 | IndirectSpecularShader.SetUniform("Frame", (Window.GetFrameCount() % 16)*919); 42 | 43 | IndirectSpecularShader.SetUniform("Project", (Camera.Project)); 44 | IndirectSpecularShader.SetUniform("InverseProject", glm::inverse(Camera.Project)); 45 | 46 | IndirectSpecularShader.SetUniform("CameraPosition", Camera.Position); 47 | IndirectSpecularShader.SetUniform("Time", Window.GetTimeOpened()); 48 | IndirectSpecularShader.SetUniform("LightDirection", glm::normalize(Shadows.Orientation)); 49 | 50 | 51 | Deferred.DeferredUnwrappedBuffer.BindImage(1, 1); 52 | Deferred.DeferredUnwrappedBuffer.BindImage(2, 0); 53 | FirstPassLighting.FirstPassLightingBuffer.BindImage(0, 2); 54 | 55 | glActiveTexture(GL_TEXTURE3); 56 | glBindTexture(GL_TEXTURE_CUBE_MAP, CubeMap.Lighting.Texture); 57 | 58 | glActiveTexture(GL_TEXTURE4); 59 | glBindTexture(GL_TEXTURE_CUBE_MAP, CubeMap.RawDeferred.Texture[1]); 60 | 61 | IndirectSpecularBuffer.BindImagePrevious(5); 62 | 63 | Deferred.DeferredUnwrappedBuffer.BindImage(0, 6); 64 | 65 | glActiveTexture(GL_TEXTURE7); 66 | glBindTexture(GL_TEXTURE_2D_ARRAY, Water.SkyTexture); 67 | 68 | Deferred.DeferredRawBuffer.BindDepthImage(8); 69 | Water.WaterBuffer.BindDepthImage(9); 70 | Water.WaterBuffer.BindImage(10); 71 | 72 | DrawPostProcessQuad(); 73 | 74 | IndirectSpecularShader.UnBind(); 75 | 76 | IndirectSpecularBuffer.UnBind(Window); 77 | 78 | } 79 | 80 | void IndirectSpecularLighting::ReloadIndirectSpecular() { 81 | IndirectSpecularShader.Reload("Shaders/IndirectSpecular"); 82 | 83 | IndirectSpecularShader.Bind(); 84 | 85 | IndirectSpecularShader.SetUniform("ViewPosition", 0); 86 | IndirectSpecularShader.SetUniform("Normal", 1); 87 | IndirectSpecularShader.SetUniform("FirstPassDiffuse", 2); 88 | IndirectSpecularShader.SetUniform("Test", 3); 89 | IndirectSpecularShader.SetUniform("CubeMapWorldPosition", 4); 90 | IndirectSpecularShader.SetUniform("Previous", 5); 91 | IndirectSpecularShader.SetUniform("Albedo", 6); 92 | IndirectSpecularShader.SetUniform("Sky", 7); 93 | IndirectSpecularShader.SetUniform("Depth", 8); 94 | IndirectSpecularShader.SetUniform("WaterDepth", 9); 95 | IndirectSpecularShader.SetUniform("WaterNormal", 10); 96 | 97 | IndirectSpecularShader.UnBind(); 98 | } 99 | 100 | } 101 | } -------------------------------------------------------------------------------- /IndirectSpecular.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "FirstPassLighting.h" 4 | 5 | namespace Open7Days { 6 | namespace Rendering { 7 | 8 | struct IndirectSpecularLighting { 9 | 10 | Shader IndirectSpecularShader; 11 | FrameBufferObjectPreviousData IndirectSpecularBuffer; 12 | 13 | bool First = true; 14 | 15 | void PrepareIndirectSpecularLighting(Window& Window); 16 | void RenderIndirectSpecularLighting(Window& Window, Camera& Camera, DeferredRenderer& Deferred, CubeMapRenderer& CubeMap, FirstPassLighting& FirstPassLighting,WaterRenderer & Water,ShadowMapper & Shadows, TextureCubeMap& Sky); 17 | void ReloadIndirectSpecular(); 18 | 19 | }; 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LightCombiner.cpp: -------------------------------------------------------------------------------- 1 | #include "LightCombiner.h" 2 | 3 | namespace Open7Days { 4 | namespace Rendering { 5 | 6 | 7 | 8 | void LightCombiner::PrepareLightCombiner() { 9 | 10 | LightCombinerShader = Shader("Shaders/LightCombiner"); 11 | 12 | LightCombinerShader.Bind(); 13 | 14 | LightCombinerShader.SetUniform("FirstPassDiffuse", 0); 15 | LightCombinerShader.SetUniform("FirstPassSpecular", 1); 16 | LightCombinerShader.SetUniform("IndirectSpecular", 2); 17 | LightCombinerShader.SetUniform("Normal", 3); 18 | LightCombinerShader.SetUniform("Albedo", 4); 19 | LightCombinerShader.SetUniform("Sky", 5); 20 | LightCombinerShader.SetUniform("Depth", 6); 21 | LightCombinerShader.SetUniform("WaterDepth", 7); 22 | LightCombinerShader.SetUniform("WaterNormal", 8); 23 | LightCombinerShader.SetUniform("WaterNormalMap", 9); 24 | 25 | LightCombinerShader.UnBind(); 26 | 27 | 28 | } 29 | 30 | void LightCombiner::CombineLighting(Window& Window, Camera& Camera, DeferredRenderer& Deferred, FirstPassLighting& First, IndirectSpecularLighting& IndirectSpecular, WaterRenderer & Water, ShadowMapper& Shadows,TextureCubeMap& Sky) { 31 | 32 | LightCombinerShader.Bind(); 33 | 34 | LightCombinerShader.SetUniform("ViewMatrix", Camera.View); 35 | LightCombinerShader.SetUniform("ProjectionMatrix", Camera.Project); 36 | LightCombinerShader.SetUniform("InverseView", glm::inverse(Camera.View)); 37 | LightCombinerShader.SetUniform("InverseProject", glm::inverse(Camera.Project)); 38 | LightCombinerShader.SetUniform("CameraPosition", Camera.Position); 39 | LightCombinerShader.SetUniform("Time", Window.GetTimeOpened()); 40 | LightCombinerShader.SetUniform("LightDirection", glm::normalize(Shadows.Orientation)); 41 | 42 | 43 | First.FirstPassLightingBuffer.BindImage(0, 0); 44 | First.FirstPassLightingBuffer.BindImage(1, 1); 45 | IndirectSpecular.IndirectSpecularBuffer.BindImage(2); 46 | Deferred.DeferredUnwrappedBuffer.BindImage(1, 3); 47 | Deferred.DeferredUnwrappedBuffer.BindImage(0, 4); 48 | glActiveTexture(GL_TEXTURE5); 49 | glBindTexture(GL_TEXTURE_2D_ARRAY, Water.SkyTexture); 50 | Deferred.DeferredRawBuffer.BindDepthImage(6); 51 | Water.WaterBuffer.BindDepthImage(7); 52 | Water.WaterBuffer.BindImage(8); 53 | glActiveTexture(GL_TEXTURE9); 54 | glBindTexture(GL_TEXTURE_2D_ARRAY, Water.WaterNormalTexture); 55 | 56 | DrawPostProcessQuad(); 57 | 58 | LightCombinerShader.UnBind(); 59 | 60 | } 61 | 62 | void LightCombiner::ReloadLightCombiner() { 63 | LightCombinerShader.Reload("Shaders/LightCombiner"); 64 | 65 | LightCombinerShader.Bind(); 66 | 67 | LightCombinerShader.SetUniform("FirstPassDiffuse", 0); 68 | LightCombinerShader.SetUniform("FirstPassSpecular", 1); 69 | LightCombinerShader.SetUniform("IndirectSpecular", 2); 70 | LightCombinerShader.SetUniform("Normal", 3); 71 | LightCombinerShader.SetUniform("Albedo", 4); 72 | LightCombinerShader.SetUniform("Sky", 5); 73 | LightCombinerShader.SetUniform("Depth", 6); 74 | LightCombinerShader.SetUniform("WaterDepth", 7); 75 | LightCombinerShader.SetUniform("WaterNormal", 8); 76 | LightCombinerShader.SetUniform("WaterNormalMap", 9); 77 | 78 | LightCombinerShader.UnBind(); 79 | } 80 | 81 | } 82 | } -------------------------------------------------------------------------------- /LightCombiner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IndirectSpecular.h" 4 | 5 | namespace Open7Days { 6 | namespace Rendering { 7 | 8 | 9 | struct LightCombiner { 10 | 11 | Shader LightCombinerShader; 12 | 13 | void PrepareLightCombiner(); 14 | void CombineLighting(Window & Window, Camera & Camera, DeferredRenderer & Deferred, FirstPassLighting & First, IndirectSpecularLighting & IndirectSpecular, WaterRenderer & Water,ShadowMapper &Shadows, TextureCubeMap & Sky); 15 | void ReloadLightCombiner(); 16 | }; 17 | 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Materials.cpp: -------------------------------------------------------------------------------- 1 | #include "Materials.h" 2 | #include 3 | #include 4 | #include 5 | #include "Dependencies/DependenciesMath.h" 6 | #include "Dependencies/DependenciesRendering.h" 7 | 8 | using namespace std::filesystem; 9 | 10 | 11 | namespace Open7Days { 12 | namespace Materials { 13 | 14 | bool AtStart(std::string Line, std::string Key) { 15 | 16 | if (Key.size() > Line.size()) 17 | return false; 18 | 19 | for (int i = 0; i < Key.size(); i++) 20 | if (Key[i] != Line[i]) 21 | return false; 22 | return true; 23 | } 24 | 25 | std::string Extract(std::string Line, int start, int end) { 26 | 27 | if (start < 0 || end > Line.length() || start > end) 28 | return ""; 29 | 30 | std::string Result = ""; 31 | 32 | for (int Character = start; Character < end; Character++) { 33 | Result += Line[Character]; 34 | } 35 | return Result; 36 | } 37 | 38 | 39 | Vector2i TransformToResolution(Vector2i CurrentPixel, Vector2i TransformToResolution) { 40 | 41 | Vector2f Normalized = Vector2f(CurrentPixel) / Vector2f(TEXTURE_RESOLUTION); 42 | 43 | Vector2i UnNormalized = Vector2i(Normalized * Vector2f(TransformToResolution)); 44 | 45 | UnNormalized = glm::clamp(UnNormalized, Vector2i(0), TransformToResolution); 46 | 47 | return UnNormalized; 48 | 49 | 50 | } 51 | 52 | 53 | 54 | sf::Image* TryLoad(std::string Path) { 55 | 56 | sf::Image* TestImage = new sf::Image(); 57 | 58 | for (auto& Format : SupportedFormats) { 59 | if (TestImage->loadFromFile(Path + Format)) 60 | return TestImage; 61 | } 62 | 63 | delete TestImage; 64 | 65 | return nullptr; 66 | 67 | } 68 | 69 | void MaterialList::Load() 70 | { 71 | 72 | std::vector TexturePaths; 73 | 74 | int SubID = 0; 75 | int TextureAmount = 0; 76 | 77 | 78 | 79 | for (const auto& Materials : directory_iterator("Textures/Materials")) { 80 | 81 | std::string FilePath = Materials.path().generic_string(); 82 | 83 | //we only care about folders, not files. We also dont care about the "empty" directory 84 | if (FilePath.find('.') != std::string::npos || FilePath.find("Empty") != std::string::npos) 85 | continue; 86 | 87 | 88 | 89 | if (!exists(FilePath + "/Material.mat")) 90 | continue; //no Material.mat file exists, so we cant properly load the things that are required 91 | 92 | std::ifstream MaterialDataFile(FilePath + "/Material.mat"); 93 | 94 | std::string Line = ""; 95 | 96 | Material TemporaryMaterial; 97 | std::string Name = ""; 98 | 99 | while (std::getline(MaterialDataFile, Line)) { 100 | 101 | //TODO: make int conversions more safe. right now, if for instance health is set to be "1000 " the program will crash 102 | if (AtStart(Line, "name")) { 103 | Name = Extract(Line, 5, Line.size()); 104 | } 105 | else if (AtStart(Line, "health")) { 106 | TemporaryMaterial.MaxHealth = std::stoi(Extract(Line, 7, Line.size())); 107 | } 108 | else if (AtStart(Line, "hardness")) { 109 | TemporaryMaterial.Hardness = std::stof(Extract(Line, 9, Line.size())); 110 | } 111 | else if (AtStart(Line, "hasmet")) { 112 | TemporaryMaterial.HasMet = Extract(Line, 7, Line.size()) == "true"; 113 | } 114 | else if (AtStart(Line, "type")) { 115 | 116 | std::string Syntax = Extract(Line, 5, Line.size()); 117 | 118 | if (Syntax == "shovel") 119 | TemporaryMaterial.type = Shovel; 120 | else if (Syntax == "axe") 121 | TemporaryMaterial.type = Axe; 122 | else 123 | TemporaryMaterial.type = Pickaxe; 124 | } 125 | else if (AtStart(Line, "icontype")) { 126 | std::string Syntax = Extract(Line, 9, Line.size()); 127 | 128 | if (Syntax == "custom") 129 | TemporaryMaterial.iconType = Custom; 130 | else if (Syntax == "item") 131 | TemporaryMaterial.iconType = Item; 132 | else 133 | TemporaryMaterial.iconType = Block; 134 | } 135 | 136 | 137 | } 138 | 139 | 140 | 141 | //check if theres already a baked texture 142 | if (!exists(FilePath + "/Combined.png")) { 143 | //TODO: bake together textures :) 144 | 145 | sf::Image* ImageColor = TryLoad(FilePath + "/Color"), * ImageAO = TryLoad(FilePath + "/AO"), * ImageRoughness = TryLoad(FilePath + "/Roughness"), * ImageMetalness = TryLoad(FilePath + "/Metalness"); 146 | 147 | //start with the required ones 148 | 149 | if (ImageColor == nullptr || ImageRoughness == nullptr || (TemporaryMaterial.HasMet && ImageMetalness == nullptr)) 150 | continue; 151 | 152 | sf::Image *SaveImage = new sf::Image(); 153 | SaveImage->create(TEXTURE_RESOLUTION, TEXTURE_RESOLUTION); 154 | 155 | for (int x = 0; x < TEXTURE_RESOLUTION; x++) { 156 | for (int y = 0; y < TEXTURE_RESOLUTION; y++) { 157 | 158 | //for heavens sake, lets stick to floats for the colors aight mate 159 | 160 | 161 | 162 | Vector2i CurrentPixel = Vector2i(x, y); 163 | 164 | Vector2i TransformedColor = TransformToResolution(CurrentPixel, Vector2i(ImageColor->getSize().x, ImageColor->getSize().y)); 165 | Vector2i TransformedRoughness = TransformToResolution(CurrentPixel, Vector2i(ImageRoughness->getSize().x, ImageRoughness->getSize().y)); 166 | 167 | 168 | 169 | 170 | auto PixelColor = ImageColor->getPixel(TransformedColor.x, TransformedColor.y); 171 | auto RoughessColor = ImageRoughness->getPixel(TransformedRoughness.x, TransformedRoughness.y); 172 | 173 | auto AmbientOcclusionColor = sf::Color(255, 255, 255, 255); 174 | auto MetalnessColor = sf::Color(255, 255, 255, 255); 175 | 176 | Vector4u CurrentColor = Vector4u(PixelColor.r, PixelColor.g, PixelColor.b, RoughessColor.r); 177 | 178 | if (ImageAO != nullptr) { 179 | 180 | Vector2i TransFormedAO = TransformToResolution(CurrentPixel, Vector2i(ImageAO->getSize().x, ImageAO->getSize().y)); 181 | AmbientOcclusionColor = ImageAO->getPixel(TransFormedAO.x, TransFormedAO.y); 182 | 183 | CurrentColor.x = (CurrentColor.x * AmbientOcclusionColor.r) / 255; 184 | CurrentColor.y = (CurrentColor.y * AmbientOcclusionColor.r) / 255; 185 | CurrentColor.z = (CurrentColor.z * AmbientOcclusionColor.r) / 255; 186 | } 187 | 188 | if (TemporaryMaterial.HasMet) { 189 | 190 | Vector2i TransformedMet = TransformToResolution(CurrentPixel, Vector2i(ImageMetalness->getSize().x, ImageMetalness->getSize().y)); 191 | MetalnessColor = ImageMetalness->getPixel(TransformedMet.x, TransformedMet.y); 192 | 193 | CurrentColor.a = (RoughessColor.r / 16) * 16 + MetalnessColor.r / 16; 194 | 195 | 196 | } 197 | 198 | SaveImage->setPixel(x, y, sf::Color(CurrentColor.x, CurrentColor.y, CurrentColor.z, CurrentColor.w)); 199 | 200 | 201 | 202 | 203 | 204 | } 205 | } 206 | 207 | SaveImage->saveToFile(FilePath + "/Combined.png"); 208 | 209 | 210 | } 211 | 212 | //load the combined .png texture 213 | 214 | TemporaryMaterial.SubTexture = TexturePaths.size(); 215 | 216 | this->Materials[Name] = TemporaryMaterial; 217 | 218 | std::cout << Name << " subtexture: " << TemporaryMaterial.SubTexture << '\n'; 219 | 220 | TexturePaths.push_back(FilePath + "/Combined.png"); 221 | 222 | 223 | 224 | 225 | 226 | } 227 | 228 | 229 | 230 | unsigned int Id; 231 | glGenTextures(1, &Id); 232 | 233 | std::cout << Id << std::endl; 234 | 235 | glBindTexture(GL_TEXTURE_2D_ARRAY, Id); 236 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); 237 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); 238 | glTexParameteri(GL_TEXTURE_2D_ARRAY, 239 | GL_TEXTURE_MIN_FILTER, 240 | GL_LINEAR_MIPMAP_LINEAR); 241 | glTexParameteri(GL_TEXTURE_2D_ARRAY, 242 | GL_TEXTURE_MAG_FILTER, 243 | GL_LINEAR); 244 | glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, TEXTURE_RESOLUTION, TEXTURE_RESOLUTION, TexturePaths.size(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 245 | 246 | for (int SubImage = 0; SubImage < TexturePaths.size(); SubImage++) { 247 | sf::Image RawImage; 248 | 249 | if (!RawImage.loadFromFile(TexturePaths[SubImage])) { 250 | std::cout << "BAD!\n"; 251 | //todo: add proper error handling 252 | } 253 | 254 | glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 255 | 0, 256 | 0, 0, SubImage, 257 | TEXTURE_RESOLUTION, TEXTURE_RESOLUTION, 1, 258 | GL_RGBA, 259 | GL_UNSIGNED_BYTE, 260 | RawImage.getPixelsPtr()); 261 | 262 | 263 | } 264 | 265 | glGenerateMipmap(GL_TEXTURE_2D_ARRAY); 266 | 267 | glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 268 | 269 | TextureMaterials = Id; 270 | 271 | 272 | } 273 | 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /Materials.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | //todo: probably another place where u wanna have settings but idk tbh 8 | #define TEXTURE_RESOLUTION 1024 9 | 10 | const std::array SupportedFormats = { ".png", ".jpg", ".jpeg", ".gif", ".bmp" }; 11 | 12 | 13 | namespace Open7Days { 14 | namespace Materials { 15 | 16 | 17 | 18 | //Specifies what type of tool is primarily used to break the material 19 | enum Type { 20 | Shovel, 21 | Axe, 22 | Pickaxe 23 | }; 24 | 25 | enum IconType { 26 | Block, 27 | Item, 28 | Custom 29 | }; 30 | 31 | struct Material { 32 | Type type; 33 | IconType iconType; 34 | unsigned short MaxHealth; 35 | float Hardness; 36 | bool HasMet; 37 | unsigned short SubTexture; 38 | 39 | 40 | 41 | }; 42 | 43 | struct MaterialList { 44 | unsigned int TextureMaterials = 0, TextureIcons = 0; 45 | 46 | //specifies the sub-texture 47 | 48 | std::map Materials; 49 | 50 | void Load(); 51 | 52 | 53 | 54 | 55 | }; 56 | 57 | 58 | 59 | 60 | 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Mesh.cpp: -------------------------------------------------------------------------------- 1 | #include "Mesh.h" 2 | #include 3 | 4 | namespace Open7Days { 5 | 6 | namespace Rendering { 7 | 8 | void Mesh::ClearVectors() { 9 | Vertices.clear(); 10 | Normals.clear(); 11 | TexCoords.clear(); 12 | Indices.clear(); 13 | Materials.clear(); 14 | MeshEntries.clear(); 15 | } 16 | 17 | Mesh::~Mesh() { 18 | //ClearVectors(); 19 | } 20 | 21 | void LoadMeshData(const char* file, Mesh& Model) { 22 | Assimp::Importer ObjectImporter; 23 | 24 | const aiScene* Scene = ObjectImporter.ReadFile(file, aiProcess_Triangulate | aiProcess_CalcTangentSpace); 25 | Mesh TemporaryModel; 26 | 27 | if (Scene) { 28 | 29 | TemporaryModel.MeshEntries.resize(Scene->mNumMeshes); 30 | 31 | 32 | unsigned int NumVertices = 0; 33 | unsigned int NumIndices = 0; 34 | 35 | // Count the number of vertices and indices 36 | for (unsigned int i = 0; i < TemporaryModel.MeshEntries.size(); i++) { 37 | TemporaryModel.MeshEntries[i].MaterialIndex = Scene->mMeshes[i]->mMaterialIndex; 38 | TemporaryModel.MeshEntries[i].NumIndices = Scene->mMeshes[i]->mNumFaces * 3; 39 | TemporaryModel.MeshEntries[i].BaseVertex = NumVertices; 40 | TemporaryModel.MeshEntries[i].BaseIndex = NumIndices; 41 | 42 | NumVertices += Scene->mMeshes[i]->mNumVertices; 43 | NumIndices += TemporaryModel.MeshEntries[i].NumIndices; 44 | } 45 | 46 | 47 | for (unsigned int i = 0; i < TemporaryModel.MeshEntries.size(); i++) { 48 | const aiMesh* aiMesh = Scene->mMeshes[i]; 49 | InitMesh(aiMesh, TemporaryModel); 50 | } 51 | 52 | int CurrentGlobalIndicie = 0, CurrentIndicieRefractive = 0, CurrentIndicieNonRefractive = 0; 53 | 54 | std::cout << "Meshentry size: " << TemporaryModel.MeshEntries.size() << '\n'; 55 | 56 | for (int MeshEntry = 0; MeshEntry < TemporaryModel.MeshEntries.size(); MeshEntry++) { 57 | 58 | std::cout << MeshEntry << '\n'; 59 | 60 | for (int Indicie = 0; Indicie < TemporaryModel.MeshEntries[MeshEntry].NumIndices; Indicie++) { 61 | 62 | Model.Vertices.push_back(TemporaryModel.Vertices[CurrentGlobalIndicie]); 63 | Model.Normals.push_back(TemporaryModel.Normals[CurrentGlobalIndicie]); 64 | Model.TexCoords.push_back(Vector3f(TemporaryModel.TexCoords[CurrentGlobalIndicie].x, TemporaryModel.TexCoords[CurrentGlobalIndicie].y, float(TemporaryModel.Materials[CurrentGlobalIndicie]) + 0.1)); 65 | Model.Indices.push_back(CurrentIndicieNonRefractive++); 66 | CurrentGlobalIndicie++; 67 | 68 | } 69 | 70 | } 71 | 72 | 73 | 74 | 75 | } 76 | else { 77 | std::cout << "Failed to load model: " << file << " (Error: " << ObjectImporter.GetErrorString() << ") \n"; 78 | } 79 | } 80 | 81 | bool InitMesh(const aiMesh* aiMesh, Mesh& mesh) { 82 | for (unsigned int i = 0; i < aiMesh->mNumVertices; i++) { 83 | const aiVector3D* VertexPos = &(aiMesh->mVertices[i]); 84 | const aiVector3D* VertexNormal = &(aiMesh->mNormals[i]); 85 | const aiVector3D* VertexTextureCoordinate = aiMesh->HasTextureCoords(0) ? &(aiMesh->mTextureCoords[0][i]) : nullptr; 86 | 87 | //if (!aiMesh->HasTangentsAndBitangents()) 88 | // std::cout << "Warning: model does not have proper tangents!\n"; 89 | 90 | 91 | 92 | mesh.Vertices.push_back(glm::vec3(VertexPos->x, VertexPos->y, VertexPos->z)); 93 | mesh.Normals.push_back(glm::vec3(VertexNormal->x, VertexNormal->y, VertexNormal->z)); 94 | 95 | 96 | if(VertexTextureCoordinate) 97 | { 98 | mesh.TexCoords.push_back(Vector3f(VertexTextureCoordinate->x, VertexTextureCoordinate->y, float(aiMesh->mMaterialIndex) + 0.1)); 99 | } 100 | else 101 | { 102 | mesh.TexCoords.push_back(Vector3f(aiVector3D(0).x, aiVector3D(0).y, float(aiMesh->mMaterialIndex) + 0.1f)); 103 | } 104 | mesh.Materials.push_back(aiMesh->mMaterialIndex); 105 | } 106 | 107 | for (unsigned int i = 0; i < aiMesh->mNumFaces; i++) { 108 | const aiFace& Face = aiMesh->mFaces[i]; 109 | if (Face.mNumIndices == 3) { //if it isn't a triangle, skip this face 110 | mesh.Indices.push_back(Face.mIndices[0]); 111 | mesh.Indices.push_back(Face.mIndices[1]); 112 | mesh.Indices.push_back(Face.mIndices[2]); 113 | } 114 | else { 115 | mesh.Indices.push_back(Face.mIndices[0]); 116 | mesh.Indices.push_back(Face.mIndices[0]); 117 | mesh.Indices.push_back(Face.mIndices[0]); 118 | } 119 | } 120 | return true; 121 | } 122 | 123 | void Model::PrepareForRendering() { 124 | glGenVertexArrays(1, &VAO); 125 | glBindVertexArray(VAO); 126 | glGenBuffers(4, VBO); 127 | 128 | glBindBuffer(GL_ARRAY_BUFFER, VBO[1]); 129 | glBufferData(GL_ARRAY_BUFFER, sizeof(ModelData.Vertices[0]) * ModelData.Vertices.size(), &ModelData.Vertices[0], GL_STATIC_DRAW); 130 | glEnableVertexAttribArray(0); 131 | glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 132 | 133 | glBindBuffer(GL_ARRAY_BUFFER, VBO[2]); 134 | glBufferData(GL_ARRAY_BUFFER, sizeof(ModelData.TexCoords[0]) * ModelData.TexCoords.size(), &ModelData.TexCoords[0], GL_STATIC_DRAW); 135 | glEnableVertexAttribArray(1); 136 | glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); 137 | 138 | glBindBuffer(GL_ARRAY_BUFFER, VBO[3]); 139 | glBufferData(GL_ARRAY_BUFFER, sizeof(ModelData.Normals[0]) * ModelData.Normals.size(), &ModelData.Normals[0], GL_STATIC_DRAW); 140 | glEnableVertexAttribArray(2); 141 | glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0); 142 | 143 | 144 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO[0]); 145 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ModelData.Indices[0]) * ModelData.Indices.size(), &ModelData.Indices[0], GL_STATIC_DRAW); 146 | 147 | 148 | 149 | glBindVertexArray(0); 150 | 151 | glBindBuffer(GL_ARRAY_BUFFER, 0); 152 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 153 | } 154 | 155 | void Model::Draw() { 156 | glBindVertexArray(VAO); 157 | 158 | glDrawElements(GL_TRIANGLES, ModelData.Vertices.size(), GL_UNSIGNED_INT, nullptr); 159 | 160 | glBindVertexArray(0); 161 | } 162 | 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /Mesh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Shader.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Open7Days { 11 | namespace Rendering { 12 | 13 | 14 | 15 | struct Mesh { //note; this is NOT a model. It is only a collection of the data required to construct a model 16 | 17 | struct MeshEntry { 18 | unsigned int NumIndices; 19 | unsigned int BaseVertex; 20 | unsigned int BaseIndex; 21 | unsigned int MaterialIndex; 22 | inline MeshEntry() : 23 | NumIndices(0), 24 | BaseVertex(0), 25 | BaseIndex(0), 26 | MaterialIndex(0) 27 | {} 28 | }; 29 | 30 | std::vector MeshEntries; 31 | std::vector Materials; 32 | 33 | std::vector Vertices; 34 | std::vector Normals; 35 | std::vector TexCoords; 36 | std::vector Indices; 37 | 38 | std::vector SingleMeshIndicies; 39 | void ClearVectors(); 40 | ~Mesh(); 41 | 42 | }; 43 | 44 | void LoadMeshData(const char* file, Mesh& Model); 45 | bool InitMesh(const aiMesh* aiMesh, Mesh& mesh); 46 | 47 | 48 | struct Model { 49 | Mesh ModelData; 50 | 51 | unsigned int VAO, VBO[4]; 52 | 53 | inline Model(const char* Model) : 54 | VAO(), 55 | VBO{}, 56 | ModelData(Mesh()) { 57 | LoadMeshData(Model, ModelData); 58 | PrepareForRendering(); 59 | } 60 | 61 | inline Model() : 62 | VAO(), 63 | VBO{}, 64 | ModelData(Mesh()) { 65 | } 66 | 67 | void PrepareForRendering(); 68 | void Draw(); 69 | 70 | }; 71 | 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Models/WaterPlane.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl None 5 | Ns 0 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.8 0.8 0.8 8 | Ks 0.8 0.8 0.8 9 | d 1 10 | illum 2 11 | -------------------------------------------------------------------------------- /Pipeline.cpp: -------------------------------------------------------------------------------- 1 | #include "Pipeline.h" 2 | #include 3 | 4 | namespace Open7Days { 5 | void Pipeline::Prepare(Window & Window, Camera & Camera) { 6 | 7 | Rendering::PreparePostProcess(); 8 | 9 | Shadows.Prepare(Camera); 10 | Deferred.PrepareDeferredRendering(Window, Camera); 11 | 12 | 13 | FirstPassLighting.Prepare(Window); 14 | Voxelizer.PrepareVoxelizer(); 15 | IndirectDiffuse.PrepareIndirectDiffuseLighting(Window); 16 | IndirectSpecular.PrepareIndirectSpecularLighting(Window); 17 | LightCombiner.PrepareLightCombiner(); 18 | CubeMap.PrepareCubeMapRenderer(); 19 | WaterRenderer.PrepareWaterRenderer(Window); 20 | 21 | EquirectangularToCubeMapShader = Rendering::Shader("Shaders/EquirectangularToCubeMapShader"); 22 | 23 | Sky = Rendering::LoadHDRI("Textures/sky.hdr", true, true, EquirectangularToCubeMapShader); 24 | 25 | glClearColor(0.0,0.0,0.0, 1.0); 26 | glEnable(GL_DEPTH_TEST); 27 | glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); 28 | 29 | //glEnable(GL_CULL_FACE); 30 | //glCullFace(GL_BACK); 31 | 32 | } 33 | void Pipeline::Run(Window & Window, Camera & Camera) { 34 | 35 | bool Running = true; 36 | sf::Event Event; 37 | sf::Clock GameClock; 38 | int Frame = 0; 39 | float T = 0.; 40 | float Speed = 18.; 41 | 42 | int FramesPerSecond = 0; 43 | float TimeElapsed = 0.0; 44 | 45 | while (Running) { 46 | while (Window.GetRawWindow()->pollEvent(Event)) {} 47 | Window.SetFrameTime(GameClock.getElapsedTime().asSeconds()); 48 | GameClock.restart(); 49 | T += Window.GetFrameTime(); 50 | Frame++; 51 | Window.SetTimeOpened(T); 52 | Window.SetFrameCount(Frame); 53 | 54 | if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Up)) 55 | Shadows.Direction.x += Speed * Window.GetFrameTime(); 56 | 57 | if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Down)) 58 | Shadows.Direction.x -= Speed * Window.GetFrameTime(); 59 | 60 | if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Left)) 61 | Shadows.Direction.y += Speed * Window.GetFrameTime(); 62 | 63 | if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Right)) 64 | Shadows.Direction.y -= Speed * Window.GetFrameTime(); 65 | 66 | if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::R) && sf::Keyboard::isKeyPressed(sf::Keyboard::Key::LControl)) { 67 | FirstPassLighting.ReloadShader(); 68 | Voxelizer.ReloadVoxelizer(); 69 | IndirectDiffuse.Reload(Window); 70 | WaterRenderer.ReloadWaterRenderer(); 71 | IndirectSpecular.ReloadIndirectSpecular(); 72 | LightCombiner.ReloadLightCombiner(); 73 | } 74 | Camera.PrevView = Camera.View; 75 | Core::HandleInput(Camera, 10.f, 0.15f, Window, sf::Mouse::isButtonPressed(sf::Mouse::Button::Middle), true); 76 | Camera.View = Core::ViewMatrix(Camera.Position, Camera.Rotation); 77 | Camera.UpdateFrustum(); 78 | 79 | FramesPerSecond++; 80 | if (TimeElapsed + 1.0 < T) { 81 | std::cout << FramesPerSecond << '\n'; 82 | TimeElapsed = T; 83 | FramesPerSecond = 0; 84 | } 85 | 86 | Chunks.GenerateChunks(Camera, Deferred.Materials); 87 | 88 | Shadows.UpdateShadowMapCascades(Window, Camera, Chunks); 89 | Deferred.RenderToDeffered(Window, Camera, Chunks); 90 | WaterRenderer.RenderWater(Camera, Window); 91 | Voxelizer.VoxelizeScene(Camera, Window, Shadows, Chunks); 92 | CubeMap.RenderToCubeMap(Window, Camera, Deferred, Shadows, Chunks); 93 | IndirectDiffuse.RenderIndirectDiffuseLighting(Window, Camera, Deferred, Shadows, Voxelizer, Sky); 94 | FirstPassLighting.RenderFirstLightingPass(Window, Camera, Deferred, Shadows, IndirectDiffuse, CubeMap, WaterRenderer); 95 | IndirectSpecular.RenderIndirectSpecularLighting(Window, Camera, Deferred, CubeMap, FirstPassLighting, WaterRenderer,Shadows, Sky); 96 | 97 | glViewport(0, 0, Window.GetResolution().x, Window.GetResolution().y); 98 | 99 | glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 100 | 101 | LightCombiner.CombineLighting(Window, Camera, Deferred, FirstPassLighting, IndirectSpecular, WaterRenderer,Shadows, Sky); 102 | 103 | Window.GetRawWindow()->display(); 104 | 105 | } 106 | 107 | 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Pipeline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "LightCombiner.h" 4 | 5 | 6 | namespace Open7Days { 7 | struct Pipeline { 8 | Rendering::ChunkContainer Chunks; 9 | Rendering::DeferredRenderer Deferred; 10 | Rendering::ShadowMapper Shadows; 11 | Rendering::FirstPassLighting FirstPassLighting; 12 | Rendering::Voxelizer Voxelizer; 13 | Rendering::IndirectDiffuseLighting IndirectDiffuse; 14 | Rendering::IndirectSpecularLighting IndirectSpecular; 15 | Rendering::LightCombiner LightCombiner; 16 | Rendering::CubeMapRenderer CubeMap; 17 | Rendering::TextureCubeMap Sky; 18 | Rendering::Shader EquirectangularToCubeMapShader; 19 | Rendering::WaterRenderer WaterRenderer; 20 | 21 | void Prepare(Window & Window, Camera & Camera); 22 | void Run(Window & Window, Camera & Camera); 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image](https://github.com/UglySwedishFish/Open7Days/blob/master/Images/Open7Days.png?raw=true) 2 | 3 | # What is Open7Days? 4 | 5 | Open 7 days is an open-source engine based on some of the technology behind the popular game 7 days to die. 6 | Right now, the engine is in a super early stage, so when looking at the code, keep in mind that 99% of it is temporary and will be cleaned 7 | up in the future! 8 | 9 | # What is the plan for Open7Days? 10 | 11 | The plan behind Open 7 Days is to eventually utilize the engine to create a game within in the same vein of 7 days to die. Right now, 12 | this is quite a far away plan but hopefully this will start being developed within the next few months. 13 | 14 | # How can I support the development of Open7Days? 15 | 16 | Right now, because the engine is in such an early stage, I advise you against actively working on it. Of course, if you see anything you 17 | see could be improved, feel free to open an issue / submit a request. 18 | 19 | # Current features implemented in Open7Days. 20 | 21 | * **Procedurally generated terrain with marching cubes** 22 | 23 | * **Cascaded exponential shadow maps** 24 | 25 | * **Indirect diffuse lighting powered with cascaded voxel ray-tracing** 26 | 27 | * **Indirect specular lighting with screen-space + cube map raytracing** 28 | 29 | * **Screen-space-refractions** 30 | 31 | * **Water rendering** 32 | 33 | * **Basic sky rendering** 34 | 35 | # Current up-to-date screenshot: 36 | 37 | ![screenshot](https://github.com/UglySwedishFish/Open7Days/blob/master/Images/Up-To-Date-Screenshot.png?raw=true) 38 | -------------------------------------------------------------------------------- /Shader.cpp: -------------------------------------------------------------------------------- 1 | #include "Shader.h" 2 | #include "GL/glad.h" 3 | #include 4 | #include 5 | #include 6 | 7 | #define throwerror(s) std::cout << s 8 | 9 | #define GLOBAL_SHADER_DEFINITIONS "#define half lowp float\n#define double highp float\n" 10 | 11 | 12 | 13 | 14 | unsigned int Open7Days::Rendering::LoadShader(unsigned int ShaderType, const std::string & File, unsigned int & Buffer, unsigned int BaseID, bool ReCreate) { 15 | std::string source = ""; //all the shader code 16 | std::ifstream file(File); 17 | 18 | if (!file.is_open()) { 19 | throwerror(static_cast("Failed to open file: ") + File); 20 | return 0; //-1 hurr durr 21 | } 22 | 23 | 24 | while (!file.eof()) { 25 | char line[50000]; 26 | file.getline(line, 50000); 27 | std::string Line = line; 28 | 29 | if (source.size() == 0) { 30 | source += Line + '\n'; 31 | source += GLOBAL_SHADER_DEFINITIONS; 32 | } 33 | else { 34 | source += Line + '\n'; 35 | } 36 | 37 | 38 | 39 | 40 | } 41 | 42 | std::cout << "BaseID: " << BaseID << '\n'; 43 | 44 | if (ReCreate) 45 | BaseID = glCreateShader(ShaderType); //compile the shader 46 | 47 | const char* csource = source.c_str(); 48 | if (ReCreate) 49 | glGenBuffers(1, &Buffer); 50 | glShaderSource(BaseID, 1, &csource, NULL); 51 | glCompileShader(BaseID); 52 | char error[15000]; 53 | glGetShaderInfoLog(BaseID, 15000, NULL, error); 54 | 55 | 56 | throwerror(error); 57 | std::string s = error; 58 | 59 | if (s.length() > 3) 60 | std::cout << "Shader: " << File << " compiled with either errors or warnings\n"; 61 | 62 | 63 | return BaseID; 64 | } 65 | 66 | Open7Days::Rendering::Shader::Shader(const std::string & vertex, const std::string & fragment) : 67 | VertexShader(LoadShader(GL_VERTEX_SHADER, vertex, VertexBuffer, VertexShader)), 68 | FragmentShader(LoadShader(GL_FRAGMENT_SHADER, fragment, FragmentBuffer, FragmentShader)), 69 | ShaderID(glCreateProgram()) { 70 | glAttachShader(ShaderID, VertexShader); 71 | glAttachShader(ShaderID, FragmentShader); 72 | glLinkProgram(ShaderID); 73 | glUseProgram(ShaderID); 74 | } 75 | Open7Days::Rendering::Shader::Shader(const std::string & vertex, const std::string & geometry, const std::string & fragment) : 76 | VertexShader(LoadShader(GL_VERTEX_SHADER, vertex, VertexBuffer, VertexShader)), 77 | GeometryShader(LoadShader(GL_GEOMETRY_SHADER, geometry, GeometryBuffer, GeometryShader)), 78 | FragmentShader(LoadShader(GL_FRAGMENT_SHADER, fragment, FragmentBuffer, FragmentShader)), 79 | ShaderID(glCreateProgram()) { 80 | glAttachShader(ShaderID, VertexShader); 81 | glAttachShader(ShaderID, GeometryShader); 82 | glAttachShader(ShaderID, FragmentShader); 83 | glLinkProgram(ShaderID); 84 | glUseProgram(ShaderID); 85 | } 86 | 87 | Open7Days::Rendering::Shader::Shader(const std::string & Directory, bool HasGeometryShader) { 88 | if (HasGeometryShader) 89 | *this = Shader(Directory + "/vert.glsl", Directory + "/geom.glsl", Directory + "/frag.glsl"); 90 | else 91 | *this = Shader(Directory + "/vert.glsl", Directory + "/frag.glsl"); 92 | } 93 | 94 | Open7Days::Rendering::Shader::Shader() : 95 | VertexShader(NULL), 96 | FragmentShader(NULL), 97 | GeometryShader(NULL), 98 | ShaderID(NULL) { 99 | } 100 | 101 | void Open7Days::Rendering::Shader::Bind() { 102 | glUseProgram(ShaderID); 103 | } 104 | 105 | void Open7Days::Rendering::Shader::UnBind() { 106 | glUseProgram(NULL); 107 | } 108 | 109 | void Open7Days::Rendering::Shader::SetUniform(const std::string & Name, int Value) { 110 | glUniform1i(glGetUniformLocation(ShaderID, Name.c_str()), Value); 111 | } 112 | 113 | void Open7Days::Rendering::Shader::SetUniform(const std::string & Name, size_t Value) { 114 | glUniform1i(glGetUniformLocation(ShaderID, Name.c_str()), Value); 115 | } 116 | 117 | void Open7Days::Rendering::Shader::SetUniform(const std::string & Name, float Value) { 118 | glUniform1f(glGetUniformLocation(ShaderID, Name.c_str()), Value); 119 | } 120 | 121 | void Open7Days::Rendering::Shader::SetUniform(const std::string & Name, bool Value) { 122 | glUniform1i(glGetUniformLocation(ShaderID, Name.c_str()), Value); 123 | } 124 | 125 | void Open7Days::Rendering::Shader::SetUniform(const std::string & Name, Vector2f Value) { 126 | glUniform2f(glGetUniformLocation(ShaderID, Name.c_str()), Value.x, Value.y); 127 | } 128 | 129 | void Open7Days::Rendering::Shader::SetUniform(const std::string & Name, Vector3f Value) { 130 | glUniform3f(glGetUniformLocation(ShaderID, Name.c_str()), Value.x, Value.y, Value.z); 131 | } 132 | 133 | void Open7Days::Rendering::Shader::SetUniform(const std::string & Name, Vector4f Value) { 134 | glUniform4f(glGetUniformLocation(ShaderID, Name.c_str()), Value.x, Value.y, Value.z, Value.w); 135 | } 136 | 137 | void Open7Days::Rendering::Shader::SetUniform(const std::string & Name, Vector2i Value) { 138 | glUniform2i(glGetUniformLocation(ShaderID, Name.c_str()), Value.x, Value.y); 139 | } 140 | 141 | void Open7Days::Rendering::Shader::SetUniform(const std::string & Name, Vector3i Value) { 142 | glUniform3i(glGetUniformLocation(ShaderID, Name.c_str()), Value.x, Value.y, Value.z); 143 | } 144 | 145 | void Open7Days::Rendering::Shader::SetUniform(const std::string & Name, Vector4i Value) { 146 | glUniform4i(glGetUniformLocation(ShaderID, Name.c_str()), Value.x, Value.y, Value.z, Value.w); 147 | } 148 | 149 | void Open7Days::Rendering::Shader::SetUniform(const std::string & Name, Matrix4f Value, bool Transpose) { 150 | glUniformMatrix4fv(glGetUniformLocation(ShaderID, Name.c_str()), 1, Transpose, glm::value_ptr(Value)); 151 | } 152 | 153 | void Open7Days::Rendering::Shader::SetUniform(const std::string& Name, Matrix3f Value, bool Transpose) { 154 | glUniformMatrix3fv(glGetUniformLocation(ShaderID, Name.c_str()), 1, Transpose, glm::value_ptr(Value)); 155 | } 156 | 157 | void Open7Days::Rendering::Shader::Reload(const std::string& vertex, const std::string& fragment) { 158 | 159 | 160 | glDetachShader(ShaderID, VertexShader); 161 | glDetachShader(ShaderID, FragmentShader); 162 | 163 | glDeleteShader(VertexShader); 164 | glDeleteShader(FragmentShader); 165 | 166 | glDeleteProgram(ShaderID); 167 | 168 | ShaderID = glCreateProgram(); 169 | 170 | 171 | VertexShader = LoadShader(GL_VERTEX_SHADER, vertex, VertexBuffer, VertexShader, true); 172 | FragmentShader = LoadShader(GL_FRAGMENT_SHADER, fragment, FragmentBuffer, FragmentShader, true); 173 | 174 | glAttachShader(ShaderID, VertexShader); 175 | glAttachShader(ShaderID, FragmentShader); 176 | glLinkProgram(ShaderID); 177 | glUseProgram(ShaderID); 178 | 179 | } 180 | 181 | void Open7Days::Rendering::Shader::Reload(const std::string& vertex, const std::string& fragment, const std::string& geometry) { 182 | glDetachShader(ShaderID, VertexShader); 183 | glDetachShader(ShaderID, FragmentShader); 184 | glDetachShader(ShaderID, GeometryShader); 185 | 186 | glDeleteShader(VertexShader); 187 | glDeleteShader(FragmentShader); 188 | glDeleteShader(GeometryShader); 189 | 190 | glDeleteProgram(ShaderID); 191 | 192 | ShaderID = glCreateProgram(); 193 | 194 | 195 | VertexShader = LoadShader(GL_VERTEX_SHADER, vertex, VertexBuffer, VertexShader, true); 196 | GeometryShader = LoadShader(GL_GEOMETRY_SHADER, geometry, GeometryBuffer, GeometryShader, true); 197 | FragmentShader = LoadShader(GL_FRAGMENT_SHADER, fragment, FragmentBuffer, FragmentShader, true); 198 | 199 | glAttachShader(ShaderID, VertexShader); 200 | glAttachShader(ShaderID, GeometryShader); 201 | glAttachShader(ShaderID, FragmentShader); 202 | glLinkProgram(ShaderID); 203 | glUseProgram(ShaderID); 204 | } 205 | 206 | void Open7Days::Rendering::Shader::Reload(const std::string& Directory) { 207 | Reload(Directory + "/vert.glsl", Directory + "/frag.glsl"); 208 | } 209 | 210 | void Open7Days::Rendering::Shader::Reload(const std::string& Directory, bool HasGeometryShader) { 211 | if(HasGeometryShader) 212 | Reload(Directory + "/vert.glsl", Directory + "/frag.glsl", Directory + "/geom.glsl"); 213 | else 214 | Reload(Directory + "/vert.glsl", Directory + "/frag.glsl", Directory + "/geom.glsl"); 215 | 216 | } 217 | 218 | Open7Days::Rendering::Shader::~Shader() { 219 | //TODO: free up shader 220 | } 221 | 222 | /* 223 | 224 | Open7Days::Rendering::Shader::Shader(const std::string & vertex, const std::string & fragment) : 225 | VertexShader(LoadShader(GL_VERTEX_SHADER, vertex, VertexBuffer, VertexShader)), 226 | FragmentShader(LoadShader(GL_FRAGMENT_SHADER, fragment, FragmentBuffer, FragmentShader)), 227 | ShaderID(glCreateProgram()) 228 | { 229 | glAttachShader(ShaderID, VertexShader); 230 | glAttachShader(ShaderID, FragmentShader); 231 | glLinkProgram(ShaderID); 232 | glUseProgram(ShaderID); 233 | }*/ 234 | -------------------------------------------------------------------------------- /Shader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Core.h" 3 | 4 | namespace Open7Days { 5 | namespace Rendering { 6 | unsigned int LoadShader(unsigned int ShaderType, const std::string & File, unsigned int &Buffer, unsigned int BaseID, bool ReCreate = true); 7 | 8 | struct Shader { 9 | unsigned int VertexShader = 0; 10 | unsigned int FragmentShader = 0; 11 | unsigned int GeometryShader = 0; 12 | 13 | unsigned int VertexBuffer = 0, FragmentBuffer = 0, GeometryBuffer = 0; 14 | unsigned int VertexID = 0, FragmentID = 0, GeometryID = 0; 15 | 16 | unsigned int ShaderID = 0; 17 | 18 | Shader(const std::string & vertex, const std::string & fragment); 19 | Shader(const std::string & vertex, const std::string & geometry, const std::string & fragment); 20 | Shader(const std::string & Directory, bool HasGeometryShader = false); 21 | Shader(); 22 | void Bind(); 23 | void UnBind(); 24 | 25 | void SetUniform(const std::string & Name, int Value); 26 | void SetUniform(const std::string & Name, size_t Value); 27 | void SetUniform(const std::string & Name, float Value); 28 | void SetUniform(const std::string & Name, bool Value); 29 | void SetUniform(const std::string & Name, Vector2f Value); 30 | void SetUniform(const std::string & Name, Vector3f Value); 31 | void SetUniform(const std::string & Name, Vector4f Value); 32 | void SetUniform(const std::string & Name, Vector2i Value); 33 | void SetUniform(const std::string & Name, Vector3i Value); 34 | void SetUniform(const std::string & Name, Vector4i Value); 35 | void SetUniform(const std::string & Name, Matrix4f Value, bool Transpose = false); 36 | void SetUniform(const std::string& Name, Matrix3f Value, bool Transpose = false); 37 | 38 | void Reload(const std::string& vertex, const std::string& fragment); 39 | void Reload(const std::string& vertex, const std::string& fragment, const std::string & geometry); 40 | 41 | void Reload(const std::string& Directory); 42 | void Reload(const std::string& Directory, bool HasGeometryShader); 43 | 44 | ~Shader(); 45 | }; 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Shaders/CubeMapDeferred/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | //texture coordinate is calculated from world position + normal later 4 | //specific details about material are stored in OutNormal.w 5 | //[3 8 bit values] 6 | //materialprimary, materialsecondary, mixfactor 7 | layout(location = 0) out vec3 OutNormal; 8 | layout(location = 1) out vec4 OutPosition; 9 | 10 | in vec3 Position; 11 | in vec3 Normal; 12 | in vec2 TexCoord; 13 | 14 | flat in uvec3 Materials; 15 | 16 | in vec3 Flag; 17 | 18 | 19 | float PackMaterialData() { 20 | 21 | float Smallest; 22 | vec2 Largest; 23 | uvec2 PrimaryMaterials; 24 | 25 | if(Materials.x == Materials.y) { 26 | 27 | Largest = vec2(Flag.x+Flag.y,Flag.z); 28 | PrimaryMaterials = Materials.xz; 29 | 30 | } 31 | else if(Materials.x == Materials.z) { 32 | Largest = vec2(Flag.x+Flag.z,Flag.y); 33 | PrimaryMaterials = Materials.xy; 34 | } 35 | else if(Materials.y == Materials.z) { 36 | Largest = vec2(Flag.x, Flag.y+Flag.z); 37 | PrimaryMaterials = Materials.xz; 38 | } 39 | else { 40 | if(Flag.x < Flag.y && Flag.x < Flag.z) { 41 | Largest = Flag.yz; 42 | PrimaryMaterials = Materials.yz; 43 | } 44 | else if(Flag.z < Flag.y) { 45 | Largest = Flag.xy; 46 | PrimaryMaterials = Materials.xy; 47 | } 48 | else { 49 | Largest = Flag.xz; 50 | PrimaryMaterials = Materials.xz; 51 | } 52 | } 53 | 54 | //Largest += Smallest / 2.f; 55 | 56 | Largest = Largest / ((Largest.x+Largest.y)/2.f); 57 | 58 | 59 | if(Largest.y > Largest.x) { 60 | Largest = Largest.yx; 61 | PrimaryMaterials = PrimaryMaterials.yx; 62 | } 63 | 64 | uint Packed = PrimaryMaterials.x * 65536u + PrimaryMaterials.y * 256u + clamp(uint(Largest.y*255.),0u,255u); 65 | 66 | return uintBitsToFloat(Packed); 67 | 68 | 69 | } 70 | 71 | float PackMaterialDataNew() { 72 | 73 | 74 | return uintBitsToFloat(Materials.x * 16777216u + Materials.y * 65536u + Materials.z * 256u + clamp(uint(Flag.x*15.),0u,15u) * 16u + clamp(uint(Flag.y*15.),0u,15u)); 75 | 76 | 77 | 78 | } 79 | 80 | 81 | void main() { 82 | 83 | 84 | OutPosition = vec4(Position, PackMaterialDataNew()); 85 | OutNormal = Normal; 86 | } -------------------------------------------------------------------------------- /Shaders/CubeMapDeferred/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | 4 | 5 | layout(location=0) in vec4 Vertices; 6 | layout(location=1) in vec4 Normals; 7 | 8 | uniform mat4 ModelMatrix; 9 | uniform mat4 IdentityMatrix; 10 | 11 | out vec3 Position; 12 | out vec3 Normal; 13 | out vec2 TexCoord; 14 | 15 | out vec3 Flag; 16 | 17 | flat out uvec3 Materials; 18 | 19 | const vec3 Flags[3] = vec3[](vec3(1.0,0.0,0.0), vec3(0.0,1.0,0.0), vec3(0.0,0.0,1.0)); 20 | 21 | 22 | void ConvertMaterials(out uvec3 Materials, out uint Flag) { 23 | uint Raw = floatBitsToUint(Vertices.w); 24 | 25 | Flag = Raw % 4u; 26 | Materials.x = Raw / 262144u; 27 | Materials.y = (Raw / 1024u) % 256u; 28 | Materials.z = (Raw / 4u) % 256u; 29 | 30 | } 31 | 32 | 33 | 34 | void main(void) { 35 | 36 | Position = vec3(ModelMatrix * vec4(Vertices.xyz,1.0)); 37 | TexCoord = vec2(Vertices.w, Normals.w); 38 | Normal = Normals.xyz; 39 | 40 | uint FlagIndex; 41 | 42 | 43 | ConvertMaterials(Materials, FlagIndex); 44 | 45 | Flag = Flags[FlagIndex]; 46 | 47 | gl_Position = IdentityMatrix * vec4(Vertices.xyz,1.0); 48 | } -------------------------------------------------------------------------------- /Shaders/CubeMapIndirectDiffuse/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | #extension GL_ARB_bindless_texture : enable 3 | 4 | in vec3 Vertice; 5 | out vec4 FinalColor; 6 | 7 | uniform samplerCube Normal; 8 | uniform samplerCube WorldPosition; 9 | uniform sampler2DArray Textures; 10 | uniform sampler2D ShadowMaps[3]; 11 | 12 | uniform mat4 ShadowCombined[3]; 13 | uniform vec3 ShadowDirection; 14 | uniform vec3 SunColor; 15 | 16 | void UnPackMaterialData(float Data, out uvec3 Materials, out vec2 Interpolation) { 17 | 18 | uint Packed = floatBitsToUint(Data); 19 | 20 | Materials.x = Packed / 16777216u; 21 | Materials.y = (Packed / 65536u) % 256u; 22 | Materials.z = (Packed / 256u) % 256u; 23 | Interpolation.x = float((Packed / 16u) % 16u) / 15.f; 24 | Interpolation.y = float(Packed % 16u) / 15.f; 25 | 26 | } 27 | 28 | vec4 TextureOld(sampler2DArray Sampler, uint Texture, float Scale, vec3 Normal, vec3 Position) { 29 | 30 | vec3 blend_weights = normalize(abs(Normal )); // Tighten up the blending zone: 31 | blend_weights = (blend_weights - 0.2); 32 | blend_weights = pow(max(blend_weights, 0),vec3(1.0)); // Force weights to sum to 1.0 (very important!) 33 | blend_weights /= (blend_weights.x + blend_weights.y + blend_weights.z ); 34 | 35 | vec4 SampleXMajor = texture(Sampler, vec3(fract(Position.yz * Scale),float(Texture))); 36 | vec4 SampleYMajor = texture(Sampler, vec3(fract(Position.zx * Scale),float(Texture))); 37 | vec4 SampleZMajor = texture(Sampler, vec3(fract(Position.xy * Scale),float(Texture))); 38 | 39 | return SampleXMajor * blend_weights.x + SampleYMajor * blend_weights.y + SampleZMajor * blend_weights.z; 40 | 41 | } 42 | 43 | 44 | float ShadowsESM(sampler2D ShadowMap, vec3 Coord) { 45 | 46 | //return (Coord.z > (texture(ShadowMap, Coord.xy).x+0.0003) ? 0. : 1.0); 47 | 48 | return clamp(exp(-10000.0*(Coord.z-(texture(ShadowMap, Coord.xy).x)-.0015)), 0.0,1.0); 49 | } 50 | 51 | 52 | float GetDirectionalShadows(vec3 WorldPosition, vec3 Normal) { 53 | vec3 ShadowNDC = vec3(0.); 54 | 55 | int Index = -1; 56 | 57 | for(int try = 0; try < 3; try++) { 58 | 59 | vec4 ShadowCoord = ShadowCombined[try] * vec4(WorldPosition, 1.0); 60 | 61 | ShadowNDC = ShadowCoord.xyz / ShadowCoord.w; 62 | 63 | 64 | 65 | 66 | if(abs(ShadowNDC.x) < 1.0 && abs(ShadowNDC.y) < 1.0) { 67 | Index = try; 68 | break; 69 | } 70 | 71 | } 72 | 73 | 74 | 75 | 76 | if(Index == -1) 77 | return 1.0; 78 | 79 | float ShadowMapSample = ShadowsESM((Index == 0 ? ShadowMaps[0] : Index == 1 ? ShadowMaps[1] : ShadowMaps[2]), ShadowNDC.xyz * 0.5 + 0.5); 80 | 81 | return ShadowMapSample * max(pow(dot(Normal,normalize(ShadowDirection)),3.),0.) * 100.; 82 | 83 | } 84 | 85 | void main() { 86 | 87 | vec3 Coord = normalize(Vertice); 88 | 89 | vec4 Position = texture(WorldPosition, Coord); 90 | vec3 Normal = texture(Normal, Coord).xyz; 91 | 92 | uvec3 Materials; 93 | vec2 Interpolation; 94 | 95 | UnPackMaterialData(Position.w, Materials, Interpolation); 96 | 97 | vec4 Texture1 = TextureOld(Textures,Materials.x, .5, Normal.xyz, Position.xyz); 98 | vec4 Texture2 = TextureOld(Textures,Materials.y, .5, Normal.xyz, Position.xyz); 99 | vec4 Texture3 = TextureOld(Textures,Materials.z, .5, Normal.xyz, Position.xyz); 100 | 101 | vec4 Texture = Texture1 * Interpolation.x + Texture2 * Interpolation.y + Texture3 * (1.0 - (Interpolation.x + Interpolation.y)); 102 | 103 | Texture.xyz = pow(Texture.xyz, vec3(2.2)); 104 | 105 | 106 | vec3 Shadows = GetDirectionalShadows(Position.xyz, Normal) * SunColor; 107 | 108 | 109 | FinalColor.xyz = Texture.xyz * Shadows; 110 | FinalColor.xyz = length(Normal) < 0.5 ? vec3(0.0) : FinalColor.xyz; 111 | 112 | FinalColor.a = length(Normal) < 0.5 ? 1.0 : 0.0; 113 | 114 | 115 | } -------------------------------------------------------------------------------- /Shaders/CubeMapIndirectDiffuse/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout (location = 0) in vec3 Vert; 3 | 4 | out vec3 Vertice; 5 | 6 | uniform mat4 IdentityMatrix; 7 | 8 | void main(void) { 9 | Vertice = Vert; 10 | gl_Position = IdentityMatrix * vec4(Vert,1.0); 11 | } -------------------------------------------------------------------------------- /Shaders/CubeMapPostProcess/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | #extension GL_ARB_bindless_texture : enable 3 | 4 | in vec3 Vertice; 5 | out vec4 FinalColor; 6 | 7 | uniform samplerCube Normal; 8 | uniform samplerCube WorldPosition; 9 | uniform sampler2DArray Textures; 10 | uniform sampler2D ShadowMaps[3]; 11 | 12 | uniform mat4 ShadowCombined[3]; 13 | uniform vec3 ShadowDirection; 14 | uniform vec3 SunColor; 15 | 16 | void UnPackMaterialData(float Data, out uvec3 Materials, out vec2 Interpolation) { 17 | 18 | uint Packed = floatBitsToUint(Data); 19 | 20 | Materials.x = Packed / 16777216u; 21 | Materials.y = (Packed / 65536u) % 256u; 22 | Materials.z = (Packed / 256u) % 256u; 23 | Interpolation.x = float((Packed / 16u) % 16u) / 15.f; 24 | Interpolation.y = float(Packed % 16u) / 15.f; 25 | 26 | } 27 | 28 | vec4 TextureOld(sampler2DArray Sampler, uint Texture, float Scale, vec3 Normal, vec3 Position) { 29 | 30 | vec3 blend_weights = normalize(abs(Normal )); // Tighten up the blending zone: 31 | blend_weights = (blend_weights - 0.2); 32 | blend_weights = pow(max(blend_weights, 0),vec3(1.0)); // Force weights to sum to 1.0 (very important!) 33 | blend_weights /= (blend_weights.x + blend_weights.y + blend_weights.z ); 34 | 35 | vec4 SampleXMajor = texture(Sampler, vec3(fract(Position.yz * Scale),float(Texture))); 36 | vec4 SampleYMajor = texture(Sampler, vec3(fract(Position.zx * Scale),float(Texture))); 37 | vec4 SampleZMajor = texture(Sampler, vec3(fract(Position.xy * Scale),float(Texture))); 38 | 39 | return SampleXMajor * blend_weights.x + SampleYMajor * blend_weights.y + SampleZMajor * blend_weights.z; 40 | 41 | } 42 | 43 | 44 | float ShadowsESM(sampler2D ShadowMap, vec3 Coord) { 45 | 46 | //return (Coord.z > (texture(ShadowMap, Coord.xy).x+0.0003) ? 0. : 1.0); 47 | 48 | return clamp(exp(-10000.0*(Coord.z-(texture(ShadowMap, Coord.xy).x)-.0015)), 0.0,1.0); 49 | } 50 | 51 | 52 | float GetDirectionalShadows(vec3 WorldPosition, vec3 Normal) { 53 | vec3 ShadowNDC = vec3(0.); 54 | 55 | int Index = -1; 56 | 57 | for(int try = 0; try < 3; try++) { 58 | 59 | vec4 ShadowCoord = ShadowCombined[try] * vec4(WorldPosition, 1.0); 60 | 61 | ShadowNDC = ShadowCoord.xyz / ShadowCoord.w; 62 | 63 | 64 | 65 | 66 | if(abs(ShadowNDC.x) < 1.0 && abs(ShadowNDC.y) < 1.0) { 67 | Index = try; 68 | break; 69 | } 70 | 71 | } 72 | 73 | 74 | 75 | 76 | if(Index == -1) 77 | return 1.0; 78 | 79 | float ShadowMapSample = ShadowsESM((Index == 0 ? ShadowMaps[0] : Index == 1 ? ShadowMaps[1] : ShadowMaps[2]), ShadowNDC.xyz * 0.5 + 0.5); 80 | 81 | return ShadowMapSample * max(pow(dot(Normal,normalize(ShadowDirection)),3.),0.) * 100.; 82 | 83 | } 84 | 85 | void main() { 86 | 87 | vec3 Coord = normalize(Vertice); 88 | 89 | vec4 Position = texture(WorldPosition, Coord); 90 | vec3 Normal = texture(Normal, Coord).xyz; 91 | 92 | uvec3 Materials; 93 | vec2 Interpolation; 94 | 95 | UnPackMaterialData(Position.w, Materials, Interpolation); 96 | 97 | vec4 Texture1 = TextureOld(Textures,Materials.x, .5, Normal.xyz, Position.xyz); 98 | vec4 Texture2 = TextureOld(Textures,Materials.y, .5, Normal.xyz, Position.xyz); 99 | vec4 Texture3 = TextureOld(Textures,Materials.z, .5, Normal.xyz, Position.xyz); 100 | 101 | vec4 Texture = Texture1 * Interpolation.x + Texture2 * Interpolation.y + Texture3 * (1.0 - (Interpolation.x + Interpolation.y)); 102 | 103 | Texture.xyz = pow(Texture.xyz, vec3(2.2)); 104 | 105 | 106 | vec3 Shadows = GetDirectionalShadows(Position.xyz, Normal) * SunColor; 107 | 108 | 109 | FinalColor.xyz = Texture.xyz * Shadows; 110 | FinalColor.xyz = length(Normal) < 0.5 ? vec3(0.0) : FinalColor.xyz; 111 | 112 | FinalColor.a = length(Normal) < 0.5 ? 1.0 : 0.0; 113 | 114 | 115 | } -------------------------------------------------------------------------------- /Shaders/CubeMapPostProcess/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout (location = 0) in vec3 Vert; 3 | 4 | out vec3 Vertice; 5 | 6 | uniform mat4 IdentityMatrix; 7 | 8 | void main(void) { 9 | Vertice = Vert; 10 | gl_Position = IdentityMatrix * vec4(Vert,1.0); 11 | } -------------------------------------------------------------------------------- /Shaders/CustomDeferred/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | //texture coordinate is calculated from world position + normal later 4 | //specific details about material are stored in OutNormal.w 5 | //[3 8 bit values] 6 | //materialprimary, materialsecondary, mixfactor 7 | layout(location = 0) out vec4 OutNormal; 8 | 9 | in vec3 Position; 10 | in vec3 Normal; 11 | in vec2 TexCoord; 12 | 13 | flat in uvec3 Materials; 14 | 15 | in vec3 Flag; 16 | 17 | 18 | float PackMaterialData() { 19 | 20 | float Smallest; 21 | vec2 Largest; 22 | uvec2 PrimaryMaterials; 23 | 24 | if(Materials.x == Materials.y) { 25 | 26 | Largest = vec2(Flag.x+Flag.y,Flag.z); 27 | PrimaryMaterials = Materials.xz; 28 | 29 | } 30 | else if(Materials.x == Materials.z) { 31 | Largest = vec2(Flag.x+Flag.z,Flag.y); 32 | PrimaryMaterials = Materials.xy; 33 | } 34 | else if(Materials.y == Materials.z) { 35 | Largest = vec2(Flag.x, Flag.y+Flag.z); 36 | PrimaryMaterials = Materials.xz; 37 | } 38 | else { 39 | if(Flag.x < Flag.y && Flag.x < Flag.z) { 40 | Largest = Flag.yz; 41 | PrimaryMaterials = Materials.yz; 42 | } 43 | else if(Flag.z < Flag.y) { 44 | Largest = Flag.xy; 45 | PrimaryMaterials = Materials.xy; 46 | } 47 | else { 48 | Largest = Flag.xz; 49 | PrimaryMaterials = Materials.xz; 50 | } 51 | } 52 | 53 | //Largest += Smallest / 2.f; 54 | 55 | Largest = Largest / ((Largest.x+Largest.y)/2.f); 56 | 57 | 58 | if(Largest.y > Largest.x) { 59 | Largest = Largest.yx; 60 | PrimaryMaterials = PrimaryMaterials.yx; 61 | } 62 | 63 | uint Packed = PrimaryMaterials.x * 65536u + PrimaryMaterials.y * 256u + clamp(uint(Largest.y*255.),0u,255u); 64 | 65 | return uintBitsToFloat(Packed); 66 | 67 | 68 | } 69 | 70 | float PackMaterialDataNew() { 71 | 72 | 73 | return uintBitsToFloat(Materials.x * 16777216u + Materials.y * 65536u + Materials.z * 256u + clamp(uint(Flag.x*15.),0u,15u) * 16u + clamp(uint(Flag.y*15.),0u,15u)); 74 | 75 | 76 | 77 | } 78 | 79 | 80 | void main() { 81 | 82 | OutNormal = vec4(normalize(Normal),PackMaterialDataNew()); 83 | } -------------------------------------------------------------------------------- /Shaders/CustomDeferred/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | 4 | 5 | layout(location=0) in vec4 Vertices; 6 | layout(location=1) in vec4 Normals; 7 | 8 | uniform mat4 ModelMatrix; 9 | uniform mat4 IdentityMatrix; 10 | 11 | out vec3 Position; 12 | out vec3 Normal; 13 | out vec2 TexCoord; 14 | 15 | out vec3 Flag; 16 | 17 | flat out uvec3 Materials; 18 | 19 | const vec3 Flags[3] = vec3[](vec3(1.0,0.0,0.0), vec3(0.0,1.0,0.0), vec3(0.0,0.0,1.0)); 20 | 21 | 22 | void ConvertMaterials(out uvec3 Materials, out uint Flag) { 23 | uint Raw = floatBitsToUint(Vertices.w); 24 | 25 | Flag = Raw % 4u; 26 | Materials.x = Raw / 262144u; 27 | Materials.y = (Raw / 1024u) % 256u; 28 | Materials.z = (Raw / 4u) % 256u; 29 | 30 | } 31 | 32 | 33 | 34 | void main(void) { 35 | 36 | Position = vec3(ModelMatrix * vec4(Vertices.xyz,1.0)); 37 | TexCoord = vec2(Vertices.w, Normals.w); 38 | Normal = Normals.xyz; 39 | 40 | uint FlagIndex; 41 | 42 | 43 | ConvertMaterials(Materials, FlagIndex); 44 | 45 | Flag = Flags[FlagIndex]; 46 | 47 | 48 | gl_Position = IdentityMatrix * vec4(Vertices.xyz,1.0); 49 | } -------------------------------------------------------------------------------- /Shaders/Deferred/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | //texture coordinate is calculated from world position + normal later 4 | //specific details about material are stored in OutNormal.w 5 | //[3 8 bit values] 6 | //materialprimary, materialsecondary, mixfactor 7 | layout(location = 0) out vec4 OutNormal; 8 | 9 | in vec3 Position; 10 | in vec3 Normal; 11 | in vec2 TexCoord; 12 | 13 | flat in uvec3 Materials; 14 | 15 | in vec3 Flag; 16 | 17 | 18 | float PackMaterialData() { 19 | 20 | float Smallest; 21 | vec2 Largest; 22 | uvec2 PrimaryMaterials; 23 | 24 | if(Materials.x == Materials.y) { 25 | 26 | Largest = vec2(Flag.x+Flag.y,Flag.z); 27 | PrimaryMaterials = Materials.xz; 28 | 29 | } 30 | else if(Materials.x == Materials.z) { 31 | Largest = vec2(Flag.x+Flag.z,Flag.y); 32 | PrimaryMaterials = Materials.xy; 33 | } 34 | else if(Materials.y == Materials.z) { 35 | Largest = vec2(Flag.x, Flag.y+Flag.z); 36 | PrimaryMaterials = Materials.xz; 37 | } 38 | else { 39 | if(Flag.x < Flag.y && Flag.x < Flag.z) { 40 | Largest = Flag.yz; 41 | PrimaryMaterials = Materials.yz; 42 | } 43 | else if(Flag.z < Flag.y) { 44 | Largest = Flag.xy; 45 | PrimaryMaterials = Materials.xy; 46 | } 47 | else { 48 | Largest = Flag.xz; 49 | PrimaryMaterials = Materials.xz; 50 | } 51 | } 52 | 53 | //Largest += Smallest / 2.f; 54 | 55 | Largest = Largest / ((Largest.x+Largest.y)/2.f); 56 | 57 | 58 | if(Largest.y > Largest.x) { 59 | Largest = Largest.yx; 60 | PrimaryMaterials = PrimaryMaterials.yx; 61 | } 62 | 63 | uint Packed = PrimaryMaterials.x * 65536u + PrimaryMaterials.y * 256u + clamp(uint(Largest.y*255.),0u,255u); 64 | 65 | return uintBitsToFloat(Packed); 66 | 67 | 68 | } 69 | 70 | float PackMaterialDataNew() { 71 | 72 | 73 | return uintBitsToFloat(Materials.x * 16777216u + Materials.y * 65536u + Materials.z * 256u + clamp(uint(Flag.x*15.),0u,15u) * 16u + clamp(uint(Flag.y*15.),0u,15u)); 74 | 75 | 76 | 77 | } 78 | 79 | 80 | void main() { 81 | 82 | OutNormal = vec4(normalize(Normal),PackMaterialDataNew()); 83 | } -------------------------------------------------------------------------------- /Shaders/Deferred/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | 4 | 5 | layout(location=0) in vec4 Vertices; 6 | layout(location=1) in vec4 Normals; 7 | 8 | uniform mat4 ModelMatrix; 9 | uniform mat4 IdentityMatrix; 10 | 11 | out vec3 Position; 12 | out vec3 Normal; 13 | out vec2 TexCoord; 14 | 15 | out vec3 Flag; 16 | 17 | flat out uvec3 Materials; 18 | 19 | const vec3 Flags[3] = vec3[](vec3(1.0,0.0,0.0), vec3(0.0,1.0,0.0), vec3(0.0,0.0,1.0)); 20 | 21 | 22 | void ConvertMaterials(out uvec3 Materials, out uint Flag) { 23 | uint Raw = floatBitsToUint(Vertices.w); 24 | 25 | Flag = Raw % 4u; 26 | Materials.x = Raw / 262144u; 27 | Materials.y = (Raw / 1024u) % 256u; 28 | Materials.z = (Raw / 4u) % 256u; 29 | 30 | } 31 | 32 | 33 | 34 | void main(void) { 35 | 36 | Position = vec3(ModelMatrix * vec4(Vertices.xyz,1.0)); 37 | TexCoord = vec2(Vertices.w, Normals.w); 38 | Normal = Normals.xyz; 39 | 40 | uint FlagIndex; 41 | 42 | 43 | ConvertMaterials(Materials, FlagIndex); 44 | 45 | Flag = Flags[FlagIndex]; 46 | 47 | 48 | gl_Position = IdentityMatrix * vec4(Vertices.xyz,1.0); 49 | } -------------------------------------------------------------------------------- /Shaders/DeferredShadow/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | out float Depth; 4 | 5 | void main() { 6 | Depth = pow(gl_FragCoord.z,1.0); 7 | } 8 | -------------------------------------------------------------------------------- /Shaders/DeferredShadow/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout(location=0) in vec4 Vertices; 3 | layout(location=1) in vec4 Normals; 4 | 5 | uniform mat4 IdentityMatrix; 6 | 7 | void main(void) { 8 | gl_Position = IdentityMatrix * vec4(Vertices.xyz,1.0); 9 | } -------------------------------------------------------------------------------- /Shaders/DeferredUnwrapper/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec2 TexCoord; 3 | 4 | layout(location = 0) out vec4 Albedo; //w component stores metalness 5 | layout(location = 1) out vec4 Normal; //w component stores roughness 6 | layout(location = 2) out vec3 ScreenSpaceWorldPosition; //might seem a bit weird to store 7 | //but its actually much faster to store it than calculating it for the screen-space based methods 8 | 9 | uniform mat4 InverseProjection; 10 | uniform mat4 InverseView; 11 | 12 | 13 | uniform sampler2D DeferredNormal; 14 | uniform sampler2D DeferredDepth; 15 | uniform sampler2DArray Textures; 16 | 17 | 18 | 19 | 20 | 21 | vec4 TextureOld(sampler2DArray Sampler, uint Texture, float Scale, vec3 Normal, vec3 Position) { 22 | 23 | vec3 blend_weights = normalize(abs(Normal )); // Tighten up the blending zone: 24 | blend_weights = (blend_weights - 0.2); 25 | blend_weights = pow(max(blend_weights, 0),vec3(1.0)); // Force weights to sum to 1.0 (very important!) 26 | blend_weights /= (blend_weights.x + blend_weights.y + blend_weights.z ); 27 | 28 | vec4 SampleXMajor = texture(Sampler, vec3(fract(Position.yz * Scale),float(Texture))); 29 | vec4 SampleYMajor = texture(Sampler, vec3(fract(Position.zx * Scale),float(Texture))); 30 | vec4 SampleZMajor = texture(Sampler, vec3(fract(Position.xy * Scale),float(Texture))); 31 | 32 | return SampleXMajor * blend_weights.x + SampleYMajor * blend_weights.y + SampleZMajor * blend_weights.z; 33 | 34 | } 35 | vec2 GenerateTextureCoordinate( float Scale, vec3 Normal, vec3 Position) { 36 | vec3 blend_weights = normalize(abs(Normal )); // Tighten up the blending zone: 37 | blend_weights = (blend_weights - 0.2); 38 | blend_weights = pow(max(blend_weights, 0),vec3(1.0)); // Force weights to sum to 1.0 (very important!) 39 | blend_weights /= (blend_weights.x + blend_weights.y + blend_weights.z ); 40 | 41 | vec2 SampleXMajor = fract(Position.yz * Scale); 42 | vec2 SampleYMajor = fract(Position.zx * Scale); 43 | vec2 SampleZMajor = fract(Position.xy * Scale); 44 | 45 | return SampleXMajor * blend_weights.x + SampleYMajor * blend_weights.y + SampleZMajor * blend_weights.z; 46 | } 47 | 48 | 49 | vec4 TextureNew(sampler2DArray Sampler, uint Texture, float Scale, vec3 Normal, vec3 Position) { 50 | 51 | return texture(Sampler, vec3(GenerateTextureCoordinate(Scale,Normal,Position), Texture)); 52 | 53 | } 54 | 55 | 56 | 57 | vec4 CalculateViewSpacePosition() { 58 | 59 | 60 | vec4 ClipSpace = vec4(TexCoord * 2.0 - 1.0, texture(DeferredDepth, TexCoord).x * 2. - 1., 1.0); 61 | vec4 ViewSpace = InverseProjection * ClipSpace; 62 | 63 | return ViewSpace / ViewSpace.w; 64 | 65 | } 66 | 67 | void UnPackMaterialData(float Data, out uvec3 Materials, out vec2 Interpolation) { 68 | 69 | uint Packed = floatBitsToUint(Data); 70 | 71 | Materials.x = Packed / 16777216u; 72 | Materials.y = (Packed / 65536u) % 256u; 73 | Materials.z = (Packed / 256u) % 256u; 74 | Interpolation.x = float((Packed / 16u) % 16u) / 15.f; 75 | Interpolation.y = float(Packed % 16u) / 15.f; 76 | 77 | } 78 | 79 | 80 | void main() { 81 | 82 | vec4 ViewSpace = CalculateViewSpacePosition(); 83 | vec3 WorldSpace = (InverseView * ViewSpace).xyz; 84 | vec4 SampleNormal = texelFetch(DeferredNormal, ivec2(gl_FragCoord.xy),0); 85 | 86 | uvec3 Materials; 87 | vec2 Interpolation; 88 | 89 | UnPackMaterialData(SampleNormal.w, Materials, Interpolation); 90 | 91 | 92 | vec4 Texture1 = TextureOld(Textures,Materials.x, .5, SampleNormal.xyz, WorldSpace); 93 | vec4 Texture2 = TextureOld(Textures,Materials.y, .5, SampleNormal.xyz, WorldSpace); 94 | vec4 Texture3 = TextureOld(Textures,Materials.z, .5, SampleNormal.xyz, WorldSpace); 95 | 96 | vec4 Texture = Texture1 * Interpolation.x + Texture2 * Interpolation.y + Texture3 * (1.0 - (Interpolation.x + Interpolation.y)); 97 | 98 | 99 | 100 | Texture.xyz = pow(Texture.xyz, vec3(2.2)); 101 | 102 | Albedo = vec4(Texture.xyz, 0.0); 103 | Normal = vec4(SampleNormal.xyz,Texture.a); 104 | ScreenSpaceWorldPosition = vec3(ViewSpace.xyz); 105 | 106 | } -------------------------------------------------------------------------------- /Shaders/DeferredUnwrapper/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout (location = 0) in vec3 Vert; 3 | layout (location = 1) in vec2 Texc; 4 | out vec2 TexCoord; 5 | 6 | void main(void) { 7 | TexCoord = Texc; 8 | gl_Position = vec4(Vert.xy,0.f,1.0); 9 | } -------------------------------------------------------------------------------- /Shaders/EquirectangularToCubeMapShader/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | out vec3 Color; 3 | in vec3 Vertice; 4 | uniform sampler2D EquirectangularMap; 5 | 6 | //Credit where credit is due, this code isn't mine; It's taken from learnopengl and it works very well from what I've seen 7 | const vec2 invAtan = vec2(0.1591, 0.3183); 8 | vec2 SampleSphericalMap(vec3 v) 9 | { 10 | vec2 uv = vec2(atan(v.z, v.x), asin(v.y)); 11 | uv *= invAtan; 12 | uv += 0.5; 13 | return uv; 14 | } 15 | 16 | 17 | void main() { 18 | Color = texture(EquirectangularMap,SampleSphericalMap(normalize(Vertice))).rgb; 19 | } -------------------------------------------------------------------------------- /Shaders/EquirectangularToCubeMapShader/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout (location = 0) in vec3 Vert; 3 | out vec3 Vertice; 4 | uniform mat4 ProjectionMatrix; 5 | uniform mat4 ViewMatrix; 6 | void main(void) { 7 | Vertice = Vert; 8 | gl_Position = (ProjectionMatrix * mat4(mat3(ViewMatrix)) * vec4(Vert,1.0)).xyww; 9 | } -------------------------------------------------------------------------------- /Shaders/FirstPassLighting/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 420 2 | 3 | in vec2 TexCoord; 4 | layout(location = 0) out vec3 Diffuse; 5 | layout(location = 1) out vec3 Specular; 6 | 7 | //TemporarySpecular will be used later in the combining stage 8 | 9 | //samplers: (ie textures) 10 | uniform sampler2D ViewPosition; 11 | 12 | uniform sampler2D Normal; 13 | uniform sampler2D BlueNoise; 14 | uniform sampler2D IndirectDiffuse; 15 | uniform sampler2D Depth; 16 | uniform sampler2D WaterDepth; 17 | uniform sampler2D WaterNormal; 18 | uniform sampler2DArray WaterNormalMap; 19 | uniform sampler2D ShadowMaps[3]; 20 | 21 | 22 | uniform float Time; 23 | 24 | 25 | uniform vec3 CameraPositionLight[3]; 26 | uniform float Size[3]; 27 | 28 | //matrices 29 | 30 | uniform mat4 ShadowCombined[3]; 31 | uniform mat4 InverseView; 32 | uniform mat4 InverseProject; 33 | 34 | //vectors 35 | 36 | uniform vec3 ShadowDirection; 37 | uniform vec3 CameraPosition; 38 | uniform vec3 SunColor; 39 | 40 | vec4 SampleInterpolatied(sampler2DArray Sampler,vec3 Coord) { 41 | 42 | float BaseTime = mod(Coord.z, 119.); 43 | 44 | int Coord1 = int(floor(BaseTime)); 45 | int Coord2 = int(ceil(BaseTime))%119; 46 | 47 | return mix(texture(Sampler, vec3(Coord.xy, Coord1)), texture(Sampler,vec3(Coord.xy, Coord2)), fract(BaseTime)); 48 | 49 | 50 | } 51 | 52 | 53 | void UnPackData(vec4 Packed, out vec3 Diffuse, out vec3 Normal, out float Depth) { 54 | 55 | vec2 UnPacked1 = unpackHalf2x16(floatBitsToUint(Packed.x)); 56 | vec2 UnPacked2 = unpackHalf2x16(floatBitsToUint(Packed.y)); 57 | vec2 UnPacked3 = unpackHalf2x16(floatBitsToUint(Packed.z)); 58 | vec2 UnPacked4 = unpackHalf2x16(floatBitsToUint(Packed.w)); 59 | 60 | Diffuse = vec3(UnPacked1, UnPacked2.x); 61 | Normal = vec3(UnPacked2.y, UnPacked3.xy); 62 | Depth = UnPacked4.x; 63 | 64 | } 65 | 66 | vec3 ImportanceGGX(vec2 xi, float roughness) 67 | { 68 | float r_square = roughness * roughness; 69 | float phi = 6.2831 * xi.x; 70 | float cos_theta = sqrt((1 - xi.y) / (1 + (r_square * r_square - 1) * xi.y)); 71 | float sin_theta = sqrt(1 - cos_theta * cos_theta); 72 | 73 | return vec3(sin_theta * cos(phi), sin_theta * sin(phi), cos_theta); 74 | } 75 | 76 | vec2 hash2(float seed) { 77 | return fract(vec2(sin(vec2(seed, seed + 0.1f))*vec2(43758.5453123f, 22578.1459123f))); 78 | } 79 | 80 | 81 | 82 | 83 | float ShadowsESM(sampler2D ShadowMap, vec3 Coord) { 84 | 85 | //return (Coord.z > (texture(ShadowMap, Coord.xy).x+0.0003) ? 0. : 1.0); 86 | 87 | return clamp(exp(-10000.0*(Coord.z-(texture(ShadowMap, Coord.xy).x)-.0015)), 0.0,1.0); 88 | } 89 | 90 | 91 | vec2 GetDirectionalShadows(vec3 WorldPosition, vec3 Normal, vec3 Incident, float Roughness, float Noise) { 92 | vec3 ShadowNDC = vec3(0.); 93 | 94 | int Index = -1; 95 | 96 | float Factor = 1.0 - 0.25 * Noise; 97 | 98 | for(int try = 0; try < 3; try++) { 99 | 100 | vec4 ShadowCoord = ShadowCombined[try] * vec4(WorldPosition, 1.0); 101 | 102 | ShadowNDC = ShadowCoord.xyz / ShadowCoord.w; 103 | 104 | 105 | 106 | 107 | if(abs(ShadowNDC.x) < Factor && abs(ShadowNDC.y) < Factor) { 108 | Index = try; 109 | break; 110 | } 111 | 112 | } 113 | 114 | 115 | 116 | 117 | if(Index == -1) 118 | return vec2(1.); 119 | 120 | float ShadowMapSample = ShadowsESM((Index == 0 ? ShadowMaps[0] : Index == 1 ? ShadowMaps[1] : ShadowMaps[2]), ShadowNDC.xyz * 0.5 + 0.5) * 100.; 121 | 122 | return vec2(ShadowMapSample * max(pow(dot(Normal,normalize(ShadowDirection)),3.),0.), 123 | ShadowMapSample * pow(max(dot(reflect(Incident,Normal), ShadowDirection),0.0),32.0 + 500.0 * (1.0-Roughness))); 124 | 125 | } 126 | 127 | 128 | vec3 TransformToWorld(vec3 Direction, vec3 Normal) { 129 | // Find an axis that is not parallel to normal 130 | vec3 majorAxis; 131 | if (abs(Normal.x) < 0.57735026919f ) { 132 | majorAxis = vec3(1, 0, 0); 133 | } else if (abs(Normal.y) < 0.57735026919f ) { 134 | majorAxis = vec3(0, 1, 0); 135 | } else { 136 | majorAxis = vec3(0, 0, 1); 137 | } 138 | 139 | // Use majorAxis to create a coordinate system relative to world space 140 | vec3 u = normalize(cross(Normal, majorAxis)); 141 | vec3 v = cross(Normal, u); 142 | vec3 w = Normal; 143 | 144 | 145 | // Transform from local coordinates to world coordinates 146 | return u * Direction.x + 147 | v * Direction.y + 148 | w * Direction.z; 149 | } 150 | 151 | 152 | float A = 0.15; 153 | float B = 0.50; 154 | float C = 0.10; 155 | float D = 0.20; 156 | float E = 0.02; 157 | float F = 0.30; 158 | float W = 11.2; 159 | 160 | vec3 Uncharted2Tonemap(vec3 x) 161 | { 162 | return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; 163 | } 164 | 165 | 166 | vec3 GetUpscaledIndirectDiffuse(vec3 Normal, float Depth) { 167 | //(1.0-dot(N, SN)) + abs(D-SD) 168 | float Closest = -1.0; 169 | vec3 Result = vec3(0.0); 170 | 171 | ivec2 BaseCoord = ivec2(gl_FragCoord.xy / 4); 172 | 173 | for(int x = -1; x<=1;x++) { 174 | for (int y = -1; y<=1;y++) { 175 | 176 | vec4 Sample = texelFetch(IndirectDiffuse, BaseCoord + ivec2(x,y),0); 177 | 178 | vec3 SampleNormal, Lighting; 179 | float SampleDepth; 180 | 181 | UnPackData(Sample, Lighting, SampleNormal, SampleDepth); 182 | 183 | float Weight = (1.0 - dot(Normal, SampleNormal)) + abs(Depth-SampleDepth); 184 | 185 | if(Weight < Closest || Closest < 0) { 186 | Closest = Weight; 187 | Result = Lighting; 188 | } 189 | 190 | 191 | } 192 | } 193 | 194 | return Result; 195 | } 196 | 197 | 198 | float zNear = 0.1; 199 | float zFar = 1000.; 200 | 201 | float LinearlizeDepth(float z) { 202 | 203 | return 2.0 * zNear * zFar / (zFar + zNear - (z*2.-1.) * (zFar - zNear)); 204 | 205 | } 206 | 207 | 208 | 209 | vec3 Volumetric(vec3 Direction, vec3 Origin, float DistanceToWorldPosition, float DitherOffset) { 210 | 211 | //grab dither offset 212 | 213 | 214 | 215 | 216 | float StepSize = DistanceToWorldPosition / 12.0f; 217 | 218 | float StepLength = DitherOffset * StepSize; 219 | 220 | vec3 OriginActual = Origin + Direction * DitherOffset * StepSize; 221 | 222 | vec3 Position = OriginActual; 223 | 224 | vec3 Result = vec3(0.); 225 | 226 | float Weight = 0.f; 227 | 228 | float Dot = max(dot(Direction, ShadowDirection), 0.); 229 | 230 | float StepLengthActualPrevious = 0.0; 231 | 232 | while (StepLength < DistanceToWorldPosition) { 233 | 234 | 235 | 236 | StepLength += StepSize; 237 | 238 | float StepLengthActual = StepLength / DistanceToWorldPosition; 239 | //if(Fake) 240 | //StepLengthActual = StepLengthActual * StepLengthActual; 241 | StepLengthActual = StepLengthActual * DistanceToWorldPosition; 242 | 243 | 244 | 245 | 246 | Position = OriginActual + Direction * StepLengthActual; 247 | 248 | float StepSizeActual = StepLengthActual - StepLengthActualPrevious; 249 | 250 | 251 | //grab shadow sample 252 | 253 | vec3 ShadowNDC = vec3(0.); 254 | 255 | int Index = -1; 256 | 257 | for (int try = 0; try < 5; try++) { 258 | 259 | vec4 ShadowCoord = ShadowCombined[try] * vec4(Position, 1.0); 260 | 261 | ShadowNDC = ShadowCoord.xyz / ShadowCoord.w; 262 | 263 | if (abs(ShadowNDC.x) < 1. && abs(ShadowNDC.y) < 1.) { 264 | Index = try; 265 | break; 266 | } 267 | 268 | } 269 | 270 | if (Index == -1) 271 | continue; 272 | 273 | ShadowNDC = ShadowNDC * .5 + .5; 274 | 275 | 276 | float CurrentWeight = StepSizeActual; 277 | 278 | Result += vec3(1.0, 0.6, 0.3) * 2.25f * ShadowsESM(ShadowMaps[Index], ShadowNDC.xyz) * CurrentWeight; 279 | Weight += CurrentWeight; 280 | 281 | StepLengthActualPrevious = StepLengthActual; 282 | 283 | 284 | 285 | 286 | } 287 | 288 | return Result / Weight; 289 | 290 | } 291 | 292 | 293 | float GetWaves(vec2 Point, float Time, int Iterations) { 294 | 295 | float Result = 0.0; 296 | float Speed = 1.0; 297 | float Multiplier = 1.0; 298 | float Weight = 1.0; 299 | float TotalWeight = 0.0; 300 | vec2 Position = Point; 301 | 302 | 303 | for(int x = 0; x < Iterations; x++) { 304 | vec2 Direction = vec2(sin(float(x)), cos(float(x))); 305 | 306 | float Height = exp2(sin(dot(Direction, Position) * Multiplier + Speed * Time) - 1.0); 307 | 308 | Position += Direction * Height * Weight * 0.05; 309 | 310 | Result += Height * Weight; 311 | TotalWeight += Weight; 312 | 313 | Weight = Weight * 0.8; 314 | Multiplier *= 1.25; 315 | Speed *= 1.1; 316 | 317 | 318 | } 319 | 320 | return Result / TotalWeight; 321 | 322 | } 323 | 324 | float Caustics(vec2 P, float Time, int Iterations) { 325 | 326 | float RawX = 1.0 - abs(GetWaves(P, Time, Iterations) * 2. -1.0); 327 | 328 | return RawX * RawX * RawX; 329 | } 330 | 331 | float ActualCaustics(vec2 P, float Time, int Iterations) { 332 | return Caustics(P, Time * 0.912, Iterations) * Caustics(P, Time* 0.959, Iterations) * Caustics(P, -Time * 0.6237, Iterations) * Caustics(P, Time, Iterations); 333 | } 334 | 335 | vec4 CalculateViewSpacePosition(float z) { 336 | 337 | 338 | vec4 ClipSpace = vec4(TexCoord * 2.0 - 1.0, z * 2. - 1., 1.0); 339 | vec4 ViewSpace = InverseProject * ClipSpace; 340 | 341 | return ViewSpace / ViewSpace.w; 342 | 343 | } 344 | 345 | void main() { 346 | 347 | //STEP 1: grab important data 348 | 349 | float Seed = gl_FragCoord.x * 1920 + gl_FragCoord.y; 350 | 351 | 352 | vec4 NormalRoughness = texture(Normal, TexCoord); 353 | vec3 ViewPosition = texture(ViewPosition, TexCoord).xyz; 354 | vec3 WorldPosition = (InverseView * vec4(ViewPosition, 1.0)).xyz; 355 | vec3 Incident = normalize(WorldPosition - CameraPosition); 356 | 357 | vec2 TexCoordNoise = (TexCoord / 128.) * textureSize(Normal, 0); 358 | 359 | vec4 NoiseFactor = texture(BlueNoise, TexCoordNoise); 360 | 361 | //START WITH DIRECT LIGHTING 362 | 363 | vec2 DirectionalShadows = GetDirectionalShadows(WorldPosition, NormalRoughness.xyz, Incident, NormalRoughness.a,NoiseFactor.x); 364 | 365 | Diffuse = SunColor * DirectionalShadows.x; 366 | 367 | float WaterHeight = 40.0 + SampleInterpolatied(WaterNormalMap, vec3(WorldPosition.xz*0.05,mod(Time*10.0, 119.))).w * 2.1; 368 | 369 | Diffuse += (clamp(WaterHeight - WorldPosition.y, 0.0, 5.0) * (ActualCaustics(WorldPosition.xz * 10.0, Time, 10) + vec3(0.0, 0.35, 0.5 )) * 5.0); 370 | 371 | 372 | 373 | float DepthSample = texture(Depth, TexCoord).x; 374 | float LinearDepthSample = LinearlizeDepth(DepthSample); 375 | 376 | Diffuse += GetUpscaledIndirectDiffuse(NormalRoughness.xyz, LinearDepthSample); 377 | 378 | Diffuse /= WorldPosition.y > WaterHeight ? 1.0 : clamp(pow(max(abs(WorldPosition.y - WaterHeight)-.333,0.0),2.0) * 5,1.0,10000.); 379 | 380 | 381 | float WaterDepthSample = texture(WaterDepth, TexCoord).x; 382 | 383 | if(WaterDepthSample > DepthSample) 384 | Specular = SunColor * DirectionalShadows.y; 385 | else { 386 | //do it for the water now! yay! 387 | 388 | Specular = SunColor * GetDirectionalShadows(vec3(InverseView * CalculateViewSpacePosition(WaterDepthSample)), texture(WaterNormal, TexCoord).xyz, Incident, 0.0,NoiseFactor.x).y; 389 | 390 | 391 | } 392 | 393 | } -------------------------------------------------------------------------------- /Shaders/FirstPassLighting/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout (location = 0) in vec3 Vert; 3 | layout (location = 1) in vec2 Texc; 4 | out vec2 TexCoord; 5 | 6 | 7 | void main(void) { 8 | TexCoord = Texc; 9 | gl_Position = vec4(Vert.xy,0.f,1.0); 10 | } -------------------------------------------------------------------------------- /Shaders/IndirectDiffuse/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 420 2 | #extension GL_ARB_bindless_texture : enable 3 | 4 | in vec2 TexCoord; 5 | 6 | layout(location = 0) out vec4 Packed; 7 | 8 | //samplers: (ie textures) 9 | uniform sampler2D ViewPosition; 10 | uniform sampler2D Normal; 11 | uniform sampler2D BlueNoise; 12 | uniform sampler2D Depth; 13 | uniform sampler2D Previous; 14 | uniform sampler2D ShadowMaps[3]; 15 | uniform sampler3D Voxels[3]; 16 | uniform samplerCube Sky; 17 | 18 | uniform int Frame; 19 | 20 | 21 | //matrices 22 | 23 | uniform mat4 ShadowCombined[3]; 24 | uniform mat4 InverseView; 25 | uniform mat4 PreviousCombined; 26 | 27 | //vectors / scalars / other 28 | 29 | uniform vec3 ShadowDirection; 30 | uniform vec3 CameraPosition; 31 | uniform vec3 SunColor; 32 | uniform vec3 CameraPositionLight[3]; 33 | uniform vec2 Resolution; 34 | uniform float Size[3]; 35 | uniform bool First; 36 | 37 | 38 | sampler3D GetVoxelVolume(int volume) { 39 | return volume == 0 ? Voxels[0] : volume == 1 ? Voxels[1] : Voxels[2]; 40 | } 41 | 42 | 43 | 44 | 45 | vec4 PackData(vec3 Normal, vec3 Diffuse, float Depth, float Temporal) { 46 | 47 | vec4 Packed; 48 | 49 | Packed.x = uintBitsToFloat(packHalf2x16(Diffuse.xy)); 50 | Packed.y = uintBitsToFloat(packHalf2x16(vec2(Diffuse.z, Normal.x))); 51 | Packed.z = uintBitsToFloat(packHalf2x16(Normal.yz)); 52 | Packed.w = uintBitsToFloat(packHalf2x16(vec2(Depth, Temporal))); 53 | 54 | return Packed; 55 | 56 | } 57 | 58 | void UnPackData(vec4 Packed, out vec3 Diffuse, out vec3 Normal, out float Depth, out float Temporal) { 59 | 60 | vec2 UnPacked1 = unpackHalf2x16(floatBitsToUint(Packed.x)); 61 | vec2 UnPacked2 = unpackHalf2x16(floatBitsToUint(Packed.y)); 62 | vec2 UnPacked3 = unpackHalf2x16(floatBitsToUint(Packed.z)); 63 | vec2 UnPacked4 = unpackHalf2x16(floatBitsToUint(Packed.w)); 64 | 65 | Diffuse = vec3(UnPacked1, UnPacked2.x); 66 | Normal = vec3(UnPacked2.y, UnPacked3.xy); 67 | Depth = UnPacked4.x; 68 | Temporal = UnPacked4.y; 69 | 70 | } 71 | 72 | 73 | vec3 TransformToVoxelSpace(int Volume, vec3 WorldPosition) { 74 | 75 | return ((WorldPosition - CameraPositionLight[Volume]) / (Size[Volume]/2.)); 76 | 77 | } 78 | 79 | vec4 ConeTrace(vec3 Origin, vec3 Direction, vec3 Normal) { 80 | 81 | vec4 Result = vec4(0.0,0.0,0.0,1.0); 82 | 83 | int Volume = 0; 84 | 85 | float StepSize = (1.0 / 64.) * Size[0]; 86 | 87 | vec3 Position = Origin + Normal * StepSize * 2.0; 88 | 89 | while(Volume != 3 && Result.a > 0.05) { 90 | 91 | Position += Direction * StepSize; 92 | 93 | vec3 Coordinate = TransformToVoxelSpace(Volume, Position); 94 | 95 | if(abs(Coordinate.x) > .96 || abs(Coordinate.y) > .96 || abs(Coordinate.z) > .96) { 96 | if(Volume == 2) 97 | break; 98 | 99 | Volume++; 100 | 101 | StepSize *= 2.0; 102 | 103 | 104 | } 105 | 106 | 107 | 108 | vec4 Sample = textureLod((Volume == 0 ? Voxels[0] : Volume == 1 ? Voxels[1] : Voxels[2]), Coordinate * 0.5 + 0.5, 0.); 109 | 110 | Sample.xyz = pow(Sample.xyz * 8.333,vec3(2.2)); 111 | 112 | Sample.a = 1.0-pow(1.0-Sample.a, 4.0); 113 | 114 | Result.xyz += Sample.xyz * Result.a; 115 | 116 | Result.a *= pow(clamp(1.0 - Sample.a, 0.0,1.0), 1.0); 117 | 118 | } 119 | 120 | float UpFactor = 1.0; 121 | float SunFactor = clamp(dot(Direction, ShadowDirection), 0.0, 1.0); 122 | 123 | Result.a *= clamp(UpFactor * 10.0, 0.0, 1.0); 124 | 125 | vec3 SkyColor = vec3(0.3,0.6,1.0) * sqrt(UpFactor); 126 | 127 | 128 | 129 | Result.xyz += pow(texture(Sky,Direction).xyz,vec3(2.2)) * pow(Result.a,128.0) * 3.0; 130 | 131 | return vec4(Result.xyz, 1.0); 132 | 133 | 134 | } 135 | 136 | 137 | 138 | 139 | vec3 TransformToWorld(vec3 Direction, vec3 Normal) { 140 | // Find an axis that is not parallel to normal 141 | vec3 majorAxis; 142 | if (abs(Normal.x) < 0.57735026919f /* 1 / sqrt(3) */) { 143 | majorAxis = vec3(1, 0, 0); 144 | } else if (abs(Normal.y) < 0.57735026919f /* 1 / sqrt(3) */) { 145 | majorAxis = vec3(0, 1, 0); 146 | } else { 147 | majorAxis = vec3(0, 0, 1); 148 | } 149 | 150 | // Use majorAxis to create a coordinate system relative to world space 151 | vec3 u = normalize(cross(Normal, majorAxis)); 152 | vec3 v = cross(Normal, u); 153 | vec3 w = Normal; 154 | 155 | 156 | // Transform from local coordinates to world coordinates 157 | return u * Direction.x + 158 | v * Direction.y + 159 | w * Direction.z; 160 | } 161 | 162 | vec2 hash2(float seed) { 163 | return fract(vec2(sin(vec2(seed, seed + 0.1f))*vec2(43758.5453123f, 22578.1459123f))); 164 | } 165 | 166 | vec3 LambertBRDF(vec3 Normal, vec2 Hash) { 167 | 168 | 169 | 170 | float r = sqrt(Hash.x); 171 | 172 | float theta = Hash.y * 6.2831; 173 | 174 | float x = r * cos(theta); 175 | float y = r * sin(theta); 176 | 177 | // Project z up to the unit hemisphere 178 | float z = sqrt(1.0f - x * x - y * y); 179 | 180 | return normalize(TransformToWorld(vec3(x,y,z), Normal)); 181 | 182 | } 183 | 184 | float zNear = 0.1; 185 | float zFar = 1000.; 186 | 187 | float LinearlizeDepth(float z) { 188 | 189 | return 2.0 * zNear * zFar / (zFar + zNear - (z*2.-1.) * (zFar - zNear)); 190 | 191 | } 192 | 193 | void main() { 194 | 195 | float Seed = (TexCoord.x + TexCoord.y) * 10000. + Frame; 196 | 197 | //STEP 1: grab important data 198 | 199 | vec4 NormalRoughness = texture(Normal, TexCoord); 200 | vec3 ViewPosition = texture(ViewPosition, TexCoord).xyz; 201 | vec3 WorldPosition = (InverseView * vec4(ViewPosition, 1.0)).xyz; 202 | vec3 Incident = normalize(WorldPosition - CameraPosition); 203 | 204 | vec2 TexCoordNoise = (TexCoord / 128.) * textureSize(Normal, 0); 205 | 206 | 207 | //vec3 VoxelSpace = (((WorldPosition+NormalRoughness.xyz * 1.)-CameraPositionLight[0])/(Size[0]/2.))*0.5+0.5; 208 | 209 | vec3 Diffuse = vec3(0.0); 210 | 211 | vec3 Direction = LambertBRDF(NormalRoughness.xyz,hash2(Seed)); 212 | 213 | if(distance(WorldPosition, CameraPosition) < (Size[2]/2.)) 214 | Diffuse = ConeTrace(WorldPosition,Direction, NormalRoughness.xyz).xyz; 215 | else 216 | Diffuse = pow(texture(Sky, Direction).xyz,vec3(2.2)) * 3.0; 217 | 218 | 219 | float Depth = LinearlizeDepth(texture(Depth, TexCoord).x); 220 | 221 | //reconstruct motion vectors 222 | 223 | 224 | 225 | float Frame = 0.0; 226 | 227 | if(!First) { 228 | 229 | vec4 NDC = PreviousCombined * vec4(WorldPosition, 1.0); 230 | 231 | NDC.xyz /= NDC.w; 232 | 233 | 234 | 235 | if (abs(NDC.x) < 1.0 && abs(NDC.y) < 1.0) { 236 | NDC.xy = NDC.xy * 0.5 + 0.5; 237 | 238 | 239 | 240 | ivec2 PreviousCoordinate = ivec2(NDC.xy * vec2(480,270)); 241 | 242 | //go through coordinate + coordinates neighboor. Find the best one 243 | 244 | float Closest = -1.0; 245 | vec4 Value = vec4(0.0); 246 | 247 | for(int x = 0; x <= 0; x++) { 248 | for(int y = 0; y <= 0; y++) { 249 | 250 | vec4 Sample = texelFetch(Previous, PreviousCoordinate + ivec2(x,y),0); 251 | 252 | vec3 SampleNormal, Lighting; 253 | float SampleDepth, SampleTemporal; 254 | 255 | UnPackData(Sample, Lighting, SampleNormal, SampleDepth, SampleTemporal); 256 | 257 | float Weight = (1.0 - dot(NormalRoughness.xyz, SampleNormal)) + abs(Depth-SampleDepth); 258 | 259 | if(Weight < Closest || Closest < 0) { 260 | Closest = Weight; 261 | Value.xyz = Lighting; 262 | Value.w = SampleTemporal; 263 | } 264 | 265 | } 266 | } 267 | 268 | if(Closest < 1.0) { 269 | Frame = min(Value.w + 1.0,21.0); 270 | 271 | Diffuse = mix(Diffuse, Value.xyz, float(Frame) / float(Frame + 1.0)); 272 | 273 | } 274 | 275 | } 276 | 277 | } 278 | 279 | 280 | 281 | 282 | 283 | Packed = PackData(NormalRoughness.xyz, Diffuse, Depth, Frame); 284 | 285 | 286 | 287 | //now, utilize temporal filtering. yeah yeah yeah yeah 288 | 289 | 290 | 291 | } -------------------------------------------------------------------------------- /Shaders/IndirectDiffuse/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout (location = 0) in vec3 Vert; 3 | layout (location = 1) in vec2 Texc; 4 | out vec2 TexCoord; 5 | 6 | 7 | void main(void) { 8 | TexCoord = Texc; 9 | gl_Position = vec4(Vert.xy,0.f,1.0); 10 | } -------------------------------------------------------------------------------- /Shaders/IndirectDiffusePacker/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 420 2 | 3 | 4 | in vec2 TexCoord; 5 | 6 | layout(location = 0) out vec4 PackedOut; 7 | 8 | uniform vec2 TexelSize; 9 | uniform sampler2D PackedData; 10 | uniform int Size; 11 | uniform mat4 InverseProject; 12 | uniform mat3 InverseView; 13 | uniform bool Vertical; 14 | 15 | vec4 PackData(vec3 Normal, vec3 Diffuse, float Depth) { 16 | 17 | vec4 Packed; 18 | 19 | Packed.x = uintBitsToFloat(packHalf2x16(Diffuse.xy)); 20 | Packed.y = uintBitsToFloat(packHalf2x16(vec2(Diffuse.z, Normal.x))); 21 | Packed.z = uintBitsToFloat(packHalf2x16(Normal.yz)); 22 | Packed.w = Depth; 23 | 24 | return Packed; 25 | 26 | } 27 | 28 | void UnPackData(vec4 Packed, out vec3 Diffuse, out vec3 Normal, out float Depth) { 29 | 30 | vec2 UnPacked1 = unpackHalf2x16(floatBitsToUint(Packed.x)); 31 | vec2 UnPacked2 = unpackHalf2x16(floatBitsToUint(Packed.y)); 32 | vec2 UnPacked3 = unpackHalf2x16(floatBitsToUint(Packed.z)); 33 | 34 | Diffuse = vec3(UnPacked1, UnPacked2.x); 35 | Normal = vec3(UnPacked2.y, UnPacked3.xy); 36 | Depth = Packed.w; 37 | 38 | } 39 | 40 | vec3 GetIncident(){ 41 | 42 | vec4 device_normal = vec4(TexCoord * 2. - 1., 0.0, 1.0); 43 | vec3 eye_normal = normalize((InverseProject * device_normal).xyz); 44 | vec3 world_normal = normalize(InverseView*eye_normal); 45 | return world_normal; 46 | } 47 | 48 | void main() { 49 | 50 | vec3 Diffuse, Normal; 51 | float Depth; 52 | 53 | ivec2 BaseCoord = ivec2(gl_FragCoord.xy); 54 | 55 | UnPackData(texelFetch(PackedData, BaseCoord,0), Diffuse, Normal, Depth); 56 | 57 | float Weight = 0.2; 58 | 59 | Diffuse *= Weight; 60 | 61 | vec3 IncidentVector = GetIncident(); 62 | 63 | for(int x = -4; x <= 4; x++) { 64 | 65 | if(x != 0) { 66 | 67 | vec3 SampleNormal, SampleDiffuse; 68 | float SampleDepth; 69 | 70 | ivec2 NewCoord = BaseCoord + ivec2(!Vertical ? x : 0, Vertical ? x : 0) * Size; 71 | 72 | UnPackData(texelFetch(PackedData, NewCoord,0),SampleDiffuse, SampleNormal, SampleDepth); 73 | 74 | if(abs(SampleDepth-Depth) < mix(0.1,1.0,pow(1.-abs(dot(Normal.xyz, IncidentVector)),2.))) { 75 | 76 | float SampleWeight = pow(max(dot(SampleNormal, Normal),0.0), 3.0) * (1.0 / (abs(x)+5.0)); 77 | 78 | Diffuse += SampleDiffuse * SampleWeight; 79 | 80 | Weight += SampleWeight; 81 | 82 | } 83 | } 84 | 85 | } 86 | 87 | PackedOut = PackData(Normal, Diffuse / Weight, Depth); 88 | 89 | 90 | } -------------------------------------------------------------------------------- /Shaders/IndirectDiffusePacker/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout (location = 0) in vec3 Vert; 3 | layout (location = 1) in vec2 Texc; 4 | out vec2 TexCoord; 5 | 6 | 7 | void main(void) { 8 | TexCoord = Texc; 9 | gl_Position = vec4(Vert.xy,0.f,1.0); 10 | } -------------------------------------------------------------------------------- /Shaders/IndirectDiffuseSpatial/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 420 2 | 3 | 4 | in vec2 TexCoord; 5 | 6 | layout(location = 0) out vec4 PackedOut; 7 | 8 | uniform vec2 TexelSize; 9 | uniform sampler2D PackedData; 10 | uniform int Size; 11 | uniform mat4 InverseProject; 12 | uniform mat3 InverseView; 13 | uniform bool Vertical; 14 | 15 | vec4 PackData(vec3 Normal, vec3 Diffuse, float Depth) { 16 | 17 | vec4 Packed; 18 | 19 | Packed.x = uintBitsToFloat(packHalf2x16(Diffuse.xy)); 20 | Packed.y = uintBitsToFloat(packHalf2x16(vec2(Diffuse.z, Normal.x))); 21 | Packed.z = uintBitsToFloat(packHalf2x16(Normal.yz)); 22 | Packed.w = uintBitsToFloat(packHalf2x16(vec2(Depth, 0.0))); 23 | 24 | return Packed; 25 | 26 | } 27 | 28 | void UnPackData(vec4 Packed, out vec3 Diffuse, out vec3 Normal, out float Depth) { 29 | 30 | vec2 UnPacked1 = unpackHalf2x16(floatBitsToUint(Packed.x)); 31 | vec2 UnPacked2 = unpackHalf2x16(floatBitsToUint(Packed.y)); 32 | vec2 UnPacked3 = unpackHalf2x16(floatBitsToUint(Packed.z)); 33 | vec2 UnPacked4 = unpackHalf2x16(floatBitsToUint(Packed.w)); 34 | 35 | Diffuse = vec3(UnPacked1, UnPacked2.x); 36 | Normal = vec3(UnPacked2.y, UnPacked3.xy); 37 | Depth = UnPacked4.x; 38 | 39 | } 40 | 41 | vec3 GetIncident(){ 42 | 43 | vec4 device_normal = vec4(TexCoord * 2. - 1., 0.0, 1.0); 44 | vec3 eye_normal = normalize((InverseProject * device_normal).xyz); 45 | vec3 world_normal = normalize(InverseView*eye_normal); 46 | return world_normal; 47 | } 48 | 49 | void main() { 50 | 51 | vec3 Diffuse, Normal; 52 | float Depth; 53 | 54 | ivec2 BaseCoord = ivec2(gl_FragCoord.xy); 55 | 56 | UnPackData(texelFetch(PackedData, BaseCoord,0), Diffuse, Normal, Depth); 57 | 58 | float Weight = 0.2; 59 | 60 | Diffuse *= Weight; 61 | 62 | vec3 IncidentVector = GetIncident(); 63 | 64 | for(int x = -3; x <= 3; x++) { 65 | 66 | if(x != 0) { 67 | 68 | vec3 SampleNormal, SampleDiffuse; 69 | float SampleDepth; 70 | 71 | ivec2 NewCoord = BaseCoord + ivec2(!Vertical ? x : 0, Vertical ? x : 0) * Size; 72 | 73 | UnPackData(texelFetch(PackedData, NewCoord,0),SampleDiffuse, SampleNormal, SampleDepth); 74 | 75 | if(abs(SampleDepth-Depth) < mix(0.5,2.0,pow(1.-abs(dot(Normal.xyz, IncidentVector)),2.))) { 76 | 77 | float SampleWeight = pow(max(dot(SampleNormal, Normal),0.0), 2.0) * (1.0 / (abs(x)+5.0)); 78 | 79 | Diffuse += SampleDiffuse * SampleWeight; 80 | 81 | Weight += SampleWeight; 82 | 83 | } 84 | } 85 | 86 | } 87 | 88 | PackedOut = PackData(Normal, Diffuse / Weight, Depth); 89 | 90 | 91 | } -------------------------------------------------------------------------------- /Shaders/IndirectDiffuseSpatial/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout (location = 0) in vec3 Vert; 3 | layout (location = 1) in vec2 Texc; 4 | out vec2 TexCoord; 5 | 6 | 7 | void main(void) { 8 | TexCoord = Texc; 9 | gl_Position = vec4(Vert.xy,0.f,1.0); 10 | } -------------------------------------------------------------------------------- /Shaders/IndirectSpecular/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 420 2 | 3 | in vec2 TexCoord; 4 | layout(location = 0) out vec4 IndirectSpecular; 5 | 6 | //samplers: (ie textures) 7 | uniform sampler2D ViewPosition; 8 | uniform sampler2D Normal; 9 | uniform sampler2D FirstPassDiffuse; 10 | uniform samplerCube Test; 11 | uniform samplerCube CubeMapWorldPosition; 12 | uniform sampler2D Albedo; 13 | uniform sampler2D Previous; 14 | uniform sampler2DArray Sky; 15 | uniform sampler2D Depth; 16 | uniform sampler2D WaterDepth; 17 | uniform sampler2D WaterNormal; 18 | 19 | uniform mat4 InverseView; 20 | uniform mat4 View; 21 | uniform mat4 Project; 22 | uniform mat4 InverseProject; 23 | uniform mat4 PreviousCombined; 24 | uniform float Time; 25 | 26 | uniform vec3 CameraPosition; 27 | uniform vec3 LightDirection; 28 | 29 | uniform int Frame; 30 | uniform bool First; 31 | 32 | vec3 ImportanceGGX(vec2 xi, float roughness) 33 | { 34 | float r_square = roughness * roughness; 35 | float phi = 6.2831 * xi.x; 36 | float cos_theta = sqrt((1 - xi.y) / (1 + (r_square * r_square - 1) * xi.y)); 37 | float sin_theta = sqrt(1 - cos_theta * cos_theta); 38 | 39 | return vec3(sin_theta * cos(phi), sin_theta * sin(phi), cos_theta); 40 | } 41 | 42 | float Seed; 43 | 44 | vec2 hash2() { 45 | return fract(vec2(sin(vec2(Seed++, Seed++))*vec2(43758.5453123f, 22578.1459123f))); 46 | } 47 | 48 | 49 | 50 | vec3 TraceCubeMap(samplerCube WorldPositionCubeMap, vec3 Direction, vec3 WorldPosition, vec3 CameraPosition, float Dither, 51 | float StepSize, float Estimation, int BinarySearchSteps, int Steps, out bool success, out float traversaldistance, float IncreaseFactor) { 52 | success = false; 53 | 54 | vec3 Hit = WorldPosition + Direction * Dither * StepSize; 55 | 56 | traversaldistance = Dither * StepSize; 57 | 58 | for(int Step = 1; Step < Steps; Step++) { 59 | 60 | Hit += Direction*StepSize; 61 | 62 | StepSize *= IncreaseFactor; 63 | 64 | traversaldistance += StepSize; 65 | 66 | vec3 PositionOnCubeMap = texture(WorldPositionCubeMap,normalize(Hit - CameraPosition), 0.f).xyz; 67 | 68 | //are we close enough to estimate a hit? 69 | 70 | if(distance(PositionOnCubeMap,Hit) < (StepSize * Estimation)) { 71 | 72 | float StepSizeBinarySearch = StepSize * 0.5; 73 | 74 | for(int StepBinarySearch=0;StepBinarySearch 0.0005f) { 121 | return TryDirection; 122 | } 123 | 124 | } 125 | return RawDirection; 126 | } 127 | 128 | vec2 ScreenSpaceTracing(vec3 ViewPos, vec3 Normal, float Roughness) { 129 | 130 | vec3 Incident = normalize(ViewPos); 131 | vec3 Direction = reflect(Incident, Normal); 132 | Direction = GetSpecularRayDirection(Direction, Normal, Incident, Roughness); 133 | 134 | float StepSize = mix(0.75,1.5,Roughness); 135 | 136 | float Traversal = 0.0; 137 | 138 | vec3 RayPos = ViewPos; 139 | 140 | for(int Step = 0; Step < int(mix(12,6,Roughness)); Step++) { 141 | Traversal += StepSize; 142 | StepSize *= 1.4; 143 | RayPos += Direction * StepSize; 144 | 145 | vec4 ScreenPos = Project * vec4(RayPos, 1.0); 146 | ScreenPos.xyz /= ScreenPos.w; 147 | 148 | float Depth = textureLod(ViewPosition,ScreenPos.xy * 0.5 + 0.5,0.).z; 149 | 150 | if(abs(ScreenPos.x) > 1.0 || abs(ScreenPos.y) > 1.0) 151 | return vec2(-1.0); 152 | 153 | if(Depth > RayPos.z) { 154 | 155 | float StepSizeBinary = StepSize * 0.5; 156 | 157 | for(int StepBinarySearch = 0; StepBinarySearch < int(mix(4,2,Roughness)); StepBinarySearch++) { 158 | 159 | ScreenPos = Project * vec4(RayPos, 1.0); 160 | ScreenPos.xyz /= ScreenPos.w; 161 | 162 | Depth = textureLod(ViewPosition,ScreenPos.xy * 0.5 + 0.5,0.).z; 163 | 164 | if(Depth > RayPos.z) { 165 | Traversal -= StepSizeBinary; 166 | RayPos -= Direction * StepSizeBinary; 167 | } 168 | else { 169 | Traversal += StepSizeBinary; 170 | RayPos += Direction * StepSizeBinary; 171 | } 172 | 173 | StepSizeBinary*=0.5; 174 | } 175 | 176 | 177 | if(abs(Depth - RayPos.z) < StepSizeBinary * 8.0) { 178 | 179 | return ScreenPos.xy; 180 | } 181 | } 182 | 183 | 184 | } 185 | return vec2(-1.); 186 | } 187 | 188 | 189 | 190 | 191 | vec4 CalculateViewSpacePosition(float z) { 192 | 193 | 194 | vec4 ClipSpace = vec4(TexCoord * 2.0 - 1.0, z * 2. - 1., 1.0); 195 | vec4 ViewSpace = InverseProject * ClipSpace; 196 | 197 | return ViewSpace / ViewSpace.w; 198 | 199 | } 200 | 201 | const vec2 invAtan = vec2(0.1591, 0.3183); 202 | vec2 SampleSphericalMap(vec3 v) 203 | { 204 | vec2 uv = vec2(atan(v.z, v.x), asin(v.y)); 205 | uv *= invAtan; 206 | uv += 0.5; 207 | return uv; 208 | } 209 | 210 | vec4 SampleInterpolatied(sampler2DArray Sampler,vec3 Coord) { 211 | 212 | float BaseTime = mod(Coord.z, 119.); 213 | 214 | int Coord1 = int(floor(BaseTime)); 215 | int Coord2 = int(ceil(BaseTime))%119; 216 | 217 | return mix(texture(Sampler, vec3(Coord.xy, Coord1)), texture(Sampler,vec3(Coord.xy, Coord2)), fract(BaseTime)); 218 | 219 | 220 | } 221 | 222 | 223 | void main() { 224 | 225 | //STEP 1: grab important data 226 | 227 | 228 | vec4 NormalRoughness = texture(Normal, TexCoord); 229 | vec3 ViewPosition = texture(ViewPosition, TexCoord).xyz; 230 | vec3 WorldPosition = (InverseView * vec4(ViewPosition, 1.0)).xyz; 231 | 232 | float Roughness = NormalRoughness.a; 233 | bool Hit; 234 | 235 | float DepthSampleWater = texture(WaterDepth, TexCoord).x; 236 | 237 | IndirectSpecular.xyz = NormalRoughness.xyz; 238 | 239 | 240 | if(texture(Depth, TexCoord).x > DepthSampleWater) { 241 | ViewPosition = CalculateViewSpacePosition(DepthSampleWater).xyz; 242 | 243 | WorldPosition = vec3(inverse(View) * vec4(ViewPosition,1.0)); 244 | NormalRoughness.xyz = texture(WaterNormal, TexCoord).xyz; 245 | Roughness = 0.0; 246 | 247 | 248 | 249 | } 250 | 251 | vec3 Incident = normalize(WorldPosition - CameraPosition); 252 | vec3 ViewNormal = vec3(vec4(NormalRoughness.xyz, 0.0) * InverseView); 253 | 254 | float Traversal; 255 | 256 | Seed = gl_FragCoord.x * 1080 + gl_FragCoord.y + Frame; 257 | 258 | //Start of with a screen space method 259 | 260 | vec2 ScreenSpaceHit = ScreenSpaceTracing(ViewPosition, ViewNormal, Roughness); 261 | 262 | //is there a hit? 263 | 264 | //IndirectSpecular = vec3(Roughness); 265 | 266 | 267 | if(abs(ScreenSpaceHit.x) < 1.0 && abs(ScreenSpaceHit.y) < 1.0) { 268 | ScreenSpaceHit = ScreenSpaceHit * 0.5 + 0.5; 269 | 270 | IndirectSpecular.xyz = texture(FirstPassDiffuse, ScreenSpaceHit).xyz * texture(Albedo, ScreenSpaceHit).xyz; 271 | 272 | 273 | } 274 | else { 275 | 276 | Seed = gl_FragCoord.x * 1080 + gl_FragCoord.y + Frame; 277 | 278 | vec3 Direction = GetSpecularRayDirection(reflect(Incident, NormalRoughness.xyz),NormalRoughness.xyz,Incident,Roughness); 279 | 280 | vec4 SpecularSample = texture(Test, TraceCubeMap(CubeMapWorldPosition,Direction , WorldPosition + NormalRoughness.xyz * 0.5, CameraPosition,0.0, mix(2.0,4.0,Roughness), mix(0.5,1.0,Roughness), int(mix(4,2,Roughness)), int(mix(12,6,Roughness)), Hit, Traversal, 1.25)); 281 | 282 | 283 | 284 | vec2 Coord = SampleSphericalMap(Direction); 285 | Coord.y = Coord.y * 2. - 1.; 286 | 287 | 288 | 289 | vec4 SkySample = Coord.y < 0.0 ? vec4(0.0) : SampleInterpolatied(Sky, vec3(1.0 - Coord,mod(Time*10.0, 119.))); 290 | 291 | 292 | 293 | vec3 BackGround = mix(vec3(0.0,0.3,0.6), (2.0 * max(dot(LightDirection,SkySample.xyz),0.) + vec3(0.0,0.3,0.6)*1.25),SkySample.w); 294 | 295 | 296 | SpecularSample.xyz = max(SpecularSample.xyz, vec3(0.)); 297 | SpecularSample.xyz += SpecularSample.aaa * BackGround; 298 | 299 | IndirectSpecular.xyz = SpecularSample.xyz; 300 | 301 | } 302 | 303 | 304 | float Frame = 0.0; 305 | 306 | if(!First) { 307 | 308 | vec4 NDC = PreviousCombined * vec4(WorldPosition, 1.0); 309 | 310 | NDC.xyz /= NDC.w; 311 | 312 | if (abs(NDC.x) < 1.0 && abs(NDC.y) < 1.0) { 313 | NDC.xy = NDC.xy * 0.5 + 0.5; 314 | 315 | vec4 Value = texture(Previous, NDC.xy); 316 | 317 | Frame = min(Value.w + 1.0,11.); 318 | 319 | IndirectSpecular.xyz = mix(IndirectSpecular.xyz, Value.xyz, min(float(Frame) / float(Frame + 1.0), mix(0.0, 2.0, sqrt(Roughness)))); 320 | 321 | 322 | } 323 | 324 | } 325 | 326 | IndirectSpecular.a = Frame; 327 | 328 | } -------------------------------------------------------------------------------- /Shaders/IndirectSpecular/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout (location = 0) in vec3 Vert; 3 | layout (location = 1) in vec2 Texc; 4 | out vec2 TexCoord; 5 | 6 | 7 | void main(void) { 8 | TexCoord = Texc; 9 | gl_Position = vec4(Vert.xy,0.f,1.0); 10 | } -------------------------------------------------------------------------------- /Shaders/LightCombiner/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 420 2 | 3 | in vec2 TexCoord; 4 | layout(location = 0) out vec3 Lighting; 5 | 6 | uniform sampler2D FirstPassDiffuse; //indirect + direct diffuse 7 | uniform sampler2D FirstPassSpecular; //direct specular 8 | uniform sampler2D IndirectSpecular; //indirect specular 9 | uniform sampler2D Normal; //contains roughness 10 | uniform sampler2D Albedo; //contains albedo + metalness 11 | uniform sampler2D ViewPosition; 12 | uniform sampler2D Depth; 13 | uniform sampler2D WaterDepth; 14 | uniform sampler2D WaterNormal; 15 | uniform sampler2DArray WaterNormalMap; 16 | uniform sampler2DArray Sky; 17 | uniform float Time; 18 | uniform vec3 LightDirection; 19 | 20 | uniform mat4 ViewMatrix; 21 | uniform mat4 ProjectionMatrix; 22 | uniform mat4 InverseView; 23 | uniform mat4 InverseProject; 24 | uniform vec3 CameraPosition; 25 | in float WaterHeightCamera; 26 | 27 | float A = 0.15; 28 | float B = 0.50; 29 | float C = 0.10; 30 | float D = 0.20; 31 | float E = 0.02; 32 | float F = 0.30; 33 | float W = 11.2; 34 | 35 | 36 | 37 | vec3 Uncharted2Tonemap(vec3 x) 38 | { 39 | return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; 40 | } 41 | 42 | vec3 Fresnel(vec3 Incident, vec3 Normal, vec3 Specular, float Roughness) { 43 | return Specular + (max(vec3(1-Roughness) - Specular,vec3(0.))) * pow(max(1.0 - abs(dot(Incident,Normal)),0.0), 5.0); 44 | } 45 | 46 | float FresnelWater(vec3 Incident, vec3 Normal) { 47 | 48 | return 0.04 + 0.96 * pow(max(1.0 - abs(dot(Incident,Normal)),0.0), 5.0); 49 | } 50 | 51 | vec4 CalculateViewSpacePosition(float z) { 52 | 53 | 54 | vec4 ClipSpace = vec4(TexCoord * 2.0 - 1.0, z * 2. - 1., 1.0); 55 | vec4 ViewSpace = InverseProject * ClipSpace; 56 | 57 | return ViewSpace / ViewSpace.w; 58 | 59 | } 60 | 61 | float zNear = 0.1; 62 | float zFar = 1000.; 63 | 64 | float LinearlizeDepth(float z) { 65 | 66 | return 2.0 * zNear * zFar / (zFar + zNear - (z*2.-1.) * (zFar - zNear)); 67 | 68 | } 69 | 70 | const vec2 invAtan = vec2(0.1591, 0.3183); 71 | vec2 SampleSphericalMap(vec3 v) 72 | { 73 | vec2 uv = vec2(atan(v.z, v.x), asin(v.y)); 74 | uv *= invAtan; 75 | uv += 0.5; 76 | return uv; 77 | } 78 | 79 | 80 | 81 | 82 | vec2 ScreenSpaceTracing(vec3 ViewPos, vec3 Normal) { 83 | 84 | vec3 Incident = normalize(ViewPos); 85 | vec3 Direction = refract(Incident, Normal,1/1.33333); 86 | 87 | float StepSize = 2.0; 88 | 89 | float Traversal = 0.0; 90 | 91 | vec3 RayPos = ViewPos; 92 | 93 | for(int Step = 0; Step < 6; Step++) { 94 | Traversal += StepSize; 95 | StepSize *= 1.4; 96 | RayPos += Direction * StepSize; 97 | 98 | vec4 ScreenPos = ProjectionMatrix * vec4(RayPos, 1.0); 99 | ScreenPos.xyz /= ScreenPos.w; 100 | 101 | float Depth = textureLod(ViewPosition,ScreenPos.xy * 0.5 + 0.5,0.).z; 102 | 103 | if(abs(ScreenPos.x) > 1.0 || abs(ScreenPos.y) > 1.0) 104 | return vec2(-1.0); 105 | 106 | if(Depth > RayPos.z) { 107 | 108 | float StepSizeBinary = StepSize * 0.5; 109 | 110 | for(int StepBinarySearch = 0; StepBinarySearch < 4; StepBinarySearch++) { 111 | 112 | ScreenPos = ProjectionMatrix * vec4(RayPos, 1.0); 113 | ScreenPos.xyz /= ScreenPos.w; 114 | 115 | Depth = textureLod(ViewPosition,ScreenPos.xy * 0.5 + 0.5,0.).z; 116 | 117 | if(Depth > RayPos.z) { 118 | Traversal -= StepSizeBinary; 119 | RayPos -= Direction * StepSizeBinary; 120 | } 121 | else { 122 | Traversal += StepSizeBinary; 123 | RayPos += Direction * StepSizeBinary; 124 | } 125 | 126 | StepSizeBinary*=0.5; 127 | } 128 | 129 | 130 | 131 | return ScreenPos.xy; 132 | 133 | 134 | } 135 | 136 | 137 | } 138 | return vec2(-1.); 139 | } 140 | 141 | 142 | float Fog(vec3 WorldPos, vec3 CamPos) { 143 | 144 | float BaseDistance = min(distance(WorldPos, CamPos) / 90.,1.0); 145 | 146 | return pow(BaseDistance,4.0); 147 | 148 | } 149 | 150 | vec4 SampleInterpolatied(sampler2DArray Sampler,vec3 Coord) { 151 | 152 | float BaseTime = mod(Coord.z, 119.); 153 | 154 | int Coord1 = int(floor(BaseTime)); 155 | int Coord2 = int(ceil(BaseTime))%119; 156 | 157 | return mix(texture(Sampler, vec3(Coord.xy, Coord1)), texture(Sampler,vec3(Coord.xy, Coord2)), fract(BaseTime)); 158 | 159 | 160 | } 161 | 162 | const float LN2 = 0.693147181; 163 | 164 | vec3 AnalyticalWaterDarkness(float Traversal, vec3 Incident) { 165 | 166 | float X = Traversal; 167 | 168 | vec3 A = vec3(1.0,0.65,0.5); 169 | vec3 B = vec3(1.0,0.5,0.65); 170 | 171 | if(X<=1) { 172 | return 0.4 * ((B-2*A)/(X+1.)+(B-A)*log(X+1)); 173 | } 174 | else { 175 | return 0.4 * ((B*(X*X+X*LN2+LN2))/((X)+1.) - A*(1 + LN2)); 176 | } 177 | 178 | } 179 | 180 | #define PI 3.14159265359 181 | vec3 decode (vec2 enc) 182 | { 183 | vec2 fenc = enc*4-2; 184 | float f = dot(fenc,fenc); 185 | float g = sqrt(1-f/4); 186 | vec3 n; 187 | n.xy = fenc*g; 188 | n.z = 1-f/2; 189 | return normalize(n); 190 | } 191 | void main() { 192 | 193 | vec4 AlbedoSample = texture(Albedo, TexCoord); 194 | vec4 RawNormalSample = texture(Normal, TexCoord); 195 | float Roughness = RawNormalSample.a; 196 | vec3 ActualAlbedo = AlbedoSample.xyz; 197 | float Metalness = AlbedoSample.a; 198 | 199 | vec3 Diffuse = texture(FirstPassDiffuse, TexCoord).xyz; 200 | vec3 Specular = texture(IndirectSpecular, TexCoord).xyz + texture(FirstPassSpecular, TexCoord).xyz; 201 | 202 | vec3 Incident = -normalize(vec3(inverse(ProjectionMatrix * mat4(mat3(ViewMatrix))) * vec4(TexCoord * 2. - 1., 1., 1.))); 203 | 204 | vec3 SpecularColor = Fresnel(Incident,RawNormalSample.xyz, mix(vec3(0.04), ActualAlbedo, Metalness), Roughness); 205 | vec3 DiffuseColor = mix(ActualAlbedo, vec3(0.0), Metalness); 206 | 207 | 208 | float DepthSample = texture(Depth, TexCoord).x; 209 | float WaterDepth = texture(WaterDepth, TexCoord).x; 210 | 211 | vec3 WorldPosition = vec3(InverseView * CalculateViewSpacePosition(DepthSample)); 212 | 213 | vec3 WaterViewPosition = CalculateViewSpacePosition(WaterDepth).xyz; 214 | 215 | vec3 WaterWorldPosition = vec3(InverseView * vec4(WaterViewPosition,1.0)); 216 | 217 | RawNormalSample.xyz = WaterDepth > DepthSample ? RawNormalSample.xyz : texture(WaterNormal, TexCoord).xyz; 218 | 219 | vec2 Coord = SampleSphericalMap(-Incident); 220 | Coord.y = Coord.y * 2. - 1.; 221 | 222 | vec4 SkyTextureSample = SampleInterpolatied(Sky, vec3(1.0 - Coord,mod(Time*10.0, 119.))); ; 223 | 224 | if(abs(Coord.x*2.-1.) > 0.998) { 225 | 226 | SkyTextureSample = mix(SampleInterpolatied(Sky, vec3(0.999,1.0-Coord.y,mod(Time*10.0, 119.))),SampleInterpolatied(Sky, vec3(0.001,1.0-Coord.y,mod(Time*10.0, 119.))),0.5); 227 | 228 | 229 | } 230 | 231 | 232 | 233 | vec4 SkySample = Coord.y < 0.01 ? vec4(0.0) :SkyTextureSample; 234 | 235 | 236 | 237 | vec3 BackGround = mix(vec3(0.0,0.3,0.6), (2.0 * max(dot(LightDirection,SkySample.xyz),0.) + vec3(0.0,0.3,0.6)*1.25),SkySample.w); 238 | 239 | vec3 RelativeCameraPosition = CameraPosition - Incident * 0.15; 240 | 241 | float ActualRelativeHeight = 40.0 + SampleInterpolatied(WaterNormalMap, vec3(RelativeCameraPosition.xz * 0.05,mod(Time*10.0, 119.))).w * 2.1; 242 | 243 | 244 | if(length(RawNormalSample.xyz) < 0.5) { 245 | 246 | 247 | 248 | Lighting = BackGround; 249 | 250 | if(RelativeCameraPosition.y < ActualRelativeHeight) 251 | Lighting = vec3(0.0); 252 | 253 | } 254 | else { 255 | 256 | bool FragmentUnderWater = RelativeCameraPosition.y < ActualRelativeHeight; 257 | bool FragmentWaterPlane = WaterDepth < DepthSample; 258 | 259 | if(!FragmentWaterPlane) { 260 | Lighting = FragmentUnderWater ? Diffuse * AlbedoSample.xyz : Diffuse * DiffuseColor + Specular * SpecularColor; 261 | 262 | Lighting = mix(Lighting, BackGround, Fog(CameraPosition,WorldPosition)); 263 | 264 | } 265 | else { 266 | 267 | vec3 NormalSampleRefraction = normalize(RawNormalSample.xyz * vec3(1.0,0.125,1.0)); 268 | 269 | 270 | vec3 BackGroundLighting = ActualAlbedo.xyz * Diffuse; 271 | 272 | 273 | 274 | 275 | WaterDepth = LinearlizeDepth(WaterDepth); 276 | DepthSample = LinearlizeDepth(DepthSample); 277 | 278 | vec2 RefractedLightingCoord = ScreenSpaceTracing(WaterViewPosition, vec3(vec4(FragmentUnderWater ? -NormalSampleRefraction.xyz : NormalSampleRefraction.xyz,0.0) * InverseView)); 279 | 280 | RefractedLightingCoord = (abs(RefractedLightingCoord.x) < 1.0 && abs(RefractedLightingCoord.y) < 1.0) ? (RefractedLightingCoord * 0.5 + 0.5) : TexCoord; 281 | 282 | vec3 RefractedLightingRaw = texture(Albedo, RefractedLightingCoord).xyz * texture(FirstPassDiffuse, RefractedLightingCoord).xyz; 283 | vec3 RefractedLighting = RefractedLightingRaw; 284 | vec3 HitWorldPosition = vec3(InverseView * vec4(CalculateViewSpacePosition(texture(Depth, RefractedLightingCoord).x).xyz,1.0)); 285 | if(!FragmentUnderWater) 286 | RefractedLighting /= clamp(pow(max(abs(HitWorldPosition.y - WaterWorldPosition.y)-.333,0.0),2.0) * 5,1.0,10000.); 287 | 288 | 289 | 290 | RefractedLighting = mix(RefractedLighting * mix(vec3(0.0, 0.35, 0.5 ),vec3(0.0,0.5,0.35),clamp(abs(WaterWorldPosition.y-WorldPosition.y),0.0,2.0)*0.5) * 2.0, Specular, FresnelWater(Incident, RawNormalSample.xyz)); 291 | 292 | Lighting = mix(RefractedLightingRaw,RefractedLighting,clamp(abs(WaterWorldPosition.y-WorldPosition.y), 0.0, 1.0)); 293 | Lighting = mix(BackGroundLighting,Lighting,clamp(abs(WaterWorldPosition.y-WorldPosition.y), 0.0, .25)*4.); 294 | 295 | Lighting = mix(Lighting, BackGround, Fog(CameraPosition,WaterWorldPosition)); 296 | 297 | 298 | 299 | 300 | } 301 | 302 | if(FragmentUnderWater) { 303 | 304 | float WorldDistance = distance(FragmentWaterPlane ? WaterWorldPosition : WorldPosition, CameraPosition); 305 | 306 | vec3 LightingRaw = Lighting; 307 | 308 | //use an analytical solution of an integral describing the water darkness at a point 309 | 310 | float T = WorldDistance; 311 | 312 | vec3 WaterDarkness = 1.0- clamp((AnalyticalWaterDarkness(WorldDistance*2.0, -Incident)),vec3(0.0),vec3(1.)); 313 | 314 | Lighting *= WaterDarkness; 315 | 316 | } 317 | 318 | } 319 | 320 | 321 | Lighting = Uncharted2Tonemap(Lighting); 322 | Lighting = pow(Lighting, vec3(0.454545)); 323 | 324 | 325 | } -------------------------------------------------------------------------------- /Shaders/LightCombiner/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout (location = 0) in vec3 Vert; 3 | layout (location = 1) in vec2 Texc; 4 | out vec2 TexCoord; 5 | 6 | uniform sampler2DArray WaterNormalMap; 7 | uniform float Time; 8 | uniform vec3 CameraPosition; 9 | 10 | out float WaterHeightCamera; 11 | 12 | 13 | vec4 SampleInterpolatied(sampler2DArray Sampler,vec3 Coord) { 14 | 15 | float BaseTime = mod(Coord.z, 119.); 16 | 17 | int Coord1 = int(floor(BaseTime)); 18 | int Coord2 = int(ceil(BaseTime))%119; 19 | 20 | return mix(texture(Sampler, vec3(Coord.xy, Coord1)), texture(Sampler,vec3(Coord.xy, Coord2)), fract(BaseTime)); 21 | 22 | 23 | } 24 | 25 | void main(void) { 26 | TexCoord = Texc; 27 | 28 | WaterHeightCamera = 40.0 + SampleInterpolatied(WaterNormalMap, vec3(CameraPosition.xz * 0.05,mod(Time*10.0, 119.))).w * 2.1; 29 | 30 | 31 | gl_Position = vec4(Vert.xy,0.f,1.0); 32 | } -------------------------------------------------------------------------------- /Shaders/ShadowGaussian/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | //super hardcoded for performance reasons 4 | 5 | //"magic" constants explained: 6 | 7 | //-0.005859375 = -3/512 8 | //0.001953125 = 1/512 9 | //0.07894736842 = (1/4)/3.16666667 10 | //0.10526315789 = (1/2)/3.16666667 11 | //0.15789473684 = (1/2)/3.16666667 12 | //0.31578947368 = 1/3.16666667 13 | //3.16666667 = 2*(1/4) + 2*(1/3) + 2*(1/2) + 1, which is the entire "sum" of the blur, 14 | //and because we want the sum of the blur to be 1 we divide by this number 15 | 16 | in vec2 TexCoord; 17 | out float Color; 18 | 19 | uniform sampler2D Image; 20 | uniform bool Vertical; 21 | uniform float TexelSize; 22 | 23 | uniform int Size; 24 | 25 | 26 | void main() { 27 | vec2 TC = TexCoord - vec2(Vertical ? 0.0 : TexelSize*3., Vertical ? TexelSize*Size : 0.0); 28 | 29 | float Weight = 0.0; 30 | 31 | for(int i=-Size;i<=Size;i++) { 32 | float cweight = 1.0 / (abs(i)+1.0); 33 | Weight += cweight; 34 | Color += texture(Image, TC).x * cweight; TC += vec2(Vertical ? 0.0 : TexelSize, Vertical ? TexelSize : 0.0); 35 | } 36 | Color /= Weight; 37 | 38 | } -------------------------------------------------------------------------------- /Shaders/ShadowGaussian/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout (location = 0) in vec3 Vert; 3 | layout (location = 1) in vec2 Texc; 4 | out vec2 TexCoord; 5 | 6 | uniform vec2 Position; 7 | uniform vec2 Scale; 8 | 9 | void main(void) { 10 | TexCoord = Texc; 11 | gl_Position = vec4(Vert.xy,0.f,1.0); 12 | } -------------------------------------------------------------------------------- /Shaders/Voxelizer/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 420 2 | #extension GL_ARB_shader_image_size : enable 3 | 4 | 5 | in FragmentData { 6 | vec3 WorldPosition; 7 | vec3 Normal; 8 | }FS_IN; 9 | 10 | 11 | 12 | uniform mat4 ShadowCombined[3]; 13 | uniform sampler2D ShadowMaps[3]; 14 | uniform vec3 ShadowDirection; 15 | uniform vec3 SunColor; 16 | uniform vec3 CameraPosition; 17 | uniform vec3 CameraPositionPrevious; 18 | uniform sampler3D PreviousVolume; 19 | uniform int Resolution; 20 | 21 | layout(rgba8) uniform image3D Voxels; 22 | uniform float Size; 23 | 24 | bool InsideCube(vec3 p, float e) { return abs(p.x) < e && abs(p.y) < e && abs(p.z) < e; } 25 | 26 | 27 | float ShadowsESM(sampler2D ShadowMap, vec3 Coord) { 28 | 29 | //return (Coord.z > (texture(ShadowMap, Coord.xy).x+0.0003) ? 1. : 0.0); 30 | 31 | return clamp(exp(-30000.0*(Coord.z-(texture(ShadowMap, Coord.xy).x)-.00015)), 0.0,1.0); 32 | } 33 | 34 | 35 | float GetDirectionalShadows(vec3 WorldPosition, vec3 Normal) { 36 | vec3 ShadowNDC = vec3(0.); 37 | 38 | int Index = -1; 39 | 40 | for(int try = 0; try < 3; try++) { 41 | 42 | vec4 ShadowCoord = ShadowCombined[try] * vec4(WorldPosition, 1.0); 43 | 44 | ShadowNDC = ShadowCoord.xyz / ShadowCoord.w; 45 | 46 | 47 | 48 | 49 | if(abs(ShadowNDC.x) < 1.0 && abs(ShadowNDC.y) < 1.0) { 50 | Index = try; 51 | break; 52 | } 53 | 54 | } 55 | 56 | 57 | 58 | 59 | if(Index == -1) 60 | return 0.0; 61 | 62 | float ShadowMapSample = ShadowsESM((Index == 0 ? ShadowMaps[0] : Index == 1 ? ShadowMaps[1] : ShadowMaps[2]), ShadowNDC.xyz * 0.5 + 0.5) * 100.; 63 | 64 | return ShadowMapSample * max(dot(Normal, ShadowDirection),0.); 65 | 66 | } 67 | 68 | 69 | 70 | void main() { 71 | 72 | 73 | 74 | 75 | 76 | if(InsideCube(FS_IN.WorldPosition, Size/2)) { 77 | vec3 Voxel = (FS_IN.WorldPosition / (Size/2)) * 0.5 + 0.5; 78 | 79 | vec3 DiffuseLighting = GetDirectionalShadows(FS_IN.WorldPosition + CameraPosition, FS_IN.Normal) * SunColor; 80 | 81 | vec4 CurrentResult = vec4(pow(DiffuseLighting* SunColor* 0.12,vec3(0.4545454545)),1.0); 82 | 83 | //reproject to previous volume. This is to avoid massive aliasing with voxels when the camera moves. (although this doesnt entirely solve it still) 84 | //does result in some temporal lag. But this is quickly overshadowed by the temporal lag already caused 85 | //by the temporal filtering 86 | 87 | 88 | //do gamma correction here for performance sakes 89 | imageStore(Voxels, ivec3(Resolution * Voxel), CurrentResult); 90 | } 91 | 92 | } -------------------------------------------------------------------------------- /Shaders/Voxelizer/geom.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout(triangles) in; 4 | layout(triangle_strip, max_vertices = 3) out; 5 | 6 | in GeometryData { 7 | vec3 Normal; 8 | vec3 WorldPosition; 9 | }GS_IN[]; 10 | 11 | out FragmentData { 12 | out vec3 WorldPosition; 13 | out vec3 Normal; 14 | }GS_OUT; 15 | 16 | uniform float Size; 17 | 18 | void main(){ 19 | vec3 p1 = GS_IN[1].WorldPosition - GS_IN[0].WorldPosition; 20 | vec3 p2 = GS_IN[2].WorldPosition - GS_IN[0].WorldPosition; 21 | vec3 p = abs(cross(p1, p2)); 22 | for(int i = 0; i < 3; i++){ //the actual voxelisation 23 | GS_OUT.WorldPosition = GS_IN[i].WorldPosition; 24 | GS_OUT.Normal = GS_IN[i].Normal; 25 | 26 | if(p.z > p.x && p.z > p.y){ 27 | gl_Position = vec4(GS_OUT.WorldPosition.x, GS_OUT.WorldPosition.y, 0, 1) / vec4(Size/2,Size/2,1,1); 28 | } else if (p.x > p.y && p.x > p.z){ 29 | gl_Position = vec4(GS_OUT.WorldPosition.y, GS_OUT.WorldPosition.z, 0, 1) / vec4(Size/2,Size/2,1,1); 30 | } else { 31 | gl_Position = vec4(GS_OUT.WorldPosition.x, GS_OUT.WorldPosition.z, 0, 1) / vec4(Size/2,Size/2,1,1); 32 | } 33 | EmitVertex(); 34 | } 35 | EndPrimitive(); 36 | } -------------------------------------------------------------------------------- /Shaders/Voxelizer/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout(location=0) in vec4 Vertices; 4 | layout(location=1) in vec4 Normals; 5 | 6 | uniform mat4 IdentitiyMatrix; 7 | uniform mat4 ModelMatrix; 8 | uniform vec3 CameraPosition; 9 | 10 | out GeometryData { 11 | out vec3 Normal; 12 | out vec3 WorldPosition; 13 | }VS_OUT; 14 | 15 | void main() { 16 | 17 | 18 | VS_OUT.WorldPosition = (vec3(ModelMatrix * vec4(Vertices.xyz,1.0)) - CameraPosition); 19 | VS_OUT.Normal = Normals.xyz; 20 | gl_Position = IdentitiyMatrix * vec4(VS_OUT.WorldPosition,1.0); 21 | } -------------------------------------------------------------------------------- /Shaders/WaterDeferred/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | layout(location = 0) out vec3 OutNormal; 4 | 5 | in vec3 Position; 6 | in vec3 Normal; 7 | in vec2 TexCoord; 8 | 9 | 10 | uniform sampler2DArray NormalMap; 11 | uniform float Time; 12 | #define ITERATIONS_NORMAL 28 13 | 14 | 15 | vec4 SampleInterpolatied(sampler2DArray Sampler,vec3 Coord) { 16 | 17 | float BaseTime = mod(Coord.z, 119.); 18 | 19 | int Coord1 = int(floor(BaseTime)); 20 | int Coord2 = int(ceil(BaseTime))%119; 21 | 22 | return mix(texture(Sampler, vec3(Coord.xy, Coord1)), texture(Sampler,vec3(Coord.xy, Coord2)), fract(BaseTime)); 23 | 24 | 25 | } 26 | 27 | 28 | 29 | void main() { 30 | 31 | vec3 NormalSample = SampleInterpolatied(NormalMap, vec3(TexCoord,mod(Time*10.0, 119.))).xyz * vec3(2.0,1.0,2.0) - vec3(1.0,0.0,1.0); 32 | 33 | //vec3 NormalSample = normalize(normal(TexCoord, 0.01, 2.1)); 34 | //NormalSample.xz *= 0.75; 35 | OutNormal = normalize(mix(NormalSample, vec3(0.0,1.0,0.0),0.5)); 36 | } -------------------------------------------------------------------------------- /Shaders/WaterDeferred/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | 4 | 5 | layout(location=0) in vec3 Vertices; 6 | layout(location=1) in vec3 TexCoords; 7 | layout(location=2) in vec3 Normals; 8 | 9 | uniform mat4 IdentityMatrix; 10 | 11 | 12 | out vec3 Position; 13 | out vec3 Normal; 14 | out vec2 TexCoord; 15 | 16 | uniform vec3 CameraPosition; 17 | uniform sampler2DArray NormalMap; 18 | uniform float Time; 19 | #define ITERATIONS_NORMAL 24 20 | 21 | 22 | vec4 SampleInterpolatied(sampler2DArray Sampler,vec3 Coord) { 23 | 24 | float BaseTime = mod(Coord.z, 119.); 25 | 26 | int Coord1 = int(floor(BaseTime)); 27 | int Coord2 = int(ceil(BaseTime))%119; 28 | 29 | return mix(texture(Sampler, vec3(Coord.xy, Coord1)), texture(Sampler,vec3(Coord.xy, Coord2)), fract(BaseTime)); 30 | 31 | 32 | } 33 | 34 | void main(void) { 35 | 36 | Position = Vertices.xyz; 37 | TexCoord = ((Position.xz)+CameraPosition.xz) * 0.05; 38 | 39 | vec4 Height = SampleInterpolatied(NormalMap, vec3(TexCoord,mod(Time*10.0, 119.))); 40 | 41 | Normal = Height.xyz; 42 | 43 | 44 | gl_Position = IdentityMatrix * vec4(Position.xyz + vec3(0.0,40.0 + Height.w * 2.1,0.0),1.0); 45 | } -------------------------------------------------------------------------------- /Shadows.cpp: -------------------------------------------------------------------------------- 1 | #include "Shadows.h" 2 | #include "Core.h" 3 | #include 4 | 5 | namespace Open7Days { 6 | namespace Rendering { 7 | 8 | void Move(Vector3f & Pos, float Speed, float RotationX, float RotationY) { 9 | Pos.x -= (cos(RotationY*(PI / 180.)) * cos(RotationX*(PI / 180.)))*Speed; 10 | Pos.y += sin(RotationX*(PI / 180.))*Speed; 11 | Pos.z -= (sin(RotationY*(PI / 180.)) * cos(RotationX*(PI / 180.)))*Speed; 12 | } 13 | 14 | void ShadowMapper::Prepare(Camera Camera) { 15 | 16 | Orientation = Vector3f(0.); 17 | 18 | Move(Orientation, 1.0, Direction.x, Direction.y - 90.0); 19 | 20 | PingPongBuffer = FrameBufferObject(Vector2i(SHADOW_MAP_RES), GL_R32F, false); 21 | 22 | for (int i = 0; i < 3; i++) { 23 | Cascades[i] = FrameBufferObject(Vector2i(SHADOW_MAP_RES), GL_R32F , true); 24 | 25 | ProjectionMatrices[i] = Core::ShadowOrthoMatrix(Ranges[i], 100.f, 1000.); 26 | 27 | ViewMatrices[i] = Core::ViewMatrix(Camera.Position + Orientation, Vector3f(Direction.x, Direction.y, 0.)); 28 | } 29 | 30 | DeferredShadow = Shader("Shaders/DeferredShadow"); 31 | ShadowGaussian = Shader("Shaders/ShadowGaussian"); 32 | } 33 | 34 | int BlurSize[] = { 3,2,1 }; 35 | 36 | void ShadowMapper::UpdateShadowMapCascades(Window & Window, Camera & Camera, ChunkContainer & Chunks) { 37 | 38 | int ToUpdate = UpdateQueue[Window.GetFrameCount() % 7]; 39 | 40 | Orientation = Vector3f(0.); 41 | 42 | Move(Orientation, 1.0, Direction.x, Direction.y - 90.0); 43 | 44 | ViewMatrices[ToUpdate] = Core::ViewMatrix(Camera.Position + Orientation * 500.0f, Vector3f(Direction.x, Direction.y, 0.)); 45 | 46 | ShadowFrustums[ToUpdate].Update(ProjectionMatrices[ToUpdate] * ViewMatrices[ToUpdate]); 47 | //temporary 48 | 49 | DeferredShadow.Bind(); 50 | 51 | Cascades[ToUpdate].Bind(); 52 | 53 | 54 | Chunks.RenderChunks(ViewMatrices[ToUpdate], ProjectionMatrices[ToUpdate], DeferredShadow, -1, Vector2f(0.0), &ShadowFrustums[ToUpdate]); 55 | 56 | 57 | Cascades[ToUpdate].UnBind(Window); 58 | 59 | 60 | DeferredShadow.UnBind(); 61 | 62 | 63 | Cascades[ToUpdate].BindDepthImage(0); 64 | 65 | ShadowGaussian.Bind(); 66 | 67 | ShadowGaussian.SetUniform("TexelSize", 1.0f / SHADOW_MAP_RES); 68 | ShadowGaussian.SetUniform("Size", BlurSize[ToUpdate]); 69 | 70 | PingPongBuffer.Bind(); 71 | 72 | ShadowGaussian.SetUniform("Vertical", false); 73 | 74 | DrawPostProcessQuad(); 75 | 76 | PingPongBuffer.UnBind(Window); 77 | 78 | PingPongBuffer.BindImage(0); 79 | 80 | Cascades[ToUpdate].Bind(); 81 | 82 | ShadowGaussian.SetUniform("Vertical", true); 83 | 84 | DrawPostProcessQuad(); 85 | 86 | Cascades[ToUpdate].UnBind(Window); 87 | 88 | ShadowGaussian.UnBind(); 89 | 90 | 91 | 92 | } 93 | void ShadowMapper::BindAndSetUniforms(Shader & Shader, int StartingTexture) { 94 | 95 | Shader.SetUniform("ShadowDirection", glm::normalize(Orientation)); 96 | Shader.SetUniform("SunColor", Vector3f(0.988, 0.831, 0.251)); 97 | 98 | for (int i = 0; i < 3; i++) { 99 | 100 | Shader.SetUniform("ShadowCombined[" + std::to_string(i) + "]", ProjectionMatrices[i] * ViewMatrices[i]); 101 | Shader.SetUniform("ShadowMaps[" + std::to_string(i) + "]", StartingTexture+i); 102 | 103 | Cascades[i].BindImage(StartingTexture + i); 104 | 105 | } 106 | 107 | } 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Shadows.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Framebuffer.h" 4 | #include "Shader.h" 5 | #include "Camera.h" 6 | #include "Chunk.h" 7 | #include 8 | #include "Texture.h" 9 | 10 | //TODO: maybe at some point add settings for this. 11 | #define SHADOW_MAP_RES 1024 12 | 13 | namespace Open7Days { 14 | namespace Rendering { 15 | 16 | const unsigned char UpdateQueue[] = { 0,0,1,0,1,0,2 }; 17 | const float Ranges[] = { 10.0,50.0,150. }; 18 | 19 | struct ShadowMapper { 20 | FrameBufferObject Cascades[3], PingPongBuffer; 21 | Matrix4f ViewMatrices[3], ProjectionMatrices[3]; 22 | 23 | Frustum ShadowFrustums[3]; 24 | 25 | Vector2f Direction = Vector2f(0.0); 26 | Vector3f Orientation = Vector3f(0.0); 27 | 28 | Shader DeferredShadow, ShadowGaussian; 29 | 30 | void Prepare(Camera Camera); 31 | void UpdateShadowMapCascades(Window & Window, Camera & Camera, ChunkContainer & Chunks); 32 | void BindAndSetUniforms(Shader & Shader, int StartingTexture = 0); 33 | 34 | }; 35 | 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Texture.cpp: -------------------------------------------------------------------------------- 1 | #include "Texture.h" 2 | #include "Dependencies/DependenciesRendering.h" 3 | #include "Framebuffer.h" 4 | 5 | namespace Open7Days { 6 | namespace Rendering { 7 | 8 | TextureGL::TextureGL(unsigned int id, Vector2i Resolution) : 9 | ID(id), Resolution(Resolution) { 10 | 11 | } 12 | void TextureGL::Bind(unsigned int target) { 13 | glActiveTexture(GL_TEXTURE0 + target); 14 | glBindTexture(GL_TEXTURE_2D, ID); 15 | } 16 | 17 | TextureGL LoadTextureGL(const std::string & Path) { 18 | unsigned int id; 19 | sf::Image Image; 20 | 21 | if (Image.loadFromFile(Path)) { 22 | 23 | Image.flipVertically(); 24 | glGenTextures(1, &id); 25 | glBindTexture(GL_TEXTURE_2D, id); 26 | 27 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 28 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 29 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Image.getSize().x, Image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, Image.getPixelsPtr()); 30 | glBindTexture(GL_TEXTURE_2D, 0); 31 | return TextureGL(id, glm::ivec2(Image.getSize().x, Image.getSize().y)); 32 | } 33 | else { 34 | return TextureGL(); 35 | } 36 | } 37 | 38 | TextureCubeMap LoadHDRI(const char* name, bool linear, bool mipmaps, Shader& EquirectangularToCubeMapShader) { 39 | 40 | 41 | TextureGL RawHDRIMap = LoadTextureGL(name); 42 | //get a somewhat accurate resolution to use for cubemap: 43 | unsigned int PixelCount = RawHDRIMap.Resolution.x * RawHDRIMap.Resolution.y; 44 | 45 | unsigned int Resolution = sqrt(static_cast(PixelCount) / 6.); //obtain a resolution 46 | unsigned int ResolutionPower2 = pow(2, round(log2(Resolution) + .25)); //force it to be a power of 2 47 | 48 | unsigned int TemporaryFrameBuffer, TemporaryRenderBuffer, FinalImage; 49 | 50 | glGenFramebuffers(1, &TemporaryFrameBuffer); 51 | glGenRenderbuffers(1, &TemporaryRenderBuffer); 52 | 53 | glBindFramebuffer(GL_FRAMEBUFFER, TemporaryFrameBuffer); 54 | glBindRenderbuffer(GL_RENDERBUFFER, TemporaryRenderBuffer); 55 | glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, ResolutionPower2, ResolutionPower2); 56 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, TemporaryRenderBuffer); 57 | 58 | glGenTextures(1, &FinalImage); 59 | glBindTexture(GL_TEXTURE_CUBE_MAP, FinalImage); 60 | for (unsigned int i = 0; i < 6; ++i) 61 | { 62 | // note that we store each face with 16 bit floating point values 63 | glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 64 | ResolutionPower2, ResolutionPower2, 0, GL_RGB, GL_FLOAT, nullptr); 65 | } 66 | glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 67 | glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 68 | glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 69 | glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST); 70 | glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST); 71 | 72 | glViewport(0, 0, ResolutionPower2, ResolutionPower2); // don't forget to configure the viewport to the capture dimensions. 73 | glBindFramebuffer(GL_FRAMEBUFFER, TemporaryFrameBuffer); 74 | 75 | EquirectangularToCubeMapShader.Bind(); 76 | 77 | glUniformMatrix4fv(glGetUniformLocation(EquirectangularToCubeMapShader.ShaderID, "ProjectionMatrix"), 1, false, glm::value_ptr(CubeProjection)); 78 | glUniform1i(glGetUniformLocation(EquirectangularToCubeMapShader.ShaderID, "EquirectangularMap"), 0); 79 | RawHDRIMap.Bind(0); 80 | 81 | for (unsigned int i = 0; i < 6; ++i) 82 | { 83 | glUniformMatrix4fv(glGetUniformLocation(EquirectangularToCubeMapShader.ShaderID, "ViewMatrix"), 1, false, glm::value_ptr(CubeViews[i])); 84 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 85 | GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, FinalImage, 0); 86 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 87 | 88 | DrawPostProcessCube(); // renders a 1x1 cube 89 | } 90 | 91 | EquirectangularToCubeMapShader.UnBind(); 92 | 93 | return TextureCubeMap(FinalImage, Vector2i(ResolutionPower2)); 94 | } 95 | 96 | 97 | TextureCubeMap::TextureCubeMap(unsigned int id, glm::ivec2 res) : 98 | ID(id), Resolution(res) { 99 | } 100 | 101 | void TextureCubeMap::Bind(unsigned int target) { 102 | glActiveTexture(GL_TEXTURE0 + target); 103 | glBindTexture(GL_TEXTURE_CUBE_MAP, ID); 104 | } 105 | 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Texture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Dependencies/DependenciesMath.h" 4 | #include 5 | #include "Shader.h" 6 | 7 | const Matrix4f CubeProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 1000.0f); 8 | const Matrix4f CubeViews[] = 9 | { 10 | glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)), 11 | glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)), 12 | glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)), 13 | glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)), 14 | glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)), 15 | glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)) 16 | }; 17 | 18 | 19 | namespace Open7Days { 20 | namespace Rendering { 21 | struct TextureGL { 22 | unsigned int ID; 23 | Vector2i Resolution; 24 | TextureGL(unsigned int id = 4294967295, Vector2i Resolution = Vector2i(0)); 25 | void Bind(unsigned int target); 26 | }; 27 | 28 | struct TextureCubeMap { 29 | unsigned int ID; 30 | glm::ivec2 Resolution; 31 | TextureCubeMap(unsigned int id = 4294967295, glm::ivec2 res = glm::ivec2(0)); 32 | void Bind(unsigned int target); 33 | }; 34 | 35 | TextureGL LoadTextureGL(const std::string & Path); 36 | TextureCubeMap LoadHDRI(const char* name, bool linear, bool mipmaps, Shader& EquirectangularToCubeMapShader); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Voxelizer.cpp: -------------------------------------------------------------------------------- 1 | #include "Voxelizer.h" 2 | #include 3 | 4 | namespace Open7Days { 5 | namespace Rendering { 6 | void Voxelizer::PrepareVoxelizer() { 7 | 8 | for(int i=0;i<6;i++) 9 | Texture[i] = VoxelTexture(VOXEL_VOLUME_RESOLUTION, 1); 10 | 11 | VoxelizingShader = Shader("Shaders/Voxelizer", true); 12 | 13 | 14 | VoxelizingShader.Bind(); 15 | 16 | VoxelizingShader.SetUniform("Voxels", 0); 17 | VoxelizingShader.SetUniform("PreviousVolume", 1); 18 | 19 | VoxelizingShader.UnBind(); 20 | 21 | } 22 | void Voxelizer::VoxelizeScene(Camera& Camera, Window& Window, ShadowMapper &Shadows, ChunkContainer& Chunks) { 23 | 24 | int ToUpdate = UpdateQueue[Window.GetFrameCount() % 7]; 25 | int ToUpdateActual = ToUpdate * 2 + ActiveTexture[ToUpdate]; 26 | int PreviousActual = ToUpdate * 2 + (!ActiveTexture[ToUpdate]); 27 | 28 | Texture[ToUpdateActual].Clear(Vector4u(0.)); 29 | 30 | glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 31 | glDisable(GL_CULL_FACE); 32 | glDisable(GL_DEPTH_TEST); 33 | glDisable(GL_BLEND); 34 | 35 | VoxelizingShader.Bind(); 36 | 37 | 38 | 39 | glViewport(0, 0, VOXEL_VOLUME_RESOLUTION, VOXEL_VOLUME_RESOLUTION); 40 | 41 | 42 | 43 | glActiveTexture(GL_TEXTURE1); 44 | glBindTexture(GL_TEXTURE_3D, Texture[PreviousActual].ID); 45 | 46 | glActiveTexture(GL_TEXTURE0); 47 | glBindTexture(GL_TEXTURE_3D, Texture[ToUpdateActual].ID); 48 | glBindImageTexture(0, Texture[ToUpdateActual].ID, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA8); 49 | 50 | 51 | 52 | VoxelizingShader.SetUniform("CameraPosition", Camera.Position); 53 | VoxelizingShader.SetUniform("CameraPositionPrevious", CameraPositions[ToUpdate]); 54 | 55 | VoxelizingShader.SetUniform("Size", VoxelVolumeSizes[ToUpdate]); 56 | VoxelizingShader.SetUniform("Resolution", VOXEL_VOLUME_RESOLUTION); 57 | 58 | Shadows.BindAndSetUniforms(VoxelizingShader, 2); 59 | 60 | Chunks.RenderChunks(Camera.View, Camera.Project, VoxelizingShader, 4, Vector2f(Camera.Position.x, Camera.Position.z)); 61 | 62 | 63 | VoxelizingShader.UnBind(); 64 | 65 | glEnable(GL_DEPTH_TEST); 66 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 67 | // glEnable(GL_CULL_FACE); 68 | 69 | CameraPositions[ToUpdate] = Camera.Position; 70 | 71 | ActiveTexture[ToUpdate] = !ActiveTexture[ToUpdate]; 72 | 73 | 74 | } 75 | void Voxelizer::SetUniforms(Shader& Shader, int StartingTexture) { 76 | 77 | for (int i = 0; i < 3; i++) { 78 | 79 | Shader.SetUniform("Size[" + std::to_string(i) + "]", VoxelVolumeSizes[i]); 80 | Shader.SetUniform("CameraPositionLight[" + std::to_string(i) + "]", CameraPositions[i]); 81 | Shader.SetUniform("Voxels[" + std::to_string(i) + "]", StartingTexture + i); 82 | 83 | glActiveTexture(GL_TEXTURE0 + StartingTexture + i); 84 | glBindTexture(GL_TEXTURE_3D, Texture[i*2+ActiveTexture[i]].ID); 85 | 86 | } 87 | 88 | } 89 | void Voxelizer::ReloadVoxelizer() { 90 | VoxelizingShader.Reload("Shaders/Voxelizer", true); 91 | 92 | 93 | VoxelizingShader.Bind(); 94 | 95 | VoxelizingShader.SetUniform("Voxels", 0); 96 | VoxelizingShader.SetUniform("PreviousVolume", 1); 97 | 98 | VoxelizingShader.UnBind(); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Voxelizer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Shadows.h" 4 | 5 | //todo: maybe a setting? :S 6 | #define VOXEL_VOLUME_RESOLUTION 64 7 | 8 | namespace Open7Days { 9 | namespace Rendering { 10 | struct VoxelTexture { 11 | unsigned int ID; 12 | unsigned int Resolution; 13 | std::vector Data; 14 | inline VoxelTexture() : 15 | ID(4294967295), 16 | Resolution(4294967295), 17 | Data(std::vector()) { 18 | } 19 | 20 | 21 | 22 | inline VoxelTexture(unsigned int resolution, unsigned int maxMipMap = 1) { 23 | Resolution = resolution; 24 | 25 | glGenTextures(1, &ID); 26 | glBindTexture(GL_TEXTURE_3D, ID); 27 | 28 | glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); 29 | glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); 30 | glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); 31 | 32 | glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 33 | glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 34 | 35 | const int levels = maxMipMap; 36 | glTexStorage3D(GL_TEXTURE_3D, levels, GL_RGBA8, Resolution, Resolution, Resolution); 37 | glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, Resolution, Resolution, Resolution, 0, GL_RGBA, GL_FLOAT, 0); 38 | glBindTexture(GL_TEXTURE_3D, 0); 39 | } 40 | 41 | inline void Clear(Vector4u) { 42 | // unsigned char CCF[] = { ClearColor.r,ClearColor.g,ClearColor.b,ClearColor.a }; 43 | glBindTexture(GL_TEXTURE_3D, ID); 44 | glClearTexImage(ID, 0, GL_RGBA, GL_FLOAT, 0); 45 | glBindTexture(GL_TEXTURE_3D, 0); 46 | } 47 | 48 | }; 49 | 50 | const float VoxelVolumeSizes[] = { 32.0,64.0,128.0 }; 51 | 52 | struct Voxelizer { 53 | 54 | VoxelTexture Texture[6]; 55 | int ActiveTexture[3] = { 0,0,0 }; 56 | 57 | Vector3f CameraPositions[3] = { Vector3f(-100000000.0),Vector3f(-100000000.0),Vector3f(-100000000.0) }; 58 | Shader VoxelizingShader; 59 | 60 | void PrepareVoxelizer(); 61 | void VoxelizeScene(Camera& Camera, Window & Window, ShadowMapper &Shadows, ChunkContainer& Chunks); 62 | void SetUniforms(Shader &Shader, int StartingTexture = 0); 63 | void ReloadVoxelizer(); 64 | 65 | }; 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /WaterRenderer.cpp: -------------------------------------------------------------------------------- 1 | #include "WaterRenderer.h" 2 | #include 3 | 4 | namespace Open7Days { 5 | namespace Rendering { 6 | void WaterRenderer::PrepareWaterRenderer(Window& Window) { 7 | WaterDeferred = Shader("Shaders/WaterDeferred"); 8 | WaterBuffer = FrameBufferObject(Window.GetResolution(), GL_RGB16F); 9 | WaterMesh = Model("Models/WaterPlane.obj"); 10 | 11 | glGenTextures(1, &WaterNormalTexture); 12 | 13 | glBindTexture(GL_TEXTURE_2D_ARRAY, WaterNormalTexture); 14 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); 15 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); 16 | glTexParameteri(GL_TEXTURE_2D_ARRAY, 17 | GL_TEXTURE_MIN_FILTER, 18 | GL_LINEAR_MIPMAP_LINEAR); 19 | glTexParameteri(GL_TEXTURE_2D_ARRAY, 20 | GL_TEXTURE_MAG_FILTER, 21 | GL_LINEAR); 22 | glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1024, 1024, 120, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 23 | 24 | for (int i = 0; i < 120; i++) { 25 | 26 | std::string Path = "Textures/Water/"; 27 | 28 | if (i < 9) 29 | Path += "000" + std::to_string(i + 1); 30 | else if (i < 99) 31 | Path += "00" + std::to_string(i + 1); 32 | else 33 | Path += "0" + std::to_string(i + 1); 34 | 35 | Path += ".png"; 36 | 37 | std::cout << Path << '\n'; 38 | 39 | sf::Image RawImage; 40 | 41 | RawImage.loadFromFile(Path); 42 | 43 | glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 44 | 0, 45 | 0, 0, i, 46 | 1024, 1024, 1, 47 | GL_RGBA, 48 | GL_UNSIGNED_BYTE, 49 | RawImage.getPixelsPtr()); 50 | 51 | } 52 | 53 | glGenerateMipmap(GL_TEXTURE_2D_ARRAY); 54 | 55 | glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 56 | 57 | 58 | glGenTextures(1, &SkyTexture); 59 | 60 | glBindTexture(GL_TEXTURE_2D_ARRAY, SkyTexture); 61 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); 62 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); 63 | glTexParameteri(GL_TEXTURE_2D_ARRAY, 64 | GL_TEXTURE_MIN_FILTER, 65 | GL_LINEAR_MIPMAP_LINEAR); 66 | glTexParameteri(GL_TEXTURE_2D_ARRAY, 67 | GL_TEXTURE_MAG_FILTER, 68 | GL_LINEAR); 69 | glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1024, 512, 120, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 70 | 71 | for (int i = 0; i < 120; i++) { 72 | 73 | std::string Path = "Textures/Clouds/"; 74 | 75 | if (i < 9) 76 | Path += "000" + std::to_string(i + 1); 77 | else if (i < 99) 78 | Path += "00" + std::to_string(i + 1); 79 | else 80 | Path += "0" + std::to_string(i + 1); 81 | 82 | Path += ".png"; 83 | 84 | std::cout << Path << '\n'; 85 | 86 | sf::Image RawImage; 87 | 88 | RawImage.loadFromFile(Path); 89 | 90 | glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 91 | 0, 92 | 0, 0, i, 93 | 1024, 512, 1, 94 | GL_RGBA, 95 | GL_UNSIGNED_BYTE, 96 | RawImage.getPixelsPtr()); 97 | 98 | } 99 | 100 | glGenerateMipmap(GL_TEXTURE_2D_ARRAY); 101 | 102 | glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 103 | 104 | 105 | } 106 | void WaterRenderer::ReloadWaterRenderer() { 107 | WaterDeferred.Reload("Shaders/WaterDeferred"); 108 | } 109 | void WaterRenderer::RenderWater(Camera& Camera, Window& Window) { 110 | 111 | WaterBuffer.Bind(); 112 | 113 | WaterDeferred.Bind(); 114 | 115 | Matrix4f View = Core::ViewMatrix(Vector3f(0.0, Camera.Position.y, 0.0), Camera.Rotation); 116 | 117 | 118 | 119 | WaterDeferred.SetUniform("IdentityMatrix", Camera.Project * View); 120 | WaterDeferred.SetUniform("Time", Window.GetTimeOpened()); 121 | WaterDeferred.SetUniform("CameraPosition", Camera.Position); 122 | 123 | glActiveTexture(GL_TEXTURE0); 124 | glBindTexture(GL_TEXTURE_2D_ARRAY, WaterNormalTexture); 125 | 126 | WaterMesh.Draw(); 127 | 128 | WaterDeferred.UnBind(); 129 | 130 | WaterBuffer.UnBind(Window); 131 | 132 | } 133 | } 134 | } -------------------------------------------------------------------------------- /WaterRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Framebuffer.h" 4 | #include "Shader.h" 5 | #include "Camera.h" 6 | #include "Mesh.h" 7 | 8 | namespace Open7Days { 9 | namespace Rendering { 10 | struct WaterRenderer { 11 | unsigned int WaterNormalTexture, SkyTexture; 12 | Shader WaterDeferred; 13 | FrameBufferObject WaterBuffer; 14 | Model WaterMesh; 15 | 16 | void PrepareWaterRenderer(Window & Window); 17 | void ReloadWaterRenderer(); 18 | void RenderWater(Camera & Camera, Window & Window); 19 | 20 | 21 | }; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Window.cpp: -------------------------------------------------------------------------------- 1 | #include "Window.h" 2 | #include 3 | #include 4 | 5 | void APIENTRY MessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void*) 6 | { 7 | std::string msg(message, length); 8 | std::ostream &ostr = (type == GL_DEBUG_TYPE_ERROR ? std::cerr : std::cout); 9 | ostr << "gl"; 10 | switch(severity) 11 | { 12 | case GL_DEBUG_SEVERITY_HIGH: 13 | ostr << "ERROR"; 14 | break; 15 | case GL_DEBUG_SEVERITY_MEDIUM: 16 | ostr << "Warning"; 17 | break; 18 | case GL_DEBUG_SEVERITY_LOW: 19 | ostr << "Alert"; 20 | break; 21 | case GL_DEBUG_SEVERITY_NOTIFICATION: 22 | ostr << "Notify"; 23 | break; 24 | default: 25 | ostr << "Unknown"; 26 | break; 27 | } 28 | ostr << " (" << id << "): "; 29 | switch(source) 30 | { 31 | case GL_DEBUG_SOURCE_API: 32 | ostr << "API"; 33 | break; 34 | case GL_DEBUG_SOURCE_WINDOW_SYSTEM: 35 | ostr << "Window system"; 36 | break; 37 | case GL_DEBUG_SOURCE_SHADER_COMPILER: 38 | ostr << "Shader compiler"; 39 | break; 40 | case GL_DEBUG_SOURCE_THIRD_PARTY: 41 | ostr << "Third party"; 42 | break; 43 | case GL_DEBUG_SOURCE_APPLICATION: 44 | ostr << "Application"; 45 | break; 46 | case GL_DEBUG_SOURCE_OTHER: 47 | ostr << "Unknown"; 48 | break; 49 | default: 50 | ostr << "???"; 51 | break; 52 | } 53 | ostr << " reported "; 54 | switch(type) 55 | { 56 | case GL_DEBUG_TYPE_ERROR: 57 | ostr << "error"; 58 | break; 59 | case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: 60 | ostr << "deprecated behaviour"; 61 | break; 62 | case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: 63 | ostr << "undefined behaviour"; 64 | break; 65 | case GL_DEBUG_TYPE_PORTABILITY: 66 | ostr << "portability issue"; 67 | break; 68 | case GL_DEBUG_TYPE_PERFORMANCE: 69 | ostr << "performance issue"; 70 | break; 71 | case GL_DEBUG_TYPE_MARKER: 72 | ostr << "annotation"; 73 | break; 74 | case GL_DEBUG_TYPE_PUSH_GROUP: 75 | ostr << "debug group push"; 76 | break; 77 | case GL_DEBUG_TYPE_POP_GROUP: 78 | ostr << "debug group pop"; 79 | break; 80 | case GL_DEBUG_TYPE_OTHER: 81 | default: 82 | ostr << "unknown"; 83 | break; 84 | } 85 | ostr << ": " << msg << std::endl; 86 | } 87 | 88 | void Window::SetResolution(Vector2i Resolution) { 89 | this->Resolution = Resolution; 90 | } 91 | 92 | Vector2i Window::GetResolution() { 93 | return Resolution; 94 | } 95 | 96 | void Window::SetFullscreen(bool Fullscreen) { 97 | this->Fullscreen = Fullscreen; 98 | } 99 | 100 | bool Window::GetFullscreen() { 101 | return Fullscreen; 102 | } 103 | 104 | void Window::SetTitle(const char * Title) { 105 | this->Title = Title; 106 | } 107 | 108 | const char * Window::GetTitle() { 109 | return Title; 110 | } 111 | 112 | float Window::GetFrameTime() { 113 | return FrameTime; 114 | } 115 | 116 | void Window::SetFrameTime(float _FrameTime) { 117 | FrameTime = _FrameTime; 118 | } 119 | 120 | void Window::SetTimeOpened(float _TimeOpened) { 121 | TimeOpened = _TimeOpened; 122 | } 123 | 124 | float Window::GetTimeOpened() { 125 | return TimeOpened; 126 | } 127 | 128 | void Window::SetFrameCount(int _FrameCount) { 129 | FrameCount = _FrameCount; 130 | } 131 | 132 | int Window::GetFrameCount() { 133 | return FrameCount; 134 | } 135 | 136 | void Window::CursorVisible(bool Visible) { 137 | RawWindow->setMouseCursorVisible(Visible); 138 | } 139 | 140 | sf::RenderWindow * Window::GetRawWindow() { 141 | return RawWindow; 142 | } 143 | 144 | Window::Window(Vector2i Resolution, bool Fullscreen) { 145 | 146 | this->Resolution = Resolution; 147 | this->Fullscreen = Fullscreen; 148 | this->FrameCount = 0; 149 | 150 | sf::ContextSettings settings; 151 | settings.depthBits = 8; 152 | settings.stencilBits = 8; 153 | settings.antialiasingLevel = 0; 154 | settings.majorVersion = 4; 155 | settings.minorVersion = 3; 156 | #ifndef NDEBUG 157 | settings.attributeFlags |= sf::ContextSettings::Debug; 158 | #endif//NDEBUG 159 | 160 | RawWindow = new sf::RenderWindow(sf::VideoMode(Resolution.x, Resolution.y), "Open7Days", Fullscreen ? sf::Style::Fullscreen : sf::Style::Resize, settings); 161 | 162 | //LOAD ICON 163 | 164 | sf::Image Icon; 165 | Icon.loadFromFile("Textures/Icon.png"); 166 | 167 | RawWindow->setIcon(256, 256, Icon.getPixelsPtr()); 168 | 169 | gladLoadGL(); //prepare glad (needs to be AFTER window creation) 170 | #ifndef NDEBUG 171 | glEnable(GL_DEBUG_OUTPUT); 172 | glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); 173 | #endif//NDEBUG 174 | glDebugMessageCallback(MessageCallback, NULL); 175 | } 176 | 177 | Window::~Window() { 178 | //RawWindow->close(); 179 | //delete RawWindow; 180 | } 181 | -------------------------------------------------------------------------------- /Window.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Dependencies/DependenciesRendering.h" 4 | #include "Dependencies/DependenciesMath.h" 5 | 6 | 7 | class Window { 8 | Vector2i Resolution; 9 | bool Fullscreen; 10 | sf::RenderWindow * RawWindow; 11 | const char * Title; 12 | float FrameTime; 13 | float TimeOpened; 14 | int FrameCount; 15 | public: 16 | void SetResolution(Vector2i Resolution); 17 | Vector2i GetResolution(); 18 | 19 | void SetFullscreen(bool Fullscreen); 20 | bool GetFullscreen(); 21 | 22 | void SetTitle(const char * Title); 23 | const char * GetTitle(); 24 | 25 | void SetFrameTime(float FrameTime); 26 | float GetFrameTime(); 27 | 28 | void SetTimeOpened(float TimeOpened); 29 | float GetTimeOpened(); 30 | 31 | void SetFrameCount(int FrameCount); 32 | int GetFrameCount(); 33 | 34 | void CursorVisible(bool Visible); 35 | 36 | sf::RenderWindow * GetRawWindow(); 37 | 38 | 39 | inline Window() : Resolution(0), Fullscreen(false), RawWindow(nullptr), Title("Open7Days "), FrameCount(0) {} 40 | Window(Vector2i Resolution, bool Fullscreen); 41 | ~Window(); 42 | }; 43 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "Pipeline.h" 2 | 3 | int main() { 4 | Window Screen = Window(Vector2i(1920, 1080), true); 5 | Open7Days::Camera Camera = Open7Days::Camera(90.0, 0.1, 1000., Vector3f(16.,128.,16.), Vector3f(0.), Screen); 6 | Open7Days::Pipeline Pipeline; 7 | Pipeline.Prepare(Screen, Camera); 8 | Pipeline.Run(Screen, Camera); 9 | } 10 | -------------------------------------------------------------------------------- /noise.h: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------------------- 2 | // 3 | // siv::PerlinNoise 4 | // Perlin noise library for modern C++ 5 | // 6 | // Copyright (C) 2013-2018 Ryo Suzuki 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files(the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions : 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | // 26 | //---------------------------------------------------------------------------------------- 27 | 28 | # pragma once 29 | # include 30 | # include 31 | # include 32 | # include 33 | 34 | namespace siv 35 | { 36 | class PerlinNoise 37 | { 38 | private: 39 | 40 | std::uint8_t p[512]; 41 | 42 | static double Fade(double t) noexcept 43 | { 44 | return t * t * t * (t * (t * 6 - 15) + 10); 45 | } 46 | 47 | static double Lerp(double t, double a, double b) noexcept 48 | { 49 | return a + t * (b - a); 50 | } 51 | 52 | static double Grad(std::uint8_t hash, double x, double y, double z) noexcept 53 | { 54 | const std::uint8_t h = hash & 15; 55 | const double u = h < 8 ? x : y; 56 | const double v = h < 4 ? y : h == 12 || h == 14 ? x : z; 57 | return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); 58 | } 59 | 60 | public: 61 | 62 | explicit PerlinNoise(std::uint32_t seed = std::default_random_engine::default_seed) 63 | { 64 | reseed(seed); 65 | } 66 | 67 | template 68 | explicit PerlinNoise(URNG& urng) 69 | { 70 | reseed(urng); 71 | } 72 | 73 | void reseed(std::uint32_t seed) 74 | { 75 | for (size_t i = 0; i < 256; ++i) 76 | { 77 | p[i] = static_cast(i); 78 | } 79 | 80 | std::shuffle(std::begin(p), std::begin(p) + 256, std::default_random_engine(seed)); 81 | 82 | for (size_t i = 0; i < 256; ++i) 83 | { 84 | p[256 + i] = p[i]; 85 | } 86 | } 87 | 88 | template 89 | void reseed(URNG& urng) 90 | { 91 | for (size_t i = 0; i < 256; ++i) 92 | { 93 | p[i] = static_cast(i); 94 | } 95 | 96 | std::shuffle(std::begin(p), std::begin(p) + 256, urng); 97 | 98 | for (size_t i = 0; i < 256; ++i) 99 | { 100 | p[256 + i] = p[i]; 101 | } 102 | } 103 | 104 | double noise(double x) const 105 | { 106 | return noise(x, 0.0, 0.0); 107 | } 108 | 109 | double noise(double x, double y) const 110 | { 111 | return noise(x, y, 0.0); 112 | } 113 | 114 | double noise(double x, double y, double z) const 115 | { 116 | const std::int32_t X = static_cast(std::floor(x)) & 255; 117 | const std::int32_t Y = static_cast(std::floor(y)) & 255; 118 | const std::int32_t Z = static_cast(std::floor(z)) & 255; 119 | 120 | x -= std::floor(x); 121 | y -= std::floor(y); 122 | z -= std::floor(z); 123 | 124 | const double u = Fade(x); 125 | const double v = Fade(y); 126 | const double w = Fade(z); 127 | 128 | const std::int32_t A = p[X] + Y, AA = p[A] + Z, AB = p[A + 1] + Z; 129 | const std::int32_t B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z; 130 | 131 | return Lerp(w, Lerp(v, Lerp(u, Grad(p[AA], x, y, z), 132 | Grad(p[BA], x - 1, y, z)), 133 | Lerp(u, Grad(p[AB], x, y - 1, z), 134 | Grad(p[BB], x - 1, y - 1, z))), 135 | Lerp(v, Lerp(u, Grad(p[AA + 1], x, y, z - 1), 136 | Grad(p[BA + 1], x - 1, y, z - 1)), 137 | Lerp(u, Grad(p[AB + 1], x, y - 1, z - 1), 138 | Grad(p[BB + 1], x - 1, y - 1, z - 1)))); 139 | } 140 | 141 | double octaveNoise(double x, std::int32_t octaves) const 142 | { 143 | double result = 0.0; 144 | double amp = 1.0; 145 | 146 | for (std::int32_t i = 0; i < octaves; ++i) 147 | { 148 | result += noise(x) * amp; 149 | x *= 2.0; 150 | amp *= 0.5; 151 | } 152 | 153 | return result; 154 | } 155 | 156 | double octaveNoise(double x, double y, std::int32_t octaves) const 157 | { 158 | double result = 0.0; 159 | double amp = 1.0; 160 | 161 | for (std::int32_t i = 0; i < octaves; ++i) 162 | { 163 | result += noise(x, y) * amp; 164 | x *= 2.0; 165 | y *= 2.0; 166 | amp *= 0.5; 167 | } 168 | 169 | return result; 170 | } 171 | 172 | double octaveNoise(double x, double y, double z, std::int32_t octaves) const 173 | { 174 | double result = 0.0; 175 | double amp = 1.0; 176 | 177 | for (std::int32_t i = 0; i < octaves; ++i) 178 | { 179 | result += noise(x, y, z) * amp; 180 | x *= 2.0; 181 | y *= 2.0; 182 | z *= 2.0; 183 | amp *= 0.5; 184 | } 185 | 186 | return result; 187 | } 188 | 189 | double noise0_1(double x) const 190 | { 191 | return noise(x) * 0.5 + 0.5; 192 | } 193 | 194 | double noise0_1(double x, double y) const 195 | { 196 | return noise(x, y) * 0.5 + 0.5; 197 | } 198 | 199 | double noise0_1(double x, double y, double z) const 200 | { 201 | return noise(x, y, z) * 0.5 + 0.5; 202 | } 203 | 204 | double octaveNoise0_1(double x, std::int32_t octaves) const 205 | { 206 | return octaveNoise(x, octaves) * 0.5 + 0.5; 207 | } 208 | 209 | double octaveNoise0_1(double x, double y, std::int32_t octaves) const 210 | { 211 | return octaveNoise(x, y, octaves) * 0.5 + 0.5; 212 | } 213 | 214 | double octaveNoise0_1(double x, double y, double z, std::int32_t octaves) const 215 | { 216 | return octaveNoise(x, y, z, octaves) * 0.5 + 0.5; 217 | } 218 | }; 219 | } --------------------------------------------------------------------------------