Improved procedural sky rendering and settings panel.

This commit is contained in:
antopilo
2022-01-10 15:16:22 -05:00
parent b8d94e94ed
commit e216686272
8 changed files with 344 additions and 44 deletions

View File

@@ -121,7 +121,7 @@ vec3 scatter(vec3 o, vec3 d, float L, vec3 Lo) {
I_R = I_M = vec3(0.);
// Compute T(P -> O) and I_M and I_R
scatterIn(o, d, L, 16.);
scatterIn(o, d, L, 32.);
// mu = cos(alpha)
float mu = dot(d, SunDirection);
@@ -141,16 +141,18 @@ uniform mat4 View;
void main()
{
// Might add camera position in here.
// It was already in there, I removed it.
vec3 O = vec3(0., 0., 0.);
vec2 NDC = UV * 2.0 - 1;
vec4 camSpace = inverse(Projection * View) * vec4(vec3(NDC, 1.0), 1.0);
mat4 newView = View;
newView[3] = vec4(0,0,0,1);
vec4 camSpace = inverse(Projection * newView) * vec4(vec3(NDC, 1.0), 1.0);
vec3 direction = normalize(camSpace.xyz);
vec3 D = direction;
vec3 col = vec3(1.0);
vec3 col = vec3(0.0);
float L = escape(O, D, AtmosphereRadius);
col = scatter(O, D, L, col);
FragColor = vec4(col, 1.);

View File

@@ -287,40 +287,317 @@ namespace Nuake {
if (ImGui::Begin("Environnement"))
{
const Ref<Environment> env = Engine::GetCurrentScene()->GetEnvironment();
if (ImGui::CollapsingHeader("Procedural Sky", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::DragFloat("Sun Intensity", &env->ProceduralSkybox->SunIntensity, 0.1f, 0.0f);
Vector3 currentDirection = env->ProceduralSkybox->SunDirection;
ImGuiHelper::DrawVec3("Sun Direction", &currentDirection);
env->ProceduralSkybox->SunDirection = glm::normalize(currentDirection);
if (ImGui::BeginTable("EnvTable", 3, ImGuiTableFlags_BordersInner))
{
ImGui::TableSetupColumn("name", 0, 0.3);
ImGui::TableSetupColumn("set", 0, 0.6);
ImGui::TableSetupColumn("reset", 0, 0.1);
Vector3 mieScattering = env->ProceduralSkybox->MieScattering * 10000.0f;
ImGuiHelper::DrawVec3("Mie Scattering", &mieScattering);
env->ProceduralSkybox->MieScattering = mieScattering / 10000.0f;
}
if (ImGui::CollapsingHeader("HDR", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::DragFloat("Exposure", &env->Exposure, .01f, 0.0f, 10.0f);
ImGui::DragFloat("Gamma", &env->Gamma, 0.1f, 0.0f, 10.0f);
}
if (ImGui::CollapsingHeader("Bloom", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::Checkbox("Enabled", &env->BloomEnabled);
float threshold = env->mBloom->GetThreshold();
ImGui::DragFloat("Threshold", &threshold, 0.01f, 0.0f, 500.0f);
env->mBloom->SetThreshold(threshold);
ImGui::TableNextColumn();
{
// Title
ImGui::Text("Sky Type");
ImGui::TableNextColumn();
int iteration = env->mBloom->GetIteration();
ImGui::DragInt("Iteration", &iteration, 1.0f, 0, 8);
env->mBloom->SetIteration(iteration);
// Here we create a dropdown for every sky type.
const char* SkyTypes[] = { "Procedural Sky", "Color" };
static int currentSkyType = (int)env->CurrentSkyType;
ImGui::Combo("##SkyType", &currentSkyType, SkyTypes, IM_ARRAYSIZE(SkyTypes));
env->CurrentSkyType = (SkyType)currentSkyType;
ImGui::TableNextColumn();
// Reset button
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string ResetType = ICON_FA_UNDO + std::string("##ResetType");
if (ImGui::Button(ResetType.c_str())) env->CurrentSkyType = SkyType::ProceduralSky;
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
if(env->CurrentSkyType == SkyType::ClearColor)
{
// Title
ImGui::Text("Clear color");
ImGui::TableNextColumn();
// Color picker
ImGui::ColorEdit4("##clearColor", &env->AmbientColor.r, ImGuiColorEditFlags_NoAlpha);
ImGui::TableNextColumn();
// Reset button
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetColor = ICON_FA_UNDO + std::string("##ResetColor");
if (ImGui::Button(resetColor.c_str())) env->AmbientColor = Color(0, 0, 0, 1);
ImGui::PopStyleColor();
}
else if (env->CurrentSkyType == SkyType::ProceduralSky)
{
{ // Sun Intensity
ImGui::Text("Sun Intensity");
ImGui::TableNextColumn();
ImGui::DragFloat("##Sun Intensity", &env->ProceduralSkybox->SunIntensity, 0.1f, 0.0f, 1000.0f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetSunIntensity = ICON_FA_UNDO + std::string("##ResetSunIntensity");
if (ImGui::Button(resetSunIntensity.c_str())) env->ProceduralSkybox->SunIntensity = 100.0f;
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{ // Sun Direction
ImGui::Text("Sun Direction");
ImGui::TableNextColumn();
Vector3 sunDirection = env->ProceduralSkybox->GetSunDirection();
ImGuiHelper::DrawVec3("##Sun Direction", &sunDirection);
env->ProceduralSkybox->SunDirection = glm::normalize(sunDirection);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetSunDirection = ICON_FA_UNDO + std::string("##resetSunDirection");
if (ImGui::Button(resetSunDirection.c_str())) env->ProceduralSkybox->SunDirection = Vector3(0.20000f, 0.95917f, 0.20000f);
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{ // Surface Radius
ImGui::Text("Surface Radius");
ImGui::TableNextColumn();
ImGui::DragFloat("##surfaceRadius", &env->ProceduralSkybox->SurfaceRadius, 100.f, 0.0f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetSurfaceRadius = ICON_FA_UNDO + std::string("##resetSurfaceRadius");
if (ImGui::Button(resetSurfaceRadius.c_str())) env->ProceduralSkybox->SurfaceRadius = 6360e3f;
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{ // Atmosphere Radius
ImGui::Text("Atmosphere Radius");
ImGui::TableNextColumn();
ImGui::DragFloat("##AtmosphereRadius", &env->ProceduralSkybox->AtmosphereRadius, 100.f, 0.0f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetAtmosphereRadius = ICON_FA_UNDO + std::string("##resetAtmosphereRadius");
if (ImGui::Button(resetAtmosphereRadius.c_str())) env->ProceduralSkybox->AtmosphereRadius = 6380e3f;
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{ // Center point
ImGui::Text("Center Point");
ImGui::TableNextColumn();
ImGuiHelper::DrawVec3("##Center Point", &env->ProceduralSkybox->CenterPoint, 0.0f, 100.0f, 100.0f);
ImGui::TableNextColumn();
if (env->ProceduralSkybox->CenterPoint.y < -env->ProceduralSkybox->AtmosphereRadius)
env->ProceduralSkybox->CenterPoint.y = -env->ProceduralSkybox->AtmosphereRadius + 1.f;
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetCenterPoint = ICON_FA_UNDO + std::string("##resetAtmosphereRadius");
if (ImGui::Button(resetCenterPoint.c_str())) env->ProceduralSkybox->CenterPoint = Vector3(0, -env->ProceduralSkybox->AtmosphereRadius, 0);
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{ // Mie Scattering
ImGui::Text("Mie Scattering");
ImGui::TableNextColumn();
Vector3 mieScattering = env->ProceduralSkybox->MieScattering * 10000.0f;
ImGuiHelper::DrawVec3("##Mie Scattering", &mieScattering, 0.0f, 100.0f, 0.01f);
if (mieScattering.x < 0) mieScattering.x = 0;
if (mieScattering.y < 0) mieScattering.y = 0;
if (mieScattering.z < 0) mieScattering.z = 0;
env->ProceduralSkybox->MieScattering = mieScattering / 10000.0f;
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetMieScattering = ICON_FA_UNDO + std::string("##resetMieScattering");
if (ImGui::Button(resetMieScattering.c_str())) env->ProceduralSkybox->MieScattering = Vector3(2e-5f);
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{ // RayleighScattering
ImGui::Text("Rayleigh Scattering");
ImGui::TableNextColumn();
Vector3 rayleighScattering = env->ProceduralSkybox->RayleighScattering * 10000.0f;
ImGuiHelper::DrawVec3("##Ray Scattering", &rayleighScattering, 0.0f, 100.0f, 0.01f);
if (rayleighScattering.r < 0) rayleighScattering.r = 0;
if (rayleighScattering.g < 0) rayleighScattering.g = 0;
if (rayleighScattering.b < 0) rayleighScattering.b = 0;
env->ProceduralSkybox->RayleighScattering = rayleighScattering / 10000.0f;
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetRayScattering = ICON_FA_UNDO + std::string("##resetRayScattering");
if (ImGui::Button(resetRayScattering.c_str())) env->ProceduralSkybox->RayleighScattering = Vector3(58e-7f, 135e-7f, 331e-7f);
ImGui::PopStyleColor();
}
}
ImGui::TableNextColumn();
{ // Exposure
ImGui::Text("Exposure");
ImGui::TableNextColumn();
ImGui::DragFloat("Exposure", &env->Exposure, .01f, 0.0f, 100.0f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetExposure = ICON_FA_UNDO + std::string("##resetExposure");
if (ImGui::Button(resetExposure.c_str())) env->Exposure = 3.5f;
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{ // Gamma
ImGui::Text("Gamma");
ImGui::TableNextColumn();
ImGui::DragFloat("Gamma", &env->Gamma, 0.1f, 0.0f, 10.0f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetGamma = ICON_FA_UNDO + std::string("##resetGamma");
if (ImGui::Button(resetGamma.c_str())) env->Gamma = 1.1f;
ImGui::PopStyleColor();
}
ImGui::EndTable();
}
if (ImGui::CollapsingHeader("Fog", ImGuiTreeNodeFlags_DefaultOpen))
if (ImGui::CollapsingHeader("Post processing", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::Checkbox("Enabled", &env->VolumetricEnabled);
ImGui::DragFloat("Volumetric Scattering", &env->VolumetricFog, .01f, 0.0f, 1.0f);
ImGui::DragFloat("Volumetric Step Count", &env->VolumetricStepCount, 1.f, 0.0f);
if (ImGui::BeginTable("EnvTable", 3, ImGuiTableFlags_BordersInner))
{
ImGui::TableSetupColumn("name", 0, 0.3);
ImGui::TableSetupColumn("set", 0, 0.6);
ImGui::TableSetupColumn("reset", 0, 0.1);
ImGui::TableNextColumn();
{
// Title
ImGui::Text("Bloom");
ImGui::TableNextColumn();
ImGui::Checkbox("##Enabled", &env->BloomEnabled);
ImGui::TableNextColumn();
// Reset button
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetBloom = ICON_FA_UNDO + std::string("##resetBloom");
if (ImGui::Button(resetBloom.c_str())) env->BloomEnabled = false;
ImGui::PopStyleColor();
}
if (env->BloomEnabled)
{
ImGui::TableNextColumn();
{
// Title
ImGui::Text("Bloom Threshold");
ImGui::TableNextColumn();
float threshold = env->mBloom->GetThreshold();
ImGui::DragFloat("##Threshold", &threshold, 0.01f, 0.0f, 500.0f);
env->mBloom->SetThreshold(threshold);
ImGui::TableNextColumn();
// Reset button
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetBloomThreshold = ICON_FA_UNDO + std::string("##resetBloomThreshold");
if (ImGui::Button(resetBloomThreshold.c_str())) env->mBloom->SetThreshold(2.4f);
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
// Title
ImGui::Text("Bloom Quality");
ImGui::TableNextColumn();
int iteration = env->mBloom->GetIteration();
ImGui::DragInt("##quality", &iteration, 1.0f, 0, 4);
env->mBloom->SetIteration(iteration);
ImGui::TableNextColumn();
// Reset button
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetQuality = ICON_FA_UNDO + std::string("##resetQuality");
if (ImGui::Button(resetQuality.c_str())) env->mBloom->SetIteration(3);
ImGui::PopStyleColor();
}
}
ImGui::TableNextColumn();
{
// Title
ImGui::Text("Volumetric");
ImGui::TableNextColumn();
ImGui::Checkbox("##VolumetricEnabled", &env->VolumetricEnabled);
ImGui::TableNextColumn();
// Reset button
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetVolumetric = ICON_FA_UNDO + std::string("##resetVolumetric");
if (ImGui::Button(resetVolumetric.c_str())) env->VolumetricEnabled = false;
ImGui::PopStyleColor();
}
if (env->VolumetricEnabled)
{
ImGui::TableNextColumn();
{
// Title
ImGui::Text("Volumetric Scattering");
ImGui::TableNextColumn();
ImGui::DragFloat("##Volumetric Scattering", &env->VolumetricFog, .01f, 0.0f, 1.0f);
ImGui::TableNextColumn();
// Reset button
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetBloomThreshold = ICON_FA_UNDO + std::string("##resetBloomThreshold");
if (ImGui::Button(resetBloomThreshold.c_str())) env->mBloom->SetThreshold(2.4f);
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
// Title
ImGui::Text("Step count");
ImGui::TableNextColumn();
ImGui::DragFloat("##Volumetric Step Count", &env->VolumetricStepCount, 1.f, 0.0f);
ImGui::TableNextColumn();
// Reset button
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetQuality = ICON_FA_UNDO + std::string("##resetQuality");
if (ImGui::Button(resetQuality.c_str())) env->VolumetricStepCount = 50.f;
ImGui::PopStyleColor();
}
}
}
ImGui::EndTable();
}
if (ImGui::CollapsingHeader("Camera", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::DragFloat("Exposure", &Engine::GetCurrentScene()->m_EditorCamera->Exposure, .01f, 0.0f, 5.0f);

View File

@@ -19,7 +19,7 @@ namespace Nuake {
void OGLRendererAPI::SetClearColor(const Color& color)
{
glClearColor(color.r, color.g, color.g, color.a);
glClearColor(color.r, color.g, color.b, color.a);
}
void OGLRendererAPI::GenBuffer(unsigned int& bufferID)

View File

@@ -68,12 +68,11 @@ namespace Nuake {
{
mVolumetric->Resize(framebuffer.GetSize());
mVolumetric->SetDepth(mGBuffer->GetTexture(GL_DEPTH_ATTACHMENT).get());
mVolumetric->Draw(mProjection, mView, lightList);
mVolumetric->Draw(mProjection , mView, lightList);
finalOutput = mVolumetric->GetFinalOutput();
}
// Copy final output to target framebuffer
framebuffer.Bind();
{
@@ -191,7 +190,16 @@ namespace Nuake {
RenderCommand::Disable(RendererEnum::DEPTH_TEST);
RenderCommand::Disable(RendererEnum::FACE_CULL);
scene.GetEnvironment()->ProceduralSkybox->Draw(mProjection, mView);
Ref<Environment> environment = scene.GetEnvironment();
if (environment->CurrentSkyType == SkyType::ProceduralSky)
{
environment->ProceduralSkybox->Draw(mProjection, mView);
}
else if (environment->CurrentSkyType == SkyType::ClearColor)
{
RenderCommand::SetClearColor(environment->AmbientColor);
RenderCommand::Clear();
}
RenderCommand::Enable(RendererEnum::FACE_CULL);
Shader* shadingShader = ShaderManager::GetShader("resources/Shaders/deferred.shader");

View File

@@ -57,6 +57,8 @@ namespace Nuake
glTexImage2D(GL_TEXTURE_2D, 0, format2, size.x, size.y, 0, format, format3, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
//glGenerateMipmap(GL_TEXTURE_2D);
}

View File

@@ -7,7 +7,7 @@
class ImGuiHelper {
public:
static void DrawVec3(const std::string label, glm::vec3* values, float resetValue = 0.0f, float columnWidth = 100.0) {
static void DrawVec3(const std::string label, glm::vec3* values, float resetValue = 0.0f, float columnWidth = 100.0, float rate = 0.1f, float min = 0.0f) {
ImGuiIO& io = ImGui::GetIO();
auto boldFont = io.Fonts->Fonts[0];
@@ -30,7 +30,7 @@ public:
ImGui::SameLine();
ImGui::PushItemWidth(availWidth);
ImGui::DragFloat("##X", &values->x, 0.1f, 0.0f, 0.0f, "%.2f");
ImGui::DragFloat("##X", &values->x, rate, min, 0.0f, "%.2f");
ImGui::PopItemWidth();
ImGui::SameLine();
@@ -44,7 +44,7 @@ public:
ImGui::PopStyleColor(3);
ImGui::SameLine();
ImGui::PushItemWidth(availWidth);
ImGui::DragFloat("##Y", &values->y, 0.1f, 0.0f, 0.0f, "%.2f");
ImGui::DragFloat("##Y", &values->y, rate, 0.0f, 0.0f, "%.2f");
ImGui::PopItemWidth();
ImGui::SameLine();
@@ -59,7 +59,7 @@ public:
ImGui::SameLine();
ImGui::PushItemWidth(availWidth);
ImGui::DragFloat("##Z", &values->z, 0.1f, 0.0f, 0.0f, "%.2f");
ImGui::DragFloat("##Z", &values->z, rate, 0.0f, 0.0f, "%.2f");
ImGui::PopItemWidth();
ImGui::PopStyleVar();

View File

@@ -30,6 +30,7 @@ namespace Nuake {
json Environment::Serialize()
{
BEGIN_SERIALIZE();
SERIALIZE_VAL(CurrentSkyType);
SERIALIZE_VAL(VolumetricFog);
SERIALIZE_VAL(VolumetricStepCount);
SERIALIZE_VEC4(AmbientColor);
@@ -40,7 +41,8 @@ namespace Nuake {
bool Environment::Deserialize(const std::string& str)
{
BEGIN_DESERIALIZE();
if (j.contains("CurrentSkyType"))
CurrentSkyType = j["CurrentSkyType"];
if (j.contains("VolumetricFog"))
VolumetricFog = j["VolumetricFog"];
if (j.contains("VolumetricStepCount"))

View File

@@ -9,10 +9,22 @@
namespace Nuake
{
enum class SkyType {
ProceduralSky = 0,
ClearColor = 1
// CubeMap
};
class Environment : public ISerializable
{
public:
Environment();
SkyType CurrentSkyType = SkyType::ClearColor;
Color AmbientColor = Color(0, 0, 0, 1);
Ref<ProceduralSky> ProceduralSkybox;
bool VolumetricEnabled = false;
float VolumetricFog = 0.90f;
float VolumetricStepCount = 50.f;
@@ -24,9 +36,6 @@ namespace Nuake
Scope<Bloom> mBloom;
Vector3 ClearColor;
glm::vec4 AmbientColor;
Ref<ProceduralSky> ProceduralSkybox;
glm::vec4 m_AmbientColor;
glm::vec4 GetAmbientColor();
void SetAmbientColor(glm::vec4 color);