Deferred Shading update
-Deferred Shading now use a dynamics pass system -Forward Shading is now capable of rendering more than three lights (Multipass) Former-commit-id: 74ed0b998d72aa9eb3bd2aab938a75985ebb2bf6
This commit is contained in:
parent
6568cc7995
commit
a332579c80
|
|
@ -1,4 +1,4 @@
|
|||
// This file was automatically generated on 20 Dec 2013 at 20:02:16
|
||||
// This file was automatically generated on 27 Dec 2013 at 22:07:53
|
||||
|
||||
/*
|
||||
Nazara Engine - Graphics module
|
||||
|
|
@ -37,6 +37,8 @@
|
|||
#include <Nazara/Graphics/ColorBackground.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/DeferredBloomPass.hpp>
|
||||
#include <Nazara/Graphics/DeferredDOFPass.hpp>
|
||||
#include <Nazara/Graphics/DeferredFinalPass.hpp>
|
||||
#include <Nazara/Graphics/DeferredFogPass.hpp>
|
||||
#include <Nazara/Graphics/DeferredForwardPass.hpp>
|
||||
#include <Nazara/Graphics/DeferredFXAAPass.hpp>
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ class NAZARA_API NzAbstractRenderTechnique : NzNonCopyable
|
|||
NzAbstractRenderTechnique();
|
||||
virtual ~NzAbstractRenderTechnique();
|
||||
|
||||
virtual void Clear(const NzScene* scene) = 0;
|
||||
virtual bool Draw(const NzScene* scene) = 0;
|
||||
virtual void Clear(const NzScene* scene) const = 0;
|
||||
virtual bool Draw(const NzScene* scene) const = 0;
|
||||
|
||||
virtual void EnableInstancing(bool instancing);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
// 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_DEFERREDBLOOMPASS_HPP
|
||||
#define NAZARA_DEFERREDBLOOMPASS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderPass.hpp>
|
||||
#include <Nazara/Renderer/RenderStates.hpp>
|
||||
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||
#include <Nazara/Renderer/ShaderProgram.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
|
||||
class NAZARA_API NzDeferredBloomPass : public NzDeferredRenderPass
|
||||
{
|
||||
public:
|
||||
NzDeferredBloomPass();
|
||||
virtual ~NzDeferredBloomPass();
|
||||
|
||||
unsigned int GetBlurPassCount() const;
|
||||
float GetBrightLuminance() const;
|
||||
float GetBrightMiddleGrey() const;
|
||||
float GetBrightThreshold() const;
|
||||
NzTexture* GetTexture(unsigned int i) const;
|
||||
|
||||
bool Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
||||
bool Resize(const NzVector2ui& dimensions);
|
||||
|
||||
void SetBlurPassCount(unsigned int passCount);
|
||||
void SetBrightLuminance(float luminance);
|
||||
void SetBrightMiddleGrey(float middleGrey);
|
||||
void SetBrightThreshold(float threshold);
|
||||
|
||||
protected:
|
||||
NzRenderStates m_bloomStates;
|
||||
NzRenderTexture m_bloomRTT;
|
||||
NzShaderProgramRef m_bloomBrightProgram;
|
||||
NzShaderProgramRef m_bloomFinalProgram;
|
||||
NzShaderProgramRef m_gaussianBlurProgram;
|
||||
NzTextureRef m_bloomTextures[2];
|
||||
NzTextureSampler m_bilinearSampler;
|
||||
mutable bool m_uniformUpdated;
|
||||
float m_brightLuminance;
|
||||
float m_brightMiddleGrey;
|
||||
float m_brightThreshold;
|
||||
int m_gaussianBlurProgramFilterLocation;
|
||||
unsigned int m_blurPassCount;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DEFERREDBLOOMPASS_HPP
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// 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_DEFERREDDOFPASS_HPP
|
||||
#define NAZARA_DEFERREDDOFPASS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderPass.hpp>
|
||||
#include <Nazara/Renderer/RenderStates.hpp>
|
||||
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||
#include <Nazara/Renderer/ShaderProgram.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
|
||||
class NAZARA_API NzDeferredDOFPass : public NzDeferredRenderPass
|
||||
{
|
||||
public:
|
||||
NzDeferredDOFPass();
|
||||
virtual ~NzDeferredDOFPass();
|
||||
|
||||
bool Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
||||
bool Resize(const NzVector2ui& dimensions);
|
||||
|
||||
protected:
|
||||
NzRenderTexture m_dofRTT;
|
||||
NzRenderStates m_states;
|
||||
NzShaderProgramRef m_blurProgram;
|
||||
NzShaderProgramRef m_dofProgram;
|
||||
NzTextureRef m_dofTextures[2];
|
||||
NzTextureSampler m_bilinearSampler;
|
||||
NzTextureSampler m_pointSampler;
|
||||
int m_blurProgramFilterLocation;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DEFERREDDOFPASS_HPP
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// 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_DEFERREDFXAAPASS_HPP
|
||||
#define NAZARA_DEFERREDFXAAPASS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderPass.hpp>
|
||||
#include <Nazara/Renderer/RenderStates.hpp>
|
||||
#include <Nazara/Renderer/ShaderProgram.hpp>
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
|
||||
class NAZARA_API NzDeferredFXAAPass : public NzDeferredRenderPass
|
||||
{
|
||||
public:
|
||||
NzDeferredFXAAPass();
|
||||
virtual ~NzDeferredFXAAPass();
|
||||
|
||||
bool Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
||||
|
||||
protected:
|
||||
NzRenderStates m_states;
|
||||
NzShaderProgramRef m_fxaaProgram;
|
||||
NzTextureSampler m_pointSampler;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DEFERREDFXAAPASS_HPP
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// 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_DEFERREDFINALPASS_HPP
|
||||
#define NAZARA_DEFERREDFINALPASS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderPass.hpp>
|
||||
#include <Nazara/Renderer/RenderStates.hpp>
|
||||
#include <Nazara/Renderer/ShaderProgram.hpp>
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
|
||||
class NAZARA_API NzDeferredFinalPass : public NzDeferredRenderPass
|
||||
{
|
||||
public:
|
||||
NzDeferredFinalPass();
|
||||
virtual ~NzDeferredFinalPass();
|
||||
|
||||
bool Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
||||
|
||||
protected:
|
||||
NzRenderStates m_states;
|
||||
NzShaderProgramRef m_program;
|
||||
NzTextureSampler m_pointSampler;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DEFERREDFINALPASS_HPP
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// 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_DEFERREDFOGPASS_HPP
|
||||
#define NAZARA_DEFERREDFOGPASS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderPass.hpp>
|
||||
#include <Nazara/Renderer/RenderStates.hpp>
|
||||
#include <Nazara/Renderer/ShaderProgram.hpp>
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
|
||||
class NAZARA_API NzDeferredFogPass : public NzDeferredRenderPass
|
||||
{
|
||||
public:
|
||||
NzDeferredFogPass();
|
||||
virtual ~NzDeferredFogPass();
|
||||
|
||||
bool Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
||||
|
||||
protected:
|
||||
NzRenderStates m_states;
|
||||
NzShaderProgramRef m_program;
|
||||
NzTextureSampler m_pointSampler;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DEFERREDFOGPASS_HPP
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// 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_DEFERREDFORWARDPASS_HPP
|
||||
#define NAZARA_DEFERREDFORWARDPASS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderPass.hpp>
|
||||
|
||||
class NzForwardRenderTechnique;
|
||||
|
||||
class NAZARA_API NzDeferredForwardPass : public NzDeferredRenderPass
|
||||
{
|
||||
public:
|
||||
NzDeferredForwardPass();
|
||||
virtual ~NzDeferredForwardPass();
|
||||
|
||||
void Initialize(NzDeferredRenderTechnique* technique);
|
||||
bool Process(const NzScene* scene, unsigned int workTexture, unsigned sceneTexture) const;
|
||||
|
||||
protected:
|
||||
const NzForwardRenderTechnique* m_forwardTechnique;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DEFERREDFORWARDPASS_HPP
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// 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_DEFERREDGEOMETRYPASS_HPP
|
||||
#define NAZARA_DEFERREDGEOMETRYPASS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderPass.hpp>
|
||||
#include <Nazara/Renderer/RenderStates.hpp>
|
||||
#include <Nazara/Renderer/ShaderProgram.hpp>
|
||||
|
||||
class NAZARA_API NzDeferredGeometryPass : public NzDeferredRenderPass
|
||||
{
|
||||
public:
|
||||
NzDeferredGeometryPass();
|
||||
virtual ~NzDeferredGeometryPass();
|
||||
|
||||
bool Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
||||
bool Resize(const NzVector2ui& dimensions);
|
||||
|
||||
protected:
|
||||
NzRenderStates m_clearStates;
|
||||
NzShaderProgramRef m_clearProgram;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DEFERREDGEOMETRYPASS_HPP
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// 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_DEFERREDPHONGLIGHTINGPASS_HPP
|
||||
#define NAZARA_DEFERREDPHONGLIGHTINGPASS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderPass.hpp>
|
||||
#include <Nazara/Renderer/ShaderProgram.hpp>
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
|
||||
class NzStaticMesh;
|
||||
|
||||
class NAZARA_API NzDeferredPhongLightingPass : public NzDeferredRenderPass
|
||||
{
|
||||
public:
|
||||
NzDeferredPhongLightingPass();
|
||||
virtual ~NzDeferredPhongLightingPass();
|
||||
|
||||
void EnableLightMeshesDrawing(bool enable);
|
||||
|
||||
bool IsLightMeshesDrawingEnabled() const;
|
||||
|
||||
bool Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
||||
|
||||
protected:
|
||||
NzMeshRef m_cone;
|
||||
NzMeshRef m_sphere;
|
||||
NzShaderProgramRef m_directionalLightProgram;
|
||||
NzShaderProgramRef m_pointLightProgram;
|
||||
NzShaderProgramRef m_spotLightProgram;
|
||||
NzTextureSampler m_pointSampler;
|
||||
NzStaticMesh* m_coneMesh;
|
||||
NzStaticMesh* m_sphereMesh;
|
||||
bool m_lightMeshesDrawing;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DEFERREDPHONGLIGHTINGPASS_HPP
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
// 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_DEFERREDRENDERPASS_HPP
|
||||
#define NAZARA_DEFERREDRENDERPASS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Graphics/Enums.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
|
||||
class NzDeferredRenderTechnique;
|
||||
class NzDeferredRenderQueue;
|
||||
class NzRenderBuffer;
|
||||
class NzRenderTexture;
|
||||
class NzScene;
|
||||
class NzTexture;
|
||||
|
||||
class NAZARA_API NzDeferredRenderPass
|
||||
{
|
||||
friend NzDeferredRenderTechnique;
|
||||
|
||||
public:
|
||||
NzDeferredRenderPass();
|
||||
virtual ~NzDeferredRenderPass();
|
||||
|
||||
void Enable(bool enable);
|
||||
|
||||
virtual void Initialize(NzDeferredRenderTechnique* technique);
|
||||
|
||||
bool IsEnabled() const;
|
||||
|
||||
virtual bool Process(const NzScene* scene, unsigned int workTexture, unsigned sceneTexture) const = 0;
|
||||
virtual bool Resize(const NzVector2ui& GBufferSize);
|
||||
|
||||
protected:
|
||||
NzVector2ui m_dimensions;
|
||||
NzDeferredRenderTechnique* m_deferredTechnique;
|
||||
NzDeferredRenderQueue* m_renderQueue;
|
||||
NzRenderBuffer* m_depthStencilBuffer;
|
||||
NzRenderTexture* m_GBufferRTT;
|
||||
NzRenderTexture* m_workRTT;
|
||||
NzTexture* m_GBuffer[4];
|
||||
NzTexture* m_workTextures[2];
|
||||
|
||||
private:
|
||||
bool m_enabled;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DEFERREDRENDERPASS_HPP
|
||||
|
|
@ -23,8 +23,6 @@ class NzStaticMesh;
|
|||
|
||||
class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourceListener
|
||||
{
|
||||
friend class NzDeferredRenderTechnique;
|
||||
|
||||
public:
|
||||
NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue);
|
||||
~NzDeferredRenderQueue();
|
||||
|
|
@ -37,10 +35,6 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourc
|
|||
|
||||
void Clear(bool fully);
|
||||
|
||||
private:
|
||||
bool OnResourceDestroy(const NzResource* resource, int index) override;
|
||||
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||
|
||||
struct SkeletalData
|
||||
{
|
||||
///TODO
|
||||
|
|
@ -84,6 +78,10 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourc
|
|||
LightContainer pointLights;
|
||||
LightContainer spotLights;
|
||||
NzForwardRenderQueue* m_forwardQueue;
|
||||
|
||||
private:
|
||||
bool OnResourceDestroy(const NzResource* resource, int index) override;
|
||||
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DEFERREDRENDERQUEUE_HPP
|
||||
|
|
|
|||
|
|
@ -9,15 +9,19 @@
|
|||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Graphics/AbstractRenderTechnique.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderPass.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderQueue.hpp>
|
||||
#include <Nazara/Graphics/ForwardRenderTechnique.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Renderer/RenderBuffer.hpp>
|
||||
#include <Nazara/Renderer/RenderStates.hpp>
|
||||
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||
#include <Nazara/Renderer/ShaderProgram.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
class NAZARA_API NzDeferredRenderTechnique : public NzAbstractRenderTechnique, public NzRenderTarget::Listener
|
||||
{
|
||||
|
|
@ -25,61 +29,47 @@ class NAZARA_API NzDeferredRenderTechnique : public NzAbstractRenderTechnique, p
|
|||
NzDeferredRenderTechnique();
|
||||
~NzDeferredRenderTechnique();
|
||||
|
||||
void Clear(const NzScene* scene);
|
||||
bool Draw(const NzScene* scene);
|
||||
void Clear(const NzScene* scene) const;
|
||||
bool Draw(const NzScene* scene) const;
|
||||
|
||||
void EnablePass(nzRenderPassType renderPass, int position, bool enable);
|
||||
|
||||
NzRenderBuffer* GetDepthStencilBuffer() const;
|
||||
NzTexture* GetGBuffer(unsigned int i) const;
|
||||
NzRenderTexture* GetGBufferRTT() const;
|
||||
const NzForwardRenderTechnique* GetForwardTechnique() const;
|
||||
NzDeferredRenderPass* GetPass(nzRenderPassType renderPass, int position = 0);
|
||||
NzAbstractRenderQueue* GetRenderQueue() override;
|
||||
nzRenderTechniqueType GetType() const override;
|
||||
NzRenderTexture* GetWorkRTT() const;
|
||||
NzTexture* GetWorkTexture(unsigned int i) const;
|
||||
|
||||
bool IsPassEnabled(nzRenderPassType renderPass, int position);
|
||||
|
||||
NzDeferredRenderPass* ResetPass(nzRenderPassType renderPass, int position);
|
||||
|
||||
void SetPass(nzRenderPassType relativeTo, int position, NzDeferredRenderPass* pass);
|
||||
|
||||
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;
|
||||
bool Resize(const NzVector2ui& dimensions) const;
|
||||
|
||||
struct RenderPassComparator
|
||||
{
|
||||
bool operator()(nzRenderPassType pass1, nzRenderPassType pass2);
|
||||
};
|
||||
|
||||
std::map<nzRenderPassType, std::map<int, std::unique_ptr<NzDeferredRenderPass>>, RenderPassComparator> m_passes;
|
||||
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 NzRenderBufferRef m_depthStencilBuffer;
|
||||
mutable NzRenderTexture m_GBufferRTT;
|
||||
mutable NzRenderTexture m_workRTT;
|
||||
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;
|
||||
mutable NzTextureRef m_workTextures[2];
|
||||
mutable NzVector2ui m_GBufferSize;
|
||||
const NzRenderTarget* m_viewerTarget;
|
||||
mutable bool m_texturesUpdated;
|
||||
int m_gaussianBlurProgramFilterLocation;
|
||||
};
|
||||
|
||||
#endif // NAZARA_FORWARDRENDERTECHNIQUE_HPP
|
||||
|
|
|
|||
|
|
@ -26,6 +26,21 @@ enum nzLightType
|
|||
nzLightType_Max = nzLightType_Spot
|
||||
};
|
||||
|
||||
enum nzRenderPassType
|
||||
{
|
||||
nzRenderPassType_AA,
|
||||
nzRenderPassType_Bloom,
|
||||
nzRenderPassType_DOF,
|
||||
nzRenderPassType_Final,
|
||||
nzRenderPassType_Fog,
|
||||
nzRenderPassType_Forward,
|
||||
nzRenderPassType_Lighting,
|
||||
nzRenderPassType_Geometry,
|
||||
nzRenderPassType_SSAO,
|
||||
|
||||
nzRenderPassType_Max = nzRenderPassType_SSAO
|
||||
};
|
||||
|
||||
enum nzRenderTechniqueType
|
||||
{
|
||||
nzRenderTechniqueType_AdvancedForward, // NzAdvancedForwardRenderTechnique
|
||||
|
|
|
|||
|
|
@ -20,26 +20,26 @@ class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique
|
|||
NzForwardRenderTechnique();
|
||||
~NzForwardRenderTechnique();
|
||||
|
||||
void Clear(const NzScene* scene);
|
||||
bool Draw(const NzScene* scene);
|
||||
void Clear(const NzScene* scene) const;
|
||||
bool Draw(const NzScene* scene) const;
|
||||
|
||||
unsigned int GetMaxLightsPerObject() const;
|
||||
unsigned int GetMaxLightPassPerObject() const;
|
||||
NzAbstractRenderQueue* GetRenderQueue() override;
|
||||
nzRenderTechniqueType GetType() const override;
|
||||
|
||||
void SetMaxLightsPerObject(unsigned int lightCount);
|
||||
void SetMaxLightPassPerObject(unsigned int passCount);
|
||||
|
||||
private:
|
||||
void DrawOpaqueModels(const NzScene* scene);
|
||||
void DrawSprites(const NzScene* scene);
|
||||
void DrawTransparentModels(const NzScene* scene);
|
||||
void DrawOpaqueModels(const NzScene* scene) const;
|
||||
void DrawSprites(const NzScene* scene) const;
|
||||
void DrawTransparentModels(const NzScene* scene) const;
|
||||
|
||||
NzForwardRenderQueue m_renderQueue;
|
||||
mutable NzForwardRenderQueue m_renderQueue;
|
||||
NzIndexBufferRef m_indexBuffer;
|
||||
NzLightManager m_directionalLights;
|
||||
NzLightManager m_lights;
|
||||
mutable NzLightManager m_directionalLights;
|
||||
mutable NzLightManager m_lights;
|
||||
NzVertexBuffer m_spriteBuffer;
|
||||
unsigned int m_maxLightsPerObject;
|
||||
unsigned int m_maxLightPassPerObject;
|
||||
};
|
||||
|
||||
#endif // NAZARA_FORWARDRENDERTECHNIQUE_HPP
|
||||
|
|
|
|||
|
|
@ -0,0 +1,309 @@
|
|||
// 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 <Nazara/Graphics/DeferredBloomPass.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NzShaderProgram* BuildBloomBrightProgram()
|
||||
{
|
||||
const nzUInt8 fragmentSource[] = {
|
||||
#include <Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag.h>
|
||||
};
|
||||
|
||||
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<NzShaderProgram> program(new NzShaderProgram(nzShaderLanguage_GLSL));
|
||||
program->SetPersistent(false);
|
||||
|
||||
if (!program->LoadShader(nzShaderType_Fragment, NzString(reinterpret_cast<const char*>(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 nzUInt8 fragmentSource[] = {
|
||||
#include <Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag.h>
|
||||
};
|
||||
|
||||
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<NzShaderProgram> program(new NzShaderProgram(nzShaderLanguage_GLSL));
|
||||
program->SetPersistent(false);
|
||||
|
||||
if (!program->LoadShader(nzShaderType_Fragment, NzString(reinterpret_cast<const char*>(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* BuildGaussianBlurProgram()
|
||||
{
|
||||
const nzUInt8 fragmentSource[] = {
|
||||
#include <Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag.h>
|
||||
};
|
||||
|
||||
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<NzShaderProgram> program(new NzShaderProgram(nzShaderLanguage_GLSL));
|
||||
program->SetPersistent(false);
|
||||
|
||||
if (!program->LoadShader(nzShaderType_Fragment, NzString(reinterpret_cast<const char*>(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();
|
||||
}
|
||||
}
|
||||
|
||||
NzDeferredBloomPass::NzDeferredBloomPass() :
|
||||
m_uniformUpdated(false),
|
||||
m_brightLuminance(0.8),
|
||||
m_brightMiddleGrey(0.5),
|
||||
m_brightThreshold(0.8),
|
||||
m_blurPassCount(5)
|
||||
{
|
||||
m_bilinearSampler.SetAnisotropyLevel(1);
|
||||
m_bilinearSampler.SetFilterMode(nzSamplerFilter_Bilinear);
|
||||
m_bilinearSampler.SetWrapMode(nzSamplerWrap_Clamp);
|
||||
|
||||
m_bloomBrightProgram = BuildBloomBrightProgram();
|
||||
m_bloomBrightProgram->SendInteger(m_bloomBrightProgram->GetUniformLocation("ColorTexture"), 0);
|
||||
|
||||
m_bloomFinalProgram = BuildBloomFinalProgram();
|
||||
m_bloomFinalProgram->SendInteger(m_bloomBrightProgram->GetUniformLocation("BloomTexture"), 1);
|
||||
m_bloomFinalProgram->SendInteger(m_bloomBrightProgram->GetUniformLocation("ColorTexture"), 0);
|
||||
|
||||
m_bloomStates.parameters[nzRendererParameter_DepthBuffer] = false;
|
||||
|
||||
for (unsigned int i = 0; i < 2; ++i)
|
||||
{
|
||||
m_bloomTextures[i] = new NzTexture;
|
||||
m_bloomTextures[i]->SetPersistent(false);
|
||||
}
|
||||
|
||||
m_gaussianBlurProgram = BuildGaussianBlurProgram();
|
||||
m_gaussianBlurProgramFilterLocation = m_gaussianBlurProgram->GetUniformLocation("Filter");
|
||||
}
|
||||
|
||||
NzDeferredBloomPass::~NzDeferredBloomPass() = default;
|
||||
|
||||
unsigned int NzDeferredBloomPass::GetBlurPassCount() const
|
||||
{
|
||||
return m_blurPassCount;
|
||||
}
|
||||
|
||||
float NzDeferredBloomPass::GetBrightLuminance() const
|
||||
{
|
||||
return m_brightLuminance;
|
||||
}
|
||||
|
||||
float NzDeferredBloomPass::GetBrightMiddleGrey() const
|
||||
{
|
||||
return m_brightMiddleGrey;
|
||||
}
|
||||
|
||||
float NzDeferredBloomPass::GetBrightThreshold() const
|
||||
{
|
||||
return m_brightThreshold;
|
||||
}
|
||||
|
||||
NzTexture* NzDeferredBloomPass::GetTexture(unsigned int i) const
|
||||
{
|
||||
#if NAZARA_GRAPHICS_SAFE
|
||||
if (i >= 2)
|
||||
{
|
||||
NazaraError("Texture index out of range (" + NzString::Number(i) + " >= 2)");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_bloomTextures[i];
|
||||
}
|
||||
|
||||
bool NzDeferredBloomPass::Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
||||
{
|
||||
NazaraUnused(scene);
|
||||
|
||||
NzRenderer::SetRenderStates(m_bloomStates);
|
||||
NzRenderer::SetTextureSampler(0, m_bilinearSampler);
|
||||
NzRenderer::SetTextureSampler(1, m_bilinearSampler);
|
||||
|
||||
m_workRTT->SetColorTarget(firstWorkTexture);
|
||||
NzRenderer::SetTarget(m_workRTT);
|
||||
NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y));
|
||||
|
||||
NzRenderer::SetShaderProgram(m_bloomBrightProgram);
|
||||
if (!m_uniformUpdated)
|
||||
{
|
||||
m_bloomBrightProgram->SendFloat(m_bloomBrightProgram->GetUniformLocation("BrightLuminance"), m_brightLuminance);
|
||||
m_bloomBrightProgram->SendFloat(m_bloomBrightProgram->GetUniformLocation("BrightMiddleGrey"), m_brightMiddleGrey);
|
||||
m_bloomBrightProgram->SendFloat(m_bloomBrightProgram->GetUniformLocation("BrightThreshold"), m_brightThreshold);
|
||||
|
||||
m_uniformUpdated = true;
|
||||
}
|
||||
|
||||
NzRenderer::SetTexture(0, m_workTextures[secondWorkTexture]);
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
|
||||
NzRenderer::SetTarget(&m_bloomRTT);
|
||||
NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x/8, m_dimensions.y/8));
|
||||
|
||||
NzRenderer::SetShaderProgram(m_gaussianBlurProgram);
|
||||
|
||||
for (unsigned int i = 0; i < m_blurPassCount; ++i)
|
||||
{
|
||||
m_bloomRTT.SetColorTarget(0); // bloomTextureA
|
||||
|
||||
m_gaussianBlurProgram->SendVector(m_gaussianBlurProgramFilterLocation, NzVector2f(1.f, 0.f));
|
||||
|
||||
NzRenderer::SetTexture(0, (i == 0) ? m_workTextures[firstWorkTexture] : static_cast<const NzTexture*>(m_bloomTextures[1]));
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
|
||||
m_bloomRTT.SetColorTarget(1); // bloomTextureB
|
||||
|
||||
m_gaussianBlurProgram->SendVector(m_gaussianBlurProgramFilterLocation, NzVector2f(0.f, 1.f));
|
||||
|
||||
NzRenderer::SetTexture(0, m_bloomTextures[0]);
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
}
|
||||
|
||||
m_workRTT->SetColorTarget(firstWorkTexture);
|
||||
NzRenderer::SetTarget(m_workRTT);
|
||||
NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y));
|
||||
|
||||
NzRenderer::SetShaderProgram(m_bloomFinalProgram);
|
||||
NzRenderer::SetTexture(0, m_bloomTextures[1]);
|
||||
NzRenderer::SetTexture(1, m_workTextures[secondWorkTexture]);
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzDeferredBloomPass::Resize(const NzVector2ui& dimensions)
|
||||
{
|
||||
NzDeferredRenderPass::Resize(dimensions);
|
||||
|
||||
m_bloomRTT.Create(true);
|
||||
for (unsigned int i = 0; i < 2; ++i)
|
||||
{
|
||||
m_bloomTextures[i]->Create(nzImageType_2D, nzPixelFormat_RGBA8, dimensions.x/8, dimensions.y/8);
|
||||
m_bloomRTT.AttachTexture(nzAttachmentPoint_Color, i, m_bloomTextures[i]);
|
||||
}
|
||||
m_bloomRTT.Unlock();
|
||||
|
||||
if (!m_bloomRTT.IsComplete())
|
||||
{
|
||||
NazaraError("Incomplete RTT");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzDeferredBloomPass::SetBlurPassCount(unsigned int passCount)
|
||||
{
|
||||
m_blurPassCount = passCount; // N'est pas une uniforme
|
||||
}
|
||||
|
||||
void NzDeferredBloomPass::SetBrightLuminance(float luminance)
|
||||
{
|
||||
m_brightLuminance = luminance;
|
||||
m_uniformUpdated = false;
|
||||
}
|
||||
|
||||
void NzDeferredBloomPass::SetBrightMiddleGrey(float middleGrey)
|
||||
{
|
||||
m_brightMiddleGrey = middleGrey;
|
||||
m_uniformUpdated = false;
|
||||
}
|
||||
|
||||
void NzDeferredBloomPass::SetBrightThreshold(float threshold)
|
||||
{
|
||||
m_brightThreshold = threshold;
|
||||
m_uniformUpdated = false;
|
||||
}
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
// 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 <Nazara/Graphics/DeferredDOFPass.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Graphics/Scene.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
// 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 = 10.0;\n"
|
||||
"float Near = 0.1;\n"
|
||||
"float Far = (1000.0) / (1000.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) / (1000.0 + 0.1 - depth * (1000.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<NzShaderProgram> 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;
|
||||
}
|
||||
|
||||
return program.release();
|
||||
}
|
||||
|
||||
|
||||
NzShaderProgram* BuildGaussianBlurProgram()
|
||||
{
|
||||
const nzUInt8 fragmentSource[] = {
|
||||
#include <Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag.h>
|
||||
};
|
||||
|
||||
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<NzShaderProgram> program(new NzShaderProgram(nzShaderLanguage_GLSL));
|
||||
program->SetPersistent(false);
|
||||
|
||||
if (!program->LoadShader(nzShaderType_Fragment, NzString(reinterpret_cast<const char*>(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();
|
||||
}
|
||||
}
|
||||
|
||||
NzDeferredDOFPass::NzDeferredDOFPass()
|
||||
{
|
||||
m_blurProgram = BuildGaussianBlurProgram();
|
||||
m_blurProgram->SendInteger(m_blurProgram->GetUniformLocation("ColorTexture"), 0);
|
||||
|
||||
m_blurProgramFilterLocation = m_blurProgram->GetUniformLocation("Filer");
|
||||
|
||||
m_dofProgram = BuildDepthOfFieldProgram();
|
||||
m_dofProgram->SendInteger(m_dofProgram->GetUniformLocation("ColorTexture"), 0);
|
||||
m_dofProgram->SendInteger(m_dofProgram->GetUniformLocation("BlurTexture"), 1);
|
||||
m_dofProgram->SendInteger(m_dofProgram->GetUniformLocation("GBuffer1"), 2);
|
||||
|
||||
for (unsigned int i = 0; i < 2; ++i)
|
||||
{
|
||||
m_dofTextures[i] = new NzTexture;
|
||||
m_dofTextures[i]->SetPersistent(false);
|
||||
}
|
||||
|
||||
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_states.parameters[nzRendererParameter_DepthBuffer] = false;
|
||||
}
|
||||
|
||||
NzDeferredDOFPass::~NzDeferredDOFPass() = default;
|
||||
|
||||
bool NzDeferredDOFPass::Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
||||
{
|
||||
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_dimensions.x/4, m_dimensions.y/4));
|
||||
|
||||
NzRenderer::SetShaderProgram(m_blurProgram);
|
||||
|
||||
const unsigned int dofBlurPass = 2;
|
||||
for (unsigned int i = 0; i < dofBlurPass; ++i)
|
||||
{
|
||||
m_dofRTT.SetColorTarget(0); // dofTextureA
|
||||
|
||||
m_blurProgram->SendVector(m_blurProgramFilterLocation, NzVector2f(1.f, 0.f));
|
||||
|
||||
NzRenderer::SetTexture(0, (i == 0) ? m_workTextures[secondWorkTexture] : static_cast<const NzTexture*>(m_dofTextures[1]));
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
|
||||
m_dofRTT.SetColorTarget(1); // dofTextureB
|
||||
|
||||
m_blurProgram->SendVector(m_blurProgramFilterLocation, NzVector2f(0.f, 1.f));
|
||||
|
||||
NzRenderer::SetTexture(0, m_dofTextures[0]);
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
}
|
||||
|
||||
m_workRTT->SetColorTarget(firstWorkTexture);
|
||||
NzRenderer::SetTarget(m_workRTT);
|
||||
NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y));
|
||||
|
||||
NzRenderer::SetShaderProgram(m_dofProgram);
|
||||
NzRenderer::SetTexture(0, m_workTextures[secondWorkTexture]);
|
||||
NzRenderer::SetTexture(1, m_dofTextures[1]);
|
||||
NzRenderer::SetTexture(2, m_GBuffer[1]);
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzDeferredDOFPass::Resize(const NzVector2ui& dimensions)
|
||||
{
|
||||
NzDeferredRenderPass::Resize(dimensions);
|
||||
|
||||
m_dofRTT.Create(true);
|
||||
for (unsigned int i = 0; i < 2; ++i)
|
||||
{
|
||||
m_dofTextures[i]->Create(nzImageType_2D, nzPixelFormat_RGBA8, dimensions.x/4, dimensions.y/4);
|
||||
m_dofRTT.AttachTexture(nzAttachmentPoint_Color, i, m_dofTextures[i]);
|
||||
}
|
||||
m_dofRTT.Unlock();
|
||||
|
||||
if (!m_dofRTT.IsComplete())
|
||||
{
|
||||
NazaraError("Incomplete RTT");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
// 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 <Nazara/Graphics/DeferredFXAAPass.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NzShaderProgram* BuildFXAAProgram()
|
||||
{
|
||||
const nzUInt8 fragmentSource[] = {
|
||||
#include <Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag.h>
|
||||
};
|
||||
|
||||
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<NzShaderProgram> program(new NzShaderProgram(nzShaderLanguage_GLSL));
|
||||
program->SetPersistent(false);
|
||||
|
||||
if (!program->LoadShader(nzShaderType_Fragment, NzString(reinterpret_cast<const char*>(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();
|
||||
}
|
||||
}
|
||||
|
||||
NzDeferredFXAAPass::NzDeferredFXAAPass()
|
||||
{
|
||||
m_fxaaProgram = BuildFXAAProgram();
|
||||
m_fxaaProgram->SendInteger(m_fxaaProgram->GetUniformLocation("ColorTexture"), 0);
|
||||
|
||||
m_pointSampler.SetAnisotropyLevel(1);
|
||||
m_pointSampler.SetFilterMode(nzSamplerFilter_Nearest);
|
||||
m_pointSampler.SetWrapMode(nzSamplerWrap_Clamp);
|
||||
|
||||
m_states.parameters[nzRendererParameter_DepthBuffer] = false;
|
||||
}
|
||||
|
||||
NzDeferredFXAAPass::~NzDeferredFXAAPass() = default;
|
||||
|
||||
bool NzDeferredFXAAPass::Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
||||
{
|
||||
NazaraUnused(scene);
|
||||
|
||||
m_workRTT->SetColorTarget(firstWorkTexture);
|
||||
NzRenderer::SetTarget(m_workRTT);
|
||||
NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y));
|
||||
|
||||
NzRenderer::SetRenderStates(m_states);
|
||||
NzRenderer::SetShaderProgram(m_fxaaProgram);
|
||||
NzRenderer::SetTexture(0, m_workTextures[secondWorkTexture]);
|
||||
NzRenderer::SetTextureSampler(0, m_pointSampler);
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
#include <Nazara/Graphics/DeferredFinalPass.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Graphics/Scene.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NzShaderProgram* BuildBlitProgram()
|
||||
{
|
||||
const nzUInt8 fragmentSource[] = {
|
||||
#include <Nazara/Graphics/Resources/DeferredShading/Shaders/Blit.frag.h>
|
||||
};
|
||||
|
||||
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<NzShaderProgram> program(new NzShaderProgram(nzShaderLanguage_GLSL));
|
||||
program->SetPersistent(false);
|
||||
|
||||
if (!program->LoadShader(nzShaderType_Fragment, NzString(reinterpret_cast<const char*>(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();
|
||||
}
|
||||
}
|
||||
|
||||
NzDeferredFinalPass::NzDeferredFinalPass()
|
||||
{
|
||||
m_program = BuildBlitProgram();
|
||||
m_program->SendInteger(m_program->GetUniformLocation("ColorTexture"), 0);
|
||||
|
||||
m_pointSampler.SetAnisotropyLevel(1);
|
||||
m_pointSampler.SetFilterMode(nzSamplerFilter_Nearest);
|
||||
m_pointSampler.SetWrapMode(nzSamplerWrap_Clamp);
|
||||
|
||||
m_states.parameters[nzRendererParameter_DepthBuffer] = false;
|
||||
}
|
||||
|
||||
NzDeferredFinalPass::~NzDeferredFinalPass() = default;
|
||||
|
||||
bool NzDeferredFinalPass::Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
||||
{
|
||||
NazaraUnused(firstWorkTexture);
|
||||
|
||||
scene->GetViewer()->ApplyView();
|
||||
|
||||
NzRenderer::SetRenderStates(m_states);
|
||||
NzRenderer::SetShaderProgram(m_program);
|
||||
NzRenderer::SetTexture(0, m_workTextures[secondWorkTexture]);
|
||||
NzRenderer::SetTextureSampler(0, m_pointSampler);
|
||||
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
// 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 <Nazara/Graphics/DeferredFogPass.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Graphics/Scene.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NzShaderProgram* BuildFogProgram()
|
||||
{
|
||||
/*const nzUInt8 fragmentSource[] = {
|
||||
#include <Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag.h>
|
||||
};*/
|
||||
|
||||
const char* fragmentSource =
|
||||
"#version 140\n"
|
||||
|
||||
"out vec4 RenderTarget0;\n"
|
||||
|
||||
"uniform sampler2D ColorTexture;\n"
|
||||
"uniform sampler2D NormalBuffer;\n"
|
||||
"uniform mat4 InvViewProjMatrix;\n"
|
||||
"uniform vec2 InvTargetSize;\n"
|
||||
"uniform vec3 EyePosition;\n"
|
||||
|
||||
"float n = 0.1;"
|
||||
"float f = 1000.0;"
|
||||
|
||||
"void main()\n"
|
||||
"{"
|
||||
"vec2 texCoord = gl_FragCoord.xy * InvTargetSize;\n"
|
||||
"\t" "vec3 color = texture(ColorTexture, texCoord).xyz;\n"
|
||||
"vec4 gVec1 = textureLod(NormalBuffer, texCoord, 0.0);\n"
|
||||
"float depth = gVec1.w*2.0 - 1.0;\n"
|
||||
"float linearDepth = (2 * n) / (f + n - depth * (f - n));"
|
||||
|
||||
"vec3 viewSpace = vec3(texCoord*2.0 - 1.0, depth);\n"
|
||||
|
||||
"vec4 worldPos = InvViewProjMatrix * vec4(viewSpace, 1.0);\n"
|
||||
"worldPos.xyz /= worldPos.w;\n"
|
||||
|
||||
/*"float lumThreshold = 0.1;"
|
||||
"float lumMultipler = 2.0;"
|
||||
//"float lumFactor = max(dot(color, vec3(0.299, 0.587, 0.114)) - lumThreshold, 0.0) / (1.0-lumThreshold);"
|
||||
"float fogFactor = (1.0 - clamp(worldPos.y-2.0, 0.0, 1.0)) - lumFactor*lumMultipler;"
|
||||
"fogFactor += (1.0 - clamp(EyePosition.y-2.5, 0.0, 1.0));"
|
||||
"fogFactor = clamp(fogFactor, 0.0, 1.0);"*/
|
||||
|
||||
"float lumThreshold = 0.8;"
|
||||
"float lumMultipler = 2.0;"
|
||||
"float luminosity = dot(color, vec3(0.299, 0.587, 0.114));"
|
||||
"float lumFactor = max(luminosity - lumThreshold, 0.0) / (1.0-lumThreshold);"
|
||||
|
||||
"vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0);\n"
|
||||
"vec2 fogrange = vec2(0, 50);\n"
|
||||
"float fogeffect = clamp( 1.0 - (fogrange.y - linearDepth*0.5*f) / (fogrange.y - fogrange.x) , 0.0, 1.0 ) * fogColor.w;\n"
|
||||
"fogeffect = max(fogeffect-lumFactor, 0.0);"
|
||||
|
||||
//fogeffect*=(1.0 - int(depth));
|
||||
"\t" "vec3 fragmentColor = color*(1.0-fogeffect) + fogColor.rgb * fogeffect;\n"
|
||||
"\t" "RenderTarget0 = vec4(fragmentColor, 1.0);\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<NzShaderProgram> program(new NzShaderProgram(nzShaderLanguage_GLSL));
|
||||
program->SetPersistent(false);
|
||||
|
||||
if (!program->LoadShader(nzShaderType_Fragment, fragmentSource/*NzString(reinterpret_cast<const char*>(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();
|
||||
}
|
||||
}
|
||||
|
||||
NzDeferredFogPass::NzDeferredFogPass()
|
||||
{
|
||||
m_program = BuildFogProgram();
|
||||
m_program->SendInteger(m_program->GetUniformLocation("ColorTexture"), 0);
|
||||
m_program->SendInteger(m_program->GetUniformLocation("NormalBuffer"), 1);
|
||||
|
||||
m_pointSampler.SetAnisotropyLevel(1);
|
||||
m_pointSampler.SetFilterMode(nzSamplerFilter_Nearest);
|
||||
m_pointSampler.SetWrapMode(nzSamplerWrap_Clamp);
|
||||
|
||||
m_states.parameters[nzRendererParameter_DepthBuffer] = false;
|
||||
}
|
||||
|
||||
NzDeferredFogPass::~NzDeferredFogPass() = default;
|
||||
|
||||
bool NzDeferredFogPass::Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
||||
{
|
||||
m_workRTT->SetColorTarget(firstWorkTexture);
|
||||
NzRenderer::SetTarget(m_workRTT);
|
||||
NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y));
|
||||
|
||||
NzRenderer::SetShaderProgram(m_program);
|
||||
m_program->SendVector(m_program->GetUniformLocation(nzShaderUniform_EyePosition), scene->GetViewer()->GetEyePosition());
|
||||
|
||||
NzRenderer::SetRenderStates(m_states);
|
||||
NzRenderer::SetTexture(0, m_workTextures[secondWorkTexture]);
|
||||
NzRenderer::SetTexture(1, m_GBuffer[1]);
|
||||
NzRenderer::SetTextureSampler(0, m_pointSampler);
|
||||
NzRenderer::SetTextureSampler(1, m_pointSampler);
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// 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 <Nazara/Graphics/DeferredForwardPass.hpp>
|
||||
#include <Nazara/Graphics/AbstractBackground.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderTechnique.hpp>
|
||||
#include <Nazara/Graphics/ForwardRenderTechnique.hpp>
|
||||
#include <Nazara/Graphics/Scene.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
NzDeferredForwardPass::NzDeferredForwardPass() = default;
|
||||
NzDeferredForwardPass::~NzDeferredForwardPass() = default;
|
||||
|
||||
void NzDeferredForwardPass::Initialize(NzDeferredRenderTechnique* technique)
|
||||
{
|
||||
NzDeferredRenderPass::Initialize(technique);
|
||||
|
||||
m_forwardTechnique = technique->GetForwardTechnique();
|
||||
}
|
||||
|
||||
bool NzDeferredForwardPass::Process(const NzScene* scene, unsigned int workTexture, unsigned sceneTexture) const
|
||||
{
|
||||
NazaraUnused(workTexture);
|
||||
|
||||
m_workRTT->SetColorTarget(sceneTexture);
|
||||
NzRenderer::SetTarget(m_workRTT);
|
||||
NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y));
|
||||
|
||||
NzAbstractBackground* background = scene->GetBackground();
|
||||
if (background)
|
||||
background->Draw(scene);
|
||||
|
||||
NzAbstractViewer* viewer = scene->GetViewer();
|
||||
|
||||
NzRenderer::SetMatrix(nzMatrixType_Projection, viewer->GetProjectionMatrix());
|
||||
NzRenderer::SetMatrix(nzMatrixType_View, viewer->GetViewMatrix());
|
||||
|
||||
m_forwardTechnique->Draw(scene);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,303 @@
|
|||
// 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 <Nazara/Graphics/DeferredGeometryPass.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderTechnique.hpp>
|
||||
#include <Nazara/Graphics/Scene.hpp>
|
||||
#include <Nazara/Renderer/Material.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||
#include <Nazara/Utility/BufferMapper.hpp>
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <Nazara/Utility/VertexStruct.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NzShaderProgram* BuildClearProgram()
|
||||
{
|
||||
const nzUInt8 fragmentSource[] = {
|
||||
#include <Nazara/Graphics/Resources/DeferredShading/Shaders/ClearGBuffer.frag.h>
|
||||
};
|
||||
|
||||
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<NzShaderProgram> program(new NzShaderProgram(nzShaderLanguage_GLSL));
|
||||
program->SetPersistent(false);
|
||||
|
||||
if (!program->LoadShader(nzShaderType_Fragment, NzString(reinterpret_cast<const char*>(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();
|
||||
}
|
||||
}
|
||||
|
||||
NzDeferredGeometryPass::NzDeferredGeometryPass()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
NzDeferredGeometryPass::~NzDeferredGeometryPass() = default;
|
||||
|
||||
bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
||||
{
|
||||
NazaraUnused(firstWorkTexture);
|
||||
NazaraUnused(secondWorkTexture);
|
||||
|
||||
NzAbstractViewer* viewer = scene->GetViewer();
|
||||
bool instancingEnabled = m_deferredTechnique->IsInstancingEnabled();
|
||||
|
||||
m_GBufferRTT->SetColorTargets({0, 1, 2}); // G-Buffer
|
||||
NzRenderer::SetTarget(m_GBufferRTT);
|
||||
NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y));
|
||||
|
||||
NzRenderer::SetRenderStates(m_clearStates);
|
||||
NzRenderer::SetShaderProgram(m_clearProgram);
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
|
||||
|
||||
NzRenderer::SetMatrix(nzMatrixType_Projection, viewer->GetProjectionMatrix());
|
||||
NzRenderer::SetMatrix(nzMatrixType_View, viewer->GetViewMatrix());
|
||||
|
||||
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 useInstancing = instancingEnabled && renderQueueInstancing;
|
||||
|
||||
// On commence par récupérer le programme du matériau
|
||||
nzUInt32 flags = nzShaderFlags_Deferred;
|
||||
if (useInstancing)
|
||||
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<NzDeferredRenderQueue::StaticData>& 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<void(nzPrimitiveMode, unsigned int, unsigned int)> DrawFunc;
|
||||
std::function<void(unsigned int, nzPrimitiveMode, unsigned int, unsigned int)> 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 (useInstancing)
|
||||
{
|
||||
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(); // Le nombre de sommets maximum avec la déclaration donnée plus hautg
|
||||
|
||||
while (instanceCount > 0)
|
||||
{
|
||||
unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount);
|
||||
instanceCount -= renderedInstanceCount;
|
||||
|
||||
NzBufferMapper<NzVertexBuffer> mapper(instanceBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedInstanceCount);
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(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;
|
||||
}
|
||||
}
|
||||
|
||||
return false; // On ne fait que remplir le G-Buffer, les work texture ne sont pas affectées
|
||||
}
|
||||
|
||||
bool NzDeferredGeometryPass::Resize(const NzVector2ui& dimensions)
|
||||
{
|
||||
NzDeferredRenderPass::Resize(dimensions);
|
||||
|
||||
/*
|
||||
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 = dimensions.x;
|
||||
unsigned int height = dimensions.y;
|
||||
|
||||
m_depthStencilBuffer->Create(nzPixelFormat_Depth24Stencil8, width, height);
|
||||
|
||||
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_GBufferRTT->Create(true);
|
||||
|
||||
// Texture 0 : Diffuse Color + Flags
|
||||
m_GBufferRTT->AttachTexture(nzAttachmentPoint_Color, 0, m_GBuffer[0]);
|
||||
|
||||
// Texture 1 : Normal map + Depth
|
||||
m_GBufferRTT->AttachTexture(nzAttachmentPoint_Color, 1, m_GBuffer[1]);
|
||||
|
||||
// Texture 2 : Specular value + Shininess
|
||||
m_GBufferRTT->AttachTexture(nzAttachmentPoint_Color, 2, m_GBuffer[2]);
|
||||
|
||||
// Texture 3 : Emission map ?
|
||||
|
||||
m_GBufferRTT->AttachBuffer(nzAttachmentPoint_DepthStencil, 0, m_deferredTechnique->GetDepthStencilBuffer());
|
||||
|
||||
m_GBufferRTT->Unlock();
|
||||
|
||||
m_workRTT->Create(true);
|
||||
|
||||
for (unsigned int i = 0; i < 2; ++i)
|
||||
{
|
||||
m_workTextures[i]->Create(nzImageType_2D, nzPixelFormat_RGBA8, width, height);
|
||||
m_workRTT->AttachTexture(nzAttachmentPoint_Color, i, m_workTextures[i]);
|
||||
}
|
||||
|
||||
m_workRTT->AttachBuffer(nzAttachmentPoint_DepthStencil, 0, m_depthStencilBuffer);
|
||||
|
||||
m_workRTT->Unlock();
|
||||
|
||||
if (!m_workRTT->IsComplete() || !m_GBufferRTT->IsComplete())
|
||||
{
|
||||
NazaraError("Incomplete RTT");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
NazaraError("Failed to create G-Buffer RTT");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,421 @@
|
|||
// 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 <Nazara/Graphics/DeferredPhongLightingPass.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderQueue.hpp>
|
||||
#include <Nazara/Graphics/Light.hpp>
|
||||
#include <Nazara/Graphics/Scene.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||
#include <Nazara/Renderer/ShaderProgramManager.hpp>
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Renderer/OpenGL.hpp> // Supprimer
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NzShaderProgram* BuildDirectionalLightProgram()
|
||||
{
|
||||
const nzUInt8 fragmentSource[] = {
|
||||
#include <Nazara/Graphics/Resources/DeferredShading/Shaders/DirectionalLight.frag.h>
|
||||
};
|
||||
|
||||
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<NzShaderProgram> program(new NzShaderProgram(nzShaderLanguage_GLSL));
|
||||
program->SetPersistent(false);
|
||||
|
||||
if (!program->LoadShader(nzShaderType_Fragment, NzString(reinterpret_cast<const char*>(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 nzUInt8 fragmentSource[] = {
|
||||
#include <Nazara/Graphics/Resources/DeferredShading/Shaders/PointLight.frag.h>
|
||||
};
|
||||
|
||||
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<NzShaderProgram> program(new NzShaderProgram(nzShaderLanguage_GLSL));
|
||||
program->SetPersistent(false);
|
||||
|
||||
if (!program->LoadShader(nzShaderType_Fragment, NzString(reinterpret_cast<const char*>(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 nzUInt8 fragmentSource[] = {
|
||||
#include <Nazara/Graphics/Resources/DeferredShading/Shaders/SpotLight.frag.h>
|
||||
};
|
||||
|
||||
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<NzShaderProgram> program(new NzShaderProgram(nzShaderLanguage_GLSL));
|
||||
program->SetPersistent(false);
|
||||
|
||||
if (!program->LoadShader(nzShaderType_Fragment, NzString(reinterpret_cast<const char*>(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();
|
||||
}
|
||||
}
|
||||
|
||||
NzDeferredPhongLightingPass::NzDeferredPhongLightingPass() :
|
||||
m_lightMeshesDrawing(false)
|
||||
{
|
||||
m_directionalLightProgram = BuildDirectionalLightProgram();
|
||||
m_pointLightProgram = BuildPointLightProgram();
|
||||
m_spotLightProgram = BuildSpotLightProgram();
|
||||
|
||||
m_pointSampler.SetAnisotropyLevel(1);
|
||||
m_pointSampler.SetFilterMode(nzSamplerFilter_Nearest);
|
||||
m_pointSampler.SetWrapMode(nzSamplerWrap_Clamp);
|
||||
|
||||
m_cone = new NzMesh;
|
||||
m_cone->SetPersistent(false);
|
||||
m_cone->CreateStatic();
|
||||
m_coneMesh = static_cast<NzStaticMesh*>(m_cone->BuildSubMesh(NzPrimitive::Cone(1.f, 1.f, 16, NzMatrix4f::Rotate(NzEulerAnglesf(90.f, 0.f, 0.f)))));
|
||||
|
||||
m_sphere = new NzMesh;
|
||||
m_sphere->SetPersistent(false);
|
||||
m_sphere->CreateStatic();
|
||||
m_sphereMesh = static_cast<NzStaticMesh*>(m_sphere->BuildSubMesh(NzPrimitive::IcoSphere(1.f, 1)));
|
||||
}
|
||||
|
||||
NzDeferredPhongLightingPass::~NzDeferredPhongLightingPass() = default;
|
||||
|
||||
void NzDeferredPhongLightingPass::EnableLightMeshesDrawing(bool enable)
|
||||
{
|
||||
m_lightMeshesDrawing = enable;
|
||||
}
|
||||
|
||||
bool NzDeferredPhongLightingPass::IsLightMeshesDrawingEnabled() const
|
||||
{
|
||||
return m_lightMeshesDrawing;
|
||||
}
|
||||
|
||||
bool NzDeferredPhongLightingPass::Process(const NzScene* scene, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
||||
{
|
||||
NazaraUnused(secondWorkTexture);
|
||||
|
||||
m_workRTT->SetColorTarget(firstWorkTexture);
|
||||
NzRenderer::SetTarget(m_workRTT);
|
||||
NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y));
|
||||
|
||||
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] = false;
|
||||
lightStates.parameters[nzRendererParameter_DepthWrite] = false;
|
||||
|
||||
// Directional lights
|
||||
if (!m_renderQueue->directionalLights.empty())
|
||||
{
|
||||
NzRenderer::SetRenderStates(lightStates);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
// 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())
|
||||
{
|
||||
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)); // Pour corriger les imperfections liées à la sphère
|
||||
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::SetStencilCompareFunction(nzRendererComparison_NotEqual, nzFaceSide_Back);
|
||||
NzRenderer::SetStencilPassOperation(nzStencilOperation_Zero, nzFaceSide_Back);
|
||||
|
||||
NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount());
|
||||
}
|
||||
|
||||
if (m_lightMeshesDrawing)
|
||||
{
|
||||
NzRenderer::Enable(nzRendererParameter_DepthBuffer, true);
|
||||
NzRenderer::Enable(nzRendererParameter_DepthWrite, true);
|
||||
NzRenderer::Enable(nzRendererParameter_FaceCulling, false);
|
||||
NzRenderer::Enable(nzRendererParameter_StencilTest, false);
|
||||
NzRenderer::SetFaceFilling(nzFaceFilling_Line);
|
||||
|
||||
NzShaderProgramManagerParams params;
|
||||
params.flags = nzShaderFlags_None;
|
||||
params.target = nzShaderTarget_Model;
|
||||
params.model.alphaMapping = false;
|
||||
params.model.alphaTest = false;
|
||||
params.model.diffuseMapping = false;
|
||||
params.model.emissiveMapping = false;
|
||||
params.model.lighting = false;
|
||||
params.model.normalMapping = false;
|
||||
params.model.parallaxMapping = false;
|
||||
params.model.specularMapping = false;
|
||||
|
||||
const NzShaderProgram* program = NzShaderProgramManager::Get(params);
|
||||
NzRenderer::SetShaderProgram(program);
|
||||
for (const NzLight* light : m_renderQueue->pointLights)
|
||||
{
|
||||
lightMatrix.SetScale(NzVector3f(light->GetRadius()*1.1f)); // Pour corriger les imperfections liées à la sphère
|
||||
lightMatrix.SetTranslation(light->GetPosition());
|
||||
|
||||
NzRenderer::SetMatrix(nzMatrixType_World, lightMatrix);
|
||||
|
||||
program->SendColor(program->GetUniformLocation(nzShaderUniform_MaterialDiffuse), light->GetColor());
|
||||
|
||||
NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount());
|
||||
}
|
||||
|
||||
NzRenderer::Enable(nzRendererParameter_DepthBuffer, false);
|
||||
NzRenderer::Enable(nzRendererParameter_DepthWrite, false);
|
||||
NzRenderer::Enable(nzRendererParameter_FaceCulling, true);
|
||||
NzRenderer::Enable(nzRendererParameter_StencilTest, true);
|
||||
NzRenderer::SetFaceFilling(nzFaceFilling_Fill);
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_renderQueue->spotLights.empty())
|
||||
{
|
||||
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_coneMesh->GetIndexBuffer();
|
||||
NzRenderer::SetIndexBuffer(indexBuffer);
|
||||
NzRenderer::SetVertexBuffer(m_coneMesh->GetVertexBuffer());
|
||||
|
||||
NzMatrix4f lightMatrix;
|
||||
lightMatrix.MakeIdentity();
|
||||
for (const NzLight* light : m_renderQueue->spotLights)
|
||||
{
|
||||
light->Enable(m_spotLightProgram, 0);
|
||||
float radius = light->GetRadius()*std::tan(NzDegreeToRadian(light->GetOuterAngle()))*1.1f;
|
||||
lightMatrix.MakeTransform(light->GetPosition(), light->GetRotation(), NzVector3f(radius, radius, light->GetRadius()));
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
if (m_lightMeshesDrawing)
|
||||
{
|
||||
NzRenderer::Enable(nzRendererParameter_DepthBuffer, true);
|
||||
NzRenderer::Enable(nzRendererParameter_DepthWrite, true);
|
||||
NzRenderer::Enable(nzRendererParameter_FaceCulling, false);
|
||||
NzRenderer::Enable(nzRendererParameter_StencilTest, false);
|
||||
NzRenderer::SetFaceFilling(nzFaceFilling_Line);
|
||||
|
||||
NzShaderProgramManagerParams params;
|
||||
params.flags = nzShaderFlags_None;
|
||||
params.target = nzShaderTarget_Model;
|
||||
params.model.alphaMapping = false;
|
||||
params.model.alphaTest = false;
|
||||
params.model.diffuseMapping = false;
|
||||
params.model.emissiveMapping = false;
|
||||
params.model.lighting = false;
|
||||
params.model.normalMapping = false;
|
||||
params.model.parallaxMapping = false;
|
||||
params.model.specularMapping = false;
|
||||
|
||||
const NzShaderProgram* program = NzShaderProgramManager::Get(params);
|
||||
NzRenderer::SetShaderProgram(program);
|
||||
for (const NzLight* light : m_renderQueue->spotLights)
|
||||
{
|
||||
float baseRadius = light->GetRadius()*std::tan(NzDegreeToRadian(light->GetOuterAngle()))*1.1f;
|
||||
lightMatrix.MakeTransform(light->GetPosition(), light->GetRotation(), NzVector3f(baseRadius, baseRadius, light->GetRadius()));
|
||||
|
||||
NzRenderer::SetMatrix(nzMatrixType_World, lightMatrix);
|
||||
|
||||
program->SendColor(program->GetUniformLocation(nzShaderUniform_MaterialDiffuse), light->GetColor());
|
||||
|
||||
NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount());
|
||||
}
|
||||
|
||||
NzRenderer::Enable(nzRendererParameter_DepthBuffer, false);
|
||||
NzRenderer::Enable(nzRendererParameter_DepthWrite, false);
|
||||
NzRenderer::Enable(nzRendererParameter_FaceCulling, true);
|
||||
NzRenderer::Enable(nzRendererParameter_StencilTest, true);
|
||||
NzRenderer::SetFaceFilling(nzFaceFilling_Fill);
|
||||
}
|
||||
}
|
||||
|
||||
NzRenderer::Enable(nzRendererParameter_StencilTest, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// 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 <Nazara/Graphics/DeferredRenderPass.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Graphics/DeferredRenderTechnique.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
NzDeferredRenderPass::NzDeferredRenderPass() :
|
||||
m_enabled(true)
|
||||
{
|
||||
}
|
||||
|
||||
NzDeferredRenderPass::~NzDeferredRenderPass() = default;
|
||||
|
||||
void NzDeferredRenderPass::Enable(bool enable)
|
||||
{
|
||||
m_enabled = enable;
|
||||
}
|
||||
|
||||
void NzDeferredRenderPass::Initialize(NzDeferredRenderTechnique* technique)
|
||||
{
|
||||
m_deferredTechnique = technique;
|
||||
m_renderQueue = static_cast<NzDeferredRenderQueue*>(technique->GetRenderQueue());
|
||||
|
||||
m_depthStencilBuffer = technique->GetDepthStencilBuffer();
|
||||
|
||||
m_GBufferRTT = technique->GetGBufferRTT();
|
||||
for (unsigned int i = 0; i < 3; ++i)
|
||||
m_GBuffer[i] = technique->GetGBuffer(i);
|
||||
|
||||
m_workRTT = technique->GetWorkRTT();
|
||||
for (unsigned int i = 0; i < 2; ++i)
|
||||
m_workTextures[i] = technique->GetWorkTexture(i);
|
||||
}
|
||||
|
||||
bool NzDeferredRenderPass::IsEnabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
bool NzDeferredRenderPass::Resize(const NzVector2ui& dimensions)
|
||||
{
|
||||
m_dimensions = dimensions;
|
||||
|
||||
return true;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -186,7 +186,8 @@ void NzForwardRenderQueue::AddSubMesh(const NzMaterial* material, const NzSubMes
|
|||
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)
|
||||
unsigned int tumasoublie = NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT;
|
||||
if (instanceCount >= 10)
|
||||
enableInstancing = true; // Apparemment oui, activons l'instancing avec ce matériau
|
||||
|
||||
staticDataContainer.resize(instanceCount);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
namespace
|
||||
{
|
||||
static NzIndexBuffer* s_indexBuffer = nullptr;
|
||||
unsigned int maxLightCount = 3; ///TODO: Constante sur le nombre maximum de lumières
|
||||
unsigned int s_maxLightPerPass = 3; ///TODO: Constante sur le nombre maximum de lumières
|
||||
unsigned int s_maxSprites = 8192;
|
||||
|
||||
NzIndexBuffer* BuildIndexBuffer()
|
||||
|
|
@ -49,7 +49,7 @@ namespace
|
|||
|
||||
NzForwardRenderTechnique::NzForwardRenderTechnique() :
|
||||
m_spriteBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_UV), s_maxSprites*4, nzBufferStorage_Hardware, nzBufferUsage_Dynamic),
|
||||
m_maxLightsPerObject(maxLightCount)
|
||||
m_maxLightPassPerObject(3)
|
||||
{
|
||||
if (!s_indexBuffer)
|
||||
s_indexBuffer = BuildIndexBuffer();
|
||||
|
|
@ -63,7 +63,7 @@ NzForwardRenderTechnique::~NzForwardRenderTechnique()
|
|||
s_indexBuffer = nullptr;
|
||||
}
|
||||
|
||||
void NzForwardRenderTechnique::Clear(const NzScene* scene)
|
||||
void NzForwardRenderTechnique::Clear(const NzScene* scene) const
|
||||
{
|
||||
NzRenderer::Enable(nzRendererParameter_DepthBuffer, true);
|
||||
NzRenderer::Enable(nzRendererParameter_DepthWrite, true);
|
||||
|
|
@ -74,7 +74,7 @@ void NzForwardRenderTechnique::Clear(const NzScene* scene)
|
|||
background->Draw(scene);
|
||||
}
|
||||
|
||||
bool NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||
bool NzForwardRenderTechnique::Draw(const NzScene* scene) const
|
||||
{
|
||||
m_directionalLights.SetLights(&m_renderQueue.directionalLights[0], m_renderQueue.directionalLights.size());
|
||||
m_lights.SetLights(&m_renderQueue.lights[0], m_renderQueue.lights.size());
|
||||
|
|
@ -141,9 +141,9 @@ bool NzForwardRenderTechnique::Draw(const NzScene* scene)
|
|||
}*/
|
||||
}
|
||||
|
||||
unsigned int NzForwardRenderTechnique::GetMaxLightsPerObject() const
|
||||
unsigned int NzForwardRenderTechnique::GetMaxLightPassPerObject() const
|
||||
{
|
||||
return m_maxLightsPerObject;
|
||||
return m_maxLightPassPerObject;
|
||||
}
|
||||
|
||||
NzAbstractRenderQueue* NzForwardRenderTechnique::GetRenderQueue()
|
||||
|
|
@ -156,26 +156,16 @@ nzRenderTechniqueType NzForwardRenderTechnique::GetType() const
|
|||
return nzRenderTechniqueType_BasicForward;
|
||||
}
|
||||
|
||||
void NzForwardRenderTechnique::SetMaxLightsPerObject(unsigned int lightCount)
|
||||
void NzForwardRenderTechnique::SetMaxLightPassPerObject(unsigned int passCount)
|
||||
{
|
||||
#if NAZARA_GRAPHICS_SAFE
|
||||
if (lightCount > maxLightCount)
|
||||
{
|
||||
NazaraError("Light count is over maximum light count (" + NzString::Number(lightCount) + " > " + NzString::Number(lightCount) + ')');
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_maxLightsPerObject = lightCount;
|
||||
m_maxLightPassPerObject = passCount;
|
||||
}
|
||||
|
||||
void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene)
|
||||
void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const
|
||||
{
|
||||
NzAbstractViewer* viewer = scene->GetViewer();
|
||||
const NzShaderProgram* lastProgram = nullptr;
|
||||
|
||||
unsigned int lightCount = 0;
|
||||
|
||||
for (auto& matIt : m_renderQueue.opaqueModels)
|
||||
{
|
||||
bool& used = std::get<0>(matIt.second);
|
||||
|
|
@ -207,11 +197,6 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene)
|
|||
// Position de la caméra
|
||||
program->SendVector(program->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition());
|
||||
|
||||
// On envoie les lumières directionnelles s'il y a (Les mêmes pour tous)
|
||||
lightCount = std::min(m_directionalLights.GetLightCount(), 3U);
|
||||
for (unsigned int i = 0; i < lightCount; ++i)
|
||||
m_directionalLights.GetLight(i)->Enable(program, i);
|
||||
|
||||
lastProgram = program;
|
||||
}
|
||||
|
||||
|
|
@ -269,51 +254,110 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene)
|
|||
|
||||
unsigned int stride = instanceBuffer->GetStride();
|
||||
|
||||
const NzForwardRenderQueue::StaticData* data = &staticData[0];
|
||||
unsigned int instanceCount = staticData.size();
|
||||
unsigned int maxInstanceCount = instanceBuffer->GetVertexCount();
|
||||
// Avec l'instancing, impossible de sélectionner les lumières pour chaque objet
|
||||
// Du coup, il n'est activé que pour les lumières directionnelles
|
||||
unsigned int lightCount = m_directionalLights.GetLightCount();
|
||||
unsigned int lightIndex = 0;
|
||||
nzRendererComparison oldDepthFunc = NzRenderer::GetDepthFunc();
|
||||
|
||||
while (instanceCount > 0)
|
||||
unsigned int passCount = (lightCount == 0) ? 1 : (lightCount-1)/s_maxLightPerPass + 1;
|
||||
for (unsigned int pass = 0; pass < passCount; ++pass)
|
||||
{
|
||||
unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount);
|
||||
instanceCount -= renderedInstanceCount;
|
||||
unsigned int renderedLightCount = std::min(lightCount, s_maxLightPerPass);
|
||||
lightCount -= renderedLightCount;
|
||||
|
||||
NzBufferMapper<NzVertexBuffer> mapper(instanceBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedInstanceCount);
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(mapper.GetPointer());
|
||||
|
||||
for (unsigned int i = 0; i < renderedInstanceCount; ++i)
|
||||
if (pass == 1)
|
||||
{
|
||||
std::memcpy(ptr, data->transformMatrix, sizeof(float)*16);
|
||||
|
||||
data++;
|
||||
ptr += stride;
|
||||
// Pour additionner le résultat des calculs de lumière
|
||||
// Aucune chance d'interférer avec les paramètres du matériau car nous ne rendons que les objets opaques
|
||||
// (Autrement dit, sans blending)
|
||||
// Quant à la fonction de profondeur, elle ne doit être appliquée que la première fois
|
||||
NzRenderer::Enable(nzRendererParameter_Blend, true);
|
||||
NzRenderer::SetBlendFunc(nzBlendFunc_One, nzBlendFunc_One);
|
||||
NzRenderer::SetDepthFunc(nzRendererComparison_Equal);
|
||||
}
|
||||
|
||||
mapper.Unmap();
|
||||
for (unsigned int i = 0; i < renderedLightCount; ++i)
|
||||
m_directionalLights.GetLight(lightIndex++)->Enable(program, i);
|
||||
|
||||
InstancedDrawFunc(renderedInstanceCount, primitiveMode, 0, indexCount);
|
||||
for (unsigned int i = renderedLightCount; i < s_maxLightPerPass; ++i)
|
||||
NzLight::Disable(program, i);
|
||||
|
||||
const NzForwardRenderQueue::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<NzVertexBuffer> mapper(instanceBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedInstanceCount);
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(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);
|
||||
}
|
||||
}
|
||||
|
||||
NzRenderer::Enable(nzRendererParameter_Blend, false);
|
||||
NzRenderer::SetDepthFunc(oldDepthFunc);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int originalLightCount = lightCount;
|
||||
for (const NzForwardRenderQueue::StaticData& data : staticData)
|
||||
{
|
||||
// Calcul des lumières les plus proches
|
||||
if (lightCount < m_maxLightsPerObject && !m_lights.IsEmpty())
|
||||
unsigned int directionalLightCount = m_directionalLights.GetLightCount();
|
||||
unsigned int otherLightCount = m_lights.ComputeClosestLights(data.transformMatrix.GetTranslation() + boundingSphere.GetPosition(), boundingSphere.radius, m_maxLightPassPerObject*s_maxLightPerPass - directionalLightCount);
|
||||
unsigned int lightCount = directionalLightCount + otherLightCount;
|
||||
|
||||
NzRenderer::SetMatrix(nzMatrixType_World, data.transformMatrix);
|
||||
unsigned int directionalLightIndex = 0;
|
||||
unsigned int otherLightIndex = 0;
|
||||
nzRendererComparison oldDepthFunc = NzRenderer::GetDepthFunc();
|
||||
|
||||
unsigned int passCount = (lightCount == 0) ? 1 : (lightCount-1)/s_maxLightPerPass + 1;
|
||||
for (unsigned int pass = 0; pass < passCount; ++pass)
|
||||
{
|
||||
unsigned int count = std::min(m_maxLightsPerObject-lightCount, m_lights.ComputeClosestLights(data.transformMatrix.GetTranslation() + boundingSphere.GetPosition(), boundingSphere.radius, maxLightCount));
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
m_lights.GetResult(i)->Enable(program, lightCount++);
|
||||
unsigned int renderedLightCount = std::min(lightCount, s_maxLightPerPass);
|
||||
lightCount -= renderedLightCount;
|
||||
|
||||
if (pass == 1)
|
||||
{
|
||||
// Pour additionner le résultat des calculs de lumière
|
||||
// Aucune chance d'interférer avec les paramètres du matériau car nous ne rendons que les objets opaques
|
||||
// (Autrement dit, sans blending)
|
||||
// Quant à la fonction de profondeur, elle ne doit être appliquée que la première fois
|
||||
NzRenderer::Enable(nzRendererParameter_Blend, true);
|
||||
NzRenderer::SetBlendFunc(nzBlendFunc_One, nzBlendFunc_One);
|
||||
NzRenderer::SetDepthFunc(nzRendererComparison_Equal);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < renderedLightCount; ++i)
|
||||
{
|
||||
if (directionalLightIndex >= directionalLightCount)
|
||||
m_lights.GetResult(otherLightIndex++)->Enable(program, i);
|
||||
else
|
||||
m_directionalLights.GetLight(directionalLightIndex++)->Enable(program, i);
|
||||
}
|
||||
|
||||
for (unsigned int i = renderedLightCount; i < s_maxLightPerPass; ++i)
|
||||
NzLight::Disable(program, i);
|
||||
|
||||
DrawFunc(primitiveMode, 0, indexCount);
|
||||
}
|
||||
|
||||
for (unsigned int i = lightCount; i < maxLightCount; ++i)
|
||||
NzLight::Disable(program, i);
|
||||
|
||||
NzRenderer::SetMatrix(nzMatrixType_World, data.transformMatrix);
|
||||
DrawFunc(primitiveMode, 0, indexCount);
|
||||
|
||||
lightCount = originalLightCount;
|
||||
NzRenderer::Enable(nzRendererParameter_Blend, false);
|
||||
NzRenderer::SetDepthFunc(oldDepthFunc);
|
||||
}
|
||||
}
|
||||
staticData.clear();
|
||||
|
|
@ -328,7 +372,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene)
|
|||
}
|
||||
}
|
||||
|
||||
void NzForwardRenderTechnique::DrawSprites(const NzScene* scene)
|
||||
void NzForwardRenderTechnique::DrawSprites(const NzScene* scene) const
|
||||
{
|
||||
NzAbstractViewer* viewer = scene->GetViewer();
|
||||
const NzShaderProgram* lastProgram = nullptr;
|
||||
|
|
@ -408,7 +452,7 @@ void NzForwardRenderTechnique::DrawSprites(const NzScene* scene)
|
|||
}
|
||||
}
|
||||
|
||||
void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene)
|
||||
void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene) const
|
||||
{
|
||||
NzAbstractViewer* viewer = scene->GetViewer();
|
||||
const NzShaderProgram* lastProgram = nullptr;
|
||||
|
|
@ -474,14 +518,14 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene)
|
|||
NzRenderer::SetVertexBuffer(vertexBuffer);
|
||||
|
||||
// Calcul des lumières les plus proches
|
||||
if (lightCount < m_maxLightsPerObject && !m_lights.IsEmpty())
|
||||
if (lightCount < s_maxLightPerPass && !m_lights.IsEmpty())
|
||||
{
|
||||
unsigned int count = std::min(m_maxLightsPerObject-lightCount, m_lights.ComputeClosestLights(matrix.GetTranslation() + staticModel.boundingSphere.GetPosition(), staticModel.boundingSphere.radius, maxLightCount));
|
||||
unsigned int count = std::min(s_maxLightPerPass - lightCount, m_lights.ComputeClosestLights(matrix.GetTranslation() + staticModel.boundingSphere.GetPosition(), staticModel.boundingSphere.radius, s_maxLightPerPass));
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
m_lights.GetResult(i)->Enable(program, lightCount++);
|
||||
}
|
||||
|
||||
for (unsigned int i = lightCount; i < maxLightCount; ++i)
|
||||
for (unsigned int i = lightCount; i < s_maxLightPerPass; ++i)
|
||||
NzLight::Disable(program, i);
|
||||
|
||||
NzRenderer::SetMatrix(nzMatrixType_World, matrix);
|
||||
|
|
|
|||
|
|
@ -29,11 +29,11 @@ void main()
|
|||
{
|
||||
vec2 texCoord = gl_FragCoord.xy * InvTargetSize;
|
||||
vec4 gVec0 = textureLod(GBuffer0, texCoord, 0.0);
|
||||
if (gVec0.w == 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);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -29,11 +29,11 @@ void main()
|
|||
{
|
||||
vec2 texCoord = gl_FragCoord.xy * InvTargetSize;
|
||||
vec4 gVec0 = textureLod(GBuffer0, texCoord, 0.0);
|
||||
if (gVec0.w == 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);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue