Graphics: Add basic reflection mapping
This commit is contained in:
parent
459c5e7a09
commit
37d36a89a6
|
|
@ -92,6 +92,7 @@ namespace Ndk
|
|||
material.BindMethod("EnableDepthSorting", &Nz::Material::EnableDepthSorting);
|
||||
material.BindMethod("EnableDepthWrite", &Nz::Material::EnableDepthWrite);
|
||||
material.BindMethod("EnableFaceCulling", &Nz::Material::EnableFaceCulling);
|
||||
material.BindMethod("EnableReflectionMapping", &Nz::Material::EnableReflectionMapping);
|
||||
material.BindMethod("EnableScissorTest", &Nz::Material::EnableScissorTest);
|
||||
material.BindMethod("EnableShadowCasting", &Nz::Material::EnableShadowCasting);
|
||||
material.BindMethod("EnableShadowReceive", &Nz::Material::EnableShadowReceive);
|
||||
|
|
@ -139,6 +140,7 @@ namespace Ndk
|
|||
material.BindMethod("IsDepthSortingEnabled", &Nz::Material::IsDepthSortingEnabled);
|
||||
material.BindMethod("IsDepthWriteEnabled", &Nz::Material::IsDepthWriteEnabled);
|
||||
material.BindMethod("IsFaceCullingEnabled", &Nz::Material::IsFaceCullingEnabled);
|
||||
material.BindMethod("IsReflectionMappingEnabled", &Nz::Material::IsReflectionMappingEnabled);
|
||||
material.BindMethod("IsScissorTestEnabled", &Nz::Material::IsScissorTestEnabled);
|
||||
material.BindMethod("IsStencilTestEnabled", &Nz::Material::IsStencilTestEnabled);
|
||||
material.BindMethod("IsShadowCastingEnabled", &Nz::Material::IsShadowCastingEnabled);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <NDK/Systems/RenderSystem.hpp>
|
||||
#include <Nazara/Graphics/ColorBackground.hpp>
|
||||
#include <Nazara/Graphics/SkyboxBackground.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <NDK/Components/CameraComponent.hpp>
|
||||
|
|
@ -181,7 +182,7 @@ namespace Ndk
|
|||
GraphicsComponent& graphicsComponent = drawable->GetComponent<GraphicsComponent>();
|
||||
graphicsComponent.EnsureBoundingVolumeUpdate();
|
||||
}
|
||||
|
||||
|
||||
bool forceInvalidation = false;
|
||||
|
||||
std::size_t visibilityHash = m_drawableCulling.Cull(camComponent.GetFrustum(), &forceInvalidation);
|
||||
|
|
@ -220,8 +221,12 @@ namespace Ndk
|
|||
Nz::SceneData sceneData;
|
||||
sceneData.ambientColor = Nz::Color(25, 25, 25);
|
||||
sceneData.background = m_background;
|
||||
sceneData.globalReflectionTexture = nullptr;
|
||||
sceneData.viewer = &camComponent;
|
||||
|
||||
if (m_background && m_background->GetBackgroundType() == Nz::BackgroundType_Skybox)
|
||||
sceneData.globalReflectionTexture = static_cast<Nz::SkyboxBackground*>(m_background.Get())->GetTexture();
|
||||
|
||||
m_renderTechnique->Clear(sceneData);
|
||||
m_renderTechnique->Draw(sceneData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ namespace Nz
|
|||
|
||||
// Other uniforms
|
||||
int eyePosition;
|
||||
int reflectionMap;
|
||||
int sceneAmbient;
|
||||
int textureOverlay;
|
||||
};
|
||||
|
|
@ -90,6 +91,8 @@ namespace Nz
|
|||
unsigned int m_maxLightPassPerObject;
|
||||
|
||||
static IndexBuffer s_quadIndexBuffer;
|
||||
static Texture s_dummyReflection;
|
||||
static TextureSampler s_reflectionSampler;
|
||||
static TextureSampler s_shadowSampler;
|
||||
static VertexBuffer s_quadVertexBuffer;
|
||||
static VertexDeclaration s_billboardInstanceDeclaration;
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ namespace Nz
|
|||
inline void EnableDepthSorting(bool depthSorting);
|
||||
inline void EnableDepthWrite(bool depthWrite);
|
||||
inline void EnableFaceCulling(bool faceCulling);
|
||||
inline void EnableReflectionMapping(bool reflection);
|
||||
inline void EnableScissorTest(bool scissorTest);
|
||||
inline void EnableShadowCasting(bool castShadows);
|
||||
inline void EnableShadowReceive(bool receiveShadows);
|
||||
|
|
@ -128,6 +129,7 @@ namespace Nz
|
|||
inline bool IsDepthSortingEnabled() const;
|
||||
inline bool IsDepthWriteEnabled() const;
|
||||
inline bool IsFaceCullingEnabled() const;
|
||||
inline bool IsReflectionMappingEnabled() const;
|
||||
inline bool IsScissorTestEnabled() const;
|
||||
inline bool IsStencilTestEnabled() const;
|
||||
inline bool IsShadowCastingEnabled() const;
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ namespace Nz
|
|||
/*!
|
||||
* \brief Enable/Disable alpha test for this material
|
||||
*
|
||||
* When enabled, all objects using this material will be rendered using alpha testing,
|
||||
* When enabled, all objects using this material will be rendered using alpha testing,
|
||||
* rejecting pixels if their alpha component is under a defined threshold.
|
||||
* This allows some kind of transparency with a much cheaper cost as it doesn't prevent any optimization (as deferred rendering or batching).
|
||||
*
|
||||
|
|
@ -252,7 +252,7 @@ namespace Nz
|
|||
* When enabled, and if depth buffer is enabled and present, all fragments generated with this material will write
|
||||
* to the depth buffer if they pass depth test.
|
||||
*
|
||||
* This is usually disabled with translucent objects, as depth test is wanted to prevent them from rendering on top of opaque objects but
|
||||
* This is usually disabled with translucent objects, as depth test is wanted to prevent them from rendering on top of opaque objects but
|
||||
* not depth writing (which could make other translucent fragments to fail depth test)
|
||||
*
|
||||
* \param depthBuffer Defines if this material will use depth write
|
||||
|
|
@ -291,6 +291,31 @@ namespace Nz
|
|||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable reflection mapping for this material
|
||||
*
|
||||
* When enabled, the material will render reflections from the object environment according to the reflection mode.
|
||||
* Whether or not this is expensive depends of the reflection mode and size.
|
||||
*
|
||||
* Please note this is only a hint for the render technique, and reflections can be forcefully enabled or disabled depending on the material shader.
|
||||
*
|
||||
* Use SetReflectionMode and SetReflectionSize to control reflection quality.
|
||||
*
|
||||
* \param reflection Defines if this material should use reflection mapping
|
||||
*
|
||||
* \remark May invalidates the pipeline
|
||||
*
|
||||
* \see IsReflectionMappingEnabled
|
||||
* \see SetReflectionMode
|
||||
* \see SetReflectionSize
|
||||
*/
|
||||
inline void Material::EnableReflectionMapping(bool reflection)
|
||||
{
|
||||
m_pipelineInfo.reflectionMapping = reflection;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable scissor test for this material
|
||||
*
|
||||
|
|
@ -782,6 +807,17 @@ namespace Nz
|
|||
return m_pipelineInfo.faceCulling;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material has reflection mapping enabled
|
||||
* \return true If it is the case
|
||||
*
|
||||
* \see EnableReflectionMapping
|
||||
*/
|
||||
inline bool Material::IsReflectionMappingEnabled() const
|
||||
{
|
||||
return m_pipelineInfo.reflectionMapping;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material has scissor test enabled
|
||||
* \return true If it is the case
|
||||
|
|
|
|||
|
|
@ -20,15 +20,16 @@ namespace Nz
|
|||
{
|
||||
struct MaterialPipelineInfo : RenderStates
|
||||
{
|
||||
bool alphaTest = false;
|
||||
bool depthSorting = false;
|
||||
bool hasAlphaMap = false;
|
||||
bool hasDiffuseMap = false;
|
||||
bool hasEmissiveMap = false;
|
||||
bool hasHeightMap = false;
|
||||
bool hasNormalMap = false;
|
||||
bool hasSpecularMap = false;
|
||||
bool shadowReceive = true;
|
||||
bool alphaTest = false;
|
||||
bool depthSorting = false;
|
||||
bool hasAlphaMap = false;
|
||||
bool hasDiffuseMap = false;
|
||||
bool hasEmissiveMap = false;
|
||||
bool hasHeightMap = false;
|
||||
bool hasNormalMap = false;
|
||||
bool hasSpecularMap = false;
|
||||
bool reflectionMapping = false;
|
||||
bool shadowReceive = true;
|
||||
|
||||
UberShaderConstRef uberShader;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ namespace Nz
|
|||
NazaraPipelineBoolMember(hasHeightMap);
|
||||
NazaraPipelineBoolMember(hasNormalMap);
|
||||
NazaraPipelineBoolMember(hasSpecularMap);
|
||||
NazaraPipelineBoolMember(reflectionMapping);
|
||||
NazaraPipelineBoolMember(shadowReceive);
|
||||
|
||||
NazaraPipelineMember(uberShader);
|
||||
|
|
@ -127,6 +128,7 @@ namespace std
|
|||
NazaraPipelineBoolMember(hasHeightMap);
|
||||
NazaraPipelineBoolMember(hasNormalMap);
|
||||
NazaraPipelineBoolMember(hasSpecularMap);
|
||||
NazaraPipelineBoolMember(reflectionMapping);
|
||||
NazaraPipelineBoolMember(shadowReceive);
|
||||
|
||||
NazaraPipelineMember(uberShader);
|
||||
|
|
|
|||
|
|
@ -13,12 +13,14 @@ namespace Nz
|
|||
{
|
||||
class AbstractBackground;
|
||||
class AbstractViewer;
|
||||
class Texture;
|
||||
|
||||
struct SceneData
|
||||
{
|
||||
Color ambientColor;
|
||||
const AbstractBackground* background;
|
||||
const AbstractViewer* viewer;
|
||||
Texture* globalReflectionTexture;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -214,8 +214,15 @@ namespace Nz
|
|||
s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData1, ComponentType_Float4, NazaraOffsetOf(ForwardRenderQueue::BillboardData, size)); // Englobe sincos
|
||||
s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData2, ComponentType_Color, NazaraOffsetOf(ForwardRenderQueue::BillboardData, color));
|
||||
|
||||
s_reflectionSampler.SetFilterMode(SamplerFilter_Bilinear);
|
||||
s_reflectionSampler.SetWrapMode(SamplerWrap_Clamp);
|
||||
|
||||
s_shadowSampler.SetFilterMode(SamplerFilter_Bilinear);
|
||||
s_shadowSampler.SetWrapMode(SamplerWrap_Clamp);
|
||||
|
||||
std::array<UInt8, 6> whitePixels = { { 255, 255, 255, 255, 255, 255 } };
|
||||
s_dummyReflection.Create(ImageType_Cubemap, PixelFormatType_L8, 1, 1);
|
||||
s_dummyReflection.Update(whitePixels.data());
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
|
@ -232,6 +239,7 @@ namespace Nz
|
|||
|
||||
void ForwardRenderTechnique::Uninitialize()
|
||||
{
|
||||
s_dummyReflection.Destroy();
|
||||
s_quadIndexBuffer.Reset();
|
||||
s_quadVertexBuffer.Reset();
|
||||
}
|
||||
|
|
@ -583,6 +591,10 @@ namespace Nz
|
|||
const Shader* lastShader = nullptr;
|
||||
const ShaderUniforms* shaderUniforms = nullptr;
|
||||
|
||||
Texture* reflectionMap = sceneData.globalReflectionTexture;
|
||||
if (!reflectionMap)
|
||||
reflectionMap = &s_dummyReflection;
|
||||
|
||||
for (auto& pipelinePair : layer.opaqueModels)
|
||||
{
|
||||
const MaterialPipeline* pipeline = pipelinePair.first;
|
||||
|
|
@ -618,6 +630,15 @@ namespace Nz
|
|||
{
|
||||
material->Apply(pipelineInstance);
|
||||
|
||||
if (shaderUniforms->reflectionMap != -1)
|
||||
{
|
||||
unsigned int textureUnit = Material::GetTextureUnit(TextureMap_ReflectionCube);
|
||||
|
||||
shader->SendInteger(shaderUniforms->reflectionMap, textureUnit);
|
||||
Renderer::SetTexture(textureUnit, reflectionMap);
|
||||
Renderer::SetTextureSampler(textureUnit, s_reflectionSampler);
|
||||
}
|
||||
|
||||
ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap;
|
||||
|
||||
// Meshes
|
||||
|
|
@ -895,6 +916,7 @@ namespace Nz
|
|||
uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &ForwardRenderTechnique::OnShaderInvalidated);
|
||||
|
||||
uniforms.eyePosition = shader->GetUniformLocation("EyePosition");
|
||||
uniforms.reflectionMap = shader->GetUniformLocation("ReflectionMap");
|
||||
uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient");
|
||||
uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay");
|
||||
|
||||
|
|
@ -1037,6 +1059,8 @@ namespace Nz
|
|||
}
|
||||
|
||||
IndexBuffer ForwardRenderTechnique::s_quadIndexBuffer;
|
||||
Texture ForwardRenderTechnique::s_dummyReflection;
|
||||
TextureSampler ForwardRenderTechnique::s_reflectionSampler;
|
||||
TextureSampler ForwardRenderTechnique::s_shadowSampler;
|
||||
VertexBuffer ForwardRenderTechnique::s_quadVertexBuffer;
|
||||
VertexDeclaration ForwardRenderTechnique::s_billboardInstanceDeclaration;
|
||||
|
|
|
|||
|
|
@ -77,19 +77,20 @@ namespace Nz
|
|||
NazaraAssert(m_pipelineInfo.uberShader, "Material pipeline has no uber shader");
|
||||
|
||||
ParameterList list;
|
||||
list.SetParameter("ALPHA_MAPPING", m_pipelineInfo.hasAlphaMap);
|
||||
list.SetParameter("ALPHA_TEST", m_pipelineInfo.alphaTest);
|
||||
list.SetParameter("COMPUTE_TBNMATRIX", m_pipelineInfo.hasNormalMap || m_pipelineInfo.hasHeightMap);
|
||||
list.SetParameter("DIFFUSE_MAPPING", m_pipelineInfo.hasDiffuseMap);
|
||||
list.SetParameter("EMISSIVE_MAPPING", m_pipelineInfo.hasEmissiveMap);
|
||||
list.SetParameter("NORMAL_MAPPING", m_pipelineInfo.hasNormalMap);
|
||||
list.SetParameter("PARALLAX_MAPPING", m_pipelineInfo.hasHeightMap);
|
||||
list.SetParameter("SHADOW_MAPPING", m_pipelineInfo.shadowReceive);
|
||||
list.SetParameter("SPECULAR_MAPPING", m_pipelineInfo.hasSpecularMap);
|
||||
list.SetParameter("TEXTURE_MAPPING", m_pipelineInfo.hasAlphaMap || m_pipelineInfo.hasDiffuseMap || m_pipelineInfo.hasEmissiveMap ||
|
||||
m_pipelineInfo.hasNormalMap || m_pipelineInfo.hasHeightMap || m_pipelineInfo.hasSpecularMap ||
|
||||
flags & ShaderFlags_TextureOverlay);
|
||||
list.SetParameter("TRANSFORM", true);
|
||||
list.SetParameter("ALPHA_MAPPING", m_pipelineInfo.hasAlphaMap);
|
||||
list.SetParameter("ALPHA_TEST", m_pipelineInfo.alphaTest);
|
||||
list.SetParameter("COMPUTE_TBNMATRIX", m_pipelineInfo.hasNormalMap || m_pipelineInfo.hasHeightMap);
|
||||
list.SetParameter("DIFFUSE_MAPPING", m_pipelineInfo.hasDiffuseMap);
|
||||
list.SetParameter("EMISSIVE_MAPPING", m_pipelineInfo.hasEmissiveMap);
|
||||
list.SetParameter("NORMAL_MAPPING", m_pipelineInfo.hasNormalMap);
|
||||
list.SetParameter("PARALLAX_MAPPING", m_pipelineInfo.hasHeightMap);
|
||||
list.SetParameter("REFLECTION_MAPPING", m_pipelineInfo.reflectionMapping);
|
||||
list.SetParameter("SHADOW_MAPPING", m_pipelineInfo.shadowReceive);
|
||||
list.SetParameter("SPECULAR_MAPPING", m_pipelineInfo.hasSpecularMap);
|
||||
list.SetParameter("TEXTURE_MAPPING", m_pipelineInfo.hasAlphaMap || m_pipelineInfo.hasDiffuseMap || m_pipelineInfo.hasEmissiveMap ||
|
||||
m_pipelineInfo.hasNormalMap || m_pipelineInfo.hasHeightMap || m_pipelineInfo.hasSpecularMap ||
|
||||
m_pipelineInfo.reflectionMapping || flags & ShaderFlags_TextureOverlay);
|
||||
list.SetParameter("TRANSFORM", true);
|
||||
|
||||
list.SetParameter("FLAG_BILLBOARD", static_cast<bool>((flags & ShaderFlags_Billboard) != 0));
|
||||
list.SetParameter("FLAG_DEFERRED", static_cast<bool>((flags & ShaderFlags_Deferred) != 0));
|
||||
|
|
@ -175,7 +176,7 @@ namespace Nz
|
|||
OverrideShader("Shaders/PhongLighting/core.vert", &vertexShader);
|
||||
#endif
|
||||
|
||||
uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING NORMAL_MAPPING PARALLAX_MAPPING SHADOW_MAPPING SPECULAR_MAPPING");
|
||||
uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING NORMAL_MAPPING PARALLAX_MAPPING REFLECTION_MAPPING SHADOW_MAPPING SPECULAR_MAPPING");
|
||||
uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX PARALLAX_MAPPING SHADOW_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH");
|
||||
|
||||
UberShaderLibrary::Register("PhongLighting", uberShader);
|
||||
|
|
|
|||
Loading…
Reference in New Issue