MandelBulb-Python/mandelbulb/resources/programs/fragment.glsl
2022-08-19 19:28:22 +02:00

175 lines
4.7 KiB
GLSL

#version 330 core
#include hg_sdf.glsl
layout (location = 0) out vec4 fragColor;
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
uniform vec3 ro;
uniform mat3 cam;
const float FOV = 2;
const int MAX_STEPS = 256;
const float MAX_DIST = 500;
const float EPSILON = 0.0005;
const float DIST_CAM = 2;
float packColor(vec3 color) {
return color.r + color.g * 256.0 + color.b * 256.0 * 256.0;
}
vec3 unpackColor(float f) {
vec3 color;
color.b = floor(f / 256.0 / 256.0);
color.g = floor((f - color.b * 256.0 * 256.0) / 256.0);
color.r = floor(f - color.b * 256.0 * 256.0 - color.g * 256.0);
// now we have a vec3 with the 3 components in range [0..255]. Let's normalize it!
return color / 255.0;
}
vec3 fOpUnionChamferId(vec3 res1, vec3 res2, float r) {
float a = res1.x;
float b = res2.x;
return vec3(min(min(a, b), (a - r + b)*sqrt(0.5)), res1.yz);
}
vec3 fOpDifferenceId(vec3 res1, vec3 res2) {
return (res1.x > -res2.x) ? res1 : vec3(-res2.x, res2.yz);
}
vec3 fOpUnionId(in vec3 res1, in vec3 res2){
return (res1.x < res2.x) ? res1 : res2;
}
vec3 map(in vec3 p){
//pMod3(p, vec3(10.0));
float planeId = 1;
float planeColor = packColor(vec3(50, 50, 50));
float planeDist = fPlane(p, vec3(0, 1, 0), 1.0);
vec3 plane = vec3(planeDist, planeColor, planeId);
float sphereId = 2;
float sphereColor = packColor(vec3(200, 0, 0));
vec3 spherePos = vec3(2.0, 0.0, 0.0);
float sphereDist = fSphere(p-spherePos, 1);
vec3 sphere = vec3(sphereDist, sphereColor, sphereId);
float playerId = 3;
float playerColor = packColor(vec3(0, 200, 0));;
vec3 playerPos = ro+vec3(0, -1, DIST_CAM);
float playerDist = fCapsule(p-playerPos, 0.2, 0.2);
vec3 player = vec3(playerDist, playerColor, playerId);
float mandelBulbId = 3;
float mandelBulbColor = packColor(vec3(50, 50, 50));;
float mandelBulbDist = fmandelBulbe(p);;
vec3 mandelBulb = vec3(mandelBulbDist, mandelBulbColor, mandelBulbId);;
//vec3 res = fOpUnionId(plane, sphere);
vec3 res = mandelBulb;
//res = fOpUnionId(res, mandelBulb);
return res;
}
vec4 rayMarch(vec3 ro, vec3 rd) {
vec3 hit = vec3(0.0);
vec3 object = vec3(0.0);
vec3 p = vec3(0.0);
float compt = 0;
for (float i = 0; i < MAX_STEPS; i++) {
p = ro + object.x * rd;
hit = map(p);
object.x += hit.x;
object.yz = hit.yz;
if (hit.z == 2 || hit.z == 3) compt += 1;
if (abs(hit.x) < EPSILON || object.x > MAX_DIST){
if (hit.z != 2) return vec4(object, compt);
return vec4(object, 0);
}
}
return vec4(object, compt);
}
vec3 getNormal(vec3 p) {
vec2 e = vec2(EPSILON, 0.0);
vec3 n = vec3(map(p).x) - vec3(map(p - e.xyy).x, map(p - e.yxy).x, map(p - e.yyx).x);
return normalize(n);
}
vec3 getLight(vec3 p, vec3 rd, vec3 color) {
vec3 lightPos = vec3(10.0, 55.0, -20.0);
vec3 L = normalize(lightPos - p);
vec3 N = getNormal(p);
vec3 V = -rd;
vec3 R = reflect(-L, N);
vec3 specColor = vec3(0.5);
vec3 specular = specColor * pow(clamp(dot(R, V), 0.0, 1.0), 10.0);
vec3 diffuse = color * clamp(dot(L, N), 0.0, 1.0);
vec3 ambient = color * 0.05;
vec3 fresnel = 0.25 * color * pow(1.0 + dot(rd, N), 3.0);
// shadows
float d = rayMarch(p + N * 0.02, normalize(lightPos)).x;
if (d < length(lightPos - p)) return ambient + fresnel;
return diffuse + ambient + specular + fresnel;
}
vec3 getMaterial(vec3 p, float color_pack, float id) {
vec3 m = vec3(0.0);
vec3 color = unpackColor(color_pack);
switch (int(id)) {
case 1:
m = vec3(0.2 + 0.4 * mod(floor(p.x) + floor(p.z), 2.0)); break;
}
return color+m;
return color;
}
void render(inout vec3 col, in vec3 ro, in mat3 cam, in vec2 uv) {
vec3 r1 = vec3(0, 0, 1);
vec3 lookAt = ro + r1;
vec3 rd = cam*normalize(vec3(uv, FOV));
vec4 result = rayMarch(ro, rd);
vec3 object = result.xyz;
vec3 glowing_color = vec3(0.5, 0, 0);
float nb_itter = result.w;
vec3 background = vec3(0, 0, 0);
if (object.x < MAX_DIST) {
vec3 p = ro + object.x * rd;
vec3 material = getMaterial(p, object.y, object.z);
col += getLight(p, rd, material);
// fog
col = mix(col, background, 1.0 - exp(-0.00002 * object.x * object.x));
} else {
// col += background - max(0.9 * rd.y, 0.0);
col = col;
}
float glow_fact = smoothstep(0, MAX_STEPS, nb_itter);
col += glowing_color*glow_fact;
}
void main() {
vec2 uv = (2.0 * gl_FragCoord.xy - u_resolution.xy) / u_resolution.y;
vec3 col;
render(col, ro, cam, uv);
// gamma correction
col = pow(col, vec3(0.4545));
fragColor = vec4(col, 1.0);
}