Skip to content

Commit

Permalink
Upload point lights from the CPU instead of hardcoding it in shader
Browse files Browse the repository at this point in the history
  • Loading branch information
nekoffski committed Mar 6, 2024
1 parent 8557a49 commit 612dbf9
Show file tree
Hide file tree
Showing 19 changed files with 305 additions and 206 deletions.
45 changes: 25 additions & 20 deletions assets/shaders/Builtin.Shader.Material.frag
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@

layout (location = 0) out vec4 outColor;

struct PointLight {
vec4 position;
vec4 color;
// attenuation factors - ax^2 + bx + c
float c;
float b;
float a;
float padding;
};


layout (set = 0, binding = 0) uniform GlobalUBO {
mat4 projection;
mat4 view;
vec3 viewPosition;
int mode;
vec4 ambientColor;
PointLight pointLights[5];
int pointLightCount;
} globalUBO;

layout (set = 1, binding = 0) uniform LocalUBO {
vec4 diffuseColor;
float shininess;
Expand Down Expand Up @@ -35,28 +56,12 @@ struct DirectionalLight {
vec4 color;
};

struct PointLight {
vec3 position;
vec4 color;

// attenuation factors - ax^2 + bx + c
float c;
float b;
float a;
};

DirectionalLight light = {
vec3(-0.57735, -0.57735, -0.57735),
vec4(0.8, 0.8, 0.8, 1.0)
};

PointLight pointLights[2] = {
{
vec3(-5.5, 0.0, -5.5), vec4(0.0, 1.0, 0.0, 1.0), 1.0, 0.35,0.44
}, {
vec3(5.5, 0.0, -5.5), vec4(1.0, 0.0, 0.0, 1.0), 1.0, 0.35, 0.44
}
};

vec4 calculateDirectionalLight(DirectionalLight light, vec3 normal, vec3 viewDirection) {
float diffuseFactor = max(dot(normal, -light.direction), 0.0);
Expand All @@ -81,13 +86,13 @@ vec4 calculateDirectionalLight(DirectionalLight light, vec3 normal, vec3 viewDir
}

vec4 calculatePointLight(PointLight light, vec3 normal, vec3 fragmentPosition, vec3 viewDirection) {
vec3 lightDirection = normalize(light.position - fragmentPosition);
vec3 lightDirection = normalize(light.position.xyz - fragmentPosition);
float diff = max(dot(normal, lightDirection), 0.0);

vec3 reflectDirection = reflect(-lightDirection, normal);
float spec = pow(max(dot(viewDirection, reflectDirection), epsilon), localUBO.shininess);

float d = length(light.position - fragmentPosition);
float d = length(light.position.xyz - fragmentPosition);
float attenuation = 1.0 / (light.c + light.b * d + light.a * (d * d));

vec4 ambient = dto.ambient;
Expand Down Expand Up @@ -122,8 +127,8 @@ void main() {
if (renderMode == 0 || renderMode == 1) {
vec3 viewDirection = normalize(dto.viewPosition - dto.fragmentPosition);
outColor = calculateDirectionalLight(light, normal, viewDirection);
for (int i = 0; i < 2; ++i)
outColor += calculatePointLight(pointLights[i], normal, dto.fragmentPosition, viewDirection);
for (int i = 0; i < globalUBO.pointLightCount; ++i)
outColor += calculatePointLight(globalUBO.pointLights[i], normal, dto.fragmentPosition, viewDirection);
} else {
outColor = vec4(abs(normal), 1.0);
}
Expand Down
8 changes: 8 additions & 0 deletions assets/shaders/Builtin.Shader.Material.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
{ "type": "vec3", "scope": "global", "name": "viewPosition" },
{ "type": "i32", "scope": "global", "name": "renderMode" },
{ "type": "vec4", "scope": "global", "name": "ambientColor" },
{
"type": "custom",
"scope": "global",
"name": "pointLights",
"size": 48,
"elements": 5
},
{ "type": "i32", "scope": "global", "name": "pointLightCount" },
{ "type": "vec4", "scope": "instance", "name": "diffuseColor" },
{ "type": "samp", "scope": "instance", "name": "diffuseTexture" },
{ "type": "samp", "scope": "instance", "name": "specularTexture" },
Expand Down
2 changes: 1 addition & 1 deletion editor/ui/Core.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "Core.h"

std::string resouceTypeToString(ResourceType type) {
std::string resourceTypeToString(ResourceType type) {
switch (type) {
case ResourceType::mesh:
return "Mesh";
Expand Down
4 changes: 2 additions & 2 deletions editor/ui/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

#include "starlight/ui/UI.h"

enum class ResourceType { mesh = 0, texture, shader };
enum class ResourceType { mesh = 0, texture, shader, material };

std::string resouceTypeToString(ResourceType type);
std::string resourceTypeToString(ResourceType type);

struct UIState {
std::optional<sl::u64> selectedEntityId;
Expand Down
184 changes: 95 additions & 89 deletions editor/ui/EntityInspectorPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,101 +26,107 @@ void EntityInspectorPanel::renderEntityUI(sl::u64 entityId) {
auto entity = m_scene->getEntity(entityId);
auto& data = m_entitiesData[entity->getId()];

sl::ui::text("Entity: {}/{}", entity->getId(), entity->getName());
sl::ui::separator();

std::vector<const char*> components = { "Mesh", "Transform", "Material" };

if (sl::ui::button("Add")) {
if (m_selectedComponentIndex == 0) {
entity->addComponent<sl::MeshComponent>();
} else if (m_selectedComponentIndex == 1) {
entity->addComponent<sl::TransformComponent>();
} else if (m_selectedComponentIndex == 2) {
entity->addComponent<sl::MaterialComponent>();
sl::ui::namedScope(fmt::format("Entity_{}", entity->getId()), [&]() {
sl::ui::text("Entity: {}/{}", entity->getId(), entity->getName());
sl::ui::separator();

std::vector<const char*> components = { "Mesh", "Transform", "Material" };

if (sl::ui::button("Add")) {
if (m_selectedComponentIndex == 0) {
entity->addComponent<sl::MeshComponent>();
} else if (m_selectedComponentIndex == 1) {
entity->addComponent<sl::TransformComponent>();
} else if (m_selectedComponentIndex == 2) {
entity->addComponent<sl::MaterialComponent>();
}
}
}

sl::ui::sameLine();

ImGui::Combo(
"##combo2", &m_selectedComponentIndex, components.data(), components.size()
);
sl::ui::separator();

if (entity->hasComponent<sl::MeshComponent>()) {
sl::ui::treeNode(
ICON_FA_PROJECT_DIAGRAM " Mesh",
[&]([[maybe_unused]] bool) {
auto meshComponent = entity->getComponent<sl::MeshComponent>();
auto meshesNames = sl::MeshManager::get().getNames();

std::vector<const char*> names = { "None" };
for (auto& name : meshesNames) names.push_back(name.c_str());

if (ImGui::Combo(
"##combo", &data.selectedMeshIndex, names.data(), names.size()
)) {
if (data.selectedMeshIndex != 0) {
const auto meshName = names[data.selectedMeshIndex];
meshComponent->mesh = sl::MeshManager::get().acquire(meshName);
} else {
meshComponent->mesh = nullptr;
}
}
}

sl::ui::sameLine();

ImGui::Combo(
"##combo2", &m_selectedComponentIndex, components.data(), components.size()
);
sl::ui::separator();
}

if (entity->hasComponent<sl::MaterialComponent>()) {
sl::ui::treeNode(
ICON_FA_GLOBE_AMERICAS " Material",
[&]([[maybe_unused]] bool) {
auto materialComponent = entity->getComponent<sl::MaterialComponent>();
auto materialNames = sl::MaterialManager::get().getNames();

std::vector<const char*> names = { "None" };
for (auto& name : materialNames) names.push_back(name.c_str());

if (ImGui::Combo(
"##combo333", &data.selectedMaterialIndex, names.data(),
names.size()
)) {
if (data.selectedMaterialIndex != 0) {
const auto materialName = names[data.selectedMaterialIndex];
materialComponent->material =
sl::MaterialManager::get().acquire(materialName);
} else {
materialComponent->material = nullptr;

if (entity->hasComponent<sl::MeshComponent>()) {
sl::ui::treeNode(
ICON_FA_PROJECT_DIAGRAM " Mesh",
[&]([[maybe_unused]] bool) {
auto meshComponent = entity->getComponent<sl::MeshComponent>();
auto meshesNames = sl::MeshManager::get().getNames();

std::vector<const char*> names = { "None" };
for (auto& name : meshesNames) names.push_back(name.c_str());

if (ImGui::Combo(
"##combo", &data.selectedMeshIndex, names.data(),
names.size()
)) {
if (data.selectedMeshIndex != 0) {
const auto meshName = names[data.selectedMeshIndex];
meshComponent->mesh =
sl::MeshManager::get().acquire(meshName);
} else {
meshComponent->mesh = nullptr;
}
}
}
}
);
sl::ui::separator();
}

if (entity->hasComponent<sl::TransformComponent>()) {
auto component = entity->getComponent<sl::TransformComponent>();
sl::ui::treeNode(
ICON_FA_STREET_VIEW " Transform",
[&]([[maybe_unused]] bool) {
auto& transform = component->transform;
sl::ui::namedScope("transform-component-ui", [&]() {
m_translationSlider.render([&](const sl::Vec3f& data) {
transform.setPosition(data);
});
);
sl::ui::separator();
}

m_scaleSlider.render([&](const sl::Vec3f& data) {
transform.setScale(data);
});
if (entity->hasComponent<sl::MaterialComponent>()) {
sl::ui::treeNode(
ICON_FA_GLOBE_AMERICAS " Material",
[&]([[maybe_unused]] bool) {
auto materialComponent =
entity->getComponent<sl::MaterialComponent>();
auto materialNames = sl::MaterialManager::get().getNames();

std::vector<const char*> names = { "None" };
for (auto& name : materialNames) names.push_back(name.c_str());

if (ImGui::Combo(
"##combo333", &data.selectedMaterialIndex, names.data(),
names.size()
)) {
if (data.selectedMaterialIndex != 0) {
const auto materialName =
names[data.selectedMaterialIndex];
materialComponent->material =
sl::MaterialManager::get().acquire(materialName);
} else {
materialComponent->material = nullptr;
}
}
}
);
sl::ui::separator();
}

m_orientationSlider.render([&](const sl::Vec3f& data) {
transform.setRotation(sl::math::orientate4(data));
if (entity->hasComponent<sl::TransformComponent>()) {
auto component = entity->getComponent<sl::TransformComponent>();
sl::ui::treeNode(
ICON_FA_STREET_VIEW " Transform",
[&]([[maybe_unused]] bool) {
auto& transform = component->transform;
sl::ui::namedScope("transform-component-ui", [&]() {
m_translationSlider.render([&](const sl::Vec3f& data) {
transform.setPosition(data);
});

m_scaleSlider.render([&](const sl::Vec3f& data) {
transform.setScale(data);
});

m_orientationSlider.render([&](const sl::Vec3f& data) {
transform.setRotation(sl::math::orientate4(data));
});
});
});
}
);
sl::ui::separator();
}
}
);
sl::ui::separator();
}
});
}
29 changes: 29 additions & 0 deletions editor/ui/ResourceInspectorPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ void ResourceInspectorPanel::renderResourceUI(
switch (type) {
case ResourceType::texture:
return renderTextureUI(sl::TextureManager::get().acquire(resourceId));
case ResourceType::mesh:
return renderMeshUI(sl::MeshManager::get().acquire(resourceId));
case ResourceType::material:
return renderMaterialUI(sl::MaterialManager::get().acquire(resourceId));
}
}

Expand All @@ -49,3 +53,28 @@ void ResourceInspectorPanel::renderTextureUI(sl::Texture* texture) {
);
});
}

void ResourceInspectorPanel::renderMaterialUI(sl::Material* material) {
sl::ui::namedScope("material-resource-panel", [&]() {
const auto props = material->getProperties();
sl::ui::text("Material");
sl::ui::separator();
sl::ui::text("{}", props.name);

const auto x = ImGui::GetWindowWidth();

sl::ui::text("Diffuse map");
m_state->getOrCreateImageHandle(props.diffuseMap)
->show({ x, x }, { 0, 0 }, { 1.0f, 1.0f });

sl::ui::text("Specular map");
m_state->getOrCreateImageHandle(props.specularMap)
->show({ x, x }, { 0, 0 }, { 1.0f, 1.0f });

sl::ui::text("Normal map");
m_state->getOrCreateImageHandle(props.normalMap)
->show({ x, x }, { 0, 0 }, { 1.0f, 1.0f });
});
}

void ResourceInspectorPanel::renderMeshUI(sl::Mesh* mesh) {}
4 changes: 4 additions & 0 deletions editor/ui/ResourceInspectorPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "Console.h"

#include "starlight/renderer/gpu/Texture.h"
#include "starlight/renderer/gpu/Mesh.h"
#include "starlight/renderer/Material.h"

class ResourceInspectorPanel {
public:
Expand All @@ -20,6 +22,8 @@ class ResourceInspectorPanel {
private:
void renderResourceUI(sl::u64 resourceId, ResourceType type);
void renderTextureUI(sl::Texture* texture);
void renderMaterialUI(sl::Material* material);
void renderMeshUI(sl::Mesh* mesh);

sl::Scene* m_scene;
UIState* m_state;
Expand Down
Loading

0 comments on commit 612dbf9

Please sign in to comment.