| #version 330 core | |
| 
 | |
| #define FOV 24 | |
| 
 | |
| #define EPSILON 0.01 | |
| #define MAX_STEPS 128 | |
| #define NEAR_D 0.1 | |
| #define FAR_D 120. | |
| 
 | |
| #define GRAD_EPSILON 0.0001 | |
| 
 | |
| #define saturate(x) clamp(x, 0, 1) | |
| 
 | |
| uniform vec2 u_Resolution; | |
| uniform vec4 u_Mouse; | |
| uniform float u_Time; | |
| 
 | |
| out vec4 color; | |
| 
 | |
| #include "hg_sdf.glsl" | |
| #include "utils.glsl" | |
| #include "march_prolog.glsl" | |
| #include "colormap_cool.glsl" | |
| 
 | |
| #define MAT_NORMALS 1. | |
| 
 | |
| vec3 ray_dir(float fov, vec2 uv) { | |
| 	float z = 1./tan(radians(fov)/2.); | |
| 	return normalize(vec3(uv, z)); | |
| } | |
| 
 | |
| SceneResult scene_f(vec3 p) { | |
| 	//SceneResult ball = SceneResult(length(p-vec3(0, 2, 0)) - 2, 3.); | |
| 	//SceneResult ball2 = SceneResult(length(p-vec3(2*sin(u_Time), 2-2*cos(u_Time), 0)) - 1, 3.); | |
| 	SceneResult plane = SceneResult(p.y+5, 2.); | |
| 
 | |
| 	// SceneResult box = SceneResult( | |
| 	// 	fOpUnionRound(fBox(p, vec3(1)), fSphere(p-vec3(.8), 1.), .2), 0.); | |
| 
 | |
| 	//SceneResult res = SceneResult( | |
| 	//	mix(fBox(p, vec3(1.)), fSphere(p, 1.), | |
| 	//		pow(sin(.5*TAU*u_Time), 0.8)), | |
| 	//	1.); | |
| 
 | |
| 	// SceneResult res = SceneResult(-p.z, 1.); | |
| 
 | |
| 	// SceneResult res = SceneResult( | |
| 	// 	fBox(p, vec3(1)), | |
| 	// 	1.); | |
| 
 | |
| 	// SceneResult res = min_sr(min_sr(ball, ball2), plane); | |
| 
 | |
| 	p -= vec3(0, 2, 0); | |
| 	//pR(p.yz, u_Time); | |
| 
 | |
| 	//float d = max(abs(p.x), max(abs(p.y), abs(p.z))) - 2.; | |
| 	//float d = fBox(p, vec3(2)); | |
| 	float d = fCircle(p, 3) - 1; | |
| 
 | |
| 	SceneResult res = min_sr(plane, SceneResult(d, 3.)); | |
| 
 | |
| 	return res; | |
| } | |
| 
 | |
| vec3 estimate_scene_normal(vec3 p) { | |
| 	vec3 dx = vec3(GRAD_EPSILON, 0, 0); | |
| 	vec3 dy = vec3(0, GRAD_EPSILON, 0); | |
| 	vec3 dz = vec3(0, 0, GRAD_EPSILON); | |
| 
 | |
| 	return normalize(vec3( | |
| 		scene_f(p + dx).d - scene_f(p - dx).d, | |
| 		scene_f(p + dy).d - scene_f(p - dy).d, | |
| 		scene_f(p + dz).d - scene_f(p - dz).d | |
| 	)); | |
| } | |
| 
 | |
| vec3 raymarch(vec3 o, vec3 d, float start, float end) { | |
| 	float t = start; | |
| 	for (int i = 0; i < MAX_STEPS; i++) { | |
| 		SceneResult sr = scene_f(o + d*t); | |
| 		if (sr.d < EPSILON || t > end) | |
| 			return vec3(t, sr.mat_idx, i); | |
| 
 | |
| 		t += sr.d; | |
| 	} | |
| 	return vec3(end, N_HIT_FAR_PLANE, MAX_STEPS); | |
| } | |
| 
 | |
| float checker(vec2 uv) { | |
| 	return sign(mod(floor(uv.x) + floor(uv.y), 2.0)); | |
| } | |
| 
 | |
| vec4 shade_material(vec3 p, vec3 norm, float mat_idx) { | |
| 	if (mat_idx <= 0.0) { | |
| 		return vec4(0); | |
| 	} | |
| 	if (mat_idx <= 1.0) { | |
| 		// return colormap((mod(p.x, 3.) + 1)/2.5); | |
| 		return vec4(norm, 1.0); | |
| 	} | |
| 	if (mat_idx <= 2.0) { | |
| 		return vec4(vec3(mix(0.8, 1.0, checker(p.xz))), 1); | |
| 	} | |
| 	if (mat_idx <= 3.0) { | |
| 		return mix(vec4(vec3(0), 1), vec4(0.05, 0, 0.1, 1), dot(vec3(3, 3, 3), norm)); | |
| 	} | |
| 
 | |
| 	return vec4(1, 0, 0, 1); | |
| 	//return | |
| } | |
| 
 | |
| vec4 shade(vec3 p, float mat_idx) { | |
| 	vec3 norm = estimate_scene_normal(p); | |
| 	vec4 color_mat = shade_material(p, norm, mat_idx); | |
| 
 | |
| 	return color_mat; | |
| } | |
| 
 | |
| void main() { | |
| 	vec2 mouse_uv = u_Mouse.xy * 2.0 / u_Resolution.xy - 1.0; | |
| 
 | |
| 	vec2 uv = gl_FragCoord.xy * 2.0 / u_Resolution.xy - 1.0; | |
| 	uv.x *= u_Resolution.x/u_Resolution.y; | |
| 
 | |
| 	float an = 0.; | |
| 	float d = 5.; | |
| 	vec3 eye = vec3(3. * sin(an), 3., 3. * cos(an)) * d; | |
| 	vec3 target = vec3(0., 2., 0.); | |
| 	mat3 lookAt = look_mat(eye, target, 0); | |
| 	vec3 dir = normalize(lookAt * ray_dir(FOV, uv)); | |
| 
 | |
| 	color = vec4(0.); | |
| 
 | |
| 	vec3 result = raymarch(eye, dir, NEAR_D, FAR_D); | |
| 	float depth = result.x; | |
| 	float mat_idx = result.y; | |
| 	float iters = result.z; | |
| 	if (depth >= FAR_D) { | |
| 	//	color = vec4(.1, .3, .9, 1.); | |
| 		return; | |
| 	} | |
| 
 | |
| 	//color = colormap(iters/MAX_STEPS+0.5); | |
| 	vec3 p = eye + dir * depth; // recast the ray | |
| 	color = shade(p, mat_idx); | |
| 	//color = vec4(vec3(depth/FAR_D), 1); | |
| 
 | |
| 	// gamma | |
|   	color = vec4(pow(clamp(color.xyz, 0.0, 1.0), vec3(0.4545)), 1.0); | |
| }
 |