Can now add lights

This commit is contained in:
Jack Christensen 2023-12-07 17:10:20 -05:00
parent fb891fa274
commit 5e2ae73649
3 changed files with 85 additions and 142 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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();