From b7b65d71195c0c185a99342c833d02285b7d91f7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 22 Oct 2013 12:54:05 +0200 Subject: [PATCH] Added Deferred Shading Former-commit-id: 926022d6306144e2f87cd293291928bda44c7a87 --- .../Nazara/Graphics/DeferredRenderQueue.hpp | 89 ++ .../Graphics/DeferredRenderTechnique.hpp | 85 ++ src/Nazara/Graphics/DeferredRenderQueue.cpp | 334 ++++ .../Graphics/DeferredRenderTechnique.cpp | 1339 +++++++++++++++++ src/Nazara/Graphics/Graphics.cpp | 4 + .../DeferredShading/Shaders/Blit.frag | 12 + .../DeferredShading/Shaders/Blit.frag.h | 1 + .../DeferredShading/Shaders/BloomBright.frag | 24 + .../Shaders/BloomBright.frag.h | 1 + .../DeferredShading/Shaders/BloomFinal.frag | 17 + .../DeferredShading/Shaders/BloomFinal.frag.h | 1 + .../DeferredShading/Shaders/ClearGBuffer.frag | 13 + .../Shaders/ClearGBuffer.frag.h | 1 + .../Shaders/DirectionalLight.frag | 81 + .../Shaders/DirectionalLight.frag.h | 1 + .../DeferredShading/Shaders/FXAA.frag | 47 + .../DeferredShading/Shaders/FXAA.frag.h | 1 + .../DeferredShading/Shaders/GaussianBlur.frag | 25 + .../Shaders/GaussianBlur.frag.h | 1 + .../DeferredShading/Shaders/PointLight.frag | 84 ++ .../DeferredShading/Shaders/PointLight.frag.h | 1 + .../DeferredShading/Shaders/SSAO.frag | 82 + .../DeferredShading/Shaders/SSAO.frag.h | 1 + .../DeferredShading/Shaders/SSAOFinal.frag | 17 + .../DeferredShading/Shaders/SSAOFinal.frag.h | 1 + .../DeferredShading/Shaders/SpotLight.frag | 90 ++ .../DeferredShading/Shaders/SpotLight.frag.h | 1 + .../DeferredShading/Textures/ssaoNoise.jpg.h | 1 + 28 files changed, 2355 insertions(+) create mode 100644 include/Nazara/Graphics/DeferredRenderQueue.hpp create mode 100644 include/Nazara/Graphics/DeferredRenderTechnique.hpp create mode 100644 src/Nazara/Graphics/DeferredRenderQueue.cpp create mode 100644 src/Nazara/Graphics/DeferredRenderTechnique.cpp create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/Blit.frag create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/Blit.frag.h create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag.h create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag.h create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/ClearGBuffer.frag create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/ClearGBuffer.frag.h create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/DirectionalLight.frag create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/DirectionalLight.frag.h create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag.h create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag.h create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/PointLight.frag create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/PointLight.frag.h create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAO.frag create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAO.frag.h create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAOFinal.frag create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAOFinal.frag.h create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/SpotLight.frag create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Shaders/SpotLight.frag.h create mode 100644 src/Nazara/Graphics/Resources/DeferredShading/Textures/ssaoNoise.jpg.h diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp new file mode 100644 index 000000000..5e6efb111 --- /dev/null +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -0,0 +1,89 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_DEFERREDRENDERQUEUE_HPP +#define NAZARA_DEFERREDRENDERQUEUE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +class NzForwardRenderQueue; +class NzMaterial; +class NzSkeletalMesh; +class NzStaticMesh; + +class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourceListener +{ + friend class NzDeferredRenderTechnique; + + public: + NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue); + ~NzDeferredRenderQueue(); + + void AddDrawable(const NzDrawable* drawable); + void AddLight(const NzLight* light); + void AddModel(const NzModel* model); + void AddSprite(const NzSprite* sprite); + void AddSubMesh(const NzMaterial* material, const NzSubMesh* subMesh, const NzMatrix4f& transformMatrix); + + void Clear(bool fully); + + private: + bool OnResourceDestroy(const NzResource* resource, int index) override; + void OnResourceReleased(const NzResource* resource, int index) override; + + struct SkeletalData + { + ///TODO + NzMatrix4f transformMatrix; + }; + + struct StaticData + { + NzMatrix4f transformMatrix; + }; + + struct BatchedModelMaterialComparator + { + bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); + }; + + struct BatchedSpriteMaterialComparator + { + bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); + }; + + struct BatchedSkeletalMeshComparator + { + bool operator()(const NzSkeletalMesh* subMesh1, const NzSkeletalMesh* subMesh2); + }; + + struct BatchedStaticMeshComparator + { + bool operator()(const NzStaticMesh* subMesh1, const NzStaticMesh* subMesh2); + }; + + typedef std::map, BatchedSkeletalMeshComparator> BatchedSkeletalMeshContainer; + typedef std::map, BatchedStaticMeshComparator> BatchedStaticMeshContainer; + typedef std::map, BatchedModelMaterialComparator> BatchedModelContainer; + typedef std::map> BatchedSpriteContainer; + typedef std::vector LightContainer; + + BatchedModelContainer opaqueModels; + BatchedSpriteContainer sprites; + LightContainer directionalLights; + LightContainer pointLights; + LightContainer spotLights; + NzForwardRenderQueue* m_forwardQueue; +}; + +#endif // NAZARA_DEFERREDRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/DeferredRenderTechnique.hpp b/include/Nazara/Graphics/DeferredRenderTechnique.hpp new file mode 100644 index 000000000..1b55db4bc --- /dev/null +++ b/include/Nazara/Graphics/DeferredRenderTechnique.hpp @@ -0,0 +1,85 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_DEFERREDRENDERTECHNIQUE_HPP +#define NAZARA_DEFERREDRENDERTECHNIQUE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class NAZARA_API NzDeferredRenderTechnique : public NzAbstractRenderTechnique, public NzRenderTarget::Listener +{ + public: + NzDeferredRenderTechnique(); + ~NzDeferredRenderTechnique(); + + void Clear(const NzScene* scene); + bool Draw(const NzScene* scene); + + NzTexture* GetGBuffer(unsigned int i) const; + NzAbstractRenderQueue* GetRenderQueue() override; + nzRenderTechniqueType GetType() const override; + NzTexture* GetWorkTexture(unsigned int i) const; + + static bool IsSupported(); + + private: + void GeomPass(const NzScene* scene); + void DirectionalLightPass(const NzScene* scene); + void PointLightPass(const NzScene* scene); + void SpotLightPass(const NzScene* scene); + bool UpdateTextures() const; + + NzForwardRenderTechnique m_forwardTechnique; // Doit être initialisé avant la RenderQueue + NzDeferredRenderQueue m_renderQueue; + NzMeshRef m_sphere; + NzStaticMesh* m_sphereMesh; + mutable NzRenderTexture m_bloomRTT; + mutable NzRenderTexture m_dofRTT; + mutable NzRenderTexture m_geometryRTT; + mutable NzRenderTexture m_ssaoRTT; + NzRenderStates m_clearStates; + NzShaderProgramRef m_aaProgram; + NzShaderProgramRef m_blitProgram; + NzShaderProgramRef m_bloomBrightProgram; + NzShaderProgramRef m_bloomFinalProgram; + NzShaderProgramRef m_clearProgram; + NzShaderProgramRef m_directionalLightProgram; + NzShaderProgramRef m_depthOfFieldProgram; + NzShaderProgramRef m_gaussianBlurProgram; + NzShaderProgramRef m_pointLightProgram; + NzShaderProgramRef m_ssaoProgram; + NzShaderProgramRef m_ssaoFinalProgram; + NzShaderProgramRef m_spotLightProgram; + mutable NzTextureRef m_bloomTextureA; + mutable NzTextureRef m_bloomTextureB; + mutable NzTextureRef m_dofTextureA; + mutable NzTextureRef m_dofTextureB; + mutable NzTextureRef m_GBuffer[4]; + mutable NzTextureRef m_ssaoTextureA; + mutable NzTextureRef m_ssaoTextureB; + mutable NzTextureRef m_ssaoNoiseTexture; + mutable NzTextureRef m_workTextureA; + mutable NzTextureRef m_workTextureB; + NzTextureSampler m_bilinearSampler; + NzTextureSampler m_pointSampler; + NzTextureSampler m_ssaoSampler; + NzVector2ui m_GBufferSize; + const NzRenderTarget* m_viewerTarget; + mutable bool m_texturesUpdated; + int m_gaussianBlurProgramFilterLocation; +}; + +#endif // NAZARA_FORWARDRENDERTECHNIQUE_HPP diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp new file mode 100644 index 000000000..4754025a3 --- /dev/null +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -0,0 +1,334 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + enum ResourceType + { + ResourceType_Material, + ResourceType_SkeletalMesh, + ResourceType_StaticMesh + }; +} + +NzDeferredRenderQueue::NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue) : +m_forwardQueue(forwardQueue) +{ +} + +NzDeferredRenderQueue::~NzDeferredRenderQueue() +{ + Clear(true); +} + +void NzDeferredRenderQueue::AddDrawable(const NzDrawable* drawable) +{ + m_forwardQueue->AddDrawable(drawable); +} + +void NzDeferredRenderQueue::AddLight(const NzLight* light) +{ + #if NAZARA_GRAPHICS_SAFE + if (!light) + { + NazaraError("Invalid light"); + return; + } + #endif + + switch (light->GetLightType()) + { + case nzLightType_Directional: + directionalLights.push_back(light); + break; + + case nzLightType_Point: + pointLights.push_back(light); + break; + + case nzLightType_Spot: + spotLights.push_back(light); + break; + } + + m_forwardQueue->AddLight(light); +} + +void NzDeferredRenderQueue::AddModel(const NzModel* model) +{ + #if NAZARA_GRAPHICS_SAFE + if (!model) + { + NazaraError("Invalid model"); + return; + } + + if (!model->IsDrawable()) + { + NazaraError("Model is not drawable"); + return; + } + #endif + + const NzMatrix4f& transformMatrix = model->GetTransformMatrix(); + + NzMesh* mesh = model->GetMesh(); + unsigned int submeshCount = mesh->GetSubMeshCount(); + + for (unsigned int i = 0; i < submeshCount; ++i) + { + NzSubMesh* subMesh = mesh->GetSubMesh(i); + NzMaterial* material = model->GetMaterial(subMesh->GetMaterialIndex()); + + AddSubMesh(material, subMesh, transformMatrix); + } +} + +void NzDeferredRenderQueue::AddSprite(const NzSprite* sprite) +{ + #if NAZARA_GRAPHICS_SAFE + if (!sprite) + { + NazaraError("Invalid sprite"); + return; + } + + if (!sprite->IsDrawable()) + { + NazaraError("Sprite is not drawable"); + return; + } + #endif + + NzMaterial* material = sprite->GetMaterial(); + if (material->IsEnabled(nzRendererParameter_Blend)) + m_forwardQueue->AddSprite(sprite); + else + sprites[material].push_back(sprite); +} + +void NzDeferredRenderQueue::AddSubMesh(const NzMaterial* material, const NzSubMesh* subMesh, const NzMatrix4f& transformMatrix) +{ + switch (subMesh->GetAnimationType()) + { + case nzAnimationType_Skeletal: + { + ///TODO + /* + ** Il y a ici deux choses importantes à gérer: + ** -Pour commencer, la mise en cache de std::vector suffisamment grands pour contenir le résultat du skinning + ** l'objectif ici est d'éviter une allocation à chaque frame, donc de réutiliser un tableau existant + ** Note: Il faudrait évaluer aussi la possibilité de conserver le buffer d'une frame à l'autre. + ** Ceci permettant de ne pas skinner inutilement ce qui ne bouge pas, ou de skinner partiellement un mesh. + ** Il faut cependant voir où stocker ce set de buffers, qui doit être communs à toutes les RQ d'une même scène. + ** + ** -Ensuite, la possibilité de regrouper les modèles skinnés identiques, une centaine de soldats marchant au pas + ** ne devrait requérir qu'un skinning. + */ + NazaraError("Skeletal mesh not supported yet, sorry"); + break; + } + + case nzAnimationType_Static: + { + if (material->IsEnabled(nzRendererParameter_Blend)) + m_forwardQueue->AddSubMesh(material, subMesh, transformMatrix); + else + { + const NzStaticMesh* staticMesh = static_cast(subMesh); + + auto pair = opaqueModels.insert(std::make_pair(material, BatchedModelContainer::mapped_type())); + if (pair.second) + material->AddResourceListener(this, ResourceType_Material); + + bool& used = std::get<0>(pair.first->second); + bool& enableInstancing = std::get<1>(pair.first->second); + + used = true; + + auto& meshMap = std::get<3>(pair.first->second); + + auto pair2 = meshMap.insert(std::make_pair(staticMesh, BatchedStaticMeshContainer::mapped_type())); + if (pair2.second) + staticMesh->AddResourceListener(this, ResourceType_StaticMesh); + + std::vector& staticDataContainer = pair2.first->second; + + unsigned int instanceCount = staticDataContainer.size() + 1; + + // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? + if (instanceCount >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) + enableInstancing = true; // Apparemment oui, activons l'instancing avec ce matériau + + staticDataContainer.resize(instanceCount); + StaticData& data = staticDataContainer.back(); + data.transformMatrix = transformMatrix; + } + + break; + } + } +} + +void NzDeferredRenderQueue::Clear(bool fully) +{ + directionalLights.clear(); + pointLights.clear(); + spotLights.clear(); + + if (fully) + { + for (auto& matIt : opaqueModels) + { + const NzMaterial* material = matIt.first; + material->RemoveResourceListener(this); + + BatchedSkeletalMeshContainer& skeletalContainer = std::get<2>(matIt.second); + for (auto& meshIt : skeletalContainer) + { + const NzSkeletalMesh* skeletalMesh = meshIt.first; + skeletalMesh->RemoveResourceListener(this); + } + + BatchedStaticMeshContainer& staticContainer = std::get<3>(matIt.second); + for (auto& meshIt : staticContainer) + { + const NzStaticMesh* staticMesh = meshIt.first; + staticMesh->RemoveResourceListener(this); + } + } + + opaqueModels.clear(); + sprites.clear(); + } + + m_forwardQueue->Clear(fully); +} + +bool NzDeferredRenderQueue::OnResourceDestroy(const NzResource* resource, int index) +{ + switch (index) + { + case ResourceType_Material: + opaqueModels.erase(static_cast(resource)); + break; + + case ResourceType_SkeletalMesh: + { + for (auto& pair : opaqueModels) + std::get<2>(pair.second).erase(static_cast(resource)); + + break; + } + + case ResourceType_StaticMesh: + { + for (auto& pair : opaqueModels) + std::get<3>(pair.second).erase(static_cast(resource)); + + break; + } + } + + return false; // Nous ne voulons plus recevoir d'évènement de cette ressource +} + +void NzDeferredRenderQueue::OnResourceReleased(const NzResource* resource, int index) +{ + OnResourceDestroy(resource, index); +} + +bool NzDeferredRenderQueue::BatchedModelMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2) +{ + nzUInt32 possibleFlags[] = { + nzShaderFlags_Deferred, + nzShaderFlags_Deferred | nzShaderFlags_Instancing + }; + + for (nzUInt32 flag : possibleFlags) + { + const NzShaderProgram* program1 = mat1->GetShaderProgram(nzShaderTarget_Model, flag); + const NzShaderProgram* program2 = mat2->GetShaderProgram(nzShaderTarget_Model, flag); + + if (program1 != program2) + return program1 < program2; + } + + const NzTexture* diffuseMap1 = mat1->GetDiffuseMap(); + const NzTexture* diffuseMap2 = mat2->GetDiffuseMap(); + if (diffuseMap1 != diffuseMap2) + return diffuseMap1 < diffuseMap2; + + return mat1 < mat2; +} + +bool NzDeferredRenderQueue::BatchedSpriteMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2) +{ + nzUInt32 possibleFlags[] = { + nzShaderFlags_Deferred + }; + + for (nzUInt32 flag : possibleFlags) + { + const NzShaderProgram* program1 = mat1->GetShaderProgram(nzShaderTarget_Model, flag); + const NzShaderProgram* program2 = mat2->GetShaderProgram(nzShaderTarget_Model, flag); + + if (program1 != program2) + return program1 < program2; + } + + const NzTexture* diffuseMap1 = mat1->GetDiffuseMap(); + const NzTexture* diffuseMap2 = mat2->GetDiffuseMap(); + if (diffuseMap1 != diffuseMap2) + return diffuseMap1 < diffuseMap2; + + return mat1 < mat2; +} + +bool NzDeferredRenderQueue::BatchedSkeletalMeshComparator::operator()(const NzSkeletalMesh* subMesh1, const NzSkeletalMesh* subMesh2) +{ + const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer(); + const NzBuffer* buffer1 = (iBuffer1) ? iBuffer1->GetBuffer() : nullptr; + + const NzIndexBuffer* iBuffer2 = subMesh1->GetIndexBuffer(); + const NzBuffer* buffer2 = (iBuffer2) ? iBuffer2->GetBuffer() : nullptr; + + if (buffer1 == buffer2) + return subMesh1 < subMesh2; + else + return buffer2 < buffer2; +} + +bool NzDeferredRenderQueue::BatchedStaticMeshComparator::operator()(const NzStaticMesh* subMesh1, const NzStaticMesh* subMesh2) +{ + const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer(); + const NzBuffer* buffer1 = (iBuffer1) ? iBuffer1->GetBuffer() : nullptr; + + const NzIndexBuffer* iBuffer2 = subMesh2->GetIndexBuffer(); + const NzBuffer* buffer2 = (iBuffer2) ? iBuffer2->GetBuffer() : nullptr; + + if (buffer1 == buffer2) + { + buffer1 = subMesh1->GetVertexBuffer()->GetBuffer(); + buffer2 = subMesh2->GetVertexBuffer()->GetBuffer(); + + if (buffer1 == buffer2) + return subMesh1 < subMesh2; + else + return buffer1 < buffer2; + } + else + return buffer1 < buffer2; +} diff --git a/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp new file mode 100644 index 000000000..c0c3f4608 --- /dev/null +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -0,0 +1,1339 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + NzShaderProgram* BuildClearProgram() + { + const char fragmentSource[] = { + #include + }; + + const char* vertexSource = + "#version 140\n" + + "in vec2 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 0.0, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, NzString(fragmentSource, sizeof(fragmentSource)))) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + return program.release(); + } + + NzShaderProgram* BuildDirectionalLightProgram() + { + const char fragmentSource[] = { + #include + }; + + const char* vertexSource = + "#version 140\n" + + "in vec2 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 0.0, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, NzString(fragmentSource, sizeof(fragmentSource)))) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + program->SendInteger(program->GetUniformLocation("GBuffer0"), 0); + program->SendInteger(program->GetUniformLocation("GBuffer1"), 1); + program->SendInteger(program->GetUniformLocation("GBuffer2"), 2); + + return program.release(); + } + + NzShaderProgram* BuildPointLightProgram() + { + const char fragmentSource[] = { + #include + }; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "uniform mat4 WorldViewProjMatrix;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, NzString(fragmentSource, sizeof(fragmentSource)))) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + program->SendInteger(program->GetUniformLocation("GBuffer0"), 0); + program->SendInteger(program->GetUniformLocation("GBuffer1"), 1); + program->SendInteger(program->GetUniformLocation("GBuffer2"), 2); + + return program.release(); + } + + NzShaderProgram* BuildSpotLightProgram() + { + const char fragmentSource[] = { + #include + }; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "uniform mat4 WorldViewProjMatrix;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, NzString(fragmentSource, sizeof(fragmentSource)))) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + program->SendInteger(program->GetUniformLocation("GBuffer0"), 0); + program->SendInteger(program->GetUniformLocation("GBuffer1"), 1); + program->SendInteger(program->GetUniformLocation("GBuffer2"), 2); + + return program.release(); + } + + NzShaderProgram* BuildBloomBrightProgram() + { + const char fragmentSource[] = { + #include + }; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, NzString(fragmentSource, sizeof(fragmentSource)))) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + program->SendInteger(program->GetUniformLocation("ColorTexture"), 0); + + return program.release(); + } + + NzShaderProgram* BuildGaussianBlurProgram() + { + const char fragmentSource[] = { + #include + }; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, NzString(fragmentSource, sizeof(fragmentSource)))) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + program->SendInteger(program->GetUniformLocation("ColorTexture"), 0); + + return program.release(); + } + + NzShaderProgram* BuildBloomFinalProgram() + { + const char fragmentSource[] = { + #include + }; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, NzString(fragmentSource, sizeof(fragmentSource)))) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + program->SendInteger(program->GetUniformLocation("ColorTexture"), 0); + program->SendInteger(program->GetUniformLocation("BloomTexture"), 1); + + return program.release(); + } + + NzShaderProgram* BuildAAProgram() + { + const char fragmentSource[] = { + #include + }; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, NzString(fragmentSource, sizeof(fragmentSource)))) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + program->SendInteger(program->GetUniformLocation("GBuffer1"), 0); + program->SendInteger(program->GetUniformLocation("NoiseTexture"), 1); + + return program.release(); + } + + NzShaderProgram* BuildSSAOProgram() + { + const char fragmentSource[] = { + #include + }; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, NzString(fragmentSource, sizeof(fragmentSource)))) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + program->SendInteger(program->GetUniformLocation("GBuffer1"), 0); + program->SendInteger(program->GetUniformLocation("NoiseTexture"), 1); + + return program.release(); + } + + NzShaderProgram* BuildSSAOFinalProgram() + { + const char fragmentSource[] = { + #include + }; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, NzString(fragmentSource, sizeof(fragmentSource)))) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + program->SendInteger(program->GetUniformLocation("ColorTexture"), 0); + program->SendInteger(program->GetUniformLocation("SSAOTexture"), 1); + + return program.release(); + } + + // http://digitalerr0r.wordpress.com/2009/05/16/xna-shader-programming-tutorial-20-depth-of-field/ + NzShaderProgram* BuildDepthOfFieldProgram() + { + const char* fragmentSource = + "#version 140\n" + + "out vec4 RenderTarget0;\n" + + "uniform sampler2D BlurTexture;\n" + "uniform sampler2D ColorTexture;\n" + "uniform sampler2D GBuffer1;\n" + "uniform vec2 InvTargetSize;" "\n" + + "float Distance = 30.0;\n" + "float Range = 100.0;\n" + "float Near = 0.1;\n" + "float Far = (5000.0) / (5000.0 - 0.1);\n" + //"float Far = 50.0;\n" + + "void main()\n" + "{\n" + "vec2 texCoord = gl_FragCoord.xy * InvTargetSize;\n" + + "// Get our original pixel from ColorMap\n" + "vec3 color = textureLod(ColorTexture, texCoord, 0.0).rgb;\n" + + "// Get our bloom pixel from bloom texture\n" + "vec3 blur = textureLod(BlurTexture, texCoord, 0.0).rgb;\n" + + "float depth = textureLod(GBuffer1, texCoord, 0.0).w;\n" + "depth = (2.0 * 0.1) / (5000.0 + 0.1 - depth * (5000.0 - 0.1));" + "depth = 1.0 - depth;\n" + + "float fSceneZ = ( -Near * Far ) / ( depth - Far);\n" + "float blurFactor = clamp(abs(fSceneZ - Distance)/Range, 0.0, 1.0);\n" + + "RenderTarget0 = vec4(mix(color, blur, blurFactor), 1.0);\n" + "}\n"; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, fragmentSource)) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + program->SendInteger(program->GetUniformLocation("ColorTexture"), 0); + program->SendInteger(program->GetUniformLocation("BlurTexture"), 1); + program->SendInteger(program->GetUniformLocation("GBuffer1"), 2); + + return program.release(); + } + + NzShaderProgram* BuildBlitProgram() + { + const char fragmentSource[] = { + #include + }; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + std::unique_ptr program(new NzShaderProgram(nzShaderLanguage_GLSL)); + program->SetPersistent(false); + + if (!program->LoadShader(nzShaderType_Fragment, NzString(fragmentSource, sizeof(fragmentSource)))) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!program->LoadShader(nzShaderType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!program->Compile()) + { + NazaraError("Failed to compile program"); + return nullptr; + } + + program->SendInteger(program->GetUniformLocation("ColorTexture"), 0); + + return program.release(); + } +} + +NzDeferredRenderTechnique::NzDeferredRenderTechnique() : +m_renderQueue(static_cast(m_forwardTechnique.GetRenderQueue())), +m_GBufferSize(0, 0), +m_texturesUpdated(false) +{ + m_aaProgram = BuildAAProgram(); + + m_blitProgram = BuildBlitProgram(); + + m_bloomBrightProgram = BuildBloomBrightProgram(); + m_bloomFinalProgram = BuildBloomFinalProgram(); + + m_clearProgram = BuildClearProgram(); + + m_clearStates.parameters[nzRendererParameter_DepthBuffer] = true; + m_clearStates.parameters[nzRendererParameter_FaceCulling] = true; + m_clearStates.parameters[nzRendererParameter_StencilTest] = true; + m_clearStates.depthFunc = nzRendererComparison_Always; + m_clearStates.frontFace.stencilCompare = nzRendererComparison_Always; + m_clearStates.frontFace.stencilPass = nzStencilOperation_Zero; + + m_gaussianBlurProgram = BuildGaussianBlurProgram(); + m_gaussianBlurProgramFilterLocation = m_gaussianBlurProgram->GetUniformLocation("Filter"); + + m_directionalLightProgram = BuildDirectionalLightProgram(); + m_pointLightProgram = BuildPointLightProgram(); + m_spotLightProgram = BuildSpotLightProgram(); + + m_depthOfFieldProgram = BuildDepthOfFieldProgram(); + + m_bilinearSampler.SetAnisotropyLevel(1); + m_bilinearSampler.SetFilterMode(nzSamplerFilter_Bilinear); + m_bilinearSampler.SetWrapMode(nzSamplerWrap_Clamp); + + m_pointSampler.SetAnisotropyLevel(1); + m_pointSampler.SetFilterMode(nzSamplerFilter_Nearest); + m_pointSampler.SetWrapMode(nzSamplerWrap_Clamp); + + m_ssaoSampler.SetAnisotropyLevel(1); + m_ssaoSampler.SetFilterMode(nzSamplerFilter_Nearest); + m_ssaoSampler.SetWrapMode(nzSamplerWrap_Repeat); + + /*const unsigned int kernelSize = 16; + + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_real_distribution dis(-1.f, 1.f); + std::uniform_real_distribution dis2(0.f, 1.f); + + std::vector kernel(kernelSize); + for (unsigned int i = 0; i < kernelSize; ++i) + { + kernel[i].Set(dis(gen), dis(gen), dis2(gen)); + kernel[i].Normalize(); + + float scale = static_cast(i) / kernelSize; + kernel[i] *= NzLerp(0.1f, 1.0f, scale * scale); + } + + int noiseDataSize = 4 * 4; + + std::vector noiseData(noiseDataSize*2); + for (int i = 0; i < noiseDataSize; ++i) + { + NzVector2f vec(dis(gen), dis(gen)); + vec.Normalize(); + + noiseData[i*2 + 0] = static_cast((vec.x*0.5f + 0.5f) * 0xFF); + noiseData[i*2 + 1] = static_cast((vec.y*0.5f + 0.5f) * 0xFF); + } + + m_ssaoNoiseTexture = new NzTexture; + m_ssaoNoiseTexture->SetPersistent(false); + m_ssaoNoiseTexture->Create(nzImageType_2D, nzPixelFormat_RG8, 4, 4); + m_ssaoNoiseTexture->Update(&noiseData[0]);*/ + + m_ssaoNoiseTexture = new NzTexture; + m_ssaoNoiseTexture->SetPersistent(false); + m_ssaoNoiseTexture->LoadFromFile("resources/noise.jpg"); + + m_ssaoProgram = BuildSSAOProgram(); + m_ssaoProgram->SendInteger(m_ssaoProgram->GetUniformLocation("NoiseTextureSize"), m_ssaoNoiseTexture->GetWidth()); + //m_ssaoProgram->SendInteger(m_ssaoProgram->GetUniformLocation("ssaoKernelSize"), kernelSize); + //m_ssaoProgram->SendVectorArray(m_ssaoProgram->GetUniformLocation("ssaoKernelOffsets"), &kernel[0], kernelSize); + + m_ssaoFinalProgram = BuildSSAOFinalProgram(); + + m_sphere = new NzMesh; + m_sphere->SetPersistent(false); + m_sphere->CreateStatic(); + m_sphereMesh = static_cast(m_sphere->BuildSubMesh(NzPrimitive::IcoSphere(1.f, 1))); + + m_bloomTextureA = new NzTexture; + m_bloomTextureA->SetPersistent(false); + + m_bloomTextureB = new NzTexture; + m_bloomTextureB->SetPersistent(false); + + m_dofTextureA = new NzTexture; + m_dofTextureA->SetPersistent(false); + + m_dofTextureB = new NzTexture; + m_dofTextureB->SetPersistent(false); + + m_ssaoTextureA = new NzTexture; + m_ssaoTextureA->SetPersistent(false); + + m_ssaoTextureB = new NzTexture; + m_ssaoTextureB->SetPersistent(false); + + m_workTextureA = new NzTexture; + m_workTextureA->SetPersistent(false); + + m_workTextureB = new NzTexture; + m_workTextureB->SetPersistent(false); + + for (unsigned int i = 0; i < 3; ++i) + { + m_GBuffer[i] = new NzTexture; + m_GBuffer[i]->SetPersistent(false); + } +} + +NzDeferredRenderTechnique::~NzDeferredRenderTechnique() +{ +} + +void NzDeferredRenderTechnique::Clear(const NzScene* scene) +{ + NazaraUnused(scene); +} + +bool NzDeferredRenderTechnique::Draw(const NzScene* scene) +{ + NzAbstractViewer* viewer = scene->GetViewer(); + NzRecti viewerViewport = NzRenderer::GetViewport(); + + if (static_cast(viewerViewport.width) != m_GBufferSize.x || static_cast(viewerViewport.height) != m_GBufferSize.y) + { + m_GBufferSize.Set(viewerViewport.width, viewerViewport.height); + m_texturesUpdated = false; + } + + if (!m_texturesUpdated && !UpdateTextures()) + { + NazaraError("Failed to update RTT"); + return false; + } + + NzRenderer::SetTarget(&m_geometryRTT); + NzRenderer::SetViewport(NzRecti(0, 0, m_GBufferSize.x, m_GBufferSize.y)); + + /****************************Passe géométrique****************************/ + m_geometryRTT.SetColorTargets({0, 1, 2}); // G-Buffer + + NzRenderer::SetRenderStates(m_clearStates); + NzRenderer::SetShaderProgram(m_clearProgram); + NzRenderer::DrawFullscreenQuad(); + + NzRenderer::SetMatrix(nzMatrixType_Projection, viewer->GetProjectionMatrix()); + NzRenderer::SetMatrix(nzMatrixType_View, viewer->GetViewMatrix()); + + GeomPass(scene); + + /****************************Passe d'éclairage****************************/ + m_geometryRTT.SetColorTarget(4); // workTextureA + + NzRenderer::SetTexture(0, m_GBuffer[0]); + NzRenderer::SetTextureSampler(0, m_pointSampler); + + NzRenderer::SetTexture(1, m_GBuffer[1]); + NzRenderer::SetTextureSampler(1, m_pointSampler); + + NzRenderer::SetTexture(2, m_GBuffer[2]); + NzRenderer::SetTextureSampler(2, m_pointSampler); + + NzRenderer::SetClearColor(NzColor::Black); + NzRenderer::Clear(nzRendererClear_Color); + + NzRenderStates lightStates; + lightStates.dstBlend = nzBlendFunc_One; + lightStates.srcBlend = nzBlendFunc_One; + lightStates.parameters[nzRendererParameter_Blend] = true; + lightStates.parameters[nzRendererParameter_DepthBuffer] = true; + lightStates.parameters[nzRendererParameter_DepthWrite] = false; + + // Directional lights + if (!m_renderQueue.directionalLights.empty()) + { + NzRenderer::SetRenderStates(lightStates); + DirectionalLightPass(scene); + } + + // Point lights/Spot lights + if (!m_renderQueue.pointLights.empty() || !m_renderQueue.spotLights.empty()) + { + // http://www.altdevblogaday.com/2011/08/08/stencil-buffer-optimisation-for-deferred-lights/ + lightStates.parameters[nzRendererParameter_StencilTest] = true; + lightStates.faceCulling = nzFaceSide_Front; + lightStates.backFace.stencilMask = 0xFF; + lightStates.backFace.stencilReference = 0; + lightStates.backFace.stencilFail = nzStencilOperation_Keep; + lightStates.backFace.stencilPass = nzStencilOperation_Keep; + lightStates.backFace.stencilZFail = nzStencilOperation_Invert; + lightStates.frontFace.stencilMask = 0xFF; + lightStates.frontFace.stencilReference = 0; + lightStates.frontFace.stencilFail = nzStencilOperation_Keep; + lightStates.frontFace.stencilPass = nzStencilOperation_Keep; + lightStates.frontFace.stencilZFail = nzStencilOperation_Invert; + + NzRenderer::SetRenderStates(lightStates); + + if (!m_renderQueue.pointLights.empty()) + PointLightPass(scene); + + if (!m_renderQueue.spotLights.empty()) + SpotLightPass(scene); + + NzRenderer::Enable(nzRendererParameter_StencilTest, false); + } + + /******************************Passe forward******************************/ + NzAbstractBackground* background = scene->GetBackground(); + if (background) + background->Draw(scene); + + NzRenderer::SetMatrix(nzMatrixType_Projection, viewer->GetProjectionMatrix()); + NzRenderer::SetMatrix(nzMatrixType_View, viewer->GetViewMatrix()); + + m_forwardTechnique.Draw(scene); + + NzRenderStates states; + states.parameters[nzRendererParameter_DepthBuffer] = false; + + NzRenderer::SetRenderStates(states); + + /****************************SSAO***************************/ + NzRenderer::SetShaderProgram(m_ssaoProgram); + + NzRenderer::SetTarget(&m_ssaoRTT); + NzRenderer::SetViewport(NzRecti(0, 0, m_GBufferSize.x/4, m_GBufferSize.y/4)); + + m_ssaoRTT.SetColorTarget(0); // ssaoTextureA + + NzRenderer::SetTexture(0, m_GBuffer[1]); + NzRenderer::SetTexture(1, m_ssaoNoiseTexture); + NzRenderer::SetTextureSampler(0, m_pointSampler); + NzRenderer::SetTextureSampler(1, m_ssaoSampler); + NzRenderer::DrawFullscreenQuad(); + + NzRenderer::SetShaderProgram(m_gaussianBlurProgram); + + const unsigned int ssaoBlurPass = 2; + for (unsigned int i = 0; i < ssaoBlurPass; ++i) + { + m_ssaoRTT.SetColorTarget(1); // ssaoTextureB + + m_gaussianBlurProgram->SendVector(m_gaussianBlurProgramFilterLocation, NzVector2f(1.f, 0.f)); + + NzRenderer::SetTexture(0, m_ssaoTextureA); + NzRenderer::DrawFullscreenQuad(); + + m_ssaoRTT.SetColorTarget(0); // ssaoTextureA + + m_gaussianBlurProgram->SendVector(m_gaussianBlurProgramFilterLocation, NzVector2f(0.f, 1.f)); + + NzRenderer::SetTexture(0, m_ssaoTextureB); + NzRenderer::DrawFullscreenQuad(); + } + + NzRenderer::SetTarget(&m_geometryRTT); + NzRenderer::SetViewport(NzRecti(0, 0, m_GBufferSize.x, m_GBufferSize.y)); + m_geometryRTT.SetColorTarget(5); // workTextureB + + NzRenderer::SetShaderProgram(m_ssaoFinalProgram); + NzRenderer::SetTexture(0, m_workTextureA); + NzRenderer::SetTexture(1, m_ssaoTextureA); + NzRenderer::SetTextureSampler(0, m_pointSampler); + NzRenderer::SetTextureSampler(1, m_bilinearSampler); + NzRenderer::DrawFullscreenQuad(); + + /****************************AA***************************/ + NzRenderer::SetShaderProgram(m_aaProgram); + + m_geometryRTT.SetColorTarget(4); // workTextureA + + NzRenderer::SetTexture(0, m_workTextureB); + NzRenderer::SetTextureSampler(0, m_pointSampler); + NzRenderer::DrawFullscreenQuad(); + + /****************************Bloom***************************/ + NzRenderer::SetTextureSampler(0, m_bilinearSampler); + NzRenderer::SetTextureSampler(1, m_bilinearSampler); + + m_geometryRTT.SetColorTarget(5); // workTextureB + + NzRenderer::SetShaderProgram(m_bloomBrightProgram); + + NzRenderer::SetTexture(0, m_workTextureA); + NzRenderer::DrawFullscreenQuad(); + + NzRenderer::SetTarget(&m_bloomRTT); + NzRenderer::SetViewport(NzRecti(0, 0, m_GBufferSize.x/8, m_GBufferSize.y/8)); + + NzRenderer::SetShaderProgram(m_gaussianBlurProgram); + + const unsigned int bloomBlurPass = 5; + for (unsigned int i = 0; i < bloomBlurPass; ++i) + { + m_bloomRTT.SetColorTarget(0); // bloomTextureA + + m_gaussianBlurProgram->SendVector(m_gaussianBlurProgramFilterLocation, NzVector2f(1.f, 0.f)); + + NzRenderer::SetTexture(0, (i == 0) ? m_workTextureB : m_bloomTextureB); + NzRenderer::DrawFullscreenQuad(); + + m_bloomRTT.SetColorTarget(1); // bloomTextureB + + m_gaussianBlurProgram->SendVector(m_gaussianBlurProgramFilterLocation, NzVector2f(0.f, 1.f)); + + NzRenderer::SetTexture(0, m_bloomTextureA); + NzRenderer::DrawFullscreenQuad(); + } + + NzRenderer::SetTarget(&m_geometryRTT); + NzRenderer::SetViewport(NzRecti(0, 0, m_GBufferSize.x, m_GBufferSize.y)); + m_geometryRTT.SetColorTarget(5); // workTextureB + + NzRenderer::SetShaderProgram(m_bloomFinalProgram); + NzRenderer::SetTexture(0, m_workTextureA); + NzRenderer::SetTexture(1, m_bloomTextureB); + NzRenderer::DrawFullscreenQuad(); + + /****************************Depth-of-Field***************************/ +/* NzRenderer::SetTextureSampler(0, m_pointSampler); + NzRenderer::SetTextureSampler(1, m_bilinearSampler); + NzRenderer::SetTextureSampler(2, m_pointSampler); + + NzRenderer::SetTarget(&m_dofRTT); + NzRenderer::SetViewport(NzRecti(0, 0, m_GBufferSize.x/4, m_GBufferSize.y/4)); + + NzRenderer::SetShaderProgram(m_gaussianBlurProgram); + + const unsigned int dofBlurPass = 2; + for (unsigned int i = 0; i < dofBlurPass; ++i) + { + m_dofRTT.SetColorTarget(0); // dofTextureA + + m_gaussianBlurProgram->SendVector(m_gaussianBlurProgramFilterLocation, NzVector2f(1.f, 0.f)); + + NzRenderer::SetTexture(0, (i == 0) ? m_workTextureB : m_dofTextureB); + NzRenderer::DrawFullscreenQuad(); + + m_dofRTT.SetColorTarget(1); // dofTextureB + + m_gaussianBlurProgram->SendVector(m_gaussianBlurProgramFilterLocation, NzVector2f(0.f, 1.f)); + + NzRenderer::SetTexture(0, m_dofTextureA); + NzRenderer::DrawFullscreenQuad(); + } + + NzRenderer::SetTarget(&m_geometryRTT); + NzRenderer::SetViewport(NzRecti(0, 0, m_GBufferSize.x, m_GBufferSize.y)); + m_geometryRTT.SetColorTarget(4); // workTextureA + + NzRenderer::SetShaderProgram(m_depthOfFieldProgram); + NzRenderer::SetTexture(0, m_workTextureB); + NzRenderer::SetTexture(1, m_dofTextureB); + NzRenderer::SetTexture(2, m_GBuffer[1]); + NzRenderer::DrawFullscreenQuad(); +*/ + /*******************************Passe finale******************************/ + scene->GetViewer()->ApplyView(); + + NzRenderer::SetRenderStates(states); + NzRenderer::SetShaderProgram(m_blitProgram); + NzRenderer::SetTexture(0, m_workTextureB); + NzRenderer::SetTextureSampler(0, m_pointSampler); + + NzRenderer::DrawFullscreenQuad(); + + return true; +} + +NzTexture* NzDeferredRenderTechnique::GetGBuffer(unsigned int i) const +{ + #if NAZARA_GRAPHICS_SAFE + if (i >= 3) + { + NazaraError("GBuffer texture index out of range (" + NzString::Number(i) + " >= 3)"); + return nullptr; + } + #endif + + return m_GBuffer[i]; +} + +NzAbstractRenderQueue* NzDeferredRenderTechnique::GetRenderQueue() +{ + return &m_renderQueue; +} + +nzRenderTechniqueType NzDeferredRenderTechnique::GetType() const +{ + return nzRenderTechniqueType_DeferredShading; +} + +NzTexture* NzDeferredRenderTechnique::GetWorkTexture(unsigned int i) const +{ + #if NAZARA_GRAPHICS_SAFE + if (i >= 2) + { + NazaraError("GBuffer texture index out of range (" + NzString::Number(i) + " >= 3)"); + return nullptr; + } + #endif + + return (i == 0) ? m_workTextureA : m_workTextureB; + +} + +bool NzDeferredRenderTechnique::IsSupported() +{ + // On ne va pas s'embêter à écrire un Deferred Renderer qui ne passe pas par le MRT, ce serait lent et inutile (OpenGL 2 garanti cette fonctionnalité en plus) + return NzRenderer::HasCapability(nzRendererCap_RenderTexture) && + NzRenderer::HasCapability(nzRendererCap_MultipleRenderTargets) && + NzRenderer::GetMaxColorAttachments() >= 6 && //FIXME: Repasser à quatre + NzRenderer::GetMaxRenderTargets() >= 4 && + NzTexture::IsFormatSupported(nzPixelFormat_RGBA32F); +} + +void NzDeferredRenderTechnique::GeomPass(const NzScene* scene) +{ + NzAbstractViewer* viewer = scene->GetViewer(); + const NzShaderProgram* lastProgram = nullptr; + + for (auto& matIt : m_renderQueue.opaqueModels) + { + bool& used = std::get<0>(matIt.second); + if (used) + { + bool& renderQueueInstancing = std::get<1>(matIt.second); + NzDeferredRenderQueue::BatchedSkeletalMeshContainer& skeletalContainer = std::get<2>(matIt.second); + NzDeferredRenderQueue::BatchedStaticMeshContainer& staticContainer = std::get<3>(matIt.second); + + if (!skeletalContainer.empty() || !staticContainer.empty()) + { + const NzMaterial* material = matIt.first; + + // Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active + // Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches + // (Le deferred shading n'a pas ce problème) + bool instancing = m_instancingEnabled && renderQueueInstancing; + + // On commence par récupérer le programme du matériau + nzUInt32 flags = nzShaderFlags_Deferred; + if (instancing) + flags |= nzShaderFlags_Instancing; + + const NzShaderProgram* program = material->GetShaderProgram(nzShaderTarget_Model, flags); + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (program != lastProgram) + { + NzRenderer::SetShaderProgram(program); + + // Couleur ambiante de la scène + program->SendColor(program->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + // Position de la caméra + program->SendVector(program->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); + + lastProgram = program; + } + + material->Apply(program); + + // Meshs squelettiques + /*if (!skeletalContainer.empty()) + { + NzRenderer::SetVertexBuffer(m_skinningBuffer); // Vertex buffer commun + for (auto& subMeshIt : container) + { + ///TODO + } + }*/ + + // Meshs statiques + for (auto& subMeshIt : staticContainer) + { + const NzStaticMesh* mesh = subMeshIt.first; + std::vector& staticData = subMeshIt.second; + + if (!staticData.empty()) + { + const NzIndexBuffer* indexBuffer = mesh->GetIndexBuffer(); + const NzVertexBuffer* vertexBuffer = mesh->GetVertexBuffer(); + + // Gestion du draw call avant la boucle de rendu + std::function DrawFunc; + std::function InstancedDrawFunc; + unsigned int indexCount; + + if (indexBuffer) + { + DrawFunc = NzRenderer::DrawIndexedPrimitives; + InstancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + DrawFunc = NzRenderer::DrawPrimitives; + InstancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); + } + + NzRenderer::SetIndexBuffer(indexBuffer); + NzRenderer::SetVertexBuffer(vertexBuffer); + + nzPrimitiveMode primitiveMode = mesh->GetPrimitiveMode(); + if (instancing) + { + NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); + + instanceBuffer->SetVertexDeclaration(NzVertexDeclaration::Get(nzVertexLayout_Matrix4)); + + unsigned int stride = instanceBuffer->GetStride(); + + const NzDeferredRenderQueue::StaticData* data = &staticData[0]; + unsigned int instanceCount = staticData.size(); + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); + + while (instanceCount > 0) + { + unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); + instanceCount -= renderedInstanceCount; + + NzBufferMapper mapper(instanceBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedInstanceCount); + nzUInt8* ptr = reinterpret_cast(mapper.GetPointer()); + + for (unsigned int i = 0; i < renderedInstanceCount; ++i) + { + std::memcpy(ptr, data->transformMatrix, sizeof(float)*16); + + data++; + ptr += stride; + } + + mapper.Unmap(); + + InstancedDrawFunc(renderedInstanceCount, primitiveMode, 0, indexCount); + } + } + else + { + for (const NzDeferredRenderQueue::StaticData& data : staticData) + { + NzRenderer::SetMatrix(nzMatrixType_World, data.transformMatrix); + DrawFunc(primitiveMode, 0, indexCount); + } + } + staticData.clear(); + } + } + } + + // Et on remet à zéro les données + renderQueueInstancing = false; + used = false; + } + } +} + +void NzDeferredRenderTechnique::DirectionalLightPass(const NzScene* scene) +{ + NzRenderer::SetShaderProgram(m_directionalLightProgram); + m_directionalLightProgram->SendColor(m_directionalLightProgram->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + m_directionalLightProgram->SendVector(m_directionalLightProgram->GetUniformLocation(nzShaderUniform_EyePosition), scene->GetViewer()->GetEyePosition()); + + for (const NzLight* light : m_renderQueue.directionalLights) + { + light->Enable(m_directionalLightProgram, 0); + NzRenderer::DrawFullscreenQuad(); + } +} + +void NzDeferredRenderTechnique::PointLightPass(const NzScene* scene) +{ + NzRenderer::SetShaderProgram(m_pointLightProgram); + m_pointLightProgram->SendColor(m_pointLightProgram->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + m_pointLightProgram->SendVector(m_pointLightProgram->GetUniformLocation(nzShaderUniform_EyePosition), scene->GetViewer()->GetEyePosition()); + + const NzIndexBuffer* indexBuffer = m_sphereMesh->GetIndexBuffer(); + NzRenderer::SetIndexBuffer(indexBuffer); + NzRenderer::SetVertexBuffer(m_sphereMesh->GetVertexBuffer()); + + NzMatrix4f lightMatrix; + lightMatrix.MakeIdentity(); + for (const NzLight* light : m_renderQueue.pointLights) + { + light->Enable(m_pointLightProgram, 0); + lightMatrix.SetScale(NzVector3f(light->GetRadius()*1.1f)); + lightMatrix.SetTranslation(light->GetPosition()); + + NzRenderer::SetMatrix(nzMatrixType_World, lightMatrix); + + // Rendu de la sphère dans le stencil buffer + NzRenderer::Enable(nzRendererParameter_ColorWrite, false); + NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); + NzRenderer::Enable(nzRendererParameter_FaceCulling, false); + NzRenderer::SetStencilCompareFunction(nzRendererComparison_Always); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + + // Rendu de la sphère comme zone d'effet + NzRenderer::Enable(nzRendererParameter_ColorWrite, true); + NzRenderer::Enable(nzRendererParameter_DepthBuffer, false); + NzRenderer::Enable(nzRendererParameter_FaceCulling, true); + NzRenderer::SetFaceCulling(nzFaceSide_Front); + NzRenderer::SetStencilCompareFunction(nzRendererComparison_NotEqual, nzFaceSide_Back); + NzRenderer::SetStencilPassOperation(nzStencilOperation_Zero, nzFaceSide_Back); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + } +} + +void NzDeferredRenderTechnique::SpotLightPass(const NzScene* scene) +{ + NzRenderer::SetShaderProgram(m_spotLightProgram); + m_spotLightProgram->SendColor(m_spotLightProgram->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + m_spotLightProgram->SendVector(m_spotLightProgram->GetUniformLocation(nzShaderUniform_EyePosition), scene->GetViewer()->GetEyePosition()); + + const NzIndexBuffer* indexBuffer = m_sphereMesh->GetIndexBuffer(); + NzRenderer::SetIndexBuffer(indexBuffer); + NzRenderer::SetVertexBuffer(m_sphereMesh->GetVertexBuffer()); + + for (const NzLight* light : m_renderQueue.spotLights) + { + light->Enable(m_spotLightProgram, 0); + NzMatrix4f lightMatrix; + lightMatrix.MakeIdentity(); + lightMatrix.SetScale(NzVector3f(light->GetRadius()*1.1f)); + lightMatrix.SetTranslation(light->GetPosition()); + + NzRenderer::SetMatrix(nzMatrixType_World, lightMatrix); + + // Rendu de la sphère dans le stencil buffer + NzRenderer::Enable(nzRendererParameter_ColorWrite, false); + NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); + NzRenderer::Enable(nzRendererParameter_FaceCulling, false); + NzRenderer::SetStencilCompareFunction(nzRendererComparison_Always); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + + // Rendu de la sphère comme zone d'effet + NzRenderer::Enable(nzRendererParameter_ColorWrite, true); + NzRenderer::Enable(nzRendererParameter_DepthBuffer, false); + NzRenderer::Enable(nzRendererParameter_FaceCulling, true); + NzRenderer::SetFaceCulling(nzFaceSide_Front); + NzRenderer::SetStencilCompareFunction(nzRendererComparison_NotEqual, nzFaceSide_Back); + NzRenderer::SetStencilPassOperation(nzStencilOperation_Zero, nzFaceSide_Back); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + } +} + +bool NzDeferredRenderTechnique::UpdateTextures() const +{ + /* + G-Buffer: + Texture0: Diffuse Color + Flags + Texture1: Normal map + Depth + Texture2: Specular value + Shininess + Texture3: N/A + */ + + try + { + NzErrorFlags errFlags(nzErrorFlag_ThrowException); + + unsigned int width = m_GBufferSize.x; + unsigned int height = m_GBufferSize.y; + + m_GBuffer[0]->Create(nzImageType_2D, nzPixelFormat_RGBA8, width, height); + m_GBuffer[1]->Create(nzImageType_2D, nzPixelFormat_RGBA32F, width, height); + m_GBuffer[2]->Create(nzImageType_2D, nzPixelFormat_RGBA8, width, height); + m_bloomTextureA->Create(nzImageType_2D, nzPixelFormat_RGBA8, width/8, height/8); + m_bloomTextureB->Create(nzImageType_2D, nzPixelFormat_RGBA8, width/8, height/8); + m_dofTextureA->Create(nzImageType_2D, nzPixelFormat_RGB8, width/4, height/4); + m_dofTextureB->Create(nzImageType_2D, nzPixelFormat_RGB8, width/4, height/4); + m_ssaoTextureA->Create(nzImageType_2D, nzPixelFormat_R8, width/4, height/4); + m_ssaoTextureB->Create(nzImageType_2D, nzPixelFormat_R8, width/4, height/4); + m_workTextureA->Create(nzImageType_2D, nzPixelFormat_RGBA8, width, height); + m_workTextureB->Create(nzImageType_2D, nzPixelFormat_RGBA8, width, height); + + m_geometryRTT.Create(true); + + // Texture 0 : Diffuse Color + Flags + m_geometryRTT.AttachTexture(nzAttachmentPoint_Color, 0, m_GBuffer[0]); + + // Texture 1 : Normal map + Depth + m_geometryRTT.AttachTexture(nzAttachmentPoint_Color, 1, m_GBuffer[1]); + + // Texture 2 : Specular value + Shininess + m_geometryRTT.AttachTexture(nzAttachmentPoint_Color, 2, m_GBuffer[2]); + + // Texture 3 : Emission map ? + + // Texture 4 : Target A + m_geometryRTT.AttachTexture(nzAttachmentPoint_Color, 4, m_workTextureA); + + // Texture 5 : Target B + m_geometryRTT.AttachTexture(nzAttachmentPoint_Color, 5, m_workTextureB); + + // Depth/stencil buffer + m_geometryRTT.AttachBuffer(nzAttachmentPoint_DepthStencil, 0, nzPixelFormat_Depth24Stencil8, width, height); + + m_geometryRTT.Unlock(); + + m_bloomRTT.Create(true); + m_bloomRTT.AttachTexture(nzAttachmentPoint_Color, 0, m_bloomTextureA); + m_bloomRTT.AttachTexture(nzAttachmentPoint_Color, 1, m_bloomTextureB); + m_bloomRTT.Unlock(); + + m_dofRTT.Create(true); + m_dofRTT.AttachTexture(nzAttachmentPoint_Color, 0, m_dofTextureA); + m_dofRTT.AttachTexture(nzAttachmentPoint_Color, 1, m_dofTextureB); + m_dofRTT.Unlock(); + + m_ssaoRTT.Create(true); + m_ssaoRTT.AttachTexture(nzAttachmentPoint_Color, 0, m_ssaoTextureA); + m_ssaoRTT.AttachTexture(nzAttachmentPoint_Color, 1, m_ssaoTextureB); + m_ssaoRTT.Unlock(); + + if (!m_bloomRTT.IsComplete() || !m_dofRTT.IsComplete() || !m_geometryRTT.IsComplete() || !m_ssaoRTT.IsComplete()) + { + NazaraError("Incomplete RTT"); + return false; + } + + m_texturesUpdated = true; + + return true; + } + catch (const std::exception& e) + { + NazaraError("Failed to create work RTT/G-Buffer"); + return false; + } +} diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index b7f74d920..3ea9f671e 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,9 @@ bool NzGraphics::Initialize() // RenderTechniques NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_BasicForward), 0, []() -> NzAbstractRenderTechnique* { return new NzForwardRenderTechnique; }); + if (NzDeferredRenderTechnique::IsSupported()) + NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_DeferredShading), 20, []() -> NzAbstractRenderTechnique* { return new NzDeferredRenderTechnique; }); + NazaraNotice("Initialized: Graphics module"); return true; diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/Blit.frag b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/Blit.frag new file mode 100644 index 000000000..2492b3ae2 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/Blit.frag @@ -0,0 +1,12 @@ +#version 140 + +out vec4 RenderTarget0; + +uniform sampler2D ColorTexture; +uniform vec2 InvTargetSize; + +void main() +{ + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; + RenderTarget0 = textureLod(ColorTexture, texCoord, 0.0); +} diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/Blit.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/Blit.frag.h new file mode 100644 index 000000000..79a6de09e --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/Blit.frag.h @@ -0,0 +1 @@ +35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,59,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag new file mode 100644 index 000000000..cd8b67b92 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag @@ -0,0 +1,24 @@ +#version 140 + +out vec4 RenderTarget0; + +uniform float BrightLuminance = 0.8; +uniform float BrightMiddleGrey = 0.5; +uniform float BrightThreshold = 0.8; +uniform sampler2D ColorTexture; +uniform sampler2D BloomTexture; +uniform vec2 InvTargetSize; + +void main() +{ + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; + + vec3 color = textureLod(ColorTexture, texCoord, 0.0).rgb; + + color *= BrightMiddleGrey/BrightLuminance; + color *= 1.0 + (color / (BrightThreshold*BrightThreshold)); + color -= 0.5; + color /= (1.0 + color); + + RenderTarget0 = vec4(color, 1.0); +}; diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag.h new file mode 100644 index 000000000..cf8884869 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag.h @@ -0,0 +1 @@ +35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,66,114,105,103,104,116,76,117,109,105,110,97,110,99,101,32,61,32,48,46,56,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,66,114,105,103,104,116,77,105,100,100,108,101,71,114,101,121,32,61,32,48,46,53,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,66,114,105,103,104,116,84,104,114,101,115,104,111,108,100,32,61,32,48,46,56,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,66,108,111,111,109,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,13,10,13,10,9,99,111,108,111,114,32,42,61,32,66,114,105,103,104,116,77,105,100,100,108,101,71,114,101,121,47,66,114,105,103,104,116,76,117,109,105,110,97,110,99,101,59,13,10,9,99,111,108,111,114,32,42,61,32,49,46,48,32,43,32,40,99,111,108,111,114,32,47,32,40,66,114,105,103,104,116,84,104,114,101,115,104,111,108,100,42,66,114,105,103,104,116,84,104,114,101,115,104,111,108,100,41,41,59,13,10,9,99,111,108,111,114,32,45,61,32,48,46,53,59,13,10,9,99,111,108,111,114,32,47,61,32,40,49,46,48,32,43,32,99,111,108,111,114,41,59,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,99,111,108,111,114,44,32,49,46,48,41,59,13,10,125,59,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag new file mode 100644 index 000000000..89b5c1945 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag @@ -0,0 +1,17 @@ +#version 140 + +out vec4 RenderTarget0; + +uniform sampler2D BloomTexture; +uniform sampler2D ColorTexture; +uniform vec2 InvTargetSize; + +void main() +{ + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; + + vec3 bloomColor = textureLod(BloomTexture, texCoord, 0.0).rgb; + vec3 originalColor = textureLod(ColorTexture, texCoord, 0.0).rgb; + + RenderTarget0 = vec4(originalColor + bloomColor, 1.0); +} diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag.h new file mode 100644 index 000000000..822e2795d --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag.h @@ -0,0 +1 @@ +35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,66,108,111,111,109,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,98,108,111,111,109,67,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,66,108,111,111,109,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,13,10,9,118,101,99,51,32,111,114,105,103,105,110,97,108,67,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,111,114,105,103,105,110,97,108,67,111,108,111,114,32,43,32,98,108,111,111,109,67,111,108,111,114,44,32,49,46,48,41,59,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/ClearGBuffer.frag b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/ClearGBuffer.frag new file mode 100644 index 000000000..ea24e038c --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/ClearGBuffer.frag @@ -0,0 +1,13 @@ +#version 140 + +out vec4 RenderTarget0; +out vec4 RenderTarget1; +out vec4 RenderTarget2; + +void main() +{ + RenderTarget0 = vec4(0.0, 0.0, 0.0, 0.0); + RenderTarget1 = vec4(0.0, 0.0, 0.0, 1.0); + RenderTarget2 = vec4(0.0, 0.0, 0.0, 0.0); + gl_FragDepth = 1.0; +} diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/ClearGBuffer.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/ClearGBuffer.frag.h new file mode 100644 index 000000000..762b4d95d --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/ClearGBuffer.frag.h @@ -0,0 +1 @@ +35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,48,46,48,44,32,48,46,48,44,32,48,46,48,44,32,48,46,48,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,48,46,48,44,32,48,46,48,44,32,48,46,48,44,32,49,46,48,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,48,46,48,44,32,48,46,48,44,32,48,46,48,44,32,48,46,48,41,59,13,10,9,103,108,95,70,114,97,103,68,101,112,116,104,32,61,32,49,46,48,59,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/DirectionalLight.frag b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/DirectionalLight.frag new file mode 100644 index 000000000..ee304c518 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/DirectionalLight.frag @@ -0,0 +1,81 @@ +#version 140 + +out vec4 RenderTarget0; + +struct Light +{ + int type; + vec4 ambient; + vec4 color; + vec2 factors; + + vec4 parameters1; + vec4 parameters2; + vec2 parameters3; +}; + +uniform vec3 EyePosition; +uniform Light Lights[1]; + +uniform sampler2D GBuffer0; +uniform sampler2D GBuffer1; +uniform sampler2D GBuffer2; + +uniform mat4 InvViewProjMatrix; +uniform vec2 InvTargetSize; +uniform vec4 SceneAmbient; + +void main() +{ + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; + vec4 gVec0 = textureLod(GBuffer0, texCoord, 0.0); + if (gVec0.w == 0.0) + { + RenderTarget0 = vec4(gVec0.xyz, 1.0); + return; + } + + vec4 gVec1 = textureLod(GBuffer1, texCoord, 0.0); + vec4 gVec2 = textureLod(GBuffer2, texCoord, 0.0); + + vec3 diffuseColor = gVec0.xyz; + vec3 normal = gVec1.xyz*2.0 - 1.0; + vec3 specularColor = gVec2.xyz; + float depth = gVec1.w*2.0 - 1.0; + float shininess = (gVec2.w == 0.0) ? 0.0 : exp2(gVec2.w*10.5); + + vec3 lightDir = -Lights[0].parameters1.xyz; + + // Ambient + vec3 lightAmbient = Lights[0].color.rgb * Lights[0].factors.x * (vec3(1.0) + SceneAmbient.rgb); + + // Diffuse + float lambert = max(dot(normal, lightDir), 0.0); + + vec3 lightDiffuse = lambert * Lights[0].color.rgb * Lights[0].factors.y; + + // Specular + vec3 lightSpecular = vec3(0.0); + if (shininess > 0.0) + { + vec3 viewSpace = vec3(texCoord*2.0 - 1.0, depth); + + vec4 worldPos = InvViewProjMatrix * vec4(viewSpace, 1.0); + worldPos.xyz /= worldPos.w; + + vec3 eyeVec = normalize(EyePosition - worldPos.xyz); + + vec3 reflection = reflect(-lightDir, normal); + float specularFactor = max(dot(reflection, eyeVec), 0.0); + specularFactor = pow(specularFactor, shininess); + + lightSpecular = specularFactor * Lights[0].color.rgb; + } + + lightSpecular *= specularColor; + + vec3 lightColor = (lightAmbient + lightDiffuse + lightSpecular); + vec4 fragmentColor = vec4(lightColor * diffuseColor, 1.0); + + RenderTarget0 = fragmentColor; +}; \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/DirectionalLight.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/DirectionalLight.frag.h new file mode 100644 index 000000000..afa64dbd0 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/DirectionalLight.frag.h @@ -0,0 +1 @@ +35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,97,109,98,105,101,110,116,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,125,59,13,10,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,49,93,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,71,66,117,102,102,101,114,48,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,71,66,117,102,102,101,114,49,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,71,66,117,102,102,101,114,50,59,13,10,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,73,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,9,118,101,99,52,32,103,86,101,99,48,32,61,32,116,101,120,116,117,114,101,76,111,100,40,71,66,117,102,102,101,114,48,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,59,13,10,9,105,102,32,40,103,86,101,99,48,46,119,32,61,61,32,48,46,48,41,13,10,9,123,13,10,9,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,103,86,101,99,48,46,120,121,122,44,32,49,46,48,41,59,13,10,9,9,114,101,116,117,114,110,59,13,10,9,125,13,10,13,10,9,118,101,99,52,32,103,86,101,99,49,32,61,32,116,101,120,116,117,114,101,76,111,100,40,71,66,117,102,102,101,114,49,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,59,13,10,9,118,101,99,52,32,103,86,101,99,50,32,61,32,116,101,120,116,117,114,101,76,111,100,40,71,66,117,102,102,101,114,50,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,59,13,10,13,10,9,118,101,99,51,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,103,86,101,99,48,46,120,121,122,59,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,103,86,101,99,49,46,120,121,122,42,50,46,48,32,45,32,49,46,48,59,13,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,103,86,101,99,50,46,120,121,122,59,13,10,9,102,108,111,97,116,32,100,101,112,116,104,32,61,32,103,86,101,99,49,46,119,42,50,46,48,32,45,32,49,46,48,59,13,10,9,102,108,111,97,116,32,115,104,105,110,105,110,101,115,115,32,61,32,40,103,86,101,99,50,46,119,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,101,120,112,50,40,103,86,101,99,50,46,119,42,49,48,46,53,41,59,13,10,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,48,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,47,47,32,65,109,98,105,101,110,116,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,76,105,103,104,116,115,91,48,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,48,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,118,101,99,51,40,49,46,48,41,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,47,47,32,68,105,102,102,117,115,101,13,10,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,48,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,48,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,105,102,32,40,115,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,118,105,101,119,83,112,97,99,101,32,61,32,118,101,99,51,40,116,101,120,67,111,111,114,100,42,50,46,48,32,45,32,49,46,48,44,32,100,101,112,116,104,41,59,13,10,13,10,9,9,118,101,99,52,32,119,111,114,108,100,80,111,115,32,61,32,73,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,105,101,119,83,112,97,99,101,44,32,49,46,48,41,59,13,10,9,9,119,111,114,108,100,80,111,115,46,120,121,122,32,47,61,32,119,111,114,108,100,80,111,115,46,119,59,13,10,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,119,111,114,108,100,80,111,115,46,120,121,122,41,59,13,10,13,10,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,115,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,48,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,125,13,10,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,115,112,101,99,117,108,97,114,67,111,108,111,114,59,13,10,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,44,32,49,46,48,41,59,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,125,59, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag new file mode 100644 index 000000000..e1a0f3d71 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag @@ -0,0 +1,47 @@ +#version 140 + +out vec4 RenderTarget0; + +uniform float FXAAReduceMul = 0.0; // 1.0/8.0 +uniform float FXAASpanMax = 8.0; +uniform sampler2D ColorTexture; +uniform vec2 InvTargetSize; + +void main() +{ + #define FXAA_REDUCE_MIN (1.0/128.0) + + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; + + vec3 rgbNW = textureLod(ColorTexture, texCoord, 0.0).rgb; + vec3 rgbNE = textureLodOffset(ColorTexture, texCoord, 0.0, ivec2(1,0)).rgb; + vec3 rgbSW = textureLodOffset(ColorTexture, texCoord, 0.0, ivec2(0,1)).rgb; + vec3 rgbSE = textureLodOffset(ColorTexture, texCoord, 0.0, ivec2(1,1)).rgb; + vec3 rgbM = textureLod(ColorTexture, texCoord, 0.0).rgb; + + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAAReduceMul), FXAA_REDUCE_MIN); + float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAASpanMax, FXAASpanMax), max(vec2(-FXAASpanMax, -FXAASpanMax), dir * rcpDirMin)) * InvTargetSize; + + vec3 rgbA = (1.0/2.0) * (textureLod(ColorTexture, texCoord + dir * (1.0/3.0 - 0.5), 0.0).rgb + textureLod(ColorTexture, texCoord + dir * (2.0/3.0 - 0.5), 0.0).rgb); + vec3 rgbB = rgbA * 1.0/2.0 + 1.0/4.0 * (textureLod(ColorTexture, texCoord + dir * (0.0/3.0 - 0.5), 0.0).rgb + textureLod(ColorTexture, texCoord + dir * (3.0/3.0 - 0.5), 0.0).rgb); + float lumaB = dot(rgbB, luma); + + vec3 fragmentColor = (lumaB < lumaMin || lumaB > lumaMax) ? rgbA : rgbB; + + RenderTarget0 = vec4(fragmentColor, 1.0); +} \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag.h new file mode 100644 index 000000000..cb9eb1472 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag.h @@ -0,0 +1 @@ +35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,70,88,65,65,82,101,100,117,99,101,77,117,108,32,61,32,48,46,48,59,32,47,47,32,49,46,48,47,56,46,48,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,70,88,65,65,83,112,97,110,77,97,120,32,61,32,56,46,48,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,32,32,32,32,35,100,101,102,105,110,101,32,70,88,65,65,95,82,69,68,85,67,69,95,77,73,78,32,32,32,40,49,46,48,47,49,50,56,46,48,41,13,10,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,32,32,32,32,118,101,99,51,32,114,103,98,78,87,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,13,10,32,32,32,32,118,101,99,51,32,114,103,98,78,69,32,61,32,116,101,120,116,117,114,101,76,111,100,79,102,102,115,101,116,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,44,32,105,118,101,99,50,40,49,44,48,41,41,46,114,103,98,59,13,10,32,32,32,32,118,101,99,51,32,114,103,98,83,87,32,61,32,116,101,120,116,117,114,101,76,111,100,79,102,102,115,101,116,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,44,32,105,118,101,99,50,40,48,44,49,41,41,46,114,103,98,59,13,10,32,32,32,32,118,101,99,51,32,114,103,98,83,69,32,61,32,116,101,120,116,117,114,101,76,111,100,79,102,102,115,101,116,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,44,32,105,118,101,99,50,40,49,44,49,41,41,46,114,103,98,59,13,10,32,32,32,32,118,101,99,51,32,114,103,98,77,32,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,13,10,13,10,32,32,32,32,118,101,99,51,32,108,117,109,97,32,61,32,118,101,99,51,40,48,46,50,57,57,44,32,48,46,53,56,55,44,32,48,46,49,49,52,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,78,87,32,61,32,100,111,116,40,114,103,98,78,87,44,32,108,117,109,97,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,78,69,32,61,32,100,111,116,40,114,103,98,78,69,44,32,108,117,109,97,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,83,87,32,61,32,100,111,116,40,114,103,98,83,87,44,32,108,117,109,97,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,83,69,32,61,32,100,111,116,40,114,103,98,83,69,44,32,108,117,109,97,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,77,32,32,61,32,100,111,116,40,114,103,98,77,44,32,32,108,117,109,97,41,59,13,10,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,77,105,110,32,61,32,109,105,110,40,108,117,109,97,77,44,32,109,105,110,40,109,105,110,40,108,117,109,97,78,87,44,32,108,117,109,97,78,69,41,44,32,109,105,110,40,108,117,109,97,83,87,44,32,108,117,109,97,83,69,41,41,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,77,97,120,32,61,32,109,97,120,40,108,117,109,97,77,44,32,109,97,120,40,109,97,120,40,108,117,109,97,78,87,44,32,108,117,109,97,78,69,41,44,32,109,97,120,40,108,117,109,97,83,87,44,32,108,117,109,97,83,69,41,41,41,59,13,10,13,10,32,32,32,32,118,101,99,50,32,100,105,114,59,32,13,10,32,32,32,32,100,105,114,46,120,32,61,32,45,40,40,108,117,109,97,78,87,32,43,32,108,117,109,97,78,69,41,32,45,32,40,108,117,109,97,83,87,32,43,32,108,117,109,97,83,69,41,41,59,13,10,32,32,32,32,100,105,114,46,121,32,61,32,32,40,40,108,117,109,97,78,87,32,43,32,108,117,109,97,83,87,41,32,45,32,40,108,117,109,97,78,69,32,43,32,108,117,109,97,83,69,41,41,59,13,10,13,10,32,32,32,32,102,108,111,97,116,32,100,105,114,82,101,100,117,99,101,32,61,32,109,97,120,40,40,108,117,109,97,78,87,32,43,32,108,117,109,97,78,69,32,43,32,108,117,109,97,83,87,32,43,32,108,117,109,97,83,69,41,32,42,32,40,48,46,50,53,32,42,32,70,88,65,65,82,101,100,117,99,101,77,117,108,41,44,32,70,88,65,65,95,82,69,68,85,67,69,95,77,73,78,41,59,13,10,32,32,32,32,102,108,111,97,116,32,114,99,112,68,105,114,77,105,110,32,61,32,49,46,48,47,40,109,105,110,40,97,98,115,40,100,105,114,46,120,41,44,32,97,98,115,40,100,105,114,46,121,41,41,32,43,32,100,105,114,82,101,100,117,99,101,41,59,13,10,32,32,32,32,100,105,114,32,61,32,109,105,110,40,118,101,99,50,40,70,88,65,65,83,112,97,110,77,97,120,44,32,70,88,65,65,83,112,97,110,77,97,120,41,44,32,109,97,120,40,118,101,99,50,40,45,70,88,65,65,83,112,97,110,77,97,120,44,32,45,70,88,65,65,83,112,97,110,77,97,120,41,44,32,100,105,114,32,42,32,114,99,112,68,105,114,77,105,110,41,41,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,32,32,32,32,118,101,99,51,32,114,103,98,65,32,61,32,40,49,46,48,47,50,46,48,41,32,42,32,40,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,49,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,32,43,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,50,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,41,59,13,10,32,32,32,32,118,101,99,51,32,114,103,98,66,32,61,32,114,103,98,65,32,42,32,49,46,48,47,50,46,48,32,43,32,49,46,48,47,52,46,48,32,42,32,40,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,48,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,32,43,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,100,105,114,32,42,32,40,51,46,48,47,51,46,48,32,45,32,48,46,53,41,44,32,48,46,48,41,46,114,103,98,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,117,109,97,66,32,61,32,100,111,116,40,114,103,98,66,44,32,108,117,109,97,41,59,13,10,13,10,9,118,101,99,51,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,40,108,117,109,97,66,32,60,32,108,117,109,97,77,105,110,32,124,124,32,108,117,109,97,66,32,62,32,108,117,109,97,77,97,120,41,32,63,32,114,103,98,65,32,58,32,114,103,98,66,59,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,102,114,97,103,109,101,110,116,67,111,108,111,114,44,32,49,46,48,41,59,13,10,125, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag new file mode 100644 index 000000000..16c3a0996 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag @@ -0,0 +1,25 @@ +// http://www.geeks3d.com/20100909/shader-library-gaussian-blur-post-processing-filter-in-glsl/ +#version 140 + +out vec4 RenderTarget0; + +uniform sampler2D ColorTexture; +uniform vec2 Filter; +uniform vec2 InvTargetSize; + +float offset[3] = float[](0.0, 1.3846153846, 3.2307692308); +float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703); + +void main() +{ + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; + vec3 color = textureLod(ColorTexture, texCoord, 0.0).rgb * weight[0]; + + for (int i = 1; i < 3; i++) + { + color += textureLod(ColorTexture, texCoord + Filter*vec2(offset[i])*InvTargetSize, 0.0).rgb * weight[i]; + color += textureLod(ColorTexture, texCoord - Filter*vec2(offset[i])*InvTargetSize, 0.0).rgb * weight[i]; + } + + RenderTarget0 = vec4(color, 1.0); +} diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag.h new file mode 100644 index 000000000..368c99770 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag.h @@ -0,0 +1 @@ +47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,101,101,107,115,51,100,46,99,111,109,47,50,48,49,48,48,57,48,57,47,115,104,97,100,101,114,45,108,105,98,114,97,114,121,45,103,97,117,115,115,105,97,110,45,98,108,117,114,45,112,111,115,116,45,112,114,111,99,101,115,115,105,110,103,45,102,105,108,116,101,114,45,105,110,45,103,108,115,108,47,13,10,35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,70,105,108,116,101,114,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,102,108,111,97,116,32,111,102,102,115,101,116,91,51,93,32,61,32,102,108,111,97,116,91,93,40,48,46,48,44,32,49,46,51,56,52,54,49,53,51,56,52,54,44,32,51,46,50,51,48,55,54,57,50,51,48,56,41,59,13,10,102,108,111,97,116,32,119,101,105,103,104,116,91,51,93,32,61,32,102,108,111,97,116,91,93,40,48,46,50,50,55,48,50,55,48,50,55,48,44,32,48,46,51,49,54,50,49,54,50,49,54,50,44,32,48,46,48,55,48,50,55,48,50,55,48,51,41,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,9,118,101,99,51,32,99,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,32,42,32,119,101,105,103,104,116,91,48,93,59,13,10,13,10,9,102,111,114,32,40,105,110,116,32,105,32,61,32,49,59,32,105,32,60,32,51,59,32,105,43,43,41,13,10,9,123,13,10,9,9,99,111,108,111,114,32,43,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,43,32,70,105,108,116,101,114,42,118,101,99,50,40,111,102,102,115,101,116,91,105,93,41,42,73,110,118,84,97,114,103,101,116,83,105,122,101,44,32,48,46,48,41,46,114,103,98,32,42,32,119,101,105,103,104,116,91,105,93,59,13,10,9,9,99,111,108,111,114,32,43,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,45,32,70,105,108,116,101,114,42,118,101,99,50,40,111,102,102,115,101,116,91,105,93,41,42,73,110,118,84,97,114,103,101,116,83,105,122,101,44,32,48,46,48,41,46,114,103,98,32,42,32,119,101,105,103,104,116,91,105,93,59,13,10,9,125,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,99,111,108,111,114,44,32,49,46,48,41,59,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/PointLight.frag b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/PointLight.frag new file mode 100644 index 000000000..fce472025 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/PointLight.frag @@ -0,0 +1,84 @@ +#version 140 + +out vec4 RenderTarget0; + +struct Light +{ + int type; + vec4 ambient; + vec4 color; + vec2 factors; + + vec4 parameters1; + vec4 parameters2; + vec2 parameters3; +}; + +uniform vec3 EyePosition; +uniform Light Lights[1]; + +uniform sampler2D GBuffer0; +uniform sampler2D GBuffer1; +uniform sampler2D GBuffer2; + +uniform mat4 InvViewProjMatrix; +uniform vec2 InvTargetSize; +uniform vec4 SceneAmbient; + +void main() +{ + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; + vec4 gVec0 = textureLod(GBuffer0, texCoord, 0.0); + if (gVec0.w == 0.0) + { + RenderTarget0 = vec4(gVec0.xyz, 1.0); + return; + } + + vec4 gVec1 = textureLod(GBuffer1, texCoord, 0.0); + vec4 gVec2 = textureLod(GBuffer2, texCoord, 0.0); + + vec3 diffuseColor = gVec0.xyz; + vec3 normal = gVec1.xyz*2.0 - 1.0; + vec3 specularColor = gVec2.xyz; + float depth = gVec1.w*2.0 - 1.0; + float shininess = (gVec2.w == 0.0) ? 0.0 : exp2(gVec2.w*10.5); + + vec3 viewSpace = vec3(texCoord*2.0 - 1.0, depth); + + vec4 worldPos = InvViewProjMatrix * vec4(viewSpace, 1.0); + worldPos.xyz /= worldPos.w; + + vec3 lightDir = Lights[0].parameters1.xyz - worldPos.xyz; + float lightDirLength = length(lightDir); + lightDir /= lightDirLength; + + float att = max(Lights[0].parameters1.w - Lights[0].parameters2.x*lightDirLength, 0.0); + + // Ambient + vec3 lightAmbient = att * Lights[0].color.rgb * Lights[0].factors.x * (vec3(1.0) + SceneAmbient.rgb); + + // Diffuse + float lambert = max(dot(normal, lightDir), 0.0); + + vec3 lightDiffuse = att * lambert * Lights[0].color.rgb * Lights[0].factors.y; + + // Specular + vec3 lightSpecular = vec3(0.0); + if (shininess > 0.0) + { + vec3 eyeVec = normalize(EyePosition - worldPos.xyz); + vec3 reflection = reflect(-lightDir, normal); + float specularFactor = max(dot(reflection, eyeVec), 0.0); + specularFactor = pow(specularFactor, shininess); + + lightSpecular = att * specularFactor * Lights[0].color.rgb; + } + + lightSpecular *= specularColor; + + vec3 lightColor = (lightAmbient + lightDiffuse + lightSpecular); + vec4 fragmentColor = vec4(lightColor * diffuseColor, 1.0); + + RenderTarget0 = fragmentColor; +}; \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/PointLight.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/PointLight.frag.h new file mode 100644 index 000000000..20d7e37f4 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/PointLight.frag.h @@ -0,0 +1 @@ +35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,97,109,98,105,101,110,116,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,125,59,13,10,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,49,93,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,71,66,117,102,102,101,114,48,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,71,66,117,102,102,101,114,49,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,71,66,117,102,102,101,114,50,59,13,10,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,73,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,9,118,101,99,52,32,103,86,101,99,48,32,61,32,116,101,120,116,117,114,101,76,111,100,40,71,66,117,102,102,101,114,48,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,59,13,10,9,105,102,32,40,103,86,101,99,48,46,119,32,61,61,32,48,46,48,41,13,10,9,123,13,10,9,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,103,86,101,99,48,46,120,121,122,44,32,49,46,48,41,59,13,10,9,9,114,101,116,117,114,110,59,13,10,9,125,13,10,13,10,9,118,101,99,52,32,103,86,101,99,49,32,61,32,116,101,120,116,117,114,101,76,111,100,40,71,66,117,102,102,101,114,49,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,59,13,10,9,118,101,99,52,32,103,86,101,99,50,32,61,32,116,101,120,116,117,114,101,76,111,100,40,71,66,117,102,102,101,114,50,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,59,13,10,13,10,9,118,101,99,51,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,103,86,101,99,48,46,120,121,122,59,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,103,86,101,99,49,46,120,121,122,42,50,46,48,32,45,32,49,46,48,59,13,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,103,86,101,99,50,46,120,121,122,59,13,10,9,102,108,111,97,116,32,100,101,112,116,104,32,61,32,103,86,101,99,49,46,119,42,50,46,48,32,45,32,49,46,48,59,13,10,9,102,108,111,97,116,32,115,104,105,110,105,110,101,115,115,32,61,32,40,103,86,101,99,50,46,119,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,101,120,112,50,40,103,86,101,99,50,46,119,42,49,48,46,53,41,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,83,112,97,99,101,32,61,32,118,101,99,51,40,116,101,120,67,111,111,114,100,42,50,46,48,32,45,32,49,46,48,44,32,100,101,112,116,104,41,59,13,10,13,10,9,118,101,99,52,32,119,111,114,108,100,80,111,115,32,61,32,73,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,105,101,119,83,112,97,99,101,44,32,49,46,48,41,59,13,10,9,119,111,114,108,100,80,111,115,46,120,121,122,32,47,61,32,119,111,114,108,100,80,111,115,46,119,59,13,10,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,48,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,119,111,114,108,100,80,111,115,46,120,121,122,59,13,10,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,13,10,13,10,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,48,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,48,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,47,47,32,65,109,98,105,101,110,116,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,48,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,48,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,118,101,99,51,40,49,46,48,41,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,47,47,32,68,105,102,102,117,115,101,13,10,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,48,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,48,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,105,102,32,40,115,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,119,111,114,108,100,80,111,115,46,120,121,122,41,59,13,10,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,115,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,48,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,125,13,10,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,115,112,101,99,117,108,97,114,67,111,108,111,114,59,13,10,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,44,32,49,46,48,41,59,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,125,59, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAO.frag b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAO.frag new file mode 100644 index 000000000..cbc4a6044 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAO.frag @@ -0,0 +1,82 @@ +#version 140 + +out vec4 RenderTarget0; + +uniform float SSAOBias = 0.0; +uniform float SSAOIntensity = 3.0; +uniform float SSAOSampleScale = 0.1; +uniform float SSAOScale = 1.0; +uniform int NoiseTextureSize; +uniform mat4 InvViewProjMatrix; +uniform sampler2D GBuffer1; +uniform sampler2D NoiseTexture; +uniform vec2 TargetSize; +uniform vec2 InvTargetSize; + +vec3 extractPosition(in float depth, in vec2 texCoord) +{ + depth = depth*2.0 - 1.0; + + vec3 viewSpace = vec3(texCoord*2.0 - 1.0, depth); + + vec4 worldPos = InvViewProjMatrix * vec4(viewSpace, 1.0); + worldPos.xyz /= worldPos.w; + + return worldPos.xyz; +} + +float doAmbientOcclusion(in vec2 texCoord, in vec3 original, in vec3 normal) +{ + vec3 newp = extractPosition(textureLod(GBuffer1, texCoord, 0.0).w, texCoord); + vec3 diff = newp - original; + float d = length(diff); + vec3 v = diff * 1.0/d; + d *= SSAOScale; + + return max(0.0, dot(normal, v) - SSAOBias) * (SSAOIntensity / (1.0 + d)); +} + +void main(void) +{ + const vec2 Kernel[16] = vec2[]( + vec2(0.53812504, 0.18565957), + vec2(0.13790712, 0.24864247), + vec2(0.33715037, 0.56794053), + vec2(-0.6999805, -0.04511441), + vec2(0.06896307, -0.15983082), + vec2(0.056099437, 0.006954967), + vec2(-0.014653638, 0.14027752), + vec2(0.010019933, -0.1924225), + vec2(-0.35775623, -0.5301969), + vec2(-0.3169221, 0.106360726), + vec2(0.010350345, -0.58698344), + vec2(-0.08972908, -0.49408212), + vec2(0.7119986, -0.0154690035), + vec2(-0.053382345, 0.059675813), + vec2(0.035267662, -0.063188605), + vec2(-0.47761092, 0.2847911)); + + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; + vec4 gVec1 = textureLod(GBuffer1, texCoord, 0.0); + + if (gVec1.w == 1.0) + { + RenderTarget0 = vec4(1.0, 0.0, 0.0, 0.0); + return; + } + + vec3 normal = gVec1.xyz*2.0 - 1.0; + + vec3 viewPos = extractPosition(gVec1.w, texCoord); + vec2 randVec = normalize(textureLod(NoiseTexture, texCoord * (TargetSize/NoiseTextureSize), 0.0).xy * 2.0 - 1.0); + + float ao = 0.0; + const int ITERATIONS = 16; + for (int i = 0; i < ITERATIONS; ++i) + { + vec2 coord = reflect(Kernel[i], randVec) * SSAOSampleScale; + ao += doAmbientOcclusion(texCoord + coord, viewPos, normal); + } + + RenderTarget0 = vec4(1.0 - ao/ITERATIONS, 0.0, 0.0, 0.0); +} \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAO.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAO.frag.h new file mode 100644 index 000000000..8306a5ac2 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAO.frag.h @@ -0,0 +1 @@ +35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,83,83,65,79,66,105,97,115,32,61,32,48,46,48,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,83,83,65,79,73,110,116,101,110,115,105,116,121,32,61,32,51,46,48,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,83,83,65,79,83,97,109,112,108,101,83,99,97,108,101,32,61,32,48,46,49,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,83,83,65,79,83,99,97,108,101,32,61,32,49,46,48,59,13,10,117,110,105,102,111,114,109,32,105,110,116,32,78,111,105,115,101,84,101,120,116,117,114,101,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,73,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,71,66,117,102,102,101,114,49,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,78,111,105,115,101,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,118,101,99,51,32,101,120,116,114,97,99,116,80,111,115,105,116,105,111,110,40,105,110,32,102,108,111,97,116,32,100,101,112,116,104,44,32,105,110,32,118,101,99,50,32,116,101,120,67,111,111,114,100,41,13,10,123,13,10,9,100,101,112,116,104,32,61,32,100,101,112,116,104,42,50,46,48,32,45,32,49,46,48,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,83,112,97,99,101,32,61,32,118,101,99,51,40,116,101,120,67,111,111,114,100,42,50,46,48,32,45,32,49,46,48,44,32,100,101,112,116,104,41,59,13,10,13,10,9,118,101,99,52,32,119,111,114,108,100,80,111,115,32,61,32,73,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,105,101,119,83,112,97,99,101,44,32,49,46,48,41,59,13,10,9,119,111,114,108,100,80,111,115,46,120,121,122,32,47,61,32,119,111,114,108,100,80,111,115,46,119,59,13,10,13,10,9,114,101,116,117,114,110,32,119,111,114,108,100,80,111,115,46,120,121,122,59,13,10,125,13,10,13,10,102,108,111,97,116,32,100,111,65,109,98,105,101,110,116,79,99,99,108,117,115,105,111,110,40,105,110,32,118,101,99,50,32,116,101,120,67,111,111,114,100,44,32,105,110,32,118,101,99,51,32,111,114,105,103,105,110,97,108,44,32,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,13,10,123,13,10,9,118,101,99,51,32,110,101,119,112,32,61,32,101,120,116,114,97,99,116,80,111,115,105,116,105,111,110,40,116,101,120,116,117,114,101,76,111,100,40,71,66,117,102,102,101,114,49,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,119,44,32,116,101,120,67,111,111,114,100,41,59,13,10,9,118,101,99,51,32,100,105,102,102,32,61,32,110,101,119,112,32,45,32,111,114,105,103,105,110,97,108,59,13,10,9,102,108,111,97,116,32,100,32,61,32,108,101,110,103,116,104,40,100,105,102,102,41,59,13,10,9,118,101,99,51,32,118,32,61,32,100,105,102,102,32,42,32,49,46,48,47,100,59,13,10,9,100,32,42,61,32,83,83,65,79,83,99,97,108,101,59,13,10,13,10,9,114,101,116,117,114,110,32,109,97,120,40,48,46,48,44,32,100,111,116,40,110,111,114,109,97,108,44,32,118,41,32,45,32,83,83,65,79,66,105,97,115,41,32,42,32,40,83,83,65,79,73,110,116,101,110,115,105,116,121,32,47,32,40,49,46,48,32,43,32,100,41,41,59,13,10,125,13,10,13,10,118,111,105,100,32,109,97,105,110,40,118,111,105,100,41,13,10,123,13,10,9,99,111,110,115,116,32,118,101,99,50,32,75,101,114,110,101,108,91,49,54,93,32,61,32,118,101,99,50,91,93,40,13,10,9,9,118,101,99,50,40,48,46,53,51,56,49,50,53,48,52,44,32,48,46,49,56,53,54,53,57,53,55,41,44,13,10,9,9,118,101,99,50,40,48,46,49,51,55,57,48,55,49,50,44,32,48,46,50,52,56,54,52,50,52,55,41,44,13,10,9,9,118,101,99,50,40,48,46,51,51,55,49,53,48,51,55,44,32,48,46,53,54,55,57,52,48,53,51,41,44,13,10,9,9,118,101,99,50,40,45,48,46,54,57,57,57,56,48,53,44,32,45,48,46,48,52,53,49,49,52,52,49,41,44,13,10,9,9,118,101,99,50,40,48,46,48,54,56,57,54,51,48,55,44,32,45,48,46,49,53,57,56,51,48,56,50,41,44,13,10,9,9,118,101,99,50,40,48,46,48,53,54,48,57,57,52,51,55,44,32,48,46,48,48,54,57,53,52,57,54,55,41,44,13,10,9,9,118,101,99,50,40,45,48,46,48,49,52,54,53,51,54,51,56,44,32,48,46,49,52,48,50,55,55,53,50,41,44,13,10,9,9,118,101,99,50,40,48,46,48,49,48,48,49,57,57,51,51,44,32,45,48,46,49,57,50,52,50,50,53,41,44,13,10,9,9,118,101,99,50,40,45,48,46,51,53,55,55,53,54,50,51,44,32,45,48,46,53,51,48,49,57,54,57,41,44,13,10,9,9,118,101,99,50,40,45,48,46,51,49,54,57,50,50,49,44,32,48,46,49,48,54,51,54,48,55,50,54,41,44,13,10,9,9,118,101,99,50,40,48,46,48,49,48,51,53,48,51,52,53,44,32,45,48,46,53,56,54,57,56,51,52,52,41,44,13,10,9,9,118,101,99,50,40,45,48,46,48,56,57,55,50,57,48,56,44,32,45,48,46,52,57,52,48,56,50,49,50,41,44,13,10,9,9,118,101,99,50,40,48,46,55,49,49,57,57,56,54,44,32,45,48,46,48,49,53,52,54,57,48,48,51,53,41,44,13,10,9,9,118,101,99,50,40,45,48,46,48,53,51,51,56,50,51,52,53,44,32,48,46,48,53,57,54,55,53,56,49,51,41,44,13,10,9,9,118,101,99,50,40,48,46,48,51,53,50,54,55,54,54,50,44,32,45,48,46,48,54,51,49,56,56,54,48,53,41,44,13,10,9,9,118,101,99,50,40,45,48,46,52,55,55,54,49,48,57,50,44,32,48,46,50,56,52,55,57,49,49,41,41,59,13,10,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,9,118,101,99,52,32,103,86,101,99,49,32,61,32,116,101,120,116,117,114,101,76,111,100,40,71,66,117,102,102,101,114,49,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,59,13,10,9,13,10,9,105,102,32,40,103,86,101,99,49,46,119,32,61,61,32,49,46,48,41,13,10,9,123,13,10,9,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,49,46,48,44,32,48,46,48,44,32,48,46,48,44,32,48,46,48,41,59,13,10,9,9,114,101,116,117,114,110,59,13,10,9,125,13,10,9,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,103,86,101,99,49,46,120,121,122,42,50,46,48,32,45,32,49,46,48,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,80,111,115,32,61,32,101,120,116,114,97,99,116,80,111,115,105,116,105,111,110,40,103,86,101,99,49,46,119,44,32,116,101,120,67,111,111,114,100,41,59,13,10,9,118,101,99,50,32,114,97,110,100,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,116,101,120,116,117,114,101,76,111,100,40,78,111,105,115,101,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,32,42,32,40,84,97,114,103,101,116,83,105,122,101,47,78,111,105,115,101,84,101,120,116,117,114,101,83,105,122,101,41,44,32,48,46,48,41,46,120,121,32,42,32,50,46,48,32,45,32,49,46,48,41,59,13,10,13,10,9,102,108,111,97,116,32,97,111,32,61,32,48,46,48,59,13,10,9,99,111,110,115,116,32,105,110,116,32,73,84,69,82,65,84,73,79,78,83,32,61,32,49,54,59,13,10,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,73,84,69,82,65,84,73,79,78,83,59,32,43,43,105,41,13,10,9,123,13,10,9,9,118,101,99,50,32,99,111,111,114,100,32,61,32,114,101,102,108,101,99,116,40,75,101,114,110,101,108,91,105,93,44,32,114,97,110,100,86,101,99,41,32,42,32,83,83,65,79,83,97,109,112,108,101,83,99,97,108,101,59,13,10,9,9,97,111,32,43,61,32,100,111,65,109,98,105,101,110,116,79,99,99,108,117,115,105,111,110,40,116,101,120,67,111,111,114,100,32,43,32,99,111,111,114,100,44,32,118,105,101,119,80,111,115,44,32,110,111,114,109,97,108,41,59,13,10,9,125,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,49,46,48,32,45,32,97,111,47,73,84,69,82,65,84,73,79,78,83,44,32,48,46,48,44,32,48,46,48,44,32,48,46,48,41,59,13,10,125, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAOFinal.frag b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAOFinal.frag new file mode 100644 index 000000000..b0b55d5a8 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAOFinal.frag @@ -0,0 +1,17 @@ +#version 140 + +out vec4 RenderTarget0; + +uniform sampler2D ColorTexture; +uniform sampler2D SSAOTexture; +uniform vec2 InvTargetSize; + +void main() +{ + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; + + vec3 color = textureLod(ColorTexture, texCoord, 0.0).rgb; + float ssao = textureLod(SSAOTexture, texCoord, 0.0).r; + + RenderTarget0 = vec4(color*ssao, 1.0); +} diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAOFinal.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAOFinal.frag.h new file mode 100644 index 000000000..f05f0097d --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SSAOFinal.frag.h @@ -0,0 +1 @@ +35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,67,111,108,111,114,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,83,83,65,79,84,101,120,116,117,114,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,111,108,111,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,67,111,108,111,114,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,103,98,59,13,10,9,102,108,111,97,116,32,115,115,97,111,32,61,32,116,101,120,116,117,114,101,76,111,100,40,83,83,65,79,84,101,120,116,117,114,101,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,46,114,59,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,99,111,108,111,114,42,115,115,97,111,44,32,49,46,48,41,59,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SpotLight.frag b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SpotLight.frag new file mode 100644 index 000000000..25637b5f6 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SpotLight.frag @@ -0,0 +1,90 @@ +#version 140 + +out vec4 RenderTarget0; + +struct Light +{ + int type; + vec4 ambient; + vec4 color; + vec2 factors; + + vec4 parameters1; + vec4 parameters2; + vec2 parameters3; +}; + +uniform vec3 EyePosition; +uniform Light Lights[1]; + +uniform sampler2D GBuffer0; +uniform sampler2D GBuffer1; +uniform sampler2D GBuffer2; + +uniform mat4 InvViewProjMatrix; +uniform vec2 InvTargetSize; +uniform vec4 SceneAmbient; + +void main() +{ + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; + vec4 gVec0 = textureLod(GBuffer0, texCoord, 0.0); + if (gVec0.w == 0.0) + { + RenderTarget0 = vec4(gVec0.xyz, 1.0); + return; + } + + vec4 gVec1 = textureLod(GBuffer1, texCoord, 0.0); + vec4 gVec2 = textureLod(GBuffer2, texCoord, 0.0); + + vec3 diffuseColor = gVec0.xyz; + vec3 normal = gVec1.xyz*2.0 - 1.0; + vec3 specularColor = gVec2.xyz; + float depth = gVec1.w*2.0 - 1.0; + float shininess = (gVec2.w == 0.0) ? 0.0 : exp2(gVec2.w*10.5); + + vec3 viewSpace = vec3(texCoord*2.0 - 1.0, depth); + + vec4 worldPos = InvViewProjMatrix * vec4(viewSpace, 1.0); + worldPos.xyz /= worldPos.w; + + vec3 lightDir = Lights[0].parameters1.xyz - worldPos.xyz; + float lightDirLength = length(lightDir); + lightDir /= lightDirLength; + + float att = max(Lights[0].parameters1.w - Lights[0].parameters2.w*lightDirLength, 0.0); + + // Ambient + vec3 lightAmbient = att * Lights[0].color.rgb * Lights[0].factors.x * (vec3(1.0) + SceneAmbient.rgb); + + // Modification de l'atténuation pour gérer le spot + float curAngle = dot(Lights[0].parameters2.xyz, -lightDir); + float outerAngle = Lights[0].parameters3.y; + float innerMinusOuterAngle = Lights[0].parameters3.x - outerAngle; + att *= max((curAngle - outerAngle) / innerMinusOuterAngle, 0.0); + + // Diffuse + float lambert = max(dot(normal, lightDir), 0.0); + + vec3 lightDiffuse = att * lambert * Lights[0].color.rgb * Lights[0].factors.y; + + // Specular + vec3 lightSpecular = vec3(0.0); + if (shininess > 0.0) + { + vec3 eyeVec = normalize(EyePosition - worldPos.xyz); + vec3 reflection = reflect(-lightDir, normal); + float specularFactor = max(dot(reflection, eyeVec), 0.0); + specularFactor = pow(specularFactor, shininess); + + lightSpecular = att * specularFactor * Lights[0].color.rgb; + } + + lightSpecular *= specularColor; + + vec3 lightColor = (lightAmbient + lightDiffuse + lightSpecular); + vec4 fragmentColor = vec4(lightColor * diffuseColor, 1.0); + + RenderTarget0 = fragmentColor; +} \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SpotLight.frag.h b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SpotLight.frag.h new file mode 100644 index 000000000..3ebdb2d98 --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Shaders/SpotLight.frag.h @@ -0,0 +1 @@ +35,118,101,114,115,105,111,110,32,49,52,48,13,10,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,97,109,98,105,101,110,116,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,125,59,13,10,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,49,93,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,71,66,117,102,102,101,114,48,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,71,66,117,102,102,101,114,49,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,71,66,117,102,102,101,114,50,59,13,10,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,73,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,9,118,101,99,52,32,103,86,101,99,48,32,61,32,116,101,120,116,117,114,101,76,111,100,40,71,66,117,102,102,101,114,48,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,59,13,10,9,105,102,32,40,103,86,101,99,48,46,119,32,61,61,32,48,46,48,41,13,10,9,123,13,10,9,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,103,86,101,99,48,46,120,121,122,44,32,49,46,48,41,59,13,10,9,9,114,101,116,117,114,110,59,13,10,9,125,13,10,13,10,9,118,101,99,52,32,103,86,101,99,49,32,61,32,116,101,120,116,117,114,101,76,111,100,40,71,66,117,102,102,101,114,49,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,59,13,10,9,118,101,99,52,32,103,86,101,99,50,32,61,32,116,101,120,116,117,114,101,76,111,100,40,71,66,117,102,102,101,114,50,44,32,116,101,120,67,111,111,114,100,44,32,48,46,48,41,59,13,10,13,10,9,118,101,99,51,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,103,86,101,99,48,46,120,121,122,59,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,103,86,101,99,49,46,120,121,122,42,50,46,48,32,45,32,49,46,48,59,13,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,103,86,101,99,50,46,120,121,122,59,13,10,9,102,108,111,97,116,32,100,101,112,116,104,32,61,32,103,86,101,99,49,46,119,42,50,46,48,32,45,32,49,46,48,59,13,10,9,102,108,111,97,116,32,115,104,105,110,105,110,101,115,115,32,61,32,40,103,86,101,99,50,46,119,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,101,120,112,50,40,103,86,101,99,50,46,119,42,49,48,46,53,41,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,83,112,97,99,101,32,61,32,118,101,99,51,40,116,101,120,67,111,111,114,100,42,50,46,48,32,45,32,49,46,48,44,32,100,101,112,116,104,41,59,13,10,13,10,9,118,101,99,52,32,119,111,114,108,100,80,111,115,32,61,32,73,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,105,101,119,83,112,97,99,101,44,32,49,46,48,41,59,13,10,9,119,111,114,108,100,80,111,115,46,120,121,122,32,47,61,32,119,111,114,108,100,80,111,115,46,119,59,13,10,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,48,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,119,111,114,108,100,80,111,115,46,120,121,122,59,13,10,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,13,10,13,10,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,48,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,48,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,47,47,32,65,109,98,105,101,110,116,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,48,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,48,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,118,101,99,51,40,49,46,48,41,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,-61,-87,110,117,97,116,105,111,110,32,112,111,117,114,32,103,-61,-87,114,101,114,32,108,101,32,115,112,111,116,13,10,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,76,105,103,104,116,115,91,48,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,44,32,45,108,105,103,104,116,68,105,114,41,59,13,10,9,102,108,111,97,116,32,111,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,48,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,48,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,32,45,32,111,117,116,101,114,65,110,103,108,101,59,13,10,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,111,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,47,47,32,68,105,102,102,117,115,101,13,10,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,48,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,48,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,105,102,32,40,115,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,119,111,114,108,100,80,111,115,46,120,121,122,41,59,13,10,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,115,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,48,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,125,13,10,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,115,112,101,99,117,108,97,114,67,111,108,111,114,59,13,10,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,44,32,49,46,48,41,59,13,10,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,125, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/DeferredShading/Textures/ssaoNoise.jpg.h b/src/Nazara/Graphics/Resources/DeferredShading/Textures/ssaoNoise.jpg.h new file mode 100644 index 000000000..e8433cbff --- /dev/null +++ b/src/Nazara/Graphics/Resources/DeferredShading/Textures/ssaoNoise.jpg.h @@ -0,0 +1 @@ +-1,-40,-1,-32,0,16,74,70,73,70,0,1,1,2,0,28,0,28,0,0,-1,-30,12,88,73,67,67,95,80,82,79,70,73,76,69,0,1,1,0,0,12,72,76,105,110,111,2,16,0,0,109,110,116,114,82,71,66,32,88,89,90,32,7,-50,0,2,0,9,0,6,0,49,0,0,97,99,115,112,77,83,70,84,0,0,0,0,73,69,67,32,115,82,71,66,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-10,-42,0,1,0,0,0,0,-45,45,72,80,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,99,112,114,116,0,0,1,80,0,0,0,51,100,101,115,99,0,0,1,-124,0,0,0,108,119,116,112,116,0,0,1,-16,0,0,0,20,98,107,112,116,0,0,2,4,0,0,0,20,114,88,89,90,0,0,2,24,0,0,0,20,103,88,89,90,0,0,2,44,0,0,0,20,98,88,89,90,0,0,2,64,0,0,0,20,100,109,110,100,0,0,2,84,0,0,0,112,100,109,100,100,0,0,2,-60,0,0,0,-120,118,117,101,100,0,0,3,76,0,0,0,-122,118,105,101,119,0,0,3,-44,0,0,0,36,108,117,109,105,0,0,3,-8,0,0,0,20,109,101,97,115,0,0,4,12,0,0,0,36,116,101,99,104,0,0,4,48,0,0,0,12,114,84,82,67,0,0,4,60,0,0,8,12,103,84,82,67,0,0,4,60,0,0,8,12,98,84,82,67,0,0,4,60,0,0,8,12,116,101,120,116,0,0,0,0,67,111,112,121,114,105,103,104,116,32,40,99,41,32,49,57,57,56,32,72,101,119,108,101,116,116,45,80,97,99,107,97,114,100,32,67,111,109,112,97,110,121,0,0,100,101,115,99,0,0,0,0,0,0,0,18,115,82,71,66,32,73,69,67,54,49,57,54,54,45,50,46,49,0,0,0,0,0,0,0,0,0,0,0,18,115,82,71,66,32,73,69,67,54,49,57,54,54,45,50,46,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,89,90,32,0,0,0,0,0,0,-13,81,0,1,0,0,0,1,22,-52,88,89,90,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,89,90,32,0,0,0,0,0,0,111,-94,0,0,56,-11,0,0,3,-112,88,89,90,32,0,0,0,0,0,0,98,-103,0,0,-73,-123,0,0,24,-38,88,89,90,32,0,0,0,0,0,0,36,-96,0,0,15,-124,0,0,-74,-49,100,101,115,99,0,0,0,0,0,0,0,22,73,69,67,32,104,116,116,112,58,47,47,119,119,119,46,105,101,99,46,99,104,0,0,0,0,0,0,0,0,0,0,0,22,73,69,67,32,104,116,116,112,58,47,47,119,119,119,46,105,101,99,46,99,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,101,115,99,0,0,0,0,0,0,0,46,73,69,67,32,54,49,57,54,54,45,50,46,49,32,68,101,102,97,117,108,116,32,82,71,66,32,99,111,108,111,117,114,32,115,112,97,99,101,32,45,32,115,82,71,66,0,0,0,0,0,0,0,0,0,0,0,46,73,69,67,32,54,49,57,54,54,45,50,46,49,32,68,101,102,97,117,108,116,32,82,71,66,32,99,111,108,111,117,114,32,115,112,97,99,101,32,45,32,115,82,71,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,101,115,99,0,0,0,0,0,0,0,44,82,101,102,101,114,101,110,99,101,32,86,105,101,119,105,110,103,32,67,111,110,100,105,116,105,111,110,32,105,110,32,73,69,67,54,49,57,54,54,45,50,46,49,0,0,0,0,0,0,0,0,0,0,0,44,82,101,102,101,114,101,110,99,101,32,86,105,101,119,105,110,103,32,67,111,110,100,105,116,105,111,110,32,105,110,32,73,69,67,54,49,57,54,54,45,50,46,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,118,105,101,119,0,0,0,0,0,19,-92,-2,0,20,95,46,0,16,-49,20,0,3,-19,-52,0,4,19,11,0,3,92,-98,0,0,0,1,88,89,90,32,0,0,0,0,0,76,9,86,0,80,0,0,0,87,31,-25,109,101,97,115,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,-113,0,0,0,2,115,105,103,32,0,0,0,0,67,82,84,32,99,117,114,118,0,0,0,0,0,0,4,0,0,0,0,5,0,10,0,15,0,20,0,25,0,30,0,35,0,40,0,45,0,50,0,55,0,59,0,64,0,69,0,74,0,79,0,84,0,89,0,94,0,99,0,104,0,109,0,114,0,119,0,124,0,-127,0,-122,0,-117,0,-112,0,-107,0,-102,0,-97,0,-92,0,-87,0,-82,0,-78,0,-73,0,-68,0,-63,0,-58,0,-53,0,-48,0,-43,0,-37,0,-32,0,-27,0,-21,0,-16,0,-10,0,-5,1,1,1,7,1,13,1,19,1,25,1,31,1,37,1,43,1,50,1,56,1,62,1,69,1,76,1,82,1,89,1,96,1,103,1,110,1,117,1,124,1,-125,1,-117,1,-110,1,-102,1,-95,1,-87,1,-79,1,-71,1,-63,1,-55,1,-47,1,-39,1,-31,1,-23,1,-14,1,-6,2,3,2,12,2,20,2,29,2,38,2,47,2,56,2,65,2,75,2,84,2,93,2,103,2,113,2,122,2,-124,2,-114,2,-104,2,-94,2,-84,2,-74,2,-63,2,-53,2,-43,2,-32,2,-21,2,-11,3,0,3,11,3,22,3,33,3,45,3,56,3,67,3,79,3,90,3,102,3,114,3,126,3,-118,3,-106,3,-94,3,-82,3,-70,3,-57,3,-45,3,-32,3,-20,3,-7,4,6,4,19,4,32,4,45,4,59,4,72,4,85,4,99,4,113,4,126,4,-116,4,-102,4,-88,4,-74,4,-60,4,-45,4,-31,4,-16,4,-2,5,13,5,28,5,43,5,58,5,73,5,88,5,103,5,119,5,-122,5,-106,5,-90,5,-75,5,-59,5,-43,5,-27,5,-10,6,6,6,22,6,39,6,55,6,72,6,89,6,106,6,123,6,-116,6,-99,6,-81,6,-64,6,-47,6,-29,6,-11,7,7,7,25,7,43,7,61,7,79,7,97,7,116,7,-122,7,-103,7,-84,7,-65,7,-46,7,-27,7,-8,8,11,8,31,8,50,8,70,8,90,8,110,8,-126,8,-106,8,-86,8,-66,8,-46,8,-25,8,-5,9,16,9,37,9,58,9,79,9,100,9,121,9,-113,9,-92,9,-70,9,-49,9,-27,9,-5,10,17,10,39,10,61,10,84,10,106,10,-127,10,-104,10,-82,10,-59,10,-36,10,-13,11,11,11,34,11,57,11,81,11,105,11,-128,11,-104,11,-80,11,-56,11,-31,11,-7,12,18,12,42,12,67,12,92,12,117,12,-114,12,-89,12,-64,12,-39,12,-13,13,13,13,38,13,64,13,90,13,116,13,-114,13,-87,13,-61,13,-34,13,-8,14,19,14,46,14,73,14,100,14,127,14,-101,14,-74,14,-46,14,-18,15,9,15,37,15,65,15,94,15,122,15,-106,15,-77,15,-49,15,-20,16,9,16,38,16,67,16,97,16,126,16,-101,16,-71,16,-41,16,-11,17,19,17,49,17,79,17,109,17,-116,17,-86,17,-55,17,-24,18,7,18,38,18,69,18,100,18,-124,18,-93,18,-61,18,-29,19,3,19,35,19,67,19,99,19,-125,19,-92,19,-59,19,-27,20,6,20,39,20,73,20,106,20,-117,20,-83,20,-50,20,-16,21,18,21,52,21,86,21,120,21,-101,21,-67,21,-32,22,3,22,38,22,73,22,108,22,-113,22,-78,22,-42,22,-6,23,29,23,65,23,101,23,-119,23,-82,23,-46,23,-9,24,27,24,64,24,101,24,-118,24,-81,24,-43,24,-6,25,32,25,69,25,107,25,-111,25,-73,25,-35,26,4,26,42,26,81,26,119,26,-98,26,-59,26,-20,27,20,27,59,27,99,27,-118,27,-78,27,-38,28,2,28,42,28,82,28,123,28,-93,28,-52,28,-11,29,30,29,71,29,112,29,-103,29,-61,29,-20,30,22,30,64,30,106,30,-108,30,-66,30,-23,31,19,31,62,31,105,31,-108,31,-65,31,-22,32,21,32,65,32,108,32,-104,32,-60,32,-16,33,28,33,72,33,117,33,-95,33,-50,33,-5,34,39,34,85,34,-126,34,-81,34,-35,35,10,35,56,35,102,35,-108,35,-62,35,-16,36,31,36,77,36,124,36,-85,36,-38,37,9,37,56,37,104,37,-105,37,-57,37,-9,38,39,38,87,38,-121,38,-73,38,-24,39,24,39,73,39,122,39,-85,39,-36,40,13,40,63,40,113,40,-94,40,-44,41,6,41,56,41,107,41,-99,41,-48,42,2,42,53,42,104,42,-101,42,-49,43,2,43,54,43,105,43,-99,43,-47,44,5,44,57,44,110,44,-94,44,-41,45,12,45,65,45,118,45,-85,45,-31,46,22,46,76,46,-126,46,-73,46,-18,47,36,47,90,47,-111,47,-57,47,-2,48,53,48,108,48,-92,48,-37,49,18,49,74,49,-126,49,-70,49,-14,50,42,50,99,50,-101,50,-44,51,13,51,70,51,127,51,-72,51,-15,52,43,52,101,52,-98,52,-40,53,19,53,77,53,-121,53,-62,53,-3,54,55,54,114,54,-82,54,-23,55,36,55,96,55,-100,55,-41,56,20,56,80,56,-116,56,-56,57,5,57,66,57,127,57,-68,57,-7,58,54,58,116,58,-78,58,-17,59,45,59,107,59,-86,59,-24,60,39,60,101,60,-92,60,-29,61,34,61,97,61,-95,61,-32,62,32,62,96,62,-96,62,-32,63,33,63,97,63,-94,63,-30,64,35,64,100,64,-90,64,-25,65,41,65,106,65,-84,65,-18,66,48,66,114,66,-75,66,-9,67,58,67,125,67,-64,68,3,68,71,68,-118,68,-50,69,18,69,85,69,-102,69,-34,70,34,70,103,70,-85,70,-16,71,53,71,123,71,-64,72,5,72,75,72,-111,72,-41,73,29,73,99,73,-87,73,-16,74,55,74,125,74,-60,75,12,75,83,75,-102,75,-30,76,42,76,114,76,-70,77,2,77,74,77,-109,77,-36,78,37,78,110,78,-73,79,0,79,73,79,-109,79,-35,80,39,80,113,80,-69,81,6,81,80,81,-101,81,-26,82,49,82,124,82,-57,83,19,83,95,83,-86,83,-10,84,66,84,-113,84,-37,85,40,85,117,85,-62,86,15,86,92,86,-87,86,-9,87,68,87,-110,87,-32,88,47,88,125,88,-53,89,26,89,105,89,-72,90,7,90,86,90,-90,90,-11,91,69,91,-107,91,-27,92,53,92,-122,92,-42,93,39,93,120,93,-55,94,26,94,108,94,-67,95,15,95,97,95,-77,96,5,96,87,96,-86,96,-4,97,79,97,-94,97,-11,98,73,98,-100,98,-16,99,67,99,-105,99,-21,100,64,100,-108,100,-23,101,61,101,-110,101,-25,102,61,102,-110,102,-24,103,61,103,-109,103,-23,104,63,104,-106,104,-20,105,67,105,-102,105,-15,106,72,106,-97,106,-9,107,79,107,-89,107,-1,108,87,108,-81,109,8,109,96,109,-71,110,18,110,107,110,-60,111,30,111,120,111,-47,112,43,112,-122,112,-32,113,58,113,-107,113,-16,114,75,114,-90,115,1,115,93,115,-72,116,20,116,112,116,-52,117,40,117,-123,117,-31,118,62,118,-101,118,-8,119,86,119,-77,120,17,120,110,120,-52,121,42,121,-119,121,-25,122,70,122,-91,123,4,123,99,123,-62,124,33,124,-127,124,-31,125,65,125,-95,126,1,126,98,126,-62,127,35,127,-124,127,-27,-128,71,-128,-88,-127,10,-127,107,-127,-51,-126,48,-126,-110,-126,-12,-125,87,-125,-70,-124,29,-124,-128,-124,-29,-123,71,-123,-85,-122,14,-122,114,-122,-41,-121,59,-121,-97,-120,4,-120,105,-120,-50,-119,51,-119,-103,-119,-2,-118,100,-118,-54,-117,48,-117,-106,-117,-4,-116,99,-116,-54,-115,49,-115,-104,-115,-1,-114,102,-114,-50,-113,54,-113,-98,-112,6,-112,110,-112,-42,-111,63,-111,-88,-110,17,-110,122,-110,-29,-109,77,-109,-74,-108,32,-108,-118,-108,-12,-107,95,-107,-55,-106,52,-106,-97,-105,10,-105,117,-105,-32,-104,76,-104,-72,-103,36,-103,-112,-103,-4,-102,104,-102,-43,-101,66,-101,-81,-100,28,-100,-119,-100,-9,-99,100,-99,-46,-98,64,-98,-82,-97,29,-97,-117,-97,-6,-96,105,-96,-40,-95,71,-95,-74,-94,38,-94,-106,-93,6,-93,118,-93,-26,-92,86,-92,-57,-91,56,-91,-87,-90,26,-90,-117,-90,-3,-89,110,-89,-32,-88,82,-88,-60,-87,55,-87,-87,-86,28,-86,-113,-85,2,-85,117,-85,-23,-84,92,-84,-48,-83,68,-83,-72,-82,45,-82,-95,-81,22,-81,-117,-80,0,-80,117,-80,-22,-79,96,-79,-42,-78,75,-78,-62,-77,56,-77,-82,-76,37,-76,-100,-75,19,-75,-118,-74,1,-74,121,-74,-16,-73,104,-73,-32,-72,89,-72,-47,-71,74,-71,-62,-70,59,-70,-75,-69,46,-69,-89,-68,33,-68,-101,-67,21,-67,-113,-66,10,-66,-124,-66,-1,-65,122,-65,-11,-64,112,-64,-20,-63,103,-63,-29,-62,95,-62,-37,-61,88,-61,-44,-60,81,-60,-50,-59,75,-59,-56,-58,70,-58,-61,-57,65,-57,-65,-56,61,-56,-68,-55,58,-55,-71,-54,56,-54,-73,-53,54,-53,-74,-52,53,-52,-75,-51,53,-51,-75,-50,54,-50,-74,-49,55,-49,-72,-48,57,-48,-70,-47,60,-47,-66,-46,63,-46,-63,-45,68,-45,-58,-44,73,-44,-53,-43,78,-43,-47,-42,85,-42,-40,-41,92,-41,-32,-40,100,-40,-24,-39,108,-39,-15,-38,118,-38,-5,-37,-128,-36,5,-36,-118,-35,16,-35,-106,-34,28,-34,-94,-33,41,-33,-81,-32,54,-32,-67,-31,68,-31,-52,-30,83,-30,-37,-29,99,-29,-21,-28,115,-28,-4,-27,-124,-26,13,-26,-106,-25,31,-25,-87,-24,50,-24,-68,-23,70,-23,-48,-22,91,-22,-27,-21,112,-21,-5,-20,-122,-19,17,-19,-100,-18,40,-18,-76,-17,64,-17,-52,-16,88,-16,-27,-15,114,-15,-1,-14,-116,-13,25,-13,-89,-12,52,-12,-62,-11,80,-11,-34,-10,109,-10,-5,-9,-118,-8,25,-8,-88,-7,56,-7,-57,-6,87,-6,-25,-5,119,-4,7,-4,-104,-3,41,-3,-70,-2,75,-2,-36,-1,109,-1,-1,-1,-37,0,67,0,3,2,2,3,2,2,3,3,3,3,4,3,3,4,5,8,5,5,4,4,5,10,7,7,6,8,12,10,12,12,11,10,11,11,13,14,18,16,13,14,17,14,11,11,16,22,16,17,19,20,21,21,21,12,15,23,24,22,20,24,18,20,21,20,-1,-37,0,67,1,3,4,4,5,4,5,9,5,5,9,20,13,11,13,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,-1,-64,0,17,8,0,64,0,64,3,1,17,0,2,17,1,3,17,1,-1,-60,0,24,0,0,3,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,6,-1,-60,0,39,16,0,2,1,4,1,3,4,3,1,1,0,0,0,0,0,0,1,2,17,0,3,18,33,49,19,34,65,81,97,113,-111,50,66,-127,82,-95,-1,-60,0,25,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,2,0,3,5,8,-1,-60,0,39,17,1,0,2,2,3,0,2,0,5,5,0,0,0,0,0,0,1,0,17,2,33,18,49,65,34,81,3,19,50,97,-95,113,-127,-79,-63,-31,-1,-38,0,12,3,1,0,2,17,3,17,0,63,0,-23,-70,118,-112,100,-50,92,-50,33,-102,-66,-86,-68,-99,19,-61,87,-49,-23,17,47,113,-50,54,-41,-90,53,-60,-102,-38,13,-69,-103,-91,-17,100,-76,-78,-50,87,-110,0,-31,-114,-123,75,-112,66,-23,-59,-6,-120,-83,-100,-107,109,-116,-102,76,-109,-79,77,-27,-37,42,-14,-48,-78,19,-75,14,36,-126,76,-110,-38,-86,123,-36,-61,-53,30,79,-67,-63,109,-77,-100,-118,-82,-75,-38,102,-123,13,66,-50,-68,-102,-78,-71,82,12,49,115,-62,-22,7,-51,77,-105,11,11,-15,-1,0,83,55,118,48,-106,-14,65,-58,74,124,85,1,-37,22,-102,77,-55,-54,-45,-28,67,99,26,2,121,-89,-28,76,-103,-15,125,-87,99,-86,35,16,-74,-108,-49,119,-102,-97,-113,-69,-108,56,-28,-98,-55,104,96,-63,-103,-82,1,-94,-62,68,-43,26,-122,58,50,-60,-44,8,4,49,-128,-117,-64,21,-90,-40,-92,59,-100,-107,-122,-127,-96,14,-64,21,-76,67,91,73,-92,56,32,28,79,-81,-127,83,-87,95,23,83,62,-112,-60,-16,-20,76,24,106,110,65,-109,84,-54,68,101,10,8,107,74,1,16,15,53,-106,-1,0,120,-30,-103,7,-67,-112,82,-35,41,22,-125,23,-29,33,0,80,-43,-9,48,107,-115,-9,-44,58,66,-38,-81,104,-53,-26,69,55,112,-57,45,3,-28,32,-87,115,-64,3,126,-124,-4,81,-36,90,50,71,-86,-110,-73,11,-112,122,-104,123,20,-112,106,-110,-68,-108,-29,96,-43,-58,75,34,48,-54,7,-104,16,13,26,89,2,56,-84,107,104,-49,123,-86,70,-50,-1,0,-26,-21,47,-47,58,94,-18,-82,72,10,-79,34,79,-126,12,-1,0,105,-37,39,27,116,119,5,-72,-40,-62,-30,87,-55,-118,-56,94,-26,1,41,-44,29,-50,86,-43,-40,-120,-27,99,85,-125,-70,-113,19,-29,93,68,-92,44,-36,-19,30,-126,43,59,-8,-51,-79,-74,95,69,-116,23,18,102,101,76,-59,79,35,-55,47,-48,-51,12,-71,-59,-104,-83,-79,-71,0,73,-87,-21,103,112,42,-17,31,38,65,-44,98,-88,-114,109,-115,-103,82,102,-82,-98,-41,115,31,42,-73,113,-110,24,106,-46,31,39,63,31,117,-70,-10,86,-50,-34,-28,-126,21,114,65,-106,-119,102,93,-57,-75,61,-76,-61,45,87,41,99,-86,0,56,18,-25,-119,58,3,-32,84,-4,95,117,51,-57,29,-3,-60,-91,118,-57,-87,-103,34,10,-20,86,111,-81,36,3,-115,-43,35,2,-39,48,-108,46,7,44,7,52,-43,123,45,7,-90,-96,-74,13,-45,-112,-108,19,38,107,114,13,74,-4,-50,-71,72,22,-63,114,28,-32,36,-28,-32,-97,-86,87,90,-101,22,-14,-27,-113,-9,37,-91,-40,102,91,96,-64,17,63,-107,14,58,-68,-96,98,42,127,-55,55,9,113,-80,24,-109,5,-128,-118,77,72,-21,-29,122,-102,92,-74,2,-115,-86,5,51,-82,106,71,114,-65,17,-84,105,-14,46,-109,-26,-91,-95,-39,-73,36,-60,10,-42,86,-91,99,-112,-27,95,114,16,-36,-122,97,122,124,5,-58,5,83,93,84,14,57,15,44,101,5,103,79,11,-29,-40,123,-44,-40,50,31,-127,-9,-28,78,-56,-128,-126,11,21,-1,0,58,20,-126,-50,-74,-43,-98,65,89,-115,-80,-84,-28,-87,50,64,17,89,11,-80,-111,-106,26,-80,-90,53,44,-22,-27,1,-23,-125,-6,86,-47,87,-36,57,2,-28,-62,-43,-114,-31,12,109,-119,-100,88,-13,67,-105,-19,114,-115,-68,82,-2,-92,48,92,-119,86,-104,-25,-70,9,53,69,-5,54,57,-14,43,62,-93,-74,-84,-28,-36,-72,-84,60,119,31,20,52,104,-120,85,35,46,2,-96,13,12,79,2,-40,-113,-70,59,117,4,-41,-57,-7,-119,-54,-116,-118,-72,0,122,-104,36,-4,86,47,-46,97,-17,12,-51,49,33,99,44,-9,1,-13,-116,82,-41,65,39,18,-84,72,22,5,96,-72,18,63,105,-120,-83,85,46,-102,-88,4,103,73,68,33,71,-20,-38,-83,96,-19,-109,-56,-29,76,-84,21,100,-35,49,-32,8,-103,-94,-41,88,-53,-59,-16,-111,108,33,-56,91,44,96,-1,0,5,83,126,-50,63,34,-44,-23,-107,125,-108,66,23,11,-65,59,6,-116,71,-70,-99,27,63,73,100,46,28,-38,50,96,119,51,-59,96,-94,13,-120,-101,-88,-126,90,-76,87,125,-36,-13,-86,-41,-109,43,110,-68,-18,29,91,-102,96,-127,73,-29,29,79,-67,110,39,87,39,19,27,-37,-90,81,-68,70,69,-104,-122,58,-110,-70,-93,-113,-44,-33,-106,-30,-72,-101,-110,-16,-50,3,-9,-111,-58,2,105,58,-44,45,-65,-113,-13,7,115,105,37,-97,33,-57,-29,17,88,45,-47,43,48,67,32,-90,34,110,50,16,85,48,35,-123,59,-6,-89,67,10,55,-29,29,-68,-106,74,7,51,-22,-110,62,-24,107,-40,-47,-105,-22,-1,0,51,-1,-39, \ No newline at end of file