better lighting

This commit is contained in:
KP 2024-07-29 18:54:14 -05:00
parent 2f40dadf3e
commit 7cd5cb59d3
4 changed files with 130 additions and 26 deletions

View file

@ -4,6 +4,7 @@ uniform sampler2D u_texture;
uniform sampler2D u_normal_texture;
uniform vec3 u_campos;
uniform vec3 u_camdir;
uniform vec3 u_highlight;
uniform float u_time;
@ -31,36 +32,26 @@ struct Light
float radius;
};
float Lambert(vec3 n, vec3 l)
{
vec3 nrmn = normalize(n);
vec3 nrml = normalize(l);
float res = dot(nrmn, nrml);
return max(res, 0.0);
}
vec4 MakeLight(vec3 norm, vec3 position, vec3 diffuse, float radius, float sharpness, float power)
{
Light light;
light.position = position;
light.diffuse = diffuse;
light.radius = radius;
// vec4 res = vec4(light.diffuse * Lambert(norm, normalize(light.position)), 1.0);
vec3 light_dir = normalize(light.position - v_position);
//vec3 view_dir = normalize(u_camdir - v_position);
vec3 view_dir = normalize(u_campos - v_position);
vec3 reflect_dir = reflect(-light_dir, norm);
float spec = max(dot(view_dir, reflect_dir), 0.0);
float diff = max(dot(norm, light_dir), 0.0);
power = 0.5;
vec3 ddiffuse = diff * light.diffuse;
power *= 0.5;
vec3 ddiffuse = diff * vec3(1.0);// * light.diffuse;
vec3 specular = power * spec * light.diffuse;
vec4 res = vec4(ddiffuse + specular, 1.0);
//vec4 res = vec4(power * spec * light.diffuse, 1.0);
float alpha = kpc(distance(light.position, v_position), light.radius * sharpness, light.radius);
res *= mix(vec4(light.diffuse, 1), vec4(0,0,0,1.0), alpha);
res *= mix(vec4(light.diffuse, 1), vec4(0,0,0,1), alpha);
return res;
}
@ -77,7 +68,7 @@ void main()
vec4 ambient = vec4(0.1, 0.1, 0.1, 1.0) * 1.5, light = ambient;
light += MakeLight(norm, u_campos, vec3(0.7), 5.0, 0.0, 1.0);
light += MakeLight(norm, vec3(2.0, 10.0, -24.0), vec3(0.7), /*5.0*/ 1000.0, 1.0, 1.0);
light += MakeLight(norm, vec3(5.0, 2.0, -7.0 + cos(u_time/35.0) * 2.0), vec3(1.0, 0.6, 0.0), 5.0, 0.6, 1.0);
light += MakeLight(norm, vec3(7, 2.0, -7.0 + -cos(u_time / 30.0) * 1.0), vec3(0.6, 0.9, 1.0), 5.0, 0.6, 1.0);

View file

@ -543,6 +543,8 @@ void Map::SanitizeSectors()
void Map::Init()
{
KP3D_LOG_INFO("Map init");
sectors.clear();
m_mesh.Reset();
sectors.reserve(10000);

View file

@ -280,8 +280,8 @@ void Editor::RenderUI()
RenderUIAbout();
// Sector window
ImGui::SetNextWindowSize({400, 500}, ImGuiCond_FirstUseEver);
ImGui::SetNextWindowPos({20, 200}, ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize({400, 600}, ImGuiCond_FirstUseEver);
ImGui::SetNextWindowPos({20, 125}, ImGuiCond_FirstUseEver);
if (show_selection_info)
{
if (ImGui::Begin("Selection Info", &show_selection_info))
@ -309,9 +309,9 @@ void Editor::RenderUI()
ImGui::CheckboxFlags("Double-sided", (unsigned*)&info.wall->user_flags, kp3d::Wall::UFLAG_DOUBLESIDED);
ImGui::SeparatorText("Materials");
RenderUIMaterialSelect("Middle", info.wall->materials[kp3d::TEX_FRONT]);
RenderUIMaterialSelect("Upper", info.wall->materials[kp3d::TEX_UPPER]);
RenderUIMaterialSelect("Lower", info.wall->materials[kp3d::TEX_LOWER]);
RenderUIMaterialSelect("Middle", &info.wall->materials[kp3d::TEX_FRONT]);
RenderUIMaterialSelect("Upper", &info.wall->materials[kp3d::TEX_UPPER]);
RenderUIMaterialSelect("Lower", &info.wall->materials[kp3d::TEX_LOWER]);
}
else if (info.sector)
{
@ -331,8 +331,8 @@ void Editor::RenderUI()
if (changed)
sandbox->map.Rebuild(kp3d::GEN_NORMALS);
ImGui::SeparatorText("Materials");
RenderUIMaterialSelect("Floor", info.sector->floor.material);
RenderUIMaterialSelect("Ceiling", info.sector->ceiling.material);
RenderUIMaterialSelect("Floor", &info.sector->floor.material);
RenderUIMaterialSelect("Ceiling", &info.sector->ceiling.material);
}
}
catch (std::bad_any_cast& e)
@ -347,6 +347,9 @@ void Editor::RenderUI()
}
//ImGui::ShowDemoWindow();
if (m_material_to_update)
RenderUIMaterialModal();
}
void Editor::RenderUIInfo()
@ -400,12 +403,18 @@ void Editor::RenderUIAbout()
}
}
void Editor::RenderUIMaterialSelect(const char* name, const kp3d::Material* material)
void Editor::RenderUIMaterialSelect(const char* name, const kp3d::Material** material)
{
ImGui::Text("%s:", name);
if (material)
if (material && *material)
{
if (ImGui::ImageButton((ImTextureID)material->textures[kp3d::MAT_TEX_DIFFUSE].GetGLID(), {96, 96})) {}
ImGui::PushID(material); // not safe, not ideal
if (ImGui::ImageButton((ImTextureID)(*material)->textures[kp3d::MAT_TEX_DIFFUSE].GetGLID(), {96, 96}))
{
m_material_to_update = material;
should_show_material_modal = true;
}
ImGui::PopID();
}
else
{
@ -415,6 +424,104 @@ void Editor::RenderUIMaterialSelect(const char* name, const kp3d::Material* mate
}
void Editor::RenderUIMaterialModal()
{
if (should_show_material_modal)
ImGui::OpenPopup("Select Material");
ImGui::SetNextWindowSize(ImVec2(960, 720), ImGuiCond_FirstUseEver);
if (ImGui::BeginPopupModal("Select Material"))
{
ImGui::InputText("Filter by Name", m_tex_filter_buf, std::size(m_tex_filter_buf));
ImGui::Separator();
bool should_remove_texture = false;
if (ImGui::Button("Remove material"))
should_remove_texture = true;
bool should_close = false;
if (ImGui::Button("Cancel"))
should_close = true;
ImGui::SameLine();
if (ImGui::Button("Clear search"))
memset(m_tex_filter_buf, 0, 512);
ImGui::Separator();
ImGui::BeginChild("TextureList");
int i = 1;
const kp3d::Material* chosen_tex = nullptr;
bool should_update_texture = false;
using namespace std::regex_constants;
for (const auto& [path, tex_ptr] : kp3d::res::material_cache)
{
if (strlen(m_tex_filter_buf) > 0)
{
try
{
if (!std::regex_search(path, std::regex(std::string(m_tex_filter_buf), icase)))
continue;
}
catch (std::regex_error& e)
{
}
}
const kp3d::Material* tex = tex_ptr.get();
ImGui::BeginGroup();
ImGui::PushID(i);
bool tex_img_button = ImGui::ImageButton((ImTextureID)tex->textures[kp3d::MAT_TEX_DIFFUSE].GetGLID(), {128, 128});
if (ImGui::IsItemHovered())
ImGui::SetTooltip(path.c_str());
if (tex_img_button)
{
should_update_texture = true;
chosen_tex = tex;
}
ImGui::PopID();
ImGui::EndGroup();
//int ww = (int)ImGui::GetTopMostPopupModal()->Size.x;
int ww = (int)ImGui::GetWindowSize().x;
// Some ugly hardcoding here
// Basically this controls the texture preview line wrapping
if (i % ((ww <= 256 ? 602 : ww - 96) / 128) != 0)
ImGui::SameLine();
i++;
}
ImGui::EndChild();
// Should we rebuild the map when we change stuff? I guess.
if (should_remove_texture)
{
*m_material_to_update = nullptr;
ImGui::CloseCurrentPopup();
should_show_material_modal = false;
sandbox->map.Rebuild(kp3d::GEN_NORMALS);
}
if (should_close)
{
ImGui::CloseCurrentPopup();
should_show_material_modal = false;
sandbox->map.Rebuild(kp3d::GEN_NORMALS);
}
if (should_update_texture)
{
*m_material_to_update = chosen_tex;
ImGui::CloseCurrentPopup();
should_show_material_modal = false;
sandbox->map.Rebuild(kp3d::GEN_NORMALS);
}
ImGui::EndPopup();
}
}
void Editor::OnScrollWheel(const kp3d::ScrollWheelEvent* e)
{
using namespace kp3d;

View file

@ -31,7 +31,8 @@ public:
void RenderUI();
void RenderUIInfo();
void RenderUIAbout();
void RenderUIMaterialSelect(const char* name, const kp3d::Material* material);
void RenderUIMaterialSelect(const char* name, const kp3d::Material** material);
void RenderUIMaterialModal();
void OnScrollWheel(const kp3d::ScrollWheelEvent* e);
void OnKeyPress(const kp3d::KeyPressEvent* e);
@ -49,5 +50,8 @@ private:
bool show_info_overlay = true;
bool show_selection_info = false;
bool show_about_view = false;
bool should_show_material_modal = false;
char m_tex_filter_buf[512];
const kp3d::Material** m_material_to_update = nullptr;
};