From 667d4d793526ca0d1de30cc53083c64abb309eed Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Sun, 12 Nov 2023 23:05:22 -0500 Subject: [PATCH] Arbitrary number of prims working --- imgui.ini | 41 ++- .../example_glfw_opengl2.vcxproj | 10 +- .../example_glfw_opengl3.vcxproj | 10 +- .../example_glfw_vulkan.vcxproj | 10 +- .../example_sdl2_directx11.vcxproj | 10 +- .../example_sdl2_opengl2.vcxproj | 10 +- .../example_sdl2_opengl3.vcxproj | 10 +- .../example_sdl2_sdlrenderer2.vcxproj | 12 +- .../example_sdl2_vulkan.vcxproj | 10 +- .../example_win32_directx10.vcxproj | 10 +- .../example_win32_directx11.vcxproj | 8 +- .../example_win32_directx12.vcxproj | 10 +- .../example_win32_directx9.vcxproj | 10 +- .../example_win32_opengl3.vcxproj | 10 +- shaders/parade_fs.glsl | 255 +++++++++++++----- src/Application.cpp | 228 ++++++++++++++-- 16 files changed, 489 insertions(+), 165 deletions(-) diff --git a/imgui.ini b/imgui.ini index f1cc1bf..56c82d3 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,10 +1,43 @@ [Window][Debug##Default] -Pos=60,60 +Pos=677,496 Size=400,400 -Collapsed=0 +Collapsed=1 [Window][Debug Window] -Pos=5,7 -Size=791,242 +Pos=5,8 +Size=791,273 Collapsed=0 +[Window][Primitives] +Pos=0,19 +Size=3440,103 +Collapsed=0 +DockId=0x00000001,0 + +[Window][Object Controls] +Pos=3046,124 +Size=394,1263 +Collapsed=0 +DockId=0x00000004,0 + +[Window][DockSpaceViewport_11111111] +Size=1920,1080 +Collapsed=0 + +[Window][DockSpace Demo] +Pos=0,0 +Size=3440,1387 +Collapsed=0 + +[Window][Dear ImGui Demo] +Pos=0,114 +Size=1553,966 +Collapsed=0 + +[Docking][Data] +DockSpace ID=0x3BC79352 Window=0x4647B76E Pos=0,19 Size=3440,1368 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=1508,975 CentralNode=1 + DockNode ID=0x00000004 Parent=0x00000002 SizeRef=394,975 Selected=0x3B5216D2 + diff --git a/imgui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj b/imgui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj index 2aa2550..a034943 100644 --- a/imgui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj +++ b/imgui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj @@ -21,34 +21,34 @@ {9CDA7840-B7A5-496D-A527-E95571496D18} example_glfw_opengl2 - 8.1 + 10.0 Application true MultiByte - v140 + v143 Application true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 diff --git a/imgui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj b/imgui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj index 4bd503a..b85d3c4 100644 --- a/imgui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj +++ b/imgui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj @@ -21,34 +21,34 @@ {4a1fb5ea-22f5-42a8-ab92-1d2df5d47fb9} example_glfw_opengl3 - 8.1 + 10.0 Application true MultiByte - v140 + v143 Application true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 diff --git a/imgui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj b/imgui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj index d0d1c5f..160d1a5 100644 --- a/imgui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj +++ b/imgui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj @@ -21,34 +21,34 @@ {57E2DF5A-6FC8-45BB-99DD-91A18C646E80} example_glfw_vulkan - 8.1 + 10.0 Application true MultiByte - v140 + v143 Application true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 diff --git a/imgui/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj b/imgui/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj index c23800c..bc6f223 100644 --- a/imgui/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj +++ b/imgui/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj @@ -21,7 +21,7 @@ {9E1987E3-1F19-45CA-B9C9-D31E791836D8} example_sdl2_directx11 - 8.1 + 10.0 example_sdl2_directx11 @@ -29,27 +29,27 @@ Application true MultiByte - v140 + v143 Application true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 diff --git a/imgui/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj b/imgui/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj index 036463f..d25c227 100644 --- a/imgui/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj +++ b/imgui/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj @@ -21,34 +21,34 @@ {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741} example_sdl2_opengl2 - 8.1 + 10.0 Application true MultiByte - v140 + v143 Application true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 diff --git a/imgui/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj b/imgui/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj index 6a81c67..eb6a21c 100644 --- a/imgui/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj +++ b/imgui/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj @@ -21,34 +21,34 @@ {BBAEB705-1669-40F3-8567-04CF6A991F4C} example_sdl2_opengl3 - 8.1 + 10.0 Application true MultiByte - v140 + v143 Application true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 diff --git a/imgui/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj b/imgui/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj index cf2c890..2f5638e 100644 --- a/imgui/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj +++ b/imgui/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj @@ -21,7 +21,7 @@ {0C0B2BEA-311F-473C-9652-87923EF639E3} example_sdl2_sdlrenderer2 - 8.1 + 10.0 example_sdl2_sdlrenderer2 @@ -29,27 +29,27 @@ Application true MultiByte - v140 + v143 Application true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 @@ -184,4 +184,4 @@ - + \ No newline at end of file diff --git a/imgui/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj b/imgui/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj index ba6afaf..a39b825 100644 --- a/imgui/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj +++ b/imgui/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj @@ -21,34 +21,34 @@ {BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3} example_sdl2_vulkan - 8.1 + 10.0 Application true MultiByte - v140 + v143 Application true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 Application false true MultiByte - v140 + v143 diff --git a/imgui/examples/example_win32_directx10/example_win32_directx10.vcxproj b/imgui/examples/example_win32_directx10/example_win32_directx10.vcxproj index d11aed8..cd645a7 100644 --- a/imgui/examples/example_win32_directx10/example_win32_directx10.vcxproj +++ b/imgui/examples/example_win32_directx10/example_win32_directx10.vcxproj @@ -21,34 +21,34 @@ {345A953E-A004-4648-B442-DC5F9F11068C} example_win32_directx10 - 8.1 + 10.0 Application true Unicode - v140 + v143 Application true Unicode - v140 + v143 Application false true Unicode - v140 + v143 Application false true Unicode - v140 + v143 diff --git a/imgui/examples/example_win32_directx11/example_win32_directx11.vcxproj b/imgui/examples/example_win32_directx11/example_win32_directx11.vcxproj index bace6a2..c6bef9e 100644 --- a/imgui/examples/example_win32_directx11/example_win32_directx11.vcxproj +++ b/imgui/examples/example_win32_directx11/example_win32_directx11.vcxproj @@ -27,27 +27,27 @@ Application true Unicode - v140 + v143 Application true Unicode - v140 + v143 Application false true Unicode - v140 + v143 Application false true Unicode - v140 + v143 diff --git a/imgui/examples/example_win32_directx12/example_win32_directx12.vcxproj b/imgui/examples/example_win32_directx12/example_win32_directx12.vcxproj index 7b64371..1f39a5e 100644 --- a/imgui/examples/example_win32_directx12/example_win32_directx12.vcxproj +++ b/imgui/examples/example_win32_directx12/example_win32_directx12.vcxproj @@ -21,34 +21,34 @@ {b4cf9797-519d-4afe-a8f4-5141a6b521d3} example_win32_directx12 - 10.0.18362.0 + 10.0 Application true Unicode - v140 + v143 Application true Unicode - v140 + v143 Application false true Unicode - v140 + v143 Application false true Unicode - v140 + v143 diff --git a/imgui/examples/example_win32_directx9/example_win32_directx9.vcxproj b/imgui/examples/example_win32_directx9/example_win32_directx9.vcxproj index 8c3f995..a8c3dd5 100644 --- a/imgui/examples/example_win32_directx9/example_win32_directx9.vcxproj +++ b/imgui/examples/example_win32_directx9/example_win32_directx9.vcxproj @@ -21,34 +21,34 @@ {4165A294-21F2-44CA-9B38-E3F935ABADF5} example_win32_directx9 - 8.1 + 10.0 Application true Unicode - v140 + v143 Application true Unicode - v140 + v143 Application false true Unicode - v140 + v143 Application false true Unicode - v140 + v143 diff --git a/imgui/examples/example_win32_opengl3/example_win32_opengl3.vcxproj b/imgui/examples/example_win32_opengl3/example_win32_opengl3.vcxproj index 98fc38f..d22ad19 100644 --- a/imgui/examples/example_win32_opengl3/example_win32_opengl3.vcxproj +++ b/imgui/examples/example_win32_opengl3/example_win32_opengl3.vcxproj @@ -21,34 +21,34 @@ {C624E5FF-D4FE-4D35-9164-B8A91864F98E} example_win32_opengl2 - 8.1 + 10.0 Application true Unicode - v140 + v143 Application true Unicode - v140 + v143 Application false true Unicode - v140 + v143 Application false true Unicode - v140 + v143 diff --git a/shaders/parade_fs.glsl b/shaders/parade_fs.glsl index cb6c47c..9460bcb 100644 --- a/shaders/parade_fs.glsl +++ b/shaders/parade_fs.glsl @@ -18,6 +18,11 @@ uniform vec3 ks; uniform float smoothing; uniform vec3 sphere_center; +const uint P_SPHERE = 0x00; +const uint P_TORUS = 0x01; +const uint P_CONE = 0x02; +const uint P_CUBE = 0x03; + struct GLSLPrimitive { vec4 position; @@ -25,109 +30,190 @@ struct GLSLPrimitive vec4 specular_color; vec4 ambient_color; - unsigned int specular_exponent; + uint specular_exponent; - unsigned int type; + uint type; float radius; float height; float inner_radius; float outer_radius; float size; + uint dummy; }; -layout(std430, binding = 0) buffer PrimitiveBuffer { +layout(std430, binding = 0) buffer PrimitiveBuffer +{ GLSLPrimitive primitives[]; }; out vec4 FragColor; -struct Torus +struct NormalEstimationData { - vec4 center; - float R; - float r; + vec3 normal; + float minDistance; + float secondMinDistance; + float smoothMinDistance; + GLSLPrimitive closestPrimitive; + GLSLPrimitive secondClosestPrimitive; }; -Torus torus; -struct Sphere + +float sphereSDF(vec3 p, vec3 center, float r) { - vec3 center; - float r; -}; - -Sphere sphere; - -void initTorus() -{ - torus.center = primitives[1].position; - torus.R = primitives[1].inner_radius; - torus.r = primitives[1].height; -} - -void initSphere() -{ - sphere.center = primitives[0].position.xyz; - sphere.r = primitives[0].radius; -} - -float sphereSDF(vec3 p, vec3 center, float r) { return length(p - center) - r; } -float torusSDF(vec3 p, vec4 center, float R, float r) { +float torusSDF(vec3 p, vec3 center, float R, float r) +{ vec2 q = vec2(length(p.xz - center.xz) - R, p.y - center.y); return length(q) - r; } -vec3 estimateNormalsSphere(vec3 p) +float coneSDF(vec3 p, vec3 center, float h, float r) { - float epsilon = 0.001; - float x = sphereSDF(vec3(p.x + epsilon, p.y, p.z), sphere.center, sphere.r) - sphereSDF(vec3(p.x - epsilon, p.y, p.z), sphere.center, sphere.r); - float y = sphereSDF(vec3(p.x, p.y + epsilon, p.z), sphere.center, sphere.r) - sphereSDF(vec3(p.x, p.y - epsilon, p.z), sphere.center, sphere.r); - float z = sphereSDF(vec3(p.x, p.y, p.z + epsilon), sphere.center, sphere.r) - sphereSDF(vec3(p.x, p.y, p.z - epsilon), sphere.center, sphere.r); - return normalize(vec3(x, y, z)); + vec2 d = abs(vec2(length(p.xz), p.y)) - vec2(r, h); + return length(d) < 0.0 ? max(d.x, -d.y) : length(max(d, vec2(0))); } -vec3 estimateNormalsTorus(vec3 p) +float cubeSDF(vec3 p, vec3 c, float s) { - float epsilon = 0.001; - float x = torusSDF(vec3(p.x + epsilon, p.y, p.z), torus.center, torus.R, torus.r) - torusSDF(vec3(p.x - epsilon, p.y, p.z), torus.center, torus.R, torus.r); - float y = torusSDF(vec3(p.x, p.y + epsilon, p.z), torus.center, torus.R, torus.r) - torusSDF(vec3(p.x, p.y - epsilon, p.z), torus.center, torus.R, torus.r); - float z = torusSDF(vec3(p.x, p.y, p.z + epsilon), torus.center, torus.R, torus.r) - torusSDF(vec3(p.x, p.y, p.z - epsilon), torus.center, torus.R, torus.r); - return normalize(vec3(x, y, z)); + float x = max(p.x - c.x - (s / 2.0), c.x - p.x - (s / 2.0)); + float y = max(p.y - c.y - (s / 2.0),c.y - p.y - (s / 2.0)); + float z = max(p.z - c.z - (s / 2.0),c.z - p.z - (s / 2.0)); + + float d = x; + d = max(d, y); + d = max(d, z); + + return d; } -float smoothMinSDF(float d1, float d2, float k) { +float sdf(vec3 pos, GLSLPrimitive prim) +{ + float d; + switch (prim.type) + { + case P_SPHERE: + { + d = sphereSDF(pos, prim.position.xyz, prim.radius); + break; + } + case P_TORUS: + { + d = torusSDF(pos, prim.position.xyz, prim.outer_radius, prim.inner_radius); + break; + } + case P_CONE: + { + d = coneSDF(pos, prim.position.xyz, prim.height, prim.radius); + break; + } + case P_CUBE: + { + d = cubeSDF(pos, prim.position.xyz, prim.size); + break; + } + default: + { + d = 0.0; + break; + } + } + return d; +} + +float smoothMinSDF(float d1, float d2, float k) +{ if (k == 0.0) k = 0.000001; float h = max(k - abs(d1 - d2), 0) / k; return min(d1, d2) - h * h * h * k * 1.0 / 6.0; } -float smoothMaxSDF(float d1, float d2, float k) { +float smoothMaxSDF(float d1, float d2, float k) +{ if (k == 0.0) k = 0.000001; float h = min(k - abs(d1 - d2), 0) / k; return min(d1, d2) - h * h * h * k * 1.0 / 6.0; } -vec3 estimateSmoothNormals(vec3 p, float smoothness) { - float epsilon = 0.001; - float d = smoothMinSDF(torusSDF(p, torus.center, torus.R, torus.r), sphereSDF(p, sphere.center, sphere.r), smoothness); - float nx = smoothMinSDF(torusSDF(vec3(p.x + epsilon, p.y, p.z), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x + epsilon, p.y, p.z), sphere.center, sphere.r), smoothness) - d; - float ny = smoothMinSDF(torusSDF(vec3(p.x, p.y + epsilon, p.z), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x, p.y + epsilon, p.z), sphere.center, sphere.r), smoothness) - d; - float nz = smoothMinSDF(torusSDF(vec3(p.x, p.y, p.z + epsilon), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x, p.y, p.z + epsilon), sphere.center, sphere.r), smoothness) - d; - return normalize(vec3(nx, ny, nz)); -} -vec3 estimateNormalsMax(vec3 p, float smoothness) { - float epsilon = 0.001; - float d = max(torusSDF(p, torus.center, torus.R, torus.r), sphereSDF(p, sphere.center, sphere.r)); - float nx = max(torusSDF(vec3(p.x + epsilon, p.y, p.z), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x + epsilon, p.y, p.z), sphere.center, sphere.r)) - d; - float ny = max(torusSDF(vec3(p.x, p.y + epsilon, p.z), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x, p.y + epsilon, p.z), sphere.center, sphere.r)) - d; - float nz = max(torusSDF(vec3(p.x, p.y, p.z + epsilon), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x, p.y, p.z + epsilon), sphere.center, sphere.r)) - d; - return normalize(vec3(nx, ny, nz)); +void estimateSmoothNormals(vec3 p, float smoothness, float epsilon, inout vec3 normals, inout vec4 color) +{ + 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]); + + float blendFactor = clamp(0.5 + 0.5 * (sdf(p, primitives[0]) - sdf(p, primitives[1])) / smoothness, 0.0, 1.0); + vec4 blendedColor = mix(primitives[0].diffuse_color, primitives[1].diffuse_color, blendFactor); + + blendFactor = clamp(0.5 + 0.5 * (sdf(p, primitives[1]) - sdf(p, primitives[2])) / smoothness, 0.0, 1.0); + vec4 blendedColor1 = mix(primitives[1].diffuse_color, primitives[2].diffuse_color, blendFactor); + + blendFactor = clamp(0.5 + 0.5 * (sdf(p, primitives[2]) - sdf(p, primitives[0])) / smoothness, 0.0, 1.0); + vec4 blendedColor2 = mix(primitives[2].diffuse_color, primitives[0].diffuse_color, blendFactor); + + vec4 blendedColor3 = mix(blendedColor, blendedColor1, blendFactor); + vec4 blendedColor4 = mix(blendedColor3, blendedColor2, blendFactor); + + + for (int i = 1; i < primitives.length(); i++) + { + 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); + + /*blendFactor = clamp(0.5 + 0.5 * (sdf(p, primitives[i-1]) - sdf(p, primitives[i])) / smoothness, 0.0, 1.0); + blendedColor = mix(primitives[i-1].diffuse_color, primitives[i].diffuse_color, blendFactor);*/ + } + nx -= d; + ny -= d; + nz -= d; + + normals = normalize(vec3(nx, ny, nz)); + //color = blendedColor4; } +vec3 estimateNormals(vec3 p, GLSLPrimitive prim, float epsilon) +{ + float x = sdf(vec3(p.x + epsilon, p.y, p.z), prim) - sdf(vec3(p.x - epsilon, p.y, p.z), prim); + float y = sdf(vec3(p.x, p.y + epsilon, p.z), prim) - sdf(vec3(p.x, p.y - epsilon, p.z), prim); + float z = sdf(vec3(p.x, p.y, p.z + epsilon), prim) - sdf(vec3(p.x, p.y, p.z - epsilon), prim); + return normalize(vec3(x, y, z)); +} + +//vec3 estimateNormalsMax(vec3 p, float smoothness) { +// float epsilon = 0.001; +// float d = max(torusSDF(p, torus.center, torus.R, torus.r), sphereSDF(p, sphere.center, sphere.r)); +// float nx = max(torusSDF(vec3(p.x + epsilon, p.y, p.z), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x + epsilon, p.y, p.z), sphere.center, sphere.r)) - d; +// float ny = max(torusSDF(vec3(p.x, p.y + epsilon, p.z), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x, p.y + epsilon, p.z), sphere.center, sphere.r)) - d; +// float nz = max(torusSDF(vec3(p.x, p.y, p.z + epsilon), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x, p.y, p.z + epsilon), sphere.center, sphere.r)) - d; +// return normalize(vec3(nx, ny, nz)); +//} + +vec4 blendColors(vec4 color1, vec4 color2, float blendFactor) +{ + return mix(color1, color2, blendFactor); +} + +float weightFunction(float distance, float k, float epsilon) { + //// Ensure 'k' is positive to avoid division by zero. + //k = max(k, 0.0001); + //// Sigmoid-like smooth transition function. + //return (k*k*k)/distance; + + if (k <= 0.0) { + // When k is zero, return 1 if the distance is zero (object is closest), else return 0. + return distance <= 0.001 ? 1.0 : 0.0; + } + else { + // As k increases, the transition becomes smoother. + return (k * k * k) / distance; + } +} void main(void) { @@ -143,10 +229,6 @@ void main(void) int spec_exponent = 40; float k = smoothing; - - initSphere(); - initTorus(); - 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); cam_dir /= cam_dir.w; @@ -154,23 +236,56 @@ void main(void) vec4 ray_dir = normalize(inverse(V) * cam_dir); + vec4 accumulatedColor = vec4(0.0); + float totalWeight = 0.0; + + int closestIndex = -1; + int secClosestIndex = -1; + while (ray_dist < max_dist && steps < max_steps) { steps++; - float distTorus = torusSDF(ray_pos.xyz, torus.center, torus.R, torus.r); - float distSphere = sphereSDF(ray_pos.xyz, sphere.center, sphere.r); - float minDist = smoothMinSDF(distTorus, distSphere, k); + float minDist = 999999.0; + + for (int i = 0; i < primitives.length(); i++) + { + float dist = sdf(ray_pos.xyz, primitives[i]); + float weight = weightFunction(dist, smoothing, epsilon); + if (dist < sdf(ray_pos.xyz, primitives[closestIndex])) + { + secClosestIndex = closestIndex; + closestIndex = i; + } + /*else if (dist < sdf(ray_pos.xyz, primitives[secClosestIndex])) + { + secClosestIndex = i; + }*/ + minDist = smoothMinSDF(minDist, dist, k); + + accumulatedColor += primitives[i].diffuse_color * weight; + totalWeight += weight; + } + + if (minDist <= epsilon) { + if (totalWeight > 0.0) { + accumulatedColor /= totalWeight; + } + vec4 ambient_color, diffuse_color; - ambient_color = primitives[0].ambient_color; - diffuse_color = primitives[0].diffuse_color; + float blendFactor = clamp(0.5 + 0.5 * (sdf(ray_pos.xyz, primitives[closestIndex]) - sdf(ray_pos.xyz, primitives[secClosestIndex])) / k, 0.0, 1.0); + vec4 blendedColor = mix(primitives[closestIndex].diffuse_color, primitives[secClosestIndex].diffuse_color, blendFactor); + + ambient_color = primitives[closestIndex].ambient_color; + diffuse_color = vec4(accumulatedColor.rgb, 1.0); vec4 ambient = vec4(la, 1.0) * ambient_color; - normals = estimateSmoothNormals(ray_pos.xyz, k); + //normals = estimateNormals(ray_pos.xyz, primitives[closestIndex], epsilon); + estimateSmoothNormals(ray_pos.xyz, k, epsilon, normals, diffuse_color); vec3 nw = normalize(normals); vec3 lw = normalize(light_pos - ray_pos.xyz); @@ -183,7 +298,7 @@ void main(void) vec3 halfwayDir = normalize(lw + vw); spec = pow(max(dot(halfwayDir, nw), 0), spec_exponent); - vec4 specular = spec * vec4(primitives[0].specular_color.rgb * ls, 1.0); + vec4 specular = spec * vec4(primitives[closestIndex].specular_color.rgb * ls, 1.0); color = (ambient + (1.0 / (dist * dist) * (diffuse + specular))).xyz; break; diff --git a/src/Application.cpp b/src/Application.cpp index 000a70b..49d1827 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -27,20 +27,23 @@ struct Primitive { - glm::vec4 position = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); - glm::vec4 diffuse_color = glm::vec4(0.8f, 0.8f, 0.8f, 1.0f); - glm::vec4 specular_color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); - glm::vec4 ambient_color = glm::vec4(0.2f, 0.2f, 0.2f, 1.0f); + glm::vec4 position = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); // 16 bytes + glm::vec4 diffuse_color = glm::vec4(0.8f, 0.8f, 0.8f, 1.0f); // 16 bytes + glm::vec4 specular_color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); // 16 bytes + glm::vec4 ambient_color = glm::vec4(0.2f, 0.2f, 0.2f, 1.0f); // 16 bytes - unsigned int specular_exponent = 40; + unsigned int specular_exponent = 40; // 4 bytes - unsigned int type = -1; + unsigned int type = -1; // 4 bytes - float radius = -1.f; - float height = -1.f; - float inner_radius = -1.f; - float outer_radius = -1.f; - float size = -1.f; + float radius = -1.f; // 4 bytes + float height = -1.f; // 4 bytes + float inner_radius = -1.f; // 4 bytes + float outer_radius = -1.f; // 4 bytes + float size = -1.f; // 4 bytes + + // Has to be a multiple of 32 bytes (96 in this case), currently only 92 + unsigned int dummy = 0; // 4 bytes }; struct Light @@ -93,6 +96,7 @@ namespace scene glm::vec3 sphere_center = { 0.0, 0.0, 0.0 }; unsigned int p_vbo = -1; + int object = 0; } namespace mouse @@ -126,6 +130,10 @@ static char* ReadShaderSource(const char* shaderFile) void AddPrimitive(Primitive newPrim) { + for (int i = 0; i < scene::primitiveData.size(); i++) + { + if (newPrim.type == scene::primitiveData[i].type) newPrim.dummy++; + } scene::primitiveData.push_back(newPrim); } @@ -208,16 +216,161 @@ void InitCanvas() } +std::string GetName(Primitive prim) +{ + std::string name; + + switch (prim.type) + { + case 0x00: + { + name = "Sphere"; + break; + } + case 0x01: + { + name = "Torus"; + break; + } + case 0x02: + { + name = "Cone"; + break; + } + case 0x03: + { + name = "Cube"; + break; + } + default: + { + name = "Primitive"; + break; + } + } + + if (prim.dummy > 0) name += "_" + std::to_string(prim.dummy); + + return name; +} + +void PrimGUI(unsigned int obj) +{ + ImGui::SliderFloat3("Position", glm::value_ptr(scene::primitiveData[obj].position), -2.0f, 2.0f); + + switch (scene::primitiveData[obj].type) + { + case 0x00: + { + ImGui::SliderFloat("Radius", &scene::primitiveData[obj].radius, 0.f, 5.0f); + break; + } + case 0x01: + { + ImGui::SliderFloat("Outer Radius", &scene::primitiveData[obj].outer_radius, 0.f, 5.0f); + ImGui::SliderFloat("Inner Radius", &scene::primitiveData[obj].inner_radius, 0.f, 5.0f); + break; + } + case 0x02: + { + break; + } + case 0x03: + { + ImGui::SliderFloat("Size", &scene::primitiveData[obj].size, 0.f, 5.0f); + break; + } + default: + { + break; + } + } + + ImGui::Separator(); + ImGui::ColorEdit3("Diffuse", glm::value_ptr(scene::primitiveData[obj].diffuse_color)); + ImGui::ColorEdit3("Specular", glm::value_ptr(scene::primitiveData[obj].specular_color)); + ImGui::ColorEdit3("Ambient", glm::value_ptr(scene::primitiveData[obj].ambient_color)); +} + +void AddSphere() +{ + Primitive s; + s.type = P_SPHERE; + s.radius = 0.5f; + AddPrimitive(s); +} +void AddTorus() +{ + Primitive t; + t.type = P_TORUS; + t.outer_radius = 0.5f; + t.inner_radius = 0.15f; + AddPrimitive(t); +} +void AddCube() +{ + Primitive c; + c.type = P_CUBE; + c.size = 0.5f; + AddPrimitive(c); +} + //Draw the ImGui user interface void draw_gui(GLFWwindow* window) -{ +{ //Begin ImGui Frame ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); + + + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + ImGui::NewFrame(); + static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode; + + // We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into, + // because it would be confusing to have two docking targets within each others. + ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; + + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(viewport->WorkPos); + ImGui::SetNextWindowSize(viewport->WorkSize); + ImGui::SetNextWindowViewport(viewport->ID); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); + window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; + window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; + window_flags |= ImGuiWindowFlags_NoBackground; + + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); + ImGui::Begin("DockSpace Demo", nullptr, window_flags); + ImGui::PopStyleVar(3); + + // Submit the DockSpace + if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) + { + ImGuiID dockspace_id = ImGui::GetID("MyDockSpace"); + ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags); + } + + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("Options")) + { + ImGui::Text("Nothing Here Yet, Check Back Later!"); + + ImGui::EndMenu(); + } + + ImGui::EndMenuBar(); + } + + ImGui::End(); + //Draw Gui - ImGui::Begin("Debug Window"); + ImGui::Begin("Object Controls"); if (ImGui::Button("Quit")) { glfwSetWindowShouldClose(window, GLFW_TRUE); @@ -226,18 +379,32 @@ void draw_gui(GLFWwindow* window) ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::SliderFloat("Smoothing", &scene::smoothing, 0.0f, 1.0f); - ImGui::SliderFloat4("Position Sphere", glm::value_ptr(scene::primitiveData[0].position), -2.0f, 2.0f); - ImGui::SliderFloat4("Position Torus", glm::value_ptr(scene::primitiveData[1].position), -2.0f, 2.0f); - ImGui::SliderFloat4("Position Cone", glm::value_ptr(scene::primitiveData[2].position), -2.0f, 2.0f); - - ImGui::End(); - - static bool show_test = false; - if (show_test) + for (int i = 0; i < scene::primitiveData.size(); i++) { - ImGui::ShowDemoWindow(&show_test); + ImGui::RadioButton(GetName(scene::primitiveData[i]).c_str(), &scene::object, i); } - + + PrimGUI(scene::object); + ImGui::End(); + + ImGui::Begin("Primitives"); + if (ImGui::Button("Sphere", ImVec2(ImGui::GetWindowSize().y * 0.5f, ImGui::GetWindowSize().y * 0.5f))) + { + AddSphere(); + InitPrimitive(); + }ImGui::SameLine(); + if (ImGui::Button("Torus", ImVec2(ImGui::GetWindowSize().y * 0.5f, ImGui::GetWindowSize().y * 0.5f))) + { + AddTorus(); + InitPrimitive(); + }ImGui::SameLine(); + if (ImGui::Button("Cube", ImVec2(ImGui::GetWindowSize().y * 0.5f, ImGui::GetWindowSize().y * 0.5f))) + { + AddCube(); + InitPrimitive(); + } + ImGui::End(); + //End ImGui Frame ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); @@ -421,7 +588,6 @@ void init() glUseProgram(scene::shader); Primitive sphere; - //sphere.position = glm::vec4(0.0f, -1.0f, 0.0f, 1.0f); sphere.diffuse_color = glm::vec4(0.f, 66.f / 255.f, 37.f / 255.f, 1.0f); sphere.type = P_SPHERE; sphere.radius = 0.25f; @@ -438,10 +604,20 @@ void init() cone.height = 0.5f; cone.radius = 0.25f; + Primitive cube; + cube.diffuse_color = glm::vec4(255.f / 255.f, 176.f / 255.f, 0.f, 1.0f); + cube.type = P_CUBE; + cube.size = 0.5f; + + Primitive sphere2; + sphere2.diffuse_color = glm::vec4(1.f, 0.f, 1.f, 1.0f); + sphere2.type = P_SPHERE; + sphere2.radius = 0.25f; + AddPrimitive(sphere); AddPrimitive(torus); - AddPrimitive(cone); - //AddPrimitive(sphere); + AddPrimitive(cube); + AddPrimitive(sphere2); InitCanvas(); InitPrimitive();