Add Phong lighting (WIP)
This commit is contained in:
@@ -25,30 +25,37 @@ namespace Nz
|
||||
}
|
||||
|
||||
BasicMaterial::BasicMaterial(MaterialPass& material) :
|
||||
m_material(material)
|
||||
BasicMaterial(material, NoInit{})
|
||||
{
|
||||
// Most common case: don't fetch texture indexes as a little optimization
|
||||
const std::shared_ptr<const MaterialSettings>& materialSettings = material.GetSettings();
|
||||
if (materialSettings == s_materialSettings)
|
||||
if (materialSettings == s_basicMaterialSettings)
|
||||
{
|
||||
m_optionIndexes = s_optionIndexes;
|
||||
m_textureIndexes = s_textureIndexes;
|
||||
m_basicOptionIndexes = s_basicOptionIndexes;
|
||||
m_basicTextureIndexes = s_basicTextureIndexes;
|
||||
m_uniformBlockIndex = s_uniformBlockIndex;
|
||||
m_uniformOffsets = s_uniformOffsets;
|
||||
m_basicUniformOffsets = s_basicUniformOffsets;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_optionIndexes.alphaTest = materialSettings->GetOptionIndex("AlphaTest");
|
||||
m_optionIndexes.hasAlphaMap = materialSettings->GetOptionIndex("HasAlphaMap");
|
||||
m_optionIndexes.hasDiffuseMap = materialSettings->GetOptionIndex("HasDiffuseMap");
|
||||
m_basicOptionIndexes.alphaTest = materialSettings->GetOptionIndex("AlphaTest");
|
||||
m_basicOptionIndexes.hasAlphaMap = materialSettings->GetOptionIndex("HasAlphaMap");
|
||||
m_basicOptionIndexes.hasDiffuseMap = materialSettings->GetOptionIndex("HasDiffuseMap");
|
||||
|
||||
m_textureIndexes.alpha = materialSettings->GetTextureIndex("Alpha");
|
||||
m_textureIndexes.diffuse = materialSettings->GetTextureIndex("Diffuse");
|
||||
m_basicTextureIndexes.alpha = materialSettings->GetTextureIndex("Alpha");
|
||||
m_basicTextureIndexes.diffuse = materialSettings->GetTextureIndex("Diffuse");
|
||||
|
||||
m_uniformBlockIndex = materialSettings->GetUniformBlockIndex("BasicSettings");
|
||||
|
||||
m_uniformOffsets.alphaThreshold = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "AlphaThreshold");
|
||||
m_uniformOffsets.diffuseColor = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "DiffuseColor");
|
||||
m_uniformBlockIndex = materialSettings->GetUniformBlockIndex("MaterialSettings");
|
||||
if (m_uniformBlockIndex != MaterialSettings::InvalidIndex)
|
||||
{
|
||||
m_basicUniformOffsets.alphaThreshold = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "AlphaThreshold");
|
||||
m_basicUniformOffsets.diffuseColor = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "DiffuseColor");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_basicUniformOffsets.alphaThreshold = MaterialSettings::InvalidIndex;
|
||||
m_basicUniformOffsets.diffuseColor = MaterialSettings::InvalidIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +65,7 @@ namespace Nz
|
||||
|
||||
const std::vector<UInt8>& bufferData = m_material.GetUniformBufferConstData(m_uniformBlockIndex);
|
||||
|
||||
return AccessByOffset<const float&>(bufferData.data(), m_uniformOffsets.alphaThreshold);
|
||||
return AccessByOffset<const float&>(bufferData.data(), m_basicUniformOffsets.alphaThreshold);
|
||||
}
|
||||
|
||||
Color BasicMaterial::GetDiffuseColor() const
|
||||
@@ -67,7 +74,7 @@ namespace Nz
|
||||
|
||||
const std::vector<UInt8>& bufferData = m_material.GetUniformBufferConstData(m_uniformBlockIndex);
|
||||
|
||||
const float* colorPtr = AccessByOffset<const float*>(bufferData.data(), m_uniformOffsets.diffuseColor);
|
||||
const float* colorPtr = AccessByOffset<const float*>(bufferData.data(), m_basicUniformOffsets.diffuseColor);
|
||||
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
||||
}
|
||||
|
||||
@@ -76,7 +83,7 @@ namespace Nz
|
||||
NazaraAssert(HasAlphaTestThreshold(), "Material has no alpha threshold uniform");
|
||||
|
||||
std::vector<UInt8>& bufferData = m_material.GetUniformBufferData(m_uniformBlockIndex);
|
||||
AccessByOffset<float&>(bufferData.data(), m_uniformOffsets.alphaThreshold) = alphaThreshold;
|
||||
AccessByOffset<float&>(bufferData.data(), m_basicUniformOffsets.alphaThreshold) = alphaThreshold;
|
||||
}
|
||||
|
||||
void BasicMaterial::SetDiffuseColor(const Color& diffuse)
|
||||
@@ -85,44 +92,45 @@ namespace Nz
|
||||
|
||||
std::vector<UInt8>& bufferData = m_material.GetUniformBufferData(m_uniformBlockIndex);
|
||||
|
||||
float* colorPtr = AccessByOffset<float*>(bufferData.data(), m_uniformOffsets.diffuseColor);
|
||||
float* colorPtr = AccessByOffset<float*>(bufferData.data(), m_basicUniformOffsets.diffuseColor);
|
||||
colorPtr[0] = diffuse.r / 255.f;
|
||||
colorPtr[1] = diffuse.g / 255.f;
|
||||
colorPtr[2] = diffuse.b / 255.f;
|
||||
colorPtr[3] = diffuse.a / 255.f;
|
||||
}
|
||||
|
||||
MaterialSettings::Builder BasicMaterial::Build(const UniformOffsets& offsets, std::vector<UInt8> defaultValues, std::vector<std::shared_ptr<UberShader>> uberShaders, std::size_t* uniformBlockIndex, OptionIndexes* optionIndexes, TextureIndexes* textureIndexes)
|
||||
MaterialSettings::Builder BasicMaterial::Build(BasicBuildOptions& options)
|
||||
{
|
||||
MaterialSettings::Builder settings;
|
||||
|
||||
std::vector<MaterialSettings::UniformVariable> variables;
|
||||
if (offsets.alphaThreshold != std::numeric_limits<std::size_t>::max())
|
||||
if (options.basicOffsets.alphaThreshold != std::numeric_limits<std::size_t>::max())
|
||||
{
|
||||
variables.push_back({
|
||||
"AlphaThreshold",
|
||||
offsets.alphaThreshold
|
||||
options.basicOffsets.alphaThreshold
|
||||
});
|
||||
}
|
||||
|
||||
if (offsets.diffuseColor != std::numeric_limits<std::size_t>::max())
|
||||
if (options.basicOffsets.diffuseColor != std::numeric_limits<std::size_t>::max())
|
||||
{
|
||||
variables.push_back({
|
||||
"DiffuseColor",
|
||||
offsets.diffuseColor
|
||||
options.basicOffsets.diffuseColor
|
||||
});
|
||||
}
|
||||
|
||||
if (offsets.alphaThreshold != std::numeric_limits<std::size_t>::max())
|
||||
AccessByOffset<float&>(defaultValues.data(), offsets.alphaThreshold) = 0.2f;
|
||||
|
||||
static_assert(sizeof(Vector4f) == 4 * sizeof(float), "Vector4f is expected to be exactly 4 floats wide");
|
||||
if (offsets.diffuseColor != std::numeric_limits<std::size_t>::max())
|
||||
AccessByOffset<Vector4f&>(defaultValues.data(), offsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
if (options.basicOffsets.alphaThreshold != std::numeric_limits<std::size_t>::max())
|
||||
AccessByOffset<float&>(options.defaultValues.data(), options.basicOffsets.alphaThreshold) = 0.2f;
|
||||
|
||||
if (options.basicOffsets.diffuseColor != std::numeric_limits<std::size_t>::max())
|
||||
AccessByOffset<Vector4f&>(options.defaultValues.data(), options.basicOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
// Textures
|
||||
if (textureIndexes)
|
||||
textureIndexes->alpha = settings.textures.size();
|
||||
if (options.basicTextureIndexes)
|
||||
options.basicTextureIndexes->alpha = settings.textures.size();
|
||||
|
||||
settings.textures.push_back({
|
||||
2,
|
||||
@@ -130,8 +138,8 @@ namespace Nz
|
||||
ImageType::E2D
|
||||
});
|
||||
|
||||
if (textureIndexes)
|
||||
textureIndexes->diffuse = settings.textures.size();
|
||||
if (options.basicTextureIndexes)
|
||||
options.basicTextureIndexes->diffuse = settings.textures.size();
|
||||
|
||||
settings.textures.push_back({
|
||||
1,
|
||||
@@ -139,15 +147,15 @@ namespace Nz
|
||||
ImageType::E2D
|
||||
});
|
||||
|
||||
if (uniformBlockIndex)
|
||||
*uniformBlockIndex = settings.uniformBlocks.size();
|
||||
if (options.uniformBlockIndex)
|
||||
*options.uniformBlockIndex = settings.uniformBlocks.size();
|
||||
|
||||
settings.uniformBlocks.push_back({
|
||||
0,
|
||||
"BasicSettings",
|
||||
offsets.totalSize,
|
||||
"MaterialSettings",
|
||||
options.basicOffsets.totalSize,
|
||||
std::move(variables),
|
||||
std::move(defaultValues)
|
||||
options.defaultValues
|
||||
});
|
||||
|
||||
// Common data
|
||||
@@ -164,7 +172,7 @@ namespace Nz
|
||||
settings.predefinedBindings[UnderlyingCast(PredefinedShaderBinding::OverlayTexture)] = 3;
|
||||
settings.predefinedBindings[UnderlyingCast(PredefinedShaderBinding::ViewerDataUbo)] = 5;
|
||||
|
||||
settings.shaders = std::move(uberShaders);
|
||||
settings.shaders = options.shaders;
|
||||
|
||||
for (std::shared_ptr<UberShader> uberShader : settings.shaders)
|
||||
{
|
||||
@@ -230,20 +238,20 @@ namespace Nz
|
||||
// Options
|
||||
|
||||
// HasDiffuseMap
|
||||
if (optionIndexes)
|
||||
optionIndexes->hasDiffuseMap = settings.options.size();
|
||||
if (options.basicOptionIndexes)
|
||||
options.basicOptionIndexes->hasDiffuseMap = settings.options.size();
|
||||
|
||||
MaterialSettings::BuildOption(settings.options, settings.shaders, "HasDiffuseMap", "HasDiffuseTexture");
|
||||
|
||||
// HasAlphaMap
|
||||
if (optionIndexes)
|
||||
optionIndexes->hasAlphaMap = settings.options.size();
|
||||
if (options.basicOptionIndexes)
|
||||
options.basicOptionIndexes->hasAlphaMap = settings.options.size();
|
||||
|
||||
MaterialSettings::BuildOption(settings.options, settings.shaders, "HasAlphaMap", "HasAlphaTexture");
|
||||
|
||||
// AlphaTest
|
||||
if (optionIndexes)
|
||||
optionIndexes->alphaTest = settings.options.size();
|
||||
if (options.basicOptionIndexes)
|
||||
options.basicOptionIndexes->alphaTest = settings.options.size();
|
||||
|
||||
MaterialSettings::BuildOption(settings.options, settings.shaders, "AlphaTest", "AlphaTest");
|
||||
|
||||
@@ -258,36 +266,46 @@ namespace Nz
|
||||
return { std::move(shader) };
|
||||
}
|
||||
|
||||
auto BasicMaterial::BuildUniformOffsets() -> std::pair<UniformOffsets, FieldOffsets>
|
||||
auto BasicMaterial::BuildUniformOffsets() -> std::pair<BasicUniformOffsets, FieldOffsets>
|
||||
{
|
||||
FieldOffsets fieldOffsets(StructLayout::Std140);
|
||||
|
||||
UniformOffsets uniformOffsets;
|
||||
BasicUniformOffsets uniformOffsets;
|
||||
uniformOffsets.alphaThreshold = fieldOffsets.AddField(StructFieldType::Float1);
|
||||
uniformOffsets.diffuseColor = fieldOffsets.AddField(StructFieldType::Float4);
|
||||
uniformOffsets.totalSize = fieldOffsets.GetSize();
|
||||
uniformOffsets.totalSize = fieldOffsets.GetAlignedSize();
|
||||
|
||||
return std::make_pair(std::move(uniformOffsets), std::move(fieldOffsets));
|
||||
}
|
||||
|
||||
bool BasicMaterial::Initialize()
|
||||
{
|
||||
std::tie(s_uniformOffsets, std::ignore) = BuildUniformOffsets();
|
||||
std::tie(s_basicUniformOffsets, std::ignore) = BuildUniformOffsets();
|
||||
|
||||
std::vector<UInt8> defaultValues(s_uniformOffsets.totalSize);
|
||||
s_materialSettings = std::make_shared<MaterialSettings>(Build(s_uniformOffsets, std::move(defaultValues), BuildShaders(), &s_uniformBlockIndex, &s_optionIndexes, &s_textureIndexes));
|
||||
std::vector<UInt8> defaultValues(s_basicUniformOffsets.totalSize);
|
||||
|
||||
BasicBuildOptions options;
|
||||
options.defaultValues.resize(s_basicUniformOffsets.totalSize);
|
||||
options.shaders = BuildShaders();
|
||||
|
||||
options.basicOffsets = s_basicUniformOffsets;
|
||||
options.basicOptionIndexes = &s_basicOptionIndexes;
|
||||
options.basicTextureIndexes = &s_basicTextureIndexes;
|
||||
options.uniformBlockIndex = &s_uniformBlockIndex;
|
||||
|
||||
s_basicMaterialSettings = std::make_shared<MaterialSettings>(Build(options));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BasicMaterial::Uninitialize()
|
||||
{
|
||||
s_materialSettings.reset();
|
||||
s_basicMaterialSettings.reset();
|
||||
}
|
||||
|
||||
std::shared_ptr<MaterialSettings> BasicMaterial::s_materialSettings;
|
||||
std::shared_ptr<MaterialSettings> BasicMaterial::s_basicMaterialSettings;
|
||||
std::size_t BasicMaterial::s_uniformBlockIndex;
|
||||
BasicMaterial::OptionIndexes BasicMaterial::s_optionIndexes;
|
||||
BasicMaterial::TextureIndexes BasicMaterial::s_textureIndexes;
|
||||
BasicMaterial::UniformOffsets BasicMaterial::s_uniformOffsets;
|
||||
BasicMaterial::BasicOptionIndexes BasicMaterial::s_basicOptionIndexes;
|
||||
BasicMaterial::BasicTextureIndexes BasicMaterial::s_basicTextureIndexes;
|
||||
BasicMaterial::BasicUniformOffsets BasicMaterial::s_basicUniformOffsets;
|
||||
}
|
||||
|
||||
@@ -26,19 +26,26 @@ namespace Nz
|
||||
|
||||
bool DepthMaterial::Initialize()
|
||||
{
|
||||
UniformOffsets offsets;
|
||||
BasicUniformOffsets offsets;
|
||||
std::tie(offsets, std::ignore) = BuildUniformOffsets();
|
||||
|
||||
std::vector<UInt8> defaultValues(offsets.totalSize);
|
||||
s_materialSettings = std::make_shared<MaterialSettings>(Build(offsets, std::move(defaultValues), BuildShaders()));
|
||||
BasicBuildOptions options;
|
||||
options.defaultValues.resize(offsets.totalSize);
|
||||
options.shaders = BuildShaders();
|
||||
|
||||
options.basicOffsets = s_basicUniformOffsets;
|
||||
options.basicOptionIndexes = &s_basicOptionIndexes;
|
||||
options.basicTextureIndexes = &s_basicTextureIndexes;
|
||||
|
||||
s_basicMaterialSettings = std::make_shared<MaterialSettings>(Build(options));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DepthMaterial::Uninitialize()
|
||||
{
|
||||
s_materialSettings.reset();
|
||||
s_basicMaterialSettings.reset();
|
||||
}
|
||||
|
||||
std::shared_ptr<MaterialSettings> DepthMaterial::s_materialSettings;
|
||||
std::shared_ptr<MaterialSettings> DepthMaterial::s_basicMaterialSettings;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Nz
|
||||
{
|
||||
ElementRenderer::~ElementRenderer() = default;
|
||||
|
||||
void ElementRenderer::Prepare(const ViewerInstance& /*viewerInstance*/, ElementRendererData& /*rendererData*/, RenderFrame& /*currentFrame*/, const Pointer<const RenderElement>* /*elements*/, std::size_t /*elementCount*/)
|
||||
void ElementRenderer::Prepare(const ViewerInstance& /*viewerInstance*/, ElementRendererData& /*rendererData*/, RenderFrame& /*currentFrame*/, const RenderStates& /*renderStates*/, const Pointer<const RenderElement>* /*elements*/, std::size_t /*elementCount*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/RenderElement.hpp>
|
||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||
#include <Nazara/Graphics/SpriteChainRenderer.hpp>
|
||||
#include <Nazara/Graphics/SubmeshRenderer.hpp>
|
||||
#include <Nazara/Graphics/ViewerInstance.hpp>
|
||||
@@ -35,6 +36,23 @@ namespace Nz
|
||||
m_elementRenderers.resize(BasicRenderElementCount);
|
||||
m_elementRenderers[UnderlyingCast(BasicRenderElement::SpriteChain)] = std::make_unique<SpriteChainRenderer>(*Graphics::Instance()->GetRenderDevice());
|
||||
m_elementRenderers[UnderlyingCast(BasicRenderElement::Submesh)] = std::make_unique<SubmeshRenderer>();
|
||||
|
||||
auto lightOffset = PredefinedLightData::GetOffsets();
|
||||
|
||||
m_lightDataBuffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
||||
if (!m_lightDataBuffer->Initialize(lightOffset.totalSize, BufferUsage::DeviceLocal))
|
||||
throw std::runtime_error("failed to create light data buffer");
|
||||
|
||||
std::vector<UInt8> staticLightData(lightOffset.totalSize);
|
||||
AccessByOffset<UInt32&>(staticLightData.data(), lightOffset.lightCountOffset) = 1;
|
||||
AccessByOffset<UInt32&>(staticLightData.data(), lightOffset.lightsOffset + lightOffset.lightMemberOffsets.type) = 0;
|
||||
AccessByOffset<Vector4f&>(staticLightData.data(), lightOffset.lightsOffset + lightOffset.lightMemberOffsets.color) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||
AccessByOffset<Vector2f&>(staticLightData.data(), lightOffset.lightsOffset + lightOffset.lightMemberOffsets.factor) = Vector2f(0.2f, 1.f);
|
||||
AccessByOffset<Vector4f&>(staticLightData.data(), lightOffset.lightsOffset + lightOffset.lightMemberOffsets.parameter1) = Vector4f(0.f, 0.f, -1.f, 1.f);
|
||||
AccessByOffset<UInt8&>(staticLightData.data(), lightOffset.lightsOffset + lightOffset.lightMemberOffsets.shadowMappingFlag) = 0;
|
||||
|
||||
if (!m_lightDataBuffer->Fill(staticLightData.data(), 0, staticLightData.size()))
|
||||
throw std::runtime_error("failed to fill light data buffer");
|
||||
}
|
||||
|
||||
void ForwardFramePipeline::InvalidateViewer(AbstractViewer* viewerInstance)
|
||||
@@ -320,16 +338,19 @@ namespace Nz
|
||||
|
||||
const auto& viewerInstance = viewer->GetViewerInstance();
|
||||
|
||||
ElementRenderer::RenderStates renderStates;
|
||||
renderStates.lightData = m_lightDataBuffer;
|
||||
|
||||
ProcessRenderQueue(viewerData.depthPrepassRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||
{
|
||||
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
|
||||
elementRenderer.Prepare(viewerInstance, *rendererData[elementType], renderFrame, elements, elementCount);
|
||||
elementRenderer.Prepare(viewerInstance, *rendererData[elementType], renderFrame, renderStates, elements, elementCount);
|
||||
});
|
||||
|
||||
ProcessRenderQueue(viewerData.forwardRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||
{
|
||||
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
|
||||
elementRenderer.Prepare(viewerInstance, *rendererData[elementType], renderFrame, elements, elementCount);
|
||||
elementRenderer.Prepare(viewerInstance, *rendererData[elementType], renderFrame, renderStates, elements, elementCount);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -113,36 +113,6 @@ namespace Nz
|
||||
m_defaultTextures.whiteTextures.fill(nullptr);
|
||||
}
|
||||
|
||||
void Graphics::FillDrawDataPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set)
|
||||
{
|
||||
// TextureOverlay
|
||||
layoutInfo.bindings.push_back({
|
||||
set, 0,
|
||||
ShaderBindingType::Texture,
|
||||
ShaderStageType_All
|
||||
});
|
||||
}
|
||||
|
||||
void Graphics::FillViewerPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set)
|
||||
{
|
||||
// ViewerData
|
||||
layoutInfo.bindings.push_back({
|
||||
set, 0,
|
||||
ShaderBindingType::UniformBuffer,
|
||||
ShaderStageType_All
|
||||
});
|
||||
}
|
||||
|
||||
void Graphics::FillWorldPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set)
|
||||
{
|
||||
// InstanceData
|
||||
layoutInfo.bindings.push_back({
|
||||
set, 0,
|
||||
ShaderBindingType::UniformBuffer,
|
||||
ShaderStageType_All
|
||||
});
|
||||
}
|
||||
|
||||
void Graphics::BuildBlitPipeline()
|
||||
{
|
||||
RenderPipelineLayoutInfo layoutInfo;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Shader/ShaderLangParser.hpp>
|
||||
#include <Nazara/Utility/BufferMapper.hpp>
|
||||
#include <Nazara/Utility/FieldOffsets.hpp>
|
||||
#include <Nazara/Utility/MaterialData.hpp>
|
||||
@@ -15,69 +16,84 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace
|
||||
{
|
||||
const UInt8 r_shader[] = {
|
||||
#include <Nazara/Graphics/Resources/Shaders/phong_material.nzsl.h>
|
||||
};
|
||||
}
|
||||
|
||||
PhongLightingMaterial::PhongLightingMaterial(MaterialPass& material) :
|
||||
m_material(material)
|
||||
BasicMaterial(material, NoInit{})
|
||||
{
|
||||
// Most common case: don't fetch texture indexes as a little optimization
|
||||
const std::shared_ptr<const MaterialSettings>& materialSettings = m_material.GetSettings();
|
||||
if (materialSettings == s_materialSettings)
|
||||
const std::shared_ptr<const MaterialSettings>& materialSettings = GetMaterial().GetSettings();
|
||||
if (materialSettings == s_phongMaterialSettings)
|
||||
{
|
||||
m_textureIndexes = s_textureIndexes;
|
||||
m_phongUniformIndex = s_phongUniformBlockIndex;
|
||||
m_basicUniformOffsets = s_basicUniformOffsets;
|
||||
m_basicOptionIndexes = s_basicOptionIndexes;
|
||||
m_basicTextureIndexes = s_basicTextureIndexes;
|
||||
|
||||
m_phongOptionIndexes = s_phongOptionIndexes;
|
||||
m_phongTextureIndexes = s_phongTextureIndexes;
|
||||
m_phongUniformOffsets = s_phongUniformOffsets;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_textureIndexes.alpha = materialSettings->GetTextureIndex("Alpha");
|
||||
m_textureIndexes.diffuse = materialSettings->GetTextureIndex("Diffuse");
|
||||
m_textureIndexes.emissive = materialSettings->GetTextureIndex("Emissive");
|
||||
m_textureIndexes.height = materialSettings->GetTextureIndex("Height");
|
||||
m_textureIndexes.normal = materialSettings->GetTextureIndex("Normal");
|
||||
m_textureIndexes.specular = materialSettings->GetTextureIndex("Specular");
|
||||
m_basicOptionIndexes.alphaTest = materialSettings->GetOptionIndex("AlphaTest");
|
||||
m_basicOptionIndexes.hasAlphaMap = materialSettings->GetOptionIndex("HasAlphaMap");
|
||||
m_basicOptionIndexes.hasDiffuseMap = materialSettings->GetOptionIndex("HasDiffuseMap");
|
||||
|
||||
m_phongUniformIndex = materialSettings->GetUniformBlockIndex("PhongSettings");
|
||||
m_phongOptionIndexes.hasEmissiveMap = materialSettings->GetOptionIndex("HasEmissiveMap");
|
||||
m_phongOptionIndexes.hasHeightMap = materialSettings->GetOptionIndex("HasHeightMap");
|
||||
m_phongOptionIndexes.hasNormalMap = materialSettings->GetOptionIndex("HasNormalMap");
|
||||
m_phongOptionIndexes.hasSpecularMap = materialSettings->GetOptionIndex("HasSpecularMap");
|
||||
|
||||
m_phongUniformOffsets.alphaThreshold = materialSettings->GetUniformBlockVariableOffset(m_phongUniformIndex, "AlphaThreshold");
|
||||
m_phongUniformOffsets.ambientColor = materialSettings->GetUniformBlockVariableOffset(m_phongUniformIndex, "AmbientColor");
|
||||
m_phongUniformOffsets.diffuseColor = materialSettings->GetUniformBlockVariableOffset(m_phongUniformIndex, "DiffuseColor");
|
||||
m_phongUniformOffsets.shininess = materialSettings->GetUniformBlockVariableOffset(m_phongUniformIndex, "Shininess");
|
||||
m_phongUniformOffsets.specularColor = materialSettings->GetUniformBlockVariableOffset(m_phongUniformIndex, "SpecularColor");
|
||||
m_basicTextureIndexes.alpha = materialSettings->GetTextureIndex("Alpha");
|
||||
m_basicTextureIndexes.diffuse = materialSettings->GetTextureIndex("Diffuse");
|
||||
|
||||
m_phongTextureIndexes.emissive = materialSettings->GetTextureIndex("Emissive");
|
||||
m_phongTextureIndexes.height = materialSettings->GetTextureIndex("Height");
|
||||
m_phongTextureIndexes.normal = materialSettings->GetTextureIndex("Normal");
|
||||
m_phongTextureIndexes.specular = materialSettings->GetTextureIndex("Specular");
|
||||
|
||||
m_uniformBlockIndex = materialSettings->GetUniformBlockIndex("MaterialSettings");
|
||||
if (m_uniformBlockIndex != MaterialSettings::InvalidIndex)
|
||||
{
|
||||
m_basicUniformOffsets.alphaThreshold = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "AlphaThreshold");
|
||||
m_basicUniformOffsets.diffuseColor = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "DiffuseColor");
|
||||
|
||||
m_phongUniformOffsets.ambientColor = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "AmbientColor");
|
||||
m_phongUniformOffsets.shininess = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "Shininess");
|
||||
m_phongUniformOffsets.specularColor = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "SpecularColor");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_basicUniformOffsets.alphaThreshold = MaterialSettings::InvalidIndex;
|
||||
m_basicUniformOffsets.diffuseColor = MaterialSettings::InvalidIndex;
|
||||
|
||||
m_phongUniformOffsets.ambientColor = MaterialSettings::InvalidIndex;
|
||||
m_phongUniformOffsets.shininess = MaterialSettings::InvalidIndex;
|
||||
m_phongUniformOffsets.specularColor = MaterialSettings::InvalidIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float PhongLightingMaterial::GetAlphaThreshold() const
|
||||
{
|
||||
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
||||
|
||||
const std::vector<UInt8>& bufferData = m_material.GetUniformBufferConstData(m_phongUniformIndex);
|
||||
return AccessByOffset<const float&>(bufferData.data(), m_phongUniformOffsets.alphaThreshold);
|
||||
}
|
||||
|
||||
Color PhongLightingMaterial::GetAmbientColor() const
|
||||
{
|
||||
NazaraAssert(HasAmbientColor(), "Material has no ambient color uniform");
|
||||
|
||||
const std::vector<UInt8>& bufferData = m_material.GetUniformBufferConstData(m_phongUniformIndex);
|
||||
const std::vector<UInt8>& bufferData = GetMaterial().GetUniformBufferConstData(m_uniformBlockIndex);
|
||||
|
||||
const float* colorPtr = AccessByOffset<const float*>(bufferData.data(), m_phongUniformOffsets.ambientColor);
|
||||
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
||||
}
|
||||
|
||||
Color PhongLightingMaterial::GetDiffuseColor() const
|
||||
{
|
||||
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
|
||||
|
||||
const std::vector<UInt8>& bufferData = m_material.GetUniformBufferConstData(m_phongUniformIndex);
|
||||
|
||||
const float* colorPtr = AccessByOffset<const float*>(bufferData.data(), m_phongUniformOffsets.diffuseColor);
|
||||
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
||||
}
|
||||
|
||||
float Nz::PhongLightingMaterial::GetShininess() const
|
||||
{
|
||||
NazaraAssert(HasShininess(), "Material has no shininess uniform");
|
||||
|
||||
const std::vector<UInt8>& bufferData = m_material.GetUniformBufferConstData(m_phongUniformIndex);
|
||||
const std::vector<UInt8>& bufferData = GetMaterial().GetUniformBufferConstData(m_uniformBlockIndex);
|
||||
return AccessByOffset<const float&>(bufferData.data(), m_phongUniformOffsets.shininess);
|
||||
}
|
||||
|
||||
@@ -85,25 +101,17 @@ namespace Nz
|
||||
{
|
||||
NazaraAssert(HasSpecularColor(), "Material has no specular color uniform");
|
||||
|
||||
const std::vector<UInt8>& bufferData = m_material.GetUniformBufferConstData(m_phongUniformIndex);
|
||||
const std::vector<UInt8>& bufferData = GetMaterial().GetUniformBufferConstData(m_uniformBlockIndex);
|
||||
|
||||
const float* colorPtr = AccessByOffset<const float*>(bufferData.data(), m_phongUniformOffsets.specularColor);
|
||||
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
||||
}
|
||||
|
||||
void PhongLightingMaterial::SetAlphaThreshold(float alphaThreshold)
|
||||
{
|
||||
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
||||
|
||||
std::vector<UInt8>& bufferData = m_material.GetUniformBufferData(m_phongUniformIndex);
|
||||
AccessByOffset<float&>(bufferData.data(), m_phongUniformOffsets.alphaThreshold) = alphaThreshold;
|
||||
}
|
||||
|
||||
void PhongLightingMaterial::SetAmbientColor(const Color& ambient)
|
||||
{
|
||||
NazaraAssert(HasAmbientColor(), "Material has no ambient color uniform");
|
||||
|
||||
std::vector<UInt8>& bufferData = m_material.GetUniformBufferData(m_phongUniformIndex);
|
||||
std::vector<UInt8>& bufferData = GetMaterial().GetUniformBufferData(m_uniformBlockIndex);
|
||||
float* colorPtr = AccessByOffset<float*>(bufferData.data(), m_phongUniformOffsets.ambientColor);
|
||||
colorPtr[0] = ambient.r / 255.f;
|
||||
colorPtr[1] = ambient.g / 255.f;
|
||||
@@ -111,23 +119,19 @@ namespace Nz
|
||||
colorPtr[3] = ambient.a / 255.f;
|
||||
}
|
||||
|
||||
void PhongLightingMaterial::SetDiffuseColor(const Color& diffuse)
|
||||
void PhongLightingMaterial::SetShininess(float shininess)
|
||||
{
|
||||
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
|
||||
NazaraAssert(HasShininess(), "Material has no shininess uniform");
|
||||
|
||||
std::vector<UInt8>& bufferData = m_material.GetUniformBufferData(m_phongUniformIndex);
|
||||
float* colorPtr = AccessByOffset<float*>(bufferData.data(), m_phongUniformOffsets.diffuseColor);
|
||||
colorPtr[0] = diffuse.r / 255.f;
|
||||
colorPtr[1] = diffuse.g / 255.f;
|
||||
colorPtr[2] = diffuse.b / 255.f;
|
||||
colorPtr[3] = diffuse.a / 255.f;
|
||||
std::vector<UInt8>& bufferData = GetMaterial().GetUniformBufferData(m_uniformBlockIndex);
|
||||
AccessByOffset<float&>(bufferData.data(), m_phongUniformOffsets.shininess) = shininess;
|
||||
}
|
||||
|
||||
void PhongLightingMaterial::SetSpecularColor(const Color& diffuse)
|
||||
{
|
||||
NazaraAssert(HasSpecularColor(), "Material has no specular color uniform");
|
||||
|
||||
std::vector<UInt8>& bufferData = m_material.GetUniformBufferData(m_phongUniformIndex);
|
||||
std::vector<UInt8>& bufferData = GetMaterial().GetUniformBufferData(m_uniformBlockIndex);
|
||||
float* colorPtr = AccessByOffset<float*>(bufferData.data(), m_phongUniformOffsets.specularColor);
|
||||
colorPtr[0] = diffuse.r / 255.f;
|
||||
colorPtr[1] = diffuse.g / 255.f;
|
||||
@@ -137,118 +141,256 @@ namespace Nz
|
||||
|
||||
const std::shared_ptr<MaterialSettings>& PhongLightingMaterial::GetSettings()
|
||||
{
|
||||
return s_materialSettings;
|
||||
return s_phongMaterialSettings;
|
||||
}
|
||||
|
||||
bool PhongLightingMaterial::Initialize()
|
||||
MaterialSettings::Builder PhongLightingMaterial::Build(PhongBuildOptions& options)
|
||||
{
|
||||
// MaterialPhongSettings
|
||||
FieldOffsets phongUniformStruct(StructLayout::Std140);
|
||||
MaterialSettings::Builder settings = BasicMaterial::Build(options);
|
||||
|
||||
s_phongUniformOffsets.alphaThreshold = phongUniformStruct.AddField(StructFieldType::Float1);
|
||||
s_phongUniformOffsets.shininess = phongUniformStruct.AddField(StructFieldType::Float1);
|
||||
s_phongUniformOffsets.ambientColor = phongUniformStruct.AddField(StructFieldType::Float4);
|
||||
s_phongUniformOffsets.diffuseColor = phongUniformStruct.AddField(StructFieldType::Float4);
|
||||
s_phongUniformOffsets.specularColor = phongUniformStruct.AddField(StructFieldType::Float4);
|
||||
assert(settings.uniformBlocks.size() == 1);
|
||||
std::vector<MaterialSettings::UniformVariable> variables = std::move(settings.uniformBlocks.front().uniforms);
|
||||
settings.uniformBlocks.clear();
|
||||
|
||||
MaterialSettings::Builder settings;
|
||||
|
||||
std::vector<MaterialSettings::UniformVariable> phongVariables;
|
||||
phongVariables.assign({
|
||||
{
|
||||
"AlphaThreshold",
|
||||
s_phongUniformOffsets.alphaThreshold
|
||||
},
|
||||
{
|
||||
"Shininess",
|
||||
s_phongUniformOffsets.shininess
|
||||
},
|
||||
{
|
||||
if (options.phongOffsets.ambientColor != std::numeric_limits<std::size_t>::max())
|
||||
{
|
||||
variables.push_back({
|
||||
"AmbientColor",
|
||||
s_phongUniformOffsets.ambientColor
|
||||
},
|
||||
{
|
||||
"DiffuseColor",
|
||||
s_phongUniformOffsets.diffuseColor
|
||||
},
|
||||
{
|
||||
options.phongOffsets.ambientColor
|
||||
});
|
||||
}
|
||||
|
||||
if (options.phongOffsets.shininess != std::numeric_limits<std::size_t>::max())
|
||||
{
|
||||
variables.push_back({
|
||||
"Shininess",
|
||||
options.phongOffsets.shininess
|
||||
});
|
||||
}
|
||||
|
||||
if (options.phongOffsets.shininess != std::numeric_limits<std::size_t>::max())
|
||||
{
|
||||
variables.push_back({
|
||||
"SpecularColor",
|
||||
s_phongUniformOffsets.specularColor
|
||||
}
|
||||
});
|
||||
options.phongOffsets.specularColor
|
||||
});
|
||||
}
|
||||
|
||||
static_assert(sizeof(Vector4f) == 4 * sizeof(float), "Vector4f is expected to be exactly 4 floats wide");
|
||||
|
||||
std::vector<UInt8> defaultValues(phongUniformStruct.GetSize());
|
||||
AccessByOffset<Vector4f&>(defaultValues.data(), s_phongUniformOffsets.ambientColor) = Vector4f(0.5f, 0.5f, 0.5f, 1.f);
|
||||
AccessByOffset<Vector4f&>(defaultValues.data(), s_phongUniformOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||
AccessByOffset<Vector4f&>(defaultValues.data(), s_phongUniformOffsets.specularColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||
AccessByOffset<float&>(defaultValues.data(), s_phongUniformOffsets.alphaThreshold) = 0.2f;
|
||||
AccessByOffset<float&>(defaultValues.data(), s_phongUniformOffsets.shininess) = 50.f;
|
||||
if (options.phongOffsets.ambientColor != std::numeric_limits<std::size_t>::max())
|
||||
AccessByOffset<Vector4f&>(options.defaultValues.data(), options.phongOffsets.ambientColor) = Vector4f(0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
s_phongUniformBlockIndex = settings.uniformBlocks.size();
|
||||
settings.uniformBlocks.push_back({
|
||||
0,
|
||||
"PhongSettings",
|
||||
phongUniformStruct.GetSize(),
|
||||
std::move(phongVariables),
|
||||
std::move(defaultValues)
|
||||
});
|
||||
if (options.phongOffsets.specularColor != std::numeric_limits<std::size_t>::max())
|
||||
AccessByOffset<Vector4f&>(options.defaultValues.data(), options.phongOffsets.specularColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
s_textureIndexes.alpha = settings.textures.size();
|
||||
settings.textures.push_back({
|
||||
2,
|
||||
"Alpha",
|
||||
ImageType::E2D
|
||||
});
|
||||
|
||||
s_textureIndexes.diffuse = settings.textures.size();
|
||||
settings.textures.push_back({
|
||||
1,
|
||||
"Diffuse",
|
||||
ImageType::E2D
|
||||
});
|
||||
if (options.phongOffsets.shininess != std::numeric_limits<std::size_t>::max())
|
||||
AccessByOffset<float&>(options.defaultValues.data(), options.phongOffsets.shininess) = 2.f;
|
||||
|
||||
// Textures
|
||||
if (options.phongTextureIndexes)
|
||||
options.phongTextureIndexes->emissive = settings.textures.size();
|
||||
|
||||
s_textureIndexes.emissive = settings.textures.size();
|
||||
settings.textures.push_back({
|
||||
3,
|
||||
7,
|
||||
"Emissive",
|
||||
ImageType::E2D
|
||||
});
|
||||
|
||||
s_textureIndexes.height = settings.textures.size();
|
||||
if (options.phongTextureIndexes)
|
||||
options.phongTextureIndexes->height = settings.textures.size();
|
||||
|
||||
settings.textures.push_back({
|
||||
4,
|
||||
8,
|
||||
"Height",
|
||||
ImageType::E2D
|
||||
});
|
||||
|
||||
s_textureIndexes.normal = settings.textures.size();
|
||||
if (options.phongTextureIndexes)
|
||||
options.phongTextureIndexes->normal = settings.textures.size();
|
||||
|
||||
settings.textures.push_back({
|
||||
5,
|
||||
9,
|
||||
"Normal",
|
||||
ImageType::E2D
|
||||
});
|
||||
|
||||
s_textureIndexes.specular = settings.textures.size();
|
||||
if (options.phongTextureIndexes)
|
||||
options.phongTextureIndexes->specular = settings.textures.size();
|
||||
|
||||
settings.textures.push_back({
|
||||
6,
|
||||
10,
|
||||
"Specular",
|
||||
ImageType::E2D
|
||||
});
|
||||
|
||||
s_materialSettings = std::make_shared<MaterialSettings>(std::move(settings));
|
||||
if (options.uniformBlockIndex)
|
||||
*options.uniformBlockIndex = settings.uniformBlocks.size();
|
||||
|
||||
settings.uniformBlocks.push_back({
|
||||
0,
|
||||
"MaterialSettings",
|
||||
options.phongOffsets.totalSize,
|
||||
std::move(variables),
|
||||
options.defaultValues
|
||||
});
|
||||
|
||||
settings.sharedUniformBlocks.push_back(PredefinedLightData::GetUniformBlock(6, ShaderStageType::Fragment));
|
||||
settings.predefinedBindings[UnderlyingCast(PredefinedShaderBinding::LightDataUbo)] = 6;
|
||||
|
||||
settings.shaders = options.shaders;
|
||||
|
||||
for (std::shared_ptr<UberShader> uberShader : settings.shaders)
|
||||
{
|
||||
constexpr std::size_t InvalidOption = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
auto FetchLocationOption = [&](const std::string& optionName)
|
||||
{
|
||||
const UberShader::Option* optionPtr;
|
||||
if (!uberShader->HasOption(optionName, &optionPtr))
|
||||
return InvalidOption;
|
||||
|
||||
if (optionPtr->type != ShaderAst::ExpressionType{ ShaderAst::PrimitiveType::Int32 })
|
||||
throw std::runtime_error("Location options must be of type i32");
|
||||
|
||||
return optionPtr->index;
|
||||
};
|
||||
|
||||
std::size_t positionLocationIndex = FetchLocationOption("PosLocation");
|
||||
std::size_t colorLocationIndex = FetchLocationOption("ColorLocation");
|
||||
std::size_t normalLocationIndex = FetchLocationOption("NormalLocation");
|
||||
std::size_t uvLocationIndex = FetchLocationOption("UvLocation");
|
||||
|
||||
uberShader->UpdateConfigCallback([=](UberShader::Config& config, const std::vector<RenderPipelineInfo::VertexBufferData>& vertexBuffers)
|
||||
{
|
||||
if (vertexBuffers.empty())
|
||||
return;
|
||||
|
||||
const VertexDeclaration& vertexDeclaration = *vertexBuffers.front().declaration;
|
||||
const auto& components = vertexDeclaration.GetComponents();
|
||||
|
||||
std::size_t locationIndex = 0;
|
||||
for (const auto& component : components)
|
||||
{
|
||||
switch (component.component)
|
||||
{
|
||||
case VertexComponent::Position:
|
||||
if (positionLocationIndex != InvalidOption)
|
||||
config.optionValues[positionLocationIndex] = static_cast<Int32>(locationIndex);
|
||||
|
||||
break;
|
||||
|
||||
case VertexComponent::Color:
|
||||
if (colorLocationIndex != InvalidOption)
|
||||
config.optionValues[colorLocationIndex] = static_cast<Int32>(locationIndex);
|
||||
|
||||
break;
|
||||
|
||||
case VertexComponent::Normal:
|
||||
if (normalLocationIndex != InvalidOption)
|
||||
config.optionValues[normalLocationIndex] = static_cast<Int32>(locationIndex);
|
||||
|
||||
break;
|
||||
|
||||
case VertexComponent::TexCoord:
|
||||
if (uvLocationIndex != InvalidOption)
|
||||
config.optionValues[uvLocationIndex] = static_cast<Int32>(locationIndex);
|
||||
|
||||
break;
|
||||
|
||||
case VertexComponent::Unused:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
++locationIndex;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Options
|
||||
|
||||
// HasEmissiveMap
|
||||
if (options.phongOptionIndexes)
|
||||
options.phongOptionIndexes->hasEmissiveMap = settings.options.size();
|
||||
|
||||
MaterialSettings::BuildOption(settings.options, settings.shaders, "HasEmissiveMap", "HasEmissiveTexture");
|
||||
|
||||
// HasHeightMap
|
||||
if (options.phongOptionIndexes)
|
||||
options.phongOptionIndexes->hasHeightMap = settings.options.size();
|
||||
|
||||
MaterialSettings::BuildOption(settings.options, settings.shaders, "HasHeightMap", "HasHeightTexture");
|
||||
|
||||
// HasNormalMap
|
||||
if (options.phongOptionIndexes)
|
||||
options.phongOptionIndexes->hasNormalMap = settings.options.size();
|
||||
|
||||
MaterialSettings::BuildOption(settings.options, settings.shaders, "HasNormalMap", "HasNormalTexture");
|
||||
|
||||
// HasSpecularMap
|
||||
if (options.phongOptionIndexes)
|
||||
options.phongOptionIndexes->hasSpecularMap = settings.options.size();
|
||||
|
||||
MaterialSettings::BuildOption(settings.options, settings.shaders, "HasSpecularMap", "HasSpecularTexture");
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<UberShader>> PhongLightingMaterial::BuildShaders()
|
||||
{
|
||||
ShaderAst::StatementPtr shaderAst = ShaderLang::Parse(std::string_view(reinterpret_cast<const char*>(r_shader), sizeof(r_shader)));
|
||||
auto shader = std::make_shared<UberShader>(ShaderStageType::Fragment | ShaderStageType::Vertex, shaderAst);
|
||||
|
||||
return { std::move(shader) };
|
||||
}
|
||||
|
||||
auto PhongLightingMaterial::BuildUniformOffsets() -> std::pair<PhongUniformOffsets, FieldOffsets>
|
||||
{
|
||||
auto basicOffsets = BasicMaterial::BuildUniformOffsets();
|
||||
FieldOffsets fieldOffsets = basicOffsets.second;
|
||||
|
||||
PhongUniformOffsets uniformOffsets;
|
||||
uniformOffsets.ambientColor = fieldOffsets.AddField(StructFieldType::Float3);
|
||||
uniformOffsets.specularColor = fieldOffsets.AddField(StructFieldType::Float3);
|
||||
uniformOffsets.shininess = fieldOffsets.AddField(StructFieldType::Float1);
|
||||
|
||||
uniformOffsets.totalSize = fieldOffsets.GetAlignedSize();
|
||||
|
||||
return std::make_pair(std::move(uniformOffsets), std::move(fieldOffsets));
|
||||
}
|
||||
|
||||
bool PhongLightingMaterial::Initialize()
|
||||
{
|
||||
std::tie(s_phongUniformOffsets, std::ignore) = BuildUniformOffsets();
|
||||
|
||||
std::vector<UInt8> defaultValues(s_phongUniformOffsets.totalSize);
|
||||
|
||||
PhongBuildOptions options;
|
||||
options.defaultValues = std::move(defaultValues);
|
||||
options.shaders = BuildShaders();
|
||||
|
||||
// Basic material
|
||||
options.basicOffsets = s_basicUniformOffsets;
|
||||
|
||||
// Phong Material
|
||||
options.phongOffsets = s_phongUniformOffsets;
|
||||
options.phongOptionIndexes = &s_phongOptionIndexes;
|
||||
options.phongTextureIndexes = &s_phongTextureIndexes;
|
||||
|
||||
s_phongMaterialSettings = std::make_shared<MaterialSettings>(Build(options));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PhongLightingMaterial::Uninitialize()
|
||||
{
|
||||
s_materialSettings.reset();
|
||||
s_phongMaterialSettings.reset();
|
||||
}
|
||||
|
||||
std::shared_ptr<MaterialSettings> PhongLightingMaterial::s_materialSettings;
|
||||
std::shared_ptr<MaterialSettings> PhongLightingMaterial::s_phongMaterialSettings;
|
||||
std::size_t PhongLightingMaterial::s_phongUniformBlockIndex;
|
||||
PhongLightingMaterial::TextureIndexes PhongLightingMaterial::s_textureIndexes;
|
||||
PhongLightingMaterial::PhongOptionIndexes PhongLightingMaterial::s_phongOptionIndexes;
|
||||
PhongLightingMaterial::PhongTextureIndexes PhongLightingMaterial::s_phongTextureIndexes;
|
||||
PhongLightingMaterial::PhongUniformOffsets PhongLightingMaterial::s_phongUniformOffsets;
|
||||
}
|
||||
|
||||
@@ -13,42 +13,40 @@ namespace Nz
|
||||
PredefinedLightData lightData;
|
||||
|
||||
FieldOffsets lightStruct(StructLayout::Std140);
|
||||
lightData.innerOffsets.type = lightStruct.AddField(StructFieldType::Int1);
|
||||
lightData.innerOffsets.color = lightStruct.AddField(StructFieldType::Float4);
|
||||
lightData.innerOffsets.factor = lightStruct.AddField(StructFieldType::Float2);
|
||||
lightData.innerOffsets.parameter1 = lightStruct.AddField(StructFieldType::Float4);
|
||||
lightData.innerOffsets.parameter2 = lightStruct.AddField(StructFieldType::Float4);
|
||||
lightData.innerOffsets.parameter3 = lightStruct.AddField(StructFieldType::Float2);
|
||||
lightData.innerOffsets.shadowMappingFlag = lightStruct.AddField(StructFieldType::Bool1);
|
||||
lightData.lightMemberOffsets.type = lightStruct.AddField(StructFieldType::Int1);
|
||||
lightData.lightMemberOffsets.color = lightStruct.AddField(StructFieldType::Float4);
|
||||
lightData.lightMemberOffsets.factor = lightStruct.AddField(StructFieldType::Float2);
|
||||
lightData.lightMemberOffsets.parameter1 = lightStruct.AddField(StructFieldType::Float4);
|
||||
lightData.lightMemberOffsets.parameter2 = lightStruct.AddField(StructFieldType::Float4);
|
||||
lightData.lightMemberOffsets.parameter3 = lightStruct.AddField(StructFieldType::Float4);
|
||||
lightData.lightMemberOffsets.shadowMappingFlag = lightStruct.AddField(StructFieldType::Bool1);
|
||||
|
||||
lightData.innerOffsets.totalSize = lightStruct.GetAlignedSize();
|
||||
lightData.lightSize = lightStruct.GetAlignedSize();
|
||||
|
||||
FieldOffsets lightDataStruct(StructLayout::Std140);
|
||||
for (std::size_t& lightOffset : lightData.lightArray)
|
||||
lightOffset = lightDataStruct.AddStruct(lightStruct);
|
||||
lightData.lightsOffset = lightDataStruct.AddStructArray(lightStruct, MaxLightCount);
|
||||
lightData.lightCountOffset = lightDataStruct.AddField(StructFieldType::UInt1);
|
||||
|
||||
lightData.lightArraySize = lightDataStruct.GetAlignedSize();
|
||||
lightData.totalSize = lightDataStruct.GetAlignedSize();
|
||||
|
||||
return lightData;
|
||||
}
|
||||
|
||||
MaterialSettings::SharedUniformBlock PredefinedLightData::GetUniformBlock()
|
||||
MaterialSettings::SharedUniformBlock PredefinedLightData::GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages)
|
||||
{
|
||||
PredefinedLightData lightData = GetOffsets();
|
||||
|
||||
std::vector<MaterialSettings::UniformVariable> lightDataVariables;
|
||||
for (std::size_t i = 0; i < lightData.lightArray.size(); ++i)
|
||||
{
|
||||
lightDataVariables.push_back({
|
||||
"LightData[" + std::to_string(i) + "]",
|
||||
lightData.lightArray[i]
|
||||
});
|
||||
}
|
||||
std::vector<MaterialSettings::UniformVariable> variables = {
|
||||
{
|
||||
{ "Lights", lightData.lightsOffset }
|
||||
}
|
||||
};
|
||||
|
||||
MaterialSettings::SharedUniformBlock uniformBlock = {
|
||||
0, //< FIXME
|
||||
"Light",
|
||||
std::move(lightDataVariables)
|
||||
bindingIndex,
|
||||
"LightData",
|
||||
std::move(variables),
|
||||
shaderStages
|
||||
};
|
||||
|
||||
return uniformBlock;
|
||||
|
||||
@@ -2,16 +2,23 @@ option HasDiffuseTexture: bool = false;
|
||||
option HasAlphaTexture: bool = false;
|
||||
option AlphaTest: bool = false;
|
||||
|
||||
// Billboard related options
|
||||
option Billboard: bool = false;
|
||||
option BillboardCenterLocation: i32 = -1;
|
||||
option BillboardColorLocation: i32 = -1;
|
||||
option BillboardSizeRotLocation: i32 = -1;
|
||||
|
||||
// Vertex declaration related options
|
||||
option PosLocation: i32 = -1;
|
||||
option ColorLocation: i32 = -1;
|
||||
option PosLocation: i32 = -1;
|
||||
option UvLocation: i32 = -1;
|
||||
|
||||
const HasVertexColor = (ColorLocation >= 0);
|
||||
const HasColor = (HasVertexColor || Billboard);
|
||||
const HasUV = (UvLocation >= 0);
|
||||
|
||||
[layout(std140)]
|
||||
struct BasicSettings
|
||||
struct MaterialSettings
|
||||
{
|
||||
AlphaThreshold: f32,
|
||||
DiffuseColor: vec4<f32>
|
||||
@@ -40,7 +47,7 @@ struct ViewerData
|
||||
|
||||
external
|
||||
{
|
||||
[binding(0)] settings: uniform<BasicSettings>,
|
||||
[binding(0)] settings: uniform<MaterialSettings>,
|
||||
[binding(1)] MaterialDiffuseMap: sampler2D<f32>,
|
||||
[binding(2)] MaterialAlphaMap: sampler2D<f32>,
|
||||
[binding(3)] TextureOverlay: sampler2D<f32>,
|
||||
@@ -52,7 +59,7 @@ external
|
||||
struct FragIn
|
||||
{
|
||||
[location(0), cond(HasUV)] uv: vec2<f32>,
|
||||
[location(1), cond(HasVertexColor)] color: vec4<f32>
|
||||
[location(1), cond(HasColor)] color: vec4<f32>
|
||||
}
|
||||
|
||||
struct FragOut
|
||||
@@ -68,7 +75,7 @@ fn main(input: FragIn) -> FragOut
|
||||
const if (HasUV)
|
||||
diffuseColor *= TextureOverlay.Sample(input.uv);
|
||||
|
||||
const if (HasVertexColor)
|
||||
const if (HasColor)
|
||||
diffuseColor *= input.color;
|
||||
|
||||
const if (HasDiffuseTexture)
|
||||
@@ -91,25 +98,70 @@ fn main(input: FragIn) -> FragOut
|
||||
// Vertex stage
|
||||
struct VertIn
|
||||
{
|
||||
[location(PosLocation)] pos: vec3<f32>,
|
||||
[location(ColorLocation), cond(HasVertexColor)] color: vec4<f32>,
|
||||
[location(UvLocation), cond(HasUV)] uv: vec2<f32>
|
||||
[location(PosLocation)]
|
||||
pos: vec3<f32>,
|
||||
|
||||
[cond(HasVertexColor), location(ColorLocation)]
|
||||
color: vec4<f32>,
|
||||
|
||||
[cond(HasUV), location(UvLocation)]
|
||||
uv: vec2<f32>,
|
||||
|
||||
[cond(Billboard), location(BillboardCenterLocation)]
|
||||
billboardCenter: vec3<f32>,
|
||||
|
||||
[cond(Billboard), location(BillboardSizeRotLocation)]
|
||||
billboardSizeRot: vec4<f32>, //< width,height,sin,cos
|
||||
|
||||
[cond(Billboard), location(BillboardColorLocation)]
|
||||
billboardColor: vec4<f32>
|
||||
}
|
||||
|
||||
struct VertOut
|
||||
{
|
||||
[location(0), cond(HasUV)] uv: vec2<f32>,
|
||||
[location(1), cond(HasVertexColor)] color: vec4<f32>,
|
||||
[location(1), cond(HasColor)] color: vec4<f32>,
|
||||
[builtin(position)] position: vec4<f32>
|
||||
}
|
||||
|
||||
[entry(vert)]
|
||||
[entry(vert), cond(Billboard)]
|
||||
fn billboardMain(input: VertIn) -> VertOut
|
||||
{
|
||||
let size = input.billboardSizeRot.xy;
|
||||
let sinCos = input.billboardSizeRot.zw;
|
||||
|
||||
let rotatedPosition = vec2<f32>(
|
||||
input.pos.x * sinCos.y - input.pos.y * sinCos.x,
|
||||
input.pos.y * sinCos.y + input.pos.x * sinCos.x
|
||||
);
|
||||
rotatedPosition *= size;
|
||||
|
||||
let cameraRight = vec3<f32>(viewerData.viewMatrix[0][0], viewerData.viewMatrix[1][0], viewerData.viewMatrix[2][0]);
|
||||
let cameraUp = vec3<f32>(viewerData.viewMatrix[0][1], viewerData.viewMatrix[1][1], viewerData.viewMatrix[2][1]);
|
||||
|
||||
let vertexPos = input.billboardCenter;
|
||||
vertexPos += cameraRight * rotatedPosition.x;
|
||||
vertexPos += cameraUp * rotatedPosition.y;
|
||||
|
||||
let output: VertOut;
|
||||
output.position = viewerData.viewProjMatrix * instanceData.worldMatrix * vec4<f32>(vertexPos, 1.0);
|
||||
|
||||
const if (HasColor)
|
||||
output.color = input.billboardColor;
|
||||
|
||||
const if (HasUV)
|
||||
output.uv = input.pos.xy + vec2<f32>(0.5, 0.5);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
[entry(vert), cond(!Billboard)]
|
||||
fn main(input: VertIn) -> VertOut
|
||||
{
|
||||
let output: VertOut;
|
||||
output.position = viewerData.viewProjMatrix * instanceData.worldMatrix * vec4<f32>(input.pos, 1.0);
|
||||
|
||||
const if (HasVertexColor)
|
||||
const if (HasColor)
|
||||
output.color = input.color;
|
||||
|
||||
const if (HasUV)
|
||||
|
||||
286
src/Nazara/Graphics/Resources/Shaders/phong_material.nzsl
Normal file
286
src/Nazara/Graphics/Resources/Shaders/phong_material.nzsl
Normal file
@@ -0,0 +1,286 @@
|
||||
// Basic material options
|
||||
option HasDiffuseTexture: bool = false;
|
||||
option HasAlphaTexture: bool = false;
|
||||
option AlphaTest: bool = false;
|
||||
|
||||
// Phong material options
|
||||
option HasEmissiveTexture: bool = false;
|
||||
option HasHeightTexture: bool = false;
|
||||
option HasNormalTexture: bool = false;
|
||||
option HasSpecularTexture: bool = false;
|
||||
|
||||
option MaxLightCount: u32 = u32(3); //< FIXME: Fix integral value types
|
||||
|
||||
// Billboard related options
|
||||
option Billboard: bool = false;
|
||||
option BillboardCenterLocation: i32 = -1;
|
||||
option BillboardColorLocation: i32 = -1;
|
||||
option BillboardSizeRotLocation: i32 = -1;
|
||||
|
||||
// Vertex declaration related options
|
||||
option ColorLocation: i32 = -1;
|
||||
option NormalLocation: i32 = -1;
|
||||
option PosLocation: i32 = -1;
|
||||
option UvLocation: i32 = -1;
|
||||
|
||||
const HasNormal = (NormalLocation >= 0);
|
||||
const HasVertexColor = (ColorLocation >= 0);
|
||||
const HasColor = (HasVertexColor || Billboard);
|
||||
const HasUV = (UvLocation >= 0);
|
||||
|
||||
[layout(std140)]
|
||||
struct MaterialSettings
|
||||
{
|
||||
// BasicSettings
|
||||
AlphaThreshold: f32,
|
||||
DiffuseColor: vec4<f32>,
|
||||
|
||||
// PhongSettings
|
||||
AmbientColor: vec3<f32>,
|
||||
SpecularColor: vec3<f32>,
|
||||
Shininess: f32,
|
||||
}
|
||||
|
||||
[layout(std140)]
|
||||
struct InstanceData
|
||||
{
|
||||
worldMatrix: mat4<f32>,
|
||||
invWorldMatrix: mat4<f32>
|
||||
}
|
||||
|
||||
// TODO: Add enums
|
||||
const DirectionalLight = 0;
|
||||
const PointLight = 1;
|
||||
const SpotLight = 2;
|
||||
|
||||
[layout(std140)]
|
||||
struct Light
|
||||
{
|
||||
type: i32,
|
||||
color: vec4<f32>,
|
||||
factor: vec2<f32>,
|
||||
parameter1: vec4<f32>,
|
||||
parameter2: vec4<f32>,
|
||||
parameter3: vec4<f32>,
|
||||
hasShadowMapping: bool
|
||||
}
|
||||
|
||||
[layout(std140)]
|
||||
struct LightData
|
||||
{
|
||||
lights: [Light; MaxLightCount],
|
||||
lightCount: u32,
|
||||
}
|
||||
|
||||
[layout(std140)]
|
||||
struct ViewerData
|
||||
{
|
||||
projectionMatrix: mat4<f32>,
|
||||
invProjectionMatrix: mat4<f32>,
|
||||
viewMatrix: mat4<f32>,
|
||||
invViewMatrix: mat4<f32>,
|
||||
viewProjMatrix: mat4<f32>,
|
||||
invViewProjMatrix: mat4<f32>,
|
||||
renderTargetSize: vec2<f32>,
|
||||
invRenderTargetSize: vec2<f32>,
|
||||
eyePosition: vec3<f32>
|
||||
}
|
||||
|
||||
external
|
||||
{
|
||||
[binding(0)] settings: uniform<MaterialSettings>,
|
||||
[binding(1)] MaterialDiffuseMap: sampler2D<f32>,
|
||||
[binding(2)] MaterialAlphaMap: sampler2D<f32>,
|
||||
[binding(3)] TextureOverlay: sampler2D<f32>,
|
||||
[binding(4)] instanceData: uniform<InstanceData>,
|
||||
[binding(5)] viewerData: uniform<ViewerData>,
|
||||
[binding(6)] lightData: uniform<LightData>,
|
||||
[binding(7)] MaterialEmissiveMap: sampler2D<f32>,
|
||||
[binding(8)] MaterialHeightMap: sampler2D<f32>,
|
||||
[binding(9)] MaterialNormalMap: sampler2D<f32>,
|
||||
[binding(10)] MaterialSpecularMap: sampler2D<f32>,
|
||||
}
|
||||
|
||||
// Fragment stage
|
||||
struct FragIn
|
||||
{
|
||||
[location(0)] worldPos: vec3<f32>,
|
||||
[location(1), cond(HasUV)] uv: vec2<f32>,
|
||||
[location(2), cond(HasColor)] color: vec4<f32>,
|
||||
[location(3), cond(HasNormal)] normal: vec3<f32>,
|
||||
}
|
||||
|
||||
struct FragOut
|
||||
{
|
||||
[location(0)] RenderTarget0: vec4<f32>
|
||||
}
|
||||
|
||||
[entry(frag)]
|
||||
fn main(input: FragIn) -> FragOut
|
||||
{
|
||||
let diffuseColor = settings.DiffuseColor;
|
||||
|
||||
const if (HasUV)
|
||||
diffuseColor *= TextureOverlay.Sample(input.uv);
|
||||
|
||||
const if (HasColor)
|
||||
diffuseColor *= input.color;
|
||||
|
||||
const if (HasDiffuseTexture)
|
||||
diffuseColor *= MaterialDiffuseMap.Sample(input.uv);
|
||||
|
||||
const if (HasAlphaTexture)
|
||||
diffuseColor.w *= MaterialAlphaMap.Sample(input.uv).x;
|
||||
|
||||
const if (AlphaTest)
|
||||
{
|
||||
if (diffuseColor.w < settings.AlphaThreshold)
|
||||
discard;
|
||||
}
|
||||
|
||||
const if (HasNormal)
|
||||
{
|
||||
let lightAmbient = vec3<f32>(0.0, 0.0, 0.0);
|
||||
let lightDiffuse = vec3<f32>(0.0, 0.0, 0.0);
|
||||
let lightSpecular = vec3<f32>(0.0, 0.0, 0.0);
|
||||
|
||||
let eyeVec = normalize(viewerData.eyePosition - input.worldPos);
|
||||
|
||||
for i in 0 -> lightData.lightCount
|
||||
{
|
||||
let light = lightData.lights[i];
|
||||
|
||||
let lightAmbientFactor = light.factor.x;
|
||||
let lightDiffuseFactor = light.factor.y;
|
||||
|
||||
// TODO: Add switch instruction
|
||||
if (light.type == DirectionalLight)
|
||||
{
|
||||
let lightDir = -(light.parameter1.xyz); //< FIXME
|
||||
|
||||
lightAmbient += light.color.rgb * lightAmbientFactor * settings.AmbientColor;
|
||||
|
||||
let lambert = max(dot(input.normal, lightDir), 0.0);
|
||||
|
||||
lightDiffuse += lambert * light.color.rgb * lightDiffuseFactor;
|
||||
|
||||
let reflection = reflect(-lightDir, input.normal);
|
||||
let specFactor = max(dot(reflection, eyeVec), 0.0);
|
||||
specFactor = pow(specFactor, settings.Shininess);
|
||||
|
||||
lightSpecular += specFactor * light.color.rgb;
|
||||
}
|
||||
else if (light.type == PointLight)
|
||||
{
|
||||
|
||||
}
|
||||
else if (light.type == SpotLight)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
lightSpecular *= settings.SpecularColor;
|
||||
|
||||
const if (HasSpecularTexture)
|
||||
lightSpecular *= MaterialSpecularMap.Sample(input.uv).rgb;
|
||||
|
||||
let lightColor = lightAmbient + lightDiffuse + lightSpecular;
|
||||
|
||||
let output: FragOut;
|
||||
output.RenderTarget0 = vec4<f32>(lightColor, 1.0) * diffuseColor;
|
||||
return output;
|
||||
}
|
||||
else
|
||||
{
|
||||
let output: FragOut;
|
||||
output.RenderTarget0 = diffuseColor.w;
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
// Vertex stage
|
||||
struct VertIn
|
||||
{
|
||||
[location(PosLocation)]
|
||||
pos: vec3<f32>,
|
||||
|
||||
[cond(HasVertexColor), location(ColorLocation)]
|
||||
color: vec4<f32>,
|
||||
|
||||
[cond(HasUV), location(UvLocation)]
|
||||
uv: vec2<f32>,
|
||||
|
||||
[cond(HasNormal), location(NormalLocation)]
|
||||
normal: vec3<f32>,
|
||||
|
||||
[cond(Billboard), location(BillboardCenterLocation)]
|
||||
billboardCenter: vec3<f32>,
|
||||
|
||||
[cond(Billboard), location(BillboardSizeRotLocation)]
|
||||
billboardSizeRot: vec4<f32>, //< width,height,sin,cos
|
||||
|
||||
[cond(Billboard), location(BillboardColorLocation)]
|
||||
billboardColor: vec4<f32>
|
||||
}
|
||||
|
||||
struct VertOut
|
||||
{
|
||||
[location(0)] worldPos: vec3<f32>,
|
||||
[location(1), cond(HasUV)] uv: vec2<f32>,
|
||||
[location(2), cond(HasColor)] color: vec4<f32>,
|
||||
[location(3), cond(HasNormal)] normal: vec3<f32>,
|
||||
[builtin(position)] position: vec4<f32>,
|
||||
}
|
||||
|
||||
[entry(vert), cond(Billboard)]
|
||||
fn billboardMain(input: VertIn) -> VertOut
|
||||
{
|
||||
let size = input.billboardSizeRot.xy;
|
||||
let sinCos = input.billboardSizeRot.zw;
|
||||
|
||||
let rotatedPosition = vec2<f32>(
|
||||
input.pos.x * sinCos.y - input.pos.y * sinCos.x,
|
||||
input.pos.y * sinCos.y + input.pos.x * sinCos.x
|
||||
);
|
||||
rotatedPosition *= size;
|
||||
|
||||
let cameraRight = vec3<f32>(viewerData.viewMatrix[0][0], viewerData.viewMatrix[1][0], viewerData.viewMatrix[2][0]);
|
||||
let cameraUp = vec3<f32>(viewerData.viewMatrix[0][1], viewerData.viewMatrix[1][1], viewerData.viewMatrix[2][1]);
|
||||
|
||||
let vertexPos = input.billboardCenter;
|
||||
vertexPos += cameraRight * rotatedPosition.x;
|
||||
vertexPos += cameraUp * rotatedPosition.y;
|
||||
|
||||
let output: VertOut;
|
||||
output.position = viewerData.viewProjMatrix * instanceData.worldMatrix * vec4<f32>(vertexPos, 1.0);
|
||||
|
||||
const if (HasColor)
|
||||
output.color = input.billboardColor;
|
||||
|
||||
const if (HasUV)
|
||||
output.uv = input.pos.xy + vec2<f32>(0.5, 0.5);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
[entry(vert), cond(!Billboard)]
|
||||
fn main(input: VertIn) -> VertOut
|
||||
{
|
||||
let worldPosition = instanceData.worldMatrix * vec4<f32>(input.pos, 1.0);
|
||||
|
||||
let output: VertOut;
|
||||
output.worldPos = worldPosition.xyz;
|
||||
output.position = viewerData.viewProjMatrix * worldPosition;
|
||||
|
||||
const if (HasColor)
|
||||
output.color = input.color;
|
||||
|
||||
const if (HasNormal)
|
||||
output.normal = input.normal;
|
||||
|
||||
const if (HasUV)
|
||||
output.uv = input.uv;
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -53,7 +53,7 @@ namespace Nz
|
||||
return std::make_unique<SpriteChainRendererData>();
|
||||
}
|
||||
|
||||
void SpriteChainRenderer::Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||
void SpriteChainRenderer::Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, const RenderStates& renderStates, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||
{
|
||||
Graphics* graphics = Graphics::Instance();
|
||||
|
||||
@@ -210,6 +210,16 @@ namespace Nz
|
||||
};
|
||||
}
|
||||
|
||||
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::LightDataUbo); bindingIndex != MaterialSettings::InvalidIndex)
|
||||
{
|
||||
auto& bindingEntry = m_bindingCache.emplace_back();
|
||||
bindingEntry.bindingIndex = bindingIndex;
|
||||
bindingEntry.content = ShaderBinding::UniformBufferBinding{
|
||||
renderStates.lightData.get(),
|
||||
0, renderStates.lightData->GetSize()
|
||||
};
|
||||
}
|
||||
|
||||
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::ViewerDataUbo); bindingIndex != MaterialSettings::InvalidIndex)
|
||||
{
|
||||
const auto& viewerBuffer = viewerInstance.GetViewerBuffer();
|
||||
|
||||
@@ -12,16 +12,12 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
SubmeshRenderer::SubmeshRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<ElementRendererData> SubmeshRenderer::InstanciateData()
|
||||
{
|
||||
return std::make_unique<SubmeshRendererData>();
|
||||
}
|
||||
|
||||
void SubmeshRenderer::Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& /*currentFrame*/, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||
void SubmeshRenderer::Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& /*currentFrame*/, const RenderStates& renderStates, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||
{
|
||||
Graphics* graphics = Graphics::Instance();
|
||||
|
||||
@@ -118,6 +114,16 @@ namespace Nz
|
||||
};
|
||||
}
|
||||
|
||||
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::LightDataUbo); bindingIndex != MaterialSettings::InvalidIndex)
|
||||
{
|
||||
auto& bindingEntry = m_bindingCache.emplace_back();
|
||||
bindingEntry.bindingIndex = bindingIndex;
|
||||
bindingEntry.content = ShaderBinding::UniformBufferBinding{
|
||||
renderStates.lightData.get(),
|
||||
0, renderStates.lightData->GetSize()
|
||||
};
|
||||
}
|
||||
|
||||
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::ViewerDataUbo); bindingIndex != MaterialSettings::InvalidIndex)
|
||||
{
|
||||
const auto& viewerBuffer = viewerInstance.GetViewerBuffer();
|
||||
|
||||
@@ -156,8 +156,11 @@ namespace Nz
|
||||
const NodeComponent& entityNode = registry.get<const NodeComponent>(entity);
|
||||
CameraComponent& entityCamera = registry.get<CameraComponent>(entity);
|
||||
|
||||
Vector3f cameraPosition = entityNode.GetPosition(CoordSys::Global);
|
||||
|
||||
ViewerInstance& viewerInstance = entityCamera.GetViewerInstance();
|
||||
viewerInstance.UpdateViewMatrix(Nz::Matrix4f::ViewMatrix(entityNode.GetPosition(CoordSys::Global), entityNode.GetRotation(CoordSys::Global)));
|
||||
viewerInstance.UpdateEyePosition(cameraPosition);
|
||||
viewerInstance.UpdateViewMatrix(Nz::Matrix4f::ViewMatrix(cameraPosition, entityNode.GetRotation(CoordSys::Global)));
|
||||
|
||||
m_pipeline->InvalidateViewer(&entityCamera);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ namespace Nz
|
||||
m_projectionMatrix(Matrix4f::Identity()),
|
||||
m_viewProjMatrix(Matrix4f::Identity()),
|
||||
m_viewMatrix(Matrix4f::Identity()),
|
||||
m_targetSize(Vector2f(0.f, 0.f)),
|
||||
m_targetSize(Vector2f::Zero()),
|
||||
m_eyePosition(Vector3f::Zero()),
|
||||
m_dataInvalided(true)
|
||||
{
|
||||
PredefinedViewerData viewerUboOffsets = PredefinedViewerData::GetOffsets();
|
||||
@@ -37,7 +38,7 @@ namespace Nz
|
||||
PredefinedViewerData viewerDataOffsets = PredefinedViewerData::GetOffsets();
|
||||
|
||||
auto& allocation = uploadPool.Allocate(viewerDataOffsets.totalSize);
|
||||
AccessByOffset<Vector3f&>(allocation.mappedPtr, viewerDataOffsets.eyePositionOffset) = m_viewMatrix.GetTranslation();
|
||||
AccessByOffset<Vector3f&>(allocation.mappedPtr, viewerDataOffsets.eyePositionOffset) = m_eyePosition;
|
||||
AccessByOffset<Vector2f&>(allocation.mappedPtr, viewerDataOffsets.invTargetSizeOffset) = 1.f / m_targetSize;
|
||||
AccessByOffset<Vector2f&>(allocation.mappedPtr, viewerDataOffsets.targetSizeOffset) = m_targetSize;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user