Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
EmaMaker | c035f424ab | |
EmaMaker | cae049b4a2 | |
EmaMaker | cf7c239bf0 | |
EmaMaker | 2257ba44de | |
EmaMaker | f2fd40da00 |
|
@ -89,7 +89,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
glm::vec3 cameraPos = glm::vec3(10.0f, 0.0f, 0.0f);
|
||||
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 10.0f);
|
||||
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, 1.0f);
|
||||
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
glm::vec3 direction = glm::vec3(0.0f, 0.0f, 1.0f);
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
#version 330 core
|
||||
|
||||
uniform vec2 u_resolution;
|
||||
uniform float u_time;
|
||||
uniform float u_deltatime;
|
||||
uniform vec3 u_camorigin;
|
||||
uniform vec3 u_camdir;
|
||||
uniform vec3 u_camup;
|
||||
out vec4 FragColor;
|
||||
|
||||
|
||||
// START OF LIGHTNING
|
||||
float ambientStrength = 0.20;
|
||||
float specularStrength = 0.5;
|
||||
vec3 lightColor = vec3(1.0);
|
||||
vec3 ambient = lightColor * ambientStrength;
|
||||
vec3 lightPos = vec3(5.0);
|
||||
// END OF LIGHTNING
|
||||
|
||||
|
||||
struct Phong{
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
float shininess;
|
||||
|
||||
float sdf;
|
||||
} phong;
|
||||
|
||||
// START OF SDFs
|
||||
phong sdfSphere(in phong color, in vec3 point, in vec3 center, float r)
|
||||
{
|
||||
color.sdf = length(point - center) - r;
|
||||
return color;
|
||||
}
|
||||
|
||||
phong sdfBox(in phong color, in vec3 point, in vec3 center, in vec3 b){
|
||||
vec3 q = abs(point - center) - b;
|
||||
phong.sdf = length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0));
|
||||
return color;
|
||||
}
|
||||
|
||||
phong opUnion( phong d1, phong d2 ) {
|
||||
if(d1.sdf < d2.sdf) return d1;
|
||||
else return d2;
|
||||
}
|
||||
|
||||
phong phongSphere = phong(vec3(1.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), ambient, 32.0, 0.0);
|
||||
phong phongBox1 = phong(vec3(0.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0), ambient, 32.0, 0.0);
|
||||
phong phongBox2 = phong(vec3(0.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0), ambient, 32.0, 0.0);
|
||||
|
||||
phong sdfScene(in vec3 p){
|
||||
return opUnion(
|
||||
opUnion(
|
||||
sdfSphere(phongSphere, p, vec3(0.0), 1),
|
||||
sdfBox(phongBox1, p, vec3(2.0, 0.0, 0.0), vec3(0.8))
|
||||
),
|
||||
sdfBox(phongBox2, p, vec3(-5.0, 0.0, 0.0), vec3(2.0, 1.0, 0.5))
|
||||
);
|
||||
}
|
||||
// END OF SDFs
|
||||
|
||||
vec3 sceneNormal(in vec3 p){
|
||||
vec3 smallstep = vec3(0.00001, 0.0, 0.0);
|
||||
float dist = sdfScene(p).sdf;
|
||||
|
||||
float gradient_x = sdfScene(p.xyz + smallstep.xyy).sdf - dist;
|
||||
float gradient_y = sdfScene(p.xyz + smallstep.yxy).sdf - dist;
|
||||
float gradient_z = sdfScene(p.xyz + smallstep.yyx).sdf - dist;
|
||||
|
||||
return normalize(vec3(gradient_x, gradient_y, gradient_z));
|
||||
}
|
||||
|
||||
|
||||
vec3 ray_march(in vec3 ro, in vec3 rd)
|
||||
{
|
||||
float total_dist = 0.0;
|
||||
vec3 pos;
|
||||
|
||||
for(int i = 0; i < 100; i++){
|
||||
// incrementally travel following the ray
|
||||
pos = ro + rd * total_dist;
|
||||
|
||||
// calculate distance from scene
|
||||
phong dist = sdfScene(pos);
|
||||
|
||||
// if close to the scene, color the pixel as needed
|
||||
if(dist.sdf <= 0.001){
|
||||
// Basic Phong illumination
|
||||
// diffuse
|
||||
lightDir = normalize(lightPos - pos);
|
||||
float diff = max(dot(sceneNormal(pos), lightDir), 0.0);
|
||||
vec3 diffuse = diff * dist.diffuse;
|
||||
|
||||
// specular
|
||||
vec3 viewDir = normalize(u_camorigin - pos);
|
||||
vec3 reflectDir = reflect(-lightDir, sceneNormal(pos));
|
||||
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
|
||||
vec3 specular = dist.shininess * spec * dist.specular;
|
||||
|
||||
return (dist.ambient + diffuse + specular) * dist.ambient;
|
||||
}
|
||||
|
||||
// increment distance by the highest possible value (sphere marching)
|
||||
total_dist += dist.sdf;
|
||||
|
||||
// if too far out, bail out
|
||||
if(total_dist > 1000) break;
|
||||
|
||||
}
|
||||
|
||||
// no hit, return background color
|
||||
return vec3(0.0);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// ray direction on canvas, normalized
|
||||
vec2 uv = (gl_FragCoord.xy/u_resolution) * 2 - 1;
|
||||
uv.x *= u_resolution.x/u_resolution.y; //account for aspect ratio
|
||||
|
||||
// https://github.com/electricsquare/raymarching-workshop
|
||||
vec3 camright = normalize(cross(u_camdir, u_camup));
|
||||
float fPersp=tan(radians(70.0));
|
||||
|
||||
// recompute the up vector, in case the camera diverges a lot from u_camup. This avoids weird distortions when looking up or down
|
||||
vec3 camup = normalize(cross(camright, u_camdir));
|
||||
|
||||
vec3 rd = normalize(uv.x * camright + uv.y * camup + u_camdir * fPersp);
|
||||
|
||||
vec3 shaded_color = ray_march(u_camorigin, rd);
|
||||
gl_FragColor = vec4(shaded_color, 1.0);
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#version 330 core
|
||||
|
||||
in vec2 fragcoord;
|
||||
|
||||
uniform vec2 u_resolution;
|
||||
uniform float u_time;
|
||||
uniform float u_deltatime;
|
||||
|
@ -14,124 +16,43 @@ vec3 box1Color = vec3(0.0, 1.0, 0.0);
|
|||
vec3 box2Color = vec3(0.0, 0.0, 1.0);
|
||||
vec3 boxLightColor = vec3( 1.0);
|
||||
|
||||
// START OF LIGHTNING
|
||||
vec3 lightColor = vec3(1.0);
|
||||
vec3 lightPos = vec3(5.0);
|
||||
vec3 lightDir;
|
||||
// END OF LIGHTNING
|
||||
|
||||
struct phongdata{
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
float shininess;
|
||||
};
|
||||
|
||||
struct phong{
|
||||
phongdata data;
|
||||
float sdf;
|
||||
};
|
||||
|
||||
phongdata phongSphere = phongdata(vec3(1.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), 256.0);
|
||||
phongdata phongBox1 = phongdata(vec3(0.0, 1.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, 1.0, 0.0), 32.0);
|
||||
phongdata phongBox2 = phongdata(vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, 1.0), 32.0);
|
||||
phongdata phongLightBox = phongdata(lightColor, lightColor, lightColor, 256.0);
|
||||
|
||||
// START OF SDFs
|
||||
float sdfSphere(in vec3 point, in vec3 center, float r)
|
||||
{
|
||||
return length(point - center) - r;
|
||||
}
|
||||
|
||||
float sdfBox(in vec3 point, in vec3 center, in vec3 b){
|
||||
vec3 q = abs(point - center) - b;
|
||||
float sdfBox(in vec3 point, in vec3 b){
|
||||
vec3 q = abs(point) - b;
|
||||
return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
|
||||
}
|
||||
|
||||
phong opUnion( phong d1, phong d2 ) {
|
||||
if(d1.sdf < d2.sdf) return d1;
|
||||
else return d2;
|
||||
float opUnion( float d1, float d2 ) { return min(d1,d2); }
|
||||
|
||||
vec3 opFiniteRepeat(in vec3 pos, in vec3 start, in vec3 reps, in vec3 replength){
|
||||
vec3 m = mod(reps, 2); // 0 if even, 1 if odd
|
||||
vec3 m1 = vec3(1.0) - m; //1 if even , 0 if odd
|
||||
|
||||
vec3 s = vec3(start+0.5*m1*replength);
|
||||
|
||||
vec3 d = round((pos-s) / replength);
|
||||
|
||||
vec3 r1 = (reps-m)*0.5;
|
||||
vec3 r = clamp(d, -r1, r1 - m1 ); //m - vec3(1.0) should be the same;
|
||||
|
||||
return pos-s-r*replength;
|
||||
}
|
||||
|
||||
phong opSmoothUnion( phong d1, phong d2, float k ) {
|
||||
float h = clamp( 0.5 + 0.5*(d2.sdf-d1.sdf)/k, 0.0, 1.0 );
|
||||
float m = (d1.sdf + d2.sdf) / 2.0;
|
||||
|
||||
phongdata data;
|
||||
data.ambient = mix(d2.data.ambient, d1.data.ambient, h) - vec3(k*h*(1.0-h));
|
||||
data.diffuse = mix(d2.data.diffuse, d1.data.diffuse, h) - vec3(k*h*(1.0-h));
|
||||
data.specular = mix(d2.data.specular, d1.data.specular, h) - vec3(k*h*(1.0-h));
|
||||
data.shininess = mix( d2.data.shininess, d1.data.shininess, h ) - k*h*(1.0-h);
|
||||
phong ret = phong(data, mix( d2.sdf, d1.sdf, h ) - k*h*(1.0-h));
|
||||
|
||||
return ret;
|
||||
float sdfScene(in vec3 p){
|
||||
return opUnion( sdfSphere(p, vec3(0.0), 1), sdfBox(opFiniteRepeat(p, vec3(0.0), vec3(2.0, 3.0, 5.0), vec3(3.0+1.0+sin(u_time))), vec3(0.8)));
|
||||
}
|
||||
|
||||
phong opIntersection( phong d1, phong d2 ) {
|
||||
if(d1.sdf < d2.sdf) return d2;
|
||||
else return d1;
|
||||
}
|
||||
|
||||
// from d2 substract d1
|
||||
phong opDifference( phong d1, phong d2 ) {
|
||||
if(-d1.sdf > d2.sdf) {
|
||||
d1.sdf *= -1;
|
||||
return d1;
|
||||
}
|
||||
else return d2;
|
||||
}
|
||||
|
||||
vec3 s = vec3(0.0);
|
||||
vec3 r = vec3(3.0, 5.0, 2.0);
|
||||
vec3 rl = vec3(2.0, 1.0, 3.0);
|
||||
vec3 l = r*rl*0.5;
|
||||
|
||||
phong sdfScene(in vec3 p){
|
||||
return opUnion(
|
||||
opUnion(
|
||||
opUnion(
|
||||
opUnion(
|
||||
phong(phongSphere, sdfSphere(p, vec3(0.0), 1)),
|
||||
phong(phongBox1, sdfBox(p, vec3(2.0, 0.0, 0.0), vec3(0.8)))
|
||||
),
|
||||
opUnion(
|
||||
opDifference(
|
||||
phong(phongBox1, sdfBox(p, vec3(-3.5, 3.5, 0.0), vec3(0.5))),
|
||||
phong(phongSphere, sdfSphere(p, vec3(-4.0, 4.0, 0.0), 1))
|
||||
),
|
||||
opDifference(
|
||||
phong(phongSphere, sdfSphere(p, vec3(-4.0, 8.0, 0.0), 0.75+ 0.25 * (1+sin(2*u_time)))),
|
||||
phong(phongBox1, sdfBox(p, vec3(-4.0, 8.0, 0.0), vec3(0.8)))
|
||||
)
|
||||
)
|
||||
),
|
||||
opUnion(
|
||||
opIntersection(
|
||||
phong(phongSphere, sdfSphere(p, vec3(0.0, 4.0, 0.0), 1)),
|
||||
phong(phongBox1, sdfBox(p, vec3(0.0, 4.5, 0.0), vec3(1)))
|
||||
),
|
||||
opSmoothUnion(
|
||||
phong(phongBox2, sdfBox(p, vec3(0.0, 0.0, 6.0), vec3(3.0, 0.2, 3.0)) ),
|
||||
phong(phongSphere, sdfSphere(p, vec3(0.0, 1.0+sin(u_time), 6.0), 1)),
|
||||
0.5
|
||||
)
|
||||
)
|
||||
),
|
||||
opUnion(
|
||||
phong(phongBox2, sdfBox(p, vec3(5.0, 0.0, 0.0), vec3(2.0, 1.0, 0.5))),
|
||||
phong(phongLightBox, sdfBox(p, lightPos, vec3(0.1)))
|
||||
)
|
||||
);
|
||||
}
|
||||
// END OF SDFs
|
||||
|
||||
vec3 sceneNormal(in vec3 p){
|
||||
vec3 smallstep = vec3(0.00001, 0.0, 0.0);
|
||||
float sdf = sdfScene(p).sdf;
|
||||
vec3 smallstep = vec3(0.0001, 0.0, 0.0);
|
||||
|
||||
float gradient_x = sdfScene(p.xyz + smallstep.xyy).sdf - sdf;
|
||||
float gradient_y = sdfScene(p.xyz + smallstep.yxy).sdf - sdf;
|
||||
float gradient_z = sdfScene(p.xyz + smallstep.yyx).sdf - sdf;
|
||||
float gradient_x = sdfScene(p.xyz + smallstep.xyy) - sdfScene(p.xyz - smallstep.xyy);
|
||||
float gradient_y = sdfScene(p.xyz + smallstep.yxy) - sdfScene(p.xyz - smallstep.yxy);
|
||||
float gradient_z = sdfScene(p.xyz + smallstep.yyx) - sdfScene(p.xyz - smallstep.yyx);
|
||||
|
||||
return normalize(vec3(gradient_x, gradient_y, gradient_z));
|
||||
}
|
||||
|
@ -141,43 +62,18 @@ vec3 ray_march(in vec3 ro, in vec3 rd)
|
|||
float total_dist = 0.0;
|
||||
vec3 pos;
|
||||
|
||||
for(int i = 0; i < 100; i++){
|
||||
// incrementally travel following the ray
|
||||
for(int i = 0; i < 35; i++){
|
||||
pos = ro + rd * total_dist;
|
||||
|
||||
// calculate distance from scene
|
||||
phong dist = sdfScene(pos);
|
||||
|
||||
// if close to the scene, color the pixel as needed
|
||||
if(dist.sdf <= 0.001){
|
||||
// Basic Phong illumination
|
||||
// ambient
|
||||
vec3 ambient = lightColor*dist.data.ambient;
|
||||
float dist = sdfScene(pos);
|
||||
|
||||
// diffuse
|
||||
lightDir = normalize(lightPos - pos);
|
||||
float diff = max(dot(sceneNormal(pos), lightDir), 0.0);
|
||||
vec3 diffuse = diff * dist.data.diffuse;
|
||||
|
||||
// specular
|
||||
vec3 viewDir = normalize(u_camorigin - pos);
|
||||
vec3 reflectDir = reflect(-lightDir, sceneNormal(pos));
|
||||
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), dist.data.shininess);
|
||||
vec3 specular = lightColor * spec * dist.data.specular;
|
||||
|
||||
return (vec3(0.1) * ambient + vec3(0.45) * diffuse +vec3(0.45) * specular);
|
||||
if(dist <= 0.001){
|
||||
return (sceneNormal(pos) * 0.5 + 0.5);
|
||||
}
|
||||
|
||||
// increment distance by the highest possible value (sphere marching)
|
||||
total_dist += dist.sdf;
|
||||
|
||||
// if too far out, bail out
|
||||
if(total_dist > 1000) break;
|
||||
total_dist += dist;
|
||||
if(total_dist > 4000) break;
|
||||
|
||||
}
|
||||
|
||||
// no hit, return background color
|
||||
return vec3(0.0);
|
||||
}
|
||||
|
||||
|
@ -197,5 +93,5 @@ void main()
|
|||
vec3 rd = normalize(uv.x * camright + uv.y * camup + u_camdir * fPersp);
|
||||
|
||||
vec3 shaded_color = ray_march(u_camorigin, rd);
|
||||
FragColor = vec4(shaded_color, 1.0);
|
||||
gl_FragColor = vec4(shaded_color, 1.0);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ int main()
|
|||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
|
||||
|
||||
/* create window */
|
||||
GLFWwindow *window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
|
||||
if (window == NULL)
|
||||
|
@ -48,8 +47,6 @@ int main()
|
|||
return -1;
|
||||
}
|
||||
|
||||
std::cout << "Using GPU: " << glGetString(GL_VENDOR) << " " << glGetString(GL_RENDERER) << "\n";
|
||||
|
||||
glViewport(0, 0, 800, 600);
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
|
|
Loading…
Reference in New Issue