render-by-index-meshid #8

Merged
kidrigger merged 6 commits from render-by-index-meshid into canon 2025-01-11 20:51:48 +01:00
13 changed files with 298 additions and 180 deletions
Showing only changes of commit 98972bfc59 - Show all commits

View File

@ -54,6 +54,13 @@ Buffer::Allocate(const Device *device, usize size, vk::BufferUsageFlags bufferUs
device->SetName(m_Buffer, name);
}
uptr
Buffer::GetDeviceAddress(const Device *device)
{
vk::BufferDeviceAddressInfo addressInfo = {.buffer = m_Buffer};
return device->m_Device.getBufferAddress(&addressInfo);
}
void
Buffer::Write(const Device *device, usize offset, usize size, const void *data)
{
@ -143,6 +150,24 @@ StorageIndexBuffer::Init(const Device *device, usize size, bool hostVisible, boo
}
}
void
IndirectBuffer::Init(const Device *device, usize size, bool hostVisible, cstr name)
{
vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndirectBuffer | vk::BufferUsageFlagBits::eShaderDeviceAddress;
if (hostVisible)
{
Allocate(device, size, usage,
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
VMA_MEMORY_USAGE_AUTO, name);
}
else
{
usage |= vk::BufferUsageFlagBits::eTransferDst;
Allocate(device, size, usage, 0, VMA_MEMORY_USAGE_AUTO, name);
}
}
void
VertexBuffer::Init(const Device *device, usize size, cstr name)
{

View File

@ -31,6 +31,9 @@ struct Buffer
void Allocate(const Device *device, usize size, vk::BufferUsageFlags bufferUsage,
VmaAllocationCreateFlags allocationFlags, VmaMemoryUsage memoryUsage, cstr name);
uptr
GetDeviceAddress(const Device *device);
// Buffer.size is used for bookkeeping
// If the buffer is Invalid, the remaining data in Buffer is used intrusively by `GpuResourceManager`.
usize m_Size_ = 0;
@ -54,6 +57,11 @@ struct StorageBuffer : Buffer
void Init(const Device *device, usize size, bool hostVisible, bool deviceAddress, cstr name = nullptr);
};
struct IndirectBuffer : Buffer
{
void Init(const Device *device, usize size, bool hostVisible, cstr name = nullptr);
};
struct StorageIndexBuffer : StorageBuffer
{
void Init(const Device *device, usize size, bool hostVisible, bool deviceAddress, cstr name = nullptr);

View File

@ -157,6 +157,8 @@ main(int, char **)
.descriptorBindingStorageBufferUpdateAfterBind = true,
.descriptorBindingPartiallyBound = true,
.runtimeDescriptorArray = true,
.bufferDeviceAddress = true,
.bufferDeviceAddressCaptureReplay = true,
},
.m_Vulkan13Features =
{

View File

@ -879,6 +879,7 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
Entity modelRootEntity = m_Registry->create();
m_Registry->emplace<CGlobalTransform>(modelRootEntity);
m_Registry->emplace<CDynamicTransform>(modelRootEntity);
m_Registry->emplace<CModel>(modelRootEntity);
entities.push_back(modelRootEntity);
assert(model.defaultScene >= 0);

View File

@ -61,6 +61,8 @@ struct Model
void Destroy(RenderResourceManager *resourceManager, EcsRegistry *registry);
};
struct CModel {};
struct AssetLoader
{
RenderResourceManager *m_ResourceManager;

View File

@ -12,6 +12,9 @@ using Entity = entt::entity;
template <typename... T>
using Without = entt::exclude_t<T...>;
template <typename... T>
using Get = entt::get_t<T...>;
[[nodiscard]]
inline bool Exists(Entity entity)
{

View File

@ -289,15 +289,15 @@ LightManager::RemoveLight(const LightHandle handle)
}
void
LightManager::SetEnvironment(Environment &&environment)
LightManager::SetEnvironment(Environment *environment)
{
m_ResourceManager->Release(m_MetaInfo.m_Skybox);
m_ResourceManager->Release(m_MetaInfo.m_Diffuse);
m_ResourceManager->Release(m_MetaInfo.m_Prefilter);
m_ResourceManager->Release(m_MetaInfo.m_BrdfLut);
m_MetaInfo.m_Skybox = environment.m_Skybox;
m_MetaInfo.m_Diffuse = environment.m_Diffuse;
m_MetaInfo.m_Prefilter = environment.m_Prefilter;
m_MetaInfo.m_BrdfLut = environment.m_BrdfLut;
m_MetaInfo.m_Skybox = environment->m_Skybox;
m_MetaInfo.m_Diffuse = environment->m_Diffuse;
m_MetaInfo.m_Prefilter = environment->m_Prefilter;
m_MetaInfo.m_BrdfLut = environment->m_BrdfLut;
}

View File

@ -55,6 +55,7 @@ struct LightManager
u16 m_PointLightOffset; // 02 24
u16 m_DirectionalLightMaxCount; // 02 26
u16 m_UnusedPadding0 = 0; // 02 28
u32 m_UnusedPadding1 = 0; // 04 32
};
RenderResourceManager *m_ResourceManager;
@ -79,7 +80,7 @@ struct LightManager
void Update();
void RemoveLight(LightHandle handle);
void SetEnvironment(Environment &&environment);
void SetEnvironment(Environment *environment);
explicit LightManager(RenderResourceManager *resourceManager);
~LightManager();

View File

@ -11,10 +11,10 @@
#include "swapchain.h"
#include "window.h"
#include "light_manager.h"
#include "asset_loader.h"
#include "camera.h"
#include "core_components.h"
#include "light_manager.h"
#include "ecs_adapter.h"
#include "frame.h"
@ -43,12 +43,10 @@ main(int, char *[])
PhysicalDevices physicalDevices = {&window, &context};
PhysicalDevice deviceToUse = FindSuitableDevice(physicalDevices);
usize physicalDeviceOffsetAlignment = deviceToUse.m_DeviceProperties.limits.minUniformBufferOffsetAlignment;
vk::Extent2D internalResolution = {1920, 1080};
internalResolution.width = (internalResolution.height * INIT_WIDTH) / INIT_HEIGHT;
CameraController cameraController = {vec3{0.0f, 0.0f, 2.0f}, vec3{0.0f}, 70_deg,
CameraController cameraController = {vec3{0.0f, 2.0f, 4.0f}, vec3{0.0f, 0.0f, 0.0f}, 70_deg,
Cast<f32>(internalResolution.width) / Cast<f32>(internalResolution.height)};
INFO("Using {} as the primary device.", deviceToUse.m_DeviceProperties.deviceName.data());
@ -56,9 +54,14 @@ main(int, char *[])
Features enabledDeviceFeatures = {
.m_Vulkan10Features =
{
.multiDrawIndirect = true,
.samplerAnisotropy = true,
.shaderInt64 = true,
},
.m_Vulkan11Features =
{
.shaderDrawParameters = true,
},
.m_Vulkan12Features =
{
.descriptorIndexing = true,
@ -105,17 +108,25 @@ main(int, char *[])
resourceManager.Release(envHdriHandle);
lightManager.SetEnvironment(std::move(environment));
lightManager.SetEnvironment(&environment);
Model model = assetLoader.LoadModelToGpu(MODEL_FILE, "Main Model");
Model model2 = assetLoader.LoadModelToGpu(MODEL_FILE2, "Main Model 2");
registry.get<CDynamicTransform>(model2.m_RootEntity).m_Position.x += 1.0f;
eastl::vector<Model> models;
for (int i = -1; i <= 1; ++i)
{
for (int j = -1; j <= 1; ++j)
{
INFO("{}, {}", i, j);
auto &model = models.emplace_back(std::move(assetLoader.LoadModelToGpu(MODEL_FILE, "Main Model")));
registry.get<CDynamicTransform>(model.m_RootEntity).m_Position = vec3(2 * i, 0, 2 * j);
}
}
UniformBuffer ubo;
constexpr usize uboTotalSize = sizeof cameraController.m_Camera + sizeof lightManager.m_MetaInfo;
constexpr usize uboLightManagerOffset = sizeof cameraController.m_Camera;
constexpr usize uboTotalSize = uboLightManagerOffset + sizeof lightManager.m_MetaInfo;
ubo.Init(&device, uboTotalSize, "Desc1 UBO");
ubo.Write(&device, 0, sizeof cameraController.m_Camera, &cameraController.m_Camera);
ubo.Write(&device, sizeof cameraController.m_Camera, sizeof lightManager.m_MetaInfo, &lightManager.m_MetaInfo);
ubo.Write(&device, uboLightManagerOffset, sizeof lightManager.m_MetaInfo, &lightManager.m_MetaInfo);
Pipeline pipeline = CreatePipeline(&device, attachmentFormat, &resourceManager);
Pipeline backgroundPipeline = CreateBackgroundPipeline(&device, attachmentFormat, &resourceManager);
@ -287,19 +298,23 @@ main(int, char *[])
uptr m_VertexPositionPtr;
uptr m_VertexDataPtr;
uptr m_MaterialPtr;
// TODO: Remove
u32 m_FirstIndex;
u32 m_IndexCount;
u8 m_Padding_[8];
};
eastl::fixed_vector<eastl::vector<NodeData>, MAX_FRAMES_IN_FLIGHT> perFrameNodeData(frameManager.m_FramesInFlight);
eastl::fixed_vector<BufferHandle, MAX_FRAMES_IN_FLIGHT> perFrameNodeBuffer(frameManager.m_FramesInFlight);
for (auto &bufferHandle : perFrameNodeBuffer)
eastl::vector<NodeData> nodeData;
eastl::vector<vk::DrawIndexedIndirectCommand> nodeDrawInfo;
eastl::fixed_vector<StorageBuffer, MAX_FRAMES_IN_FLIGHT> nodeBuffers;
eastl::fixed_vector<IndirectBuffer, MAX_FRAMES_IN_FLIGHT> nodeIndirectBuffers;
eastl::fixed_vector<uptr, MAX_FRAMES_IN_FLIGHT> perFrameNodeBufferPtr;
for (u32 i = 0; i < frameManager.m_FramesInFlight; ++i)
{
StorageBuffer buffer;
buffer.Init(&device, sizeof(NodeData) * 100'000, true);
bufferHandle = resourceManager.Commit(&buffer);
auto *buffer = &nodeBuffers.push_back();
buffer->Init(&device, sizeof(NodeData) * 100'000, true, true, "Node Buffer");
auto *indirect = &nodeIndirectBuffers.push_back();
indirect->Init(&device, sizeof(vk::DrawIndexedIndirectCommand) * 100'000, true);
perFrameNodeBufferPtr.push_back(buffer->GetDeviceAddress(&device));
}
swapchain.RegisterResizeCallback(
@ -324,19 +339,28 @@ main(int, char *[])
auto rootNodeUpdateView = registry.view<CDynamicTransform, CGlobalTransform>(Without<CParent<CDynamicTransform>>{});
auto rootModel = registry.group<CModel>(Get<CDynamicTransform>{});
auto nodeWithParentsUpdateView = registry.view<CDynamicTransform, CParent<CDynamicTransform>, CGlobalTransform>();
nodeWithParentsUpdateView.use<CParent<CDynamicTransform>>();
auto renderableObjectsGroup = registry.group<CGlobalTransform, CMesh, CMaterial>();
lightManager.Update();
ubo.Write(&device, uboLightManagerOffset, sizeof lightManager.m_MetaInfo, &lightManager.m_MetaInfo);
resourceManager.Update();
while (window.Poll())
{
Time::Update();
auto *rot = &registry.get<CDynamicTransform>(model.m_RootEntity).m_Rotation;
*rot = glm::rotate(*rot, Cast<f32>(30_deg * Time::m_Delta), vec3{0.0f, 1.0f, 0.0f});
u32 index = 0;
for (auto [entity, dynTrans] : rootModel.each())
{
dynTrans.m_Rotation =
glm::rotate(dynTrans.m_Rotation, Cast<f32>(30_deg * (++index) * Time::m_Delta), vec3{0.0f, 1.0f, 0.0f});
}
Frame *currentFrame = frameManager.GetNextFrame(&swapchain, &window);
@ -392,23 +416,31 @@ main(int, char *[])
registry.get<CGlobalTransform>(parent.m_ParentEntity).m_Transform * translation * rotation * scale;
}
usize objectCount = renderableObjectsGroup.size();
auto *nodeData = &perFrameNodeData[currentFrame->m_FrameIdx];
nodeData->clear();
nodeData->reserve(objectCount);
u32 objectCount = Cast<u32>(renderableObjectsGroup.size());
nodeData.clear();
nodeDrawInfo.clear();
nodeData.reserve(objectCount);
nodeDrawInfo.reserve(objectCount);
for (auto [entity, globalTransform, mesh, material] : renderableObjectsGroup.each())
{
nodeData->push_back({
nodeData.push_back({
.m_Transform = globalTransform.m_Transform,
.m_VertexPositionPtr = mesh.m_VertexPositionPtr,
.m_VertexDataPtr = mesh.m_VertexDataPtr,
.m_MaterialPtr = material.m_MaterialPtr,
.m_FirstIndex = mesh.m_FirstIndex,
.m_IndexCount = mesh.m_IndexCount,
});
nodeDrawInfo.push_back({
.indexCount = mesh.m_IndexCount,
.instanceCount = 1,
.firstIndex = mesh.m_FirstIndex,
.vertexOffset = 0,
.firstInstance = 0,
});
}
resourceManager.Write(perFrameNodeBuffer[currentFrame->m_FrameIdx], 0, objectCount * sizeof(NodeData),
nodeData->data());
nodeBuffers[currentFrame->m_FrameIdx].Write(&device, 0, objectCount * sizeof(NodeData), nodeData.data());
nodeIndirectBuffers[currentFrame->m_FrameIdx].Write(&device, 0, objectCount * sizeof nodeDrawInfo[0],
nodeDrawInfo.data());
vk::CommandBufferBeginInfo beginInfo = {.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit};
AbortIfFailed(cmd.begin(&beginInfo));
@ -458,14 +490,12 @@ main(int, char *[])
cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline.m_Pipeline);
// TODO("Get the data to the GPU");
// auto nodeHandle = perFrameNodeBuffer[currentFrame->m_FrameIdx];
auto &nodeBuffer = perFrameNodeData[currentFrame->m_FrameIdx];
for (auto &node : nodeBuffer)
{
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, 0, sizeof node, &node);
cmd.drawIndexed(node.m_IndexCount, 1, node.m_FirstIndex, 0, 0);
}
auto nodeBufferAddr = perFrameNodeBufferPtr[currentFrame->m_FrameIdx];
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, 0, sizeof nodeBufferAddr, &nodeBufferAddr);
cmd.drawIndexedIndirect(nodeIndirectBuffers[currentFrame->m_FrameIdx].m_Buffer, 0, objectCount,
sizeof nodeDrawInfo[0]);
cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, backgroundPipeline.m_Pipeline);
@ -527,9 +557,13 @@ main(int, char *[])
device.WaitIdle();
for (auto bufferHandle : perFrameNodeBuffer)
for (auto buffer : nodeIndirectBuffers)
{
resourceManager.Release(bufferHandle);
buffer.Destroy(&device);
}
for (auto buffer : nodeBuffers)
{
buffer.Destroy(&device);
}
for (auto depthImage : depthImages)
{
@ -543,6 +577,8 @@ main(int, char *[])
device.m_Device.destroy(descriptorPool, nullptr);
model.Destroy(&resourceManager, &registry);
model2.Destroy(&resourceManager, &registry);
for (auto &model : models)
{
model.Destroy(&resourceManager, &registry);
}
}

View File

@ -641,9 +641,9 @@ RenderResourceManager::RenderResourceManager(Device *device, u16 maxSize, bool u
INFO("Max Texture Count: {}", texturesCount);
INFO("Max Storage Texture Count: {}", storageTexturesCount);
m_Geometry.InitStorage(device, Megabyte(128u));
m_Index.InitIndex(device, Megabyte(8u));
m_Material.InitStorage(device, Kilobyte(560u));
m_Geometry.InitStorage(device, Gigabyte(1u));
m_Index.InitIndex(device, Megabyte(256u));
m_Material.InitStorage(device, Gigabyte(1u));
m_BufferManager.Init(buffersCount);
m_TextureManager.Init(texturesCount);
m_StorageTextureManager.Init(storageTexturesCount);

View File

@ -20,13 +20,36 @@ struct Material
// We might be able to go upto 64 without pains.
};
struct PointLight
{
vec3 m_Position;
float m_Range;
uint m_Color;
float m_Intensity;
};
struct DirectionalLight
{
vec3 m_Direction;
float m_Validity_;
uint m_Color;
float m_Intensity;
};
// ---------- Bindless Bindings ----------
#define INVALID_HANDLE 0xFFFFFFFF
layout (std430, set = 0, binding = 0) readonly buffer PointLightBuffer {
PointLight lights[];
} pointLightBuffers[];
layout (std430, set = 0, binding = 0) readonly buffer DirectionLightBuffer {
DirectionalLight lights[];
} directionalLightBuffers[];
layout (set = 0, binding = 1) uniform sampler2D textures[];
layout (set = 0, binding = 1) uniform samplerCube textureCubes[];
// ---------- Buffer References ----------
layout(std430, buffer_reference, buffer_reference_align=16) readonly buffer VPositionRef {
vec4 Positions[];
@ -41,13 +64,20 @@ layout(std430, buffer_reference, buffer_reference_align=8) readonly buffer Mater
};
layout(std430, buffer_reference, buffer_reference_align=8) readonly buffer MaterialRef {
vec4 m_AlbedoFactor; // 16 16
vec3 m_EmissionFactor; // 12 28
float m_MetalFactor; // 04 32
float m_RoughFactor; // 04 36
uint m_AlbedoTex; // 04 40
uint m_NormalTex; // 04 44
uint m_MetalRoughTex; // 04 48
uint m_OcclusionTex; // 04 52
uint m_EmissionTex; // 04 56
Material material;
};
// Node
struct Node
{
mat4 globalTransform; // 64 64
VPositionRef pVertexPosition; // 08 72
VDataRef pVertexData; // 08 80
MaterialRef pMaterial; // 08 88
// pad // 08 96
};
layout(std430, buffer_reference, buffer_reference_align=8) readonly buffer NodeRef {
Node nodes[];
};

View File

@ -1,4 +1,4 @@
#version 450
#version 460
#pragma shader_stage(fragment)
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable
#extension GL_EXT_buffer_reference : require
@ -11,15 +11,12 @@ layout (location = 0) in vec4 in_Position;
layout (location = 1) in vec4 in_Normal;
layout (location = 2) in vec4 in_Color0;
layout (location = 3) in vec2 in_TexCoord0;
layout (location = 4) in flat uint in_DrawID;
layout (location = 0) out vec4 outColor;
layout(push_constant) uniform Constants
{
mat4 globalTransform;
uint64_t vertexPos;
uint64_t vertexDat;
MaterialRef g_Material;
layout (push_constant) uniform Const {
NodeRef nodes;
};
vec4 GetAlbedo(vec4 albedoFactor, uint texHandle, vec4 in_Color0, vec2 uv)
@ -159,99 +156,99 @@ vec3 GetPBRContrib(vec3 albedo, vec3 lightColor, vec3 viewDir, vec3 normal, floa
return ndotl * radiance * (kDiffuse * albedo / PI + specular);
}
//
//vec3 GetPointLightInfluence(vec3 albedo, vec2 MetalRough, vec3 Position, vec3 Normal)
//{
// if (lights.LightHandle == INVALID_HANDLE)
// return 0.0f.xxx;
//
// uint Offset = IndexerOffset(lights.PointLightIndexer);
// uint Count = IndexerCount(lights.PointLightIndexer);
//
// vec3 ViewDir = normalize(Camera.Position.xyz - Position);
//
// float Metallic = MetalRough.r;
// float Roughness = MetalRough.g;
//
// // Dielectric F_0 based on LearnOpenGL.
// // TODO: Cite
// vec3 F_0 = 0.04f.xxx;
// F_0 = lerp(F_0, albedo, Metallic);
//
// vec3 Contrib = 0.0f;
// for (uint i = 0; i < Count; ++i)
// {
// PointLight Light = PointLightBuffer[lights.LightHandle][i + Offset];
//
// if (Light.Range < 0.0f)
// continue;
//
// vec3 LightDir = vec3(Light.Position) - Position;
// float LightDistance = length(LightDir);
//
// if (LightDistance > Light.Range)
// continue;
//
// LightDir /= LightDistance; // Normalization
//
// // Color Unpack
// float R = (Light.Color & 0xFF000000) >> 24;
// float G = (Light.Color & 0x00FF0000) >> 16;
// float B = (Light.Color & 0x0000FF00) >> 8;
//
// vec3 LightColor = Light.Intensity * vec3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255
//
// Contrib += GetPBRContrib(albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, LightDistance);
// }
//
// return Contrib;
//}
//
//vec3 GetDirectionalLightInfluence(vec3 albedo, float2 MetalRough, vec3 Position, vec3 Normal)
//{
// if (lights.LightHandle == INVALID_HANDLE)
// return 0.0f.xxx;
//
// uint Count = IndexerCount(lights.DirectionalLightIndexer);
//
// vec3 ViewDir = normalize(Camera.Position.xyz - Position);
//
// float Metallic = MetalRough.r;
// float Roughness = MetalRough.g;
//
// // Dielectric F_0 based on LearnOpenGL.
// // TODO: Cite
// vec3 F_0 = 0.04f.xxx;
// F_0 = lerp(F_0, albedo, Metallic);
//
// vec3 Contrib = 0.0f;
// for (uint i = 0; i < Count; ++i)
// {
// DirectionalLight Light = DirectionalLightBuffer[lights.LightHandle][i];
//
// if (Light.Validity_ < 0.0f)
// continue;
//
// vec3 LightDir = -normalize(vec3(Light.Direction));
//
// // Color Unpack
// float R = (Light.Color & 0xFF000000) >> 24;
// float G = (Light.Color & 0x00FF0000) >> 16;
// float B = (Light.Color & 0x0000FF00) >> 8;
//
// vec3 LightColor = Light.Intensity * vec3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255
//
// Contrib += GetPBRContrib(albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, 1.0f);
// }
//
// return Contrib;
//}
//
vec3 GetPointLightInfluence(vec3 albedo, vec2 metalRough, vec3 position, vec3 normal)
{
if (lights.m_LightHandle == INVALID_HANDLE)
return 0.0f.xxx;
uint offset = IndexerOffset(lights.m_PointLightIndexer);
uint count = IndexerCount(lights.m_PointLightIndexer);
vec3 viewDir = normalize(camera.m_Position.xyz - position);
float metallic = metalRough.r;
float roughness = metalRough.g;
// Dielectric F_0 based on LearnOpenGL.
// TODO: Cite
vec3 f0 = vec3(0.04f);
f0 = mix(f0, albedo, metallic);
vec3 contrib = vec3(0.0f);
for (uint i = 0; i < count; ++i)
{
PointLight light = pointLightBuffers[lights.m_LightHandle].lights[i + offset];
if (light.m_Range < 0.0f)
continue;
vec3 lightDir = vec3(light.m_Position) - position;
float lightDistance = length(lightDir);
if (lightDistance > light.m_Range)
continue;
lightDir /= lightDistance; // Normalization
// Color Unpack
float r = (light.m_Color & 0xFF000000) >> 24;
float g = (light.m_Color & 0x00FF0000) >> 16;
float b = (light.m_Color & 0x0000FF00) >> 8;
vec3 lightColor = light.m_Intensity * vec3(r, g, b) * 0.00392156862f; // 0.00392156862 = 1/255
contrib += GetPBRContrib(albedo, lightColor, viewDir, normal, metallic, roughness, f0, lightDir, lightDistance);
}
return contrib;
}
vec3 GetDirectionalLightInfluence(vec3 albedo, vec2 metalRough, vec3 position, vec3 normal)
{
if (lights.m_LightHandle == INVALID_HANDLE)
return 0.0f.xxx;
uint count = IndexerCount(lights.m_DirectionalLightIndexer);
vec3 viewDir = normalize(camera.m_Position.xyz - position);
float metallic = metalRough.r;
float roughness = metalRough.g;
// Dielectric F_0 based on LearnOpenGL.
// TODO: Cite
vec3 f0 = vec3(0.04f);
f0 = mix(f0, albedo, metallic);
vec3 contrib = vec3(0.0f);
for (uint i = 0; i < count; ++i)
{
DirectionalLight light = directionalLightBuffers[lights.m_LightHandle].lights[i];
if (light.m_Validity_ < 0.0f)
continue;
vec3 lightDir = -normalize(light.m_Direction);
// Color Unpack
float r = (light.m_Color & 0xFF000000) >> 24;
float g = (light.m_Color & 0x00FF0000) >> 16;
float b = (light.m_Color & 0x0000FF00) >> 8;
vec3 lightColor = light.m_Intensity * vec3(r, g, b) * 0.00392156862f; // 0.00392156862 = 1/255
contrib += GetPBRContrib(albedo, lightColor, viewDir, normal, metallic, roughness, f0, lightDir, 1.0f);
}
return contrib;
}
vec3 GetAmbientInfluence(vec3 albedo, float metal, float roughness, vec3 Position, vec3 Normal, float Occlusion)
{
vec3 ViewDir = normalize(camera.m_Position.xyz - Position);
float CosineFactor = max(dot(Normal, ViewDir), 0.0f); // Normal instead of Halfway since there's no halfway in ambient.
vec3 F_0 = 0.04f.xxx;
F_0 = mix(F_0, albedo, metal);
vec3 K_Specular = FresnelSchlickRoughness(CosineFactor, F_0, roughness);
@ -280,21 +277,24 @@ vec3 GetAmbientInfluence(vec3 albedo, float metal, float roughness, vec3 Positio
}
void main() {
Material material = nodes.nodes[nonuniformEXT(in_DrawID)].pMaterial.material;
vec4 albedoA = GetAlbedo(g_Material.m_AlbedoFactor, g_Material.m_AlbedoTex, in_Color0, in_TexCoord0);
vec4 albedoA = GetAlbedo(material.m_AlbedoFactor, material.m_AlbedoTex, in_Color0, in_TexCoord0);
vec3 albedo = albedoA.rgb;
float alpha = albedoA.a;
vec3 normal = GetNormal(g_Material.m_NormalTex, in_Position.xyz, normalize(in_Normal.xyz), in_TexCoord0);
vec3 normal = GetNormal(material.m_NormalTex, in_Position.xyz, normalize(in_Normal.xyz), in_TexCoord0);
vec3 emission = GetEmissive(g_Material.m_EmissionFactor, g_Material.m_EmissionTex, in_TexCoord0);
vec3 emission = GetEmissive(material.m_EmissionFactor, material.m_EmissionTex, in_TexCoord0);
vec2 metalRough = GetMetalRough(g_Material.m_MetalFactor, g_Material.m_RoughFactor, g_Material.m_MetalRoughTex, in_TexCoord0);
float occlusion = GetOcclusion(g_Material.m_OcclusionTex, in_TexCoord0);
vec2 metalRough = GetMetalRough(material.m_MetalFactor, material.m_RoughFactor, material.m_MetalRoughTex, in_TexCoord0);
float occlusion = GetOcclusion(material.m_OcclusionTex, in_TexCoord0);
vec3 pointLumin = GetPointLightInfluence(albedo, metalRough, in_Position.xyz, normal);
vec3 directionalLumin = GetDirectionalLightInfluence(albedo, metalRough, in_Position.xyz, normal);
vec3 ambientLumin = GetAmbientInfluence(albedo, metalRough.r, metalRough.g, in_Position.xyz, normal, occlusion);
outColor = vec4(Uncharted2Tonemap(ambientLumin + emission), alpha);
// outColor = vec4(0.5f + 0.5f * normal, 1.0f);
}
vec3 viewDir = normalize(camera.m_Position.xyz - in_Position.xyz);
outColor = vec4(Uncharted2Tonemap(pointLumin + directionalLumin + ambientLumin + emission), alpha);
}

View File

@ -1,21 +1,27 @@
#version 450
#version 460
#pragma shader_stage(vertex)
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable
#extension GL_EXT_buffer_reference : require
#extension GL_EXT_nonuniform_qualifier : require
#include "bindless_structs.glsl"
#include "graphics_bindings.glsl"
layout(location=0) out vec4 outWorldNormal;
layout(location=1) out vec4 outWorldPosition;
layout(location=0) out vec4 outWorldPosition;
layout(location=1) out vec4 outWorldNormal;
layout(location=2) out vec4 outColor;
layout(location=3) out vec2 outUV0;
layout(location=4) out uint drawID;
//
//layout(push_constant) uniform Constants {
// mat4 globalTransform;
// VPositionRef pVertexPosition;
// VDataRef pVertexData;
// uint64_t materialIdx;
//};
layout(push_constant) uniform Constants {
mat4 globalTransform;
VPositionRef pVertexPosition;
VDataRef pVertexData;
uint64_t materialIdx;
layout (push_constant) uniform Const {
NodeRef nodes;
};
void main() {
@ -25,10 +31,14 @@ void main() {
vec3( 0.0f, 0.0f, 1.0f ),
};
outWorldNormal = vec4(normalize(transpose(inverse(mat3(globalTransform))) * pVertexData.Data[gl_VertexIndex].Normal.xyz), 0.0f);
drawID = gl_DrawID;
Node n = nodes.nodes[gl_DrawID];
outWorldPosition = globalTransform * vec4(pVertexPosition.Positions[gl_VertexIndex].xyz, 1.0f);
outWorldNormal = normalize(n.globalTransform * vec4(n.pVertexData.Data[gl_VertexIndex].Normal.xyz, 0.0f));
outWorldPosition = n.globalTransform * vec4(n.pVertexPosition.Positions[gl_VertexIndex].xyz, 1.0f);
gl_Position = camera.m_Projection * camera.m_View * outWorldPosition;
outColor = vec4(pVertexData.Data[gl_VertexIndex].Color.rgb, 1.0f); //vec3(colors[gl_VertexIndex % 3]);
outUV0 = pVertexData.Data[gl_VertexIndex].TexCoord0;
outColor = vec4(n.pVertexData.Data[gl_VertexIndex].Color.rgb, 1.0f);
// outColor = vec4(colors[gl_VertexIndex % 3], 1.0f);
outUV0 = n.pVertexData.Data[gl_VertexIndex].TexCoord0;
}