diff --git a/imgui.ini b/imgui.ini index 3276003..c6080ef 100644 --- a/imgui.ini +++ b/imgui.ini @@ -15,8 +15,8 @@ Collapsed=0 DockId=0x00000001,0 [Window][Object Controls] -Pos=1532,124 -Size=388,937 +Pos=1521,124 +Size=399,956 Collapsed=0 DockId=0x00000004,0 @@ -26,7 +26,7 @@ Collapsed=0 [Window][DockSpace Demo] Pos=0,0 -Size=1920,1061 +Size=1920,1080 Collapsed=0 [Window][Dear ImGui Demo] @@ -35,9 +35,9 @@ Size=1553,966 Collapsed=0 [Docking][Data] -DockSpace ID=0x3BC79352 Window=0x4647B76E Pos=0,19 Size=1920,1042 Split=Y +DockSpace ID=0x3BC79352 Window=0x4647B76E Pos=0,19 Size=1920,1061 Split=Y DockNode ID=0x00000001 Parent=0x3BC79352 SizeRef=1904,103 Selected=0x8CCBC963 DockNode ID=0x00000002 Parent=0x3BC79352 SizeRef=1904,956 Split=X - DockNode ID=0x00000003 Parent=0x00000002 SizeRef=1530,956 CentralNode=1 - DockNode ID=0x00000004 Parent=0x00000002 SizeRef=388,956 Selected=0x3B5216D2 + DockNode ID=0x00000003 Parent=0x00000002 SizeRef=1519,956 CentralNode=1 + DockNode ID=0x00000004 Parent=0x00000002 SizeRef=399,956 Selected=0x3B5216D2 diff --git a/shaders/parade_fs.glsl b/shaders/parade_fs.glsl index fe740a7..3364d3f 100644 --- a/shaders/parade_fs.glsl +++ b/shaders/parade_fs.glsl @@ -16,7 +16,7 @@ const uint P_CONE = 0x02; const uint P_CUBE = 0x03; const uint P_ROUNDED_CUBE = 0x04; -bool twoExists = false; +//bool twoExists = false; struct GLSLPrimitive { @@ -105,6 +105,19 @@ float roundedCubeSDF(vec3 p, vec3 center, float s, float r) { return length(max(abs(p - center) - vec3(s), vec3(0))) - r; } +//float round(vec3 pos, GLSLPrimitive prim, float radius) +//{ +// return sdf(pos, prim) - radius; +//} + +float sdBox() +{ + vec3 p = vec3(0.0, 0.0, 0.0); + vec3 b = vec3(0.0, 0.0, 0.1); + vec3 q = abs(p) - b; + return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0); +} + float sdf(vec3 pos, GLSLPrimitive prim) { float d; @@ -133,6 +146,8 @@ float sdf(vec3 pos, GLSLPrimitive prim) case P_ROUNDED_CUBE: { d = roundedCubeSDF(pos, prim.position.xyz, prim.size, prim.radius); + //d = round(pos, prim, prim.radius); + //d = sdBox(); break; } default: @@ -158,75 +173,13 @@ float smoothMaxSDF(float d1, float d2, float k) return max(d1, d2) - h * h * k * 0.25; } -float opSmoothSubtraction(float d1, float d2, float k) +// From Inigo Quilez +float smoothSubSDF(float d1, float d2, float k) { float h = clamp(0.5 - 0.5 * (d2 + d1) / k, 0.0, 1.0); return mix(d2, -d1, h) + k * h * (1.0 - h); } -//void estimateSmoothNormals(vec3 p, float smoothness, float epsilon, inout vec3 normals) -//{ -// float d, nx, ny, nz; -// -// for (int i = 0; i < primitives.length(); i++) -// { -// if (i == 0) -// { -// d = sdf(p, primitives[0]); -// nx = sdf(vec3(p.x + epsilon, p.y, p.z), primitives[0]); -// ny = sdf(vec3(p.x, p.y + epsilon, p.z), primitives[0]); -// nz = sdf(vec3(p.x, p.y, p.z + epsilon), primitives[0]); -// } -// if (primitives[i].subtract == 1) continue; -// else -// { -// d = smoothMinSDF(d, sdf(p, primitives[i]), smoothness); -// nx = smoothMinSDF(nx, sdf(vec3(p.x + epsilon, p.y, p.z), primitives[i]), smoothness); -// ny = smoothMinSDF(ny, sdf(vec3(p.x, p.y + epsilon, p.z), primitives[i]), smoothness); -// nz = smoothMinSDF(nz, sdf(vec3(p.x, p.y, p.z + epsilon), primitives[i]), smoothness); -// } -// } -// -// for (int i = 0; i < primitives.length(); i++) -// { -// if (primitives[i].subtract == 1) -// { -// d = smoothMaxSDF(d, -sdf(p, primitives[i]), smoothness); -// nx = smoothMaxSDF(nx, -sdf(vec3(p.x + epsilon, p.y, p.z), primitives[i]), smoothness); -// ny = smoothMaxSDF(ny, -sdf(vec3(p.x, p.y + epsilon, p.z), primitives[i]), smoothness); -// nz = smoothMaxSDF(nz, -sdf(vec3(p.x, p.y, p.z + epsilon), primitives[i]), smoothness); -// } -// } -// -// nx -= d; -// ny -= d; -// nz -= d; -// -// normals = normalize(vec3(nx, ny, nz)); -//} - -//void estimateSmoothNormalsMax(vec3 p, float smoothness, float epsilon, inout vec3 normals) -//{ -// float d = sdf(p, primitives[0]); -// float nx = sdf(vec3(p.x + epsilon, p.y, p.z), primitives[0]); -// float ny = sdf(vec3(p.x, p.y + epsilon, p.z), primitives[0]); -// float nz = sdf(vec3(p.x, p.y, p.z + epsilon), primitives[0]); -// -// -// for (int i = 0; i < primitives.length(); i++) -// { -// d = smoothMaxSDF(d, sdf(p, primitives[i]), smoothness); -// nx = smoothMaxSDF(nx, sdf(vec3(p.x + epsilon, p.y, p.z), primitives[i]), smoothness); -// ny = smoothMaxSDF(ny, sdf(vec3(p.x, p.y + epsilon, p.z), primitives[i]), smoothness); -// nz = smoothMaxSDF(nz, sdf(vec3(p.x, p.y, p.z + epsilon), primitives[i]), smoothness); -// } -// nx -= d; -// ny -= d; -// nz -= d; -// -// normals = normalize(vec3(nx, ny, nz)); -//} - float calcDist(vec3 pos, inout float dist) { for (int i = 0; i < primitives.length(); i++) @@ -236,7 +189,7 @@ float calcDist(vec3 pos, inout float dist) if (primitives[i].subtract == 0) dist = smoothMinSDF(dist, newDist, smoothing); else - dist = opSmoothSubtraction(newDist, dist, smoothing); + dist = smoothSubSDF(newDist, dist, smoothing); } return dist; @@ -253,7 +206,7 @@ float calcDist2(vec3 pos) if (primitives[i].subtract == 0) dist = smoothMinSDF(newDist, dist, smoothing); else - dist = opSmoothSubtraction(newDist, dist, smoothing); + dist = smoothSubSDF(newDist, dist, smoothing); } return dist; @@ -261,20 +214,6 @@ float calcDist2(vec3 pos) vec3 estimateNormals(vec3 p, float epsilon) { - /*float d1 = 99999.0; - float d2 = 99999.0; - - float x = calcDist(vec3(p.x + epsilon, p.y, p.z), d1) - calcDist(vec3(p.x - epsilon, p.y, p.z), d2); - - d1 = 99999.0; - d2 = 99999.0; - float y = calcDist(vec3(p.x, p.y + epsilon, p.z), d1) - calcDist(vec3(p.x, p.y - epsilon, p.z), d2); - - d1 = 99999.0; - d2 = 99999.0; - float z = calcDist(vec3(p.x, p.y, p.z + epsilon), d1) - calcDist(vec3(p.x, p.y, p.z - epsilon), d2); - return normalize(vec3(x, y, z));*/ - vec2 e = vec2(1.0, -1.0) * 0.5773; return normalize(e.xyy * calcDist2(p + e.xyy * epsilon) + e.yyx * calcDist2(p + e.yyx * epsilon) + @@ -303,9 +242,7 @@ float weightFunction(float distance, float k, float epsilon) vec4 renderLight(vec4 position) { vec4 newPosition = position; - newPosition.x = position.y; - newPosition.y = -position.x; - vec4 matPos = P * V * M * newPosition; + vec4 matPos = P * V * newPosition; matPos /= matPos.w; vec2 screenPos = 2.0 * vec2(gl_FragCoord.x / window_width, gl_FragCoord.y / window_height) - 1.0; float aspectRatio = float(window_width) / float(window_height); @@ -317,7 +254,7 @@ vec4 renderLight(vec4 position) { vec4 color; if (length(screenPos - centerScreenPos) < radius && length(screenPos - centerScreenPos) > radius * 0.9) { - color = vec4(1.0, 0.95, 0.6, 1.0); + color = vec4(0.957, 0.827, 0.369, 1.0); } else { color = vec4(0.0); @@ -326,7 +263,7 @@ vec4 renderLight(vec4 position) { return color; } -void main(void) +vec4 RayMarch(vec2 coords, vec2 offset) { vec3 normals; vec4 color = vec4(0.0); @@ -337,11 +274,9 @@ void main(void) float epsilon = 0.001; int steps = 0; int max_steps = 1000; - vec3 light_pos = vec3(0.0, 1.0, 0.0); float k = smoothing; - vec2 ndc_pos = 2.0 * vec2(gl_FragCoord.x / window_width, gl_FragCoord.y / window_height) - 1.0; - vec4 cam_dir = inverse(P) * vec4(ndc_pos, 1.0, 1.0); + vec4 cam_dir = inverse(P) * vec4(coords + offset, 1.0, 1.0); cam_dir /= cam_dir.w; cam_dir = vec4(cam_dir.xyz, 0.0); @@ -359,14 +294,14 @@ void main(void) { steps++; float minDist = 999999.0; - + calcDist(ray_pos.xyz, minDist); for (int i = 0; i < primitives.length(); i++) { float weight = weightFunction(minDist, smoothing, epsilon); accumulatedDiffuse += primitives[i].diffuse_color * weight; - accumulatedSpecular += primitives[i].specular_color * weight; + accumulatedSpecular += primitives[i].specular_color * weight; accumulatedAmbient += primitives[i].ambient_color * weight; accumulatedSpecExp += primitives[i].specular_exponent * weight; totalWeight += weight; @@ -404,7 +339,7 @@ void main(void) vec3 vw = normalize(cam_pos - ray_pos.xyz); vec3 halfwayDir = normalize(lw + vw); - spec = pow(max(dot(halfwayDir, nw), 0), int(accumulatedSpecExp)); + spec = pow(max(dot(halfwayDir, nw), 0), int(accumulatedSpecExp)); specular += spec * accumulatedSpecular * lights[i].specular_color; @@ -418,5 +353,27 @@ void main(void) } for (int i = 0; i < lights.length(); i++) lightColor += renderLight(lights[i].position); - FragColor = mix(color, lightColor, lightColor.a); + return vec4(mix(color, lightColor, lightColor.a).rgb, 0.0); +} + +void main(void) +{ + vec4 finalColor = vec4(0.0); + int AA = 1; // Set the level of anti-aliasing + float invAA = 1.0 / float(AA*AA); + + vec2 ndc_pos = 2.0 * vec2(gl_FragCoord.x / window_width, gl_FragCoord.y / window_height) - 1.0; + + for (int y = 0; y < AA; ++y) { + for (int x = 0; x < AA; ++x) { + vec2 offset = vec2(float(x) / float(window_width), float(y) / float(window_height)); + finalColor += RayMarch(ndc_pos, offset * invAA); + } + } + + finalColor.rgb /= float(AA*AA); + finalColor.r = pow(finalColor.r, 1.0 / 2.2); + finalColor.g = pow(finalColor.g, 1.0 / 2.2); + finalColor.b = pow(finalColor.b, 1.0 / 2.2); + FragColor = finalColor; } \ No newline at end of file diff --git a/src/Application.cpp b/src/Application.cpp index dfc1d0e..3ef19e9 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -64,6 +64,7 @@ namespace scene unsigned int l_vbo = -1; unsigned int p_vbo = -1; int object = 0; + int light = 0; } namespace mouse @@ -140,6 +141,10 @@ void UpdatePrimitive() glBindBuffer(GL_SHADER_STORAGE_BUFFER, scene::p_vbo); glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, scene::primitiveData.size() * sizeof(Primitive), scene::primitiveData.data()); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, scene::l_vbo); + glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, scene::lightData.size() * sizeof(Light), scene::lightData.data()); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); } static unsigned int CompileShader(unsigned int type, const std::string& source) @@ -299,6 +304,14 @@ void PrimGUI(unsigned int obj) ImGui::SliderInt("Specular Exponent", &scene::primitiveData[obj].specular_exponent, 1, 500); } +void LightGui(unsigned int lht) +{ + ImGui::SliderFloat3("Light Position", glm::value_ptr(scene::lightData[lht].position), -2.0f, 2.0f); + ImGui::ColorEdit3("Light Diffuse", glm::value_ptr(scene::lightData[lht].diffuse_color)); + ImGui::ColorEdit3("Light Specular", glm::value_ptr(scene::lightData[lht].specular_color)); + ImGui::ColorEdit3("Light Ambient", glm::value_ptr(scene::lightData[lht].ambient_color)); +} + //Draw the ImGui user interface void draw_gui(GLFWwindow* window) { @@ -377,6 +390,16 @@ void draw_gui(GLFWwindow* window) ImGui::Separator(); PrimGUI(scene::object); + ImGui::Separator(); + + for (int i = 0; i < scene::lightData.size(); i++) + { + std::string name = "Light_" + std::to_string(i); + ImGui::RadioButton(name.c_str(), &scene::light, i); + } + ImGui::Separator(); + + LightGui(scene::light); ImGui::End(); ImGui::Begin("Primitives"); @@ -403,13 +426,13 @@ void draw_gui(GLFWwindow* window) AddPrimitive(P_ROUNDED_CUBE); scene::object = scene::primitiveData.size() - 1; InitPrimitive(); - }/*ImGui::SameLine(); + }ImGui::SameLine(); if (ImGui::Button("Point Light", ImVec2(ImGui::GetWindowSize().y * 0.5f, ImGui::GetWindowSize().y * 0.5f))) { AddLight(); - scene::object = scene::primitiveData.size() - 1; - InitPrimitive(); - }*/ + scene::light = scene::lightData.size() - 1; + InitLights(); + } ImGui::End(); //End ImGui Frame @@ -580,48 +603,11 @@ void init() scene::shader = CreateShader("shaders/parade_vs.glsl", "shaders/parade_fs.glsl"); glUseProgram(scene::shader); - AddPrimitive(P_ROUNDED_CUBE); + AddPrimitive(P_CUBE); Light l; - l.position = glm::vec4{ -sqrt(3.f) / 3.f, sqrt(3.f) / 3.f, -sqrt(3.f) / 3.f, 1.f }; - l.diffuse_color = glm::vec4{ 142.f / 255.f, 202.f / 255.f, 230.f / 255.f, 1.f }; + l.position = glm::vec4{ sqrt(3.f) / 3.f, sqrt(3.f) / 3.f, sqrt(3.f) / 3.f, 1.f }; scene::lightData.push_back(l); - Light l2; - l2.position = glm::vec4{ sqrt(3.f) / 3.f, sqrt(3.f) / 3.f, sqrt(3.f) / 3.f, 1.f}; - l2.diffuse_color = glm::vec4(255.f / 255.f, 183.f / 255.f, 3.f / 255.f, 1.f); - scene::lightData.push_back(l2); - Light l3; - l3.position = glm::vec4{ ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, 1.f }; - l3.diffuse_color = glm::vec4{ ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), 1.f }; - scene::lightData.push_back(l3); - Light l4; - l4.position = glm::vec4{ ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, 1.f }; - l4.diffuse_color = glm::vec4{ ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), 1.f }; - scene::lightData.push_back(l4); - Light l5; - l5.position = glm::vec4{ ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, 1.f }; - l5.diffuse_color = glm::vec4{ ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), 1.f }; - scene::lightData.push_back(l5); - Light l6; - l6.position = glm::vec4{ ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, 1.f }; - l6.diffuse_color = glm::vec4{ ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), 1.f }; - scene::lightData.push_back(l6); - Light l7; - l7.position = glm::vec4{ ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, 1.f }; - l7.diffuse_color = glm::vec4{ ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), 1.f }; - scene::lightData.push_back(l7); - Light l8; - l8.position = glm::vec4{ ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, 1.f }; - l8.diffuse_color = glm::vec4{ ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), 1.f }; - scene::lightData.push_back(l8); - Light l9; - l9.position = glm::vec4{ ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, 1.f }; - l9.diffuse_color = glm::vec4{ ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), 1.f }; - scene::lightData.push_back(l9); - Light l10; - l10.position = glm::vec4{ ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, ((double)rand() / (RAND_MAX)) * 2 - 1, 1.f }; - l10.diffuse_color = glm::vec4{ ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), ((double)rand() / (RAND_MAX)), 1.f }; - scene::lightData.push_back(l10); InitCanvas(); InitPrimitive();