diff --git a/game_folder/shaders/compute/Final_step.glsl_error.txt b/game_folder/shaders/compute/Final_step.glsl_error.txt deleted file mode 100644 index 2aecb4c5..00000000 --- a/game_folder/shaders/compute/Final_step.glsl_error.txt +++ /dev/null @@ -1,796 +0,0 @@ -#version 430 -//4*4 ray bundle -#define group_size 8 -#define buffer_size 64 - -layout(local_size_x = group_size, local_size_y = group_size) in; -layout(rgba32f, binding = 0) uniform image2D bloom; -layout(rgba8, binding = 1) uniform image2D final_color; -layout(rgba32f, binding = 2) uniform image2D DE_input; -layout(rgba32f, binding = 3) uniform image2D color_HDR; - -//?? -shared vec4 de_sph[1][1]; - - -struct ray -{ - vec3 pos; - vec3 dir; -}; - -struct gl_camera -{ - vec3 position; - vec3 dirx; - vec3 diry; - vec3 dirz; - vec2 resolution; - float aspect_ratio; - float FOV; - float focus; - float bokeh; - float exposure; - float mblur; - float speckle; - float size; - float bloomintensity; - float bloomtreshold; - float bloomradius; - int stepN; - int step; -}; - - -ivec2 getGpos(int index) -{ - int y = index/group_size; - int x = index%group_size; - return ivec2(x,y); -} - -uniform gl_camera Camera; -float fovray; - -ray get_ray(vec2 screen_pos) -{ - vec2 shift = Camera.FOV*(2.f*screen_pos - 1.f)*vec2(Camera.aspect_ratio, 1.f); - ray cray; - cray.pos = Camera.position + Camera.size*(Camera.dirx*shift.x + Camera.diry*shift.y); - cray.dir = normalize(Camera.dirx*shift.x + Camera.diry*shift.y + Camera.dirz); - float aspect_ratio_ratio = Camera.aspect_ratio/(Camera.resolution.x/Camera.resolution.y); - fovray = 1.41*Camera.FOV*max(1.f/aspect_ratio_ratio, aspect_ratio_ratio)/Camera.resolution.x; //pixel FOV - return cray; -} - -#define COL col_scene -#define DE de_scene - -uniform float iFracScale; -uniform float iFracAng1; -uniform float iFracAng2; -uniform vec3 iFracShift; -uniform vec3 iFracCol; -uniform vec3 iMarblePos; -uniform float iMarbleRad; -uniform float iFlagScale; -uniform vec3 iFlagPos; -uniform int FRACTAL_ITER; -uniform int MARBLE_MODE; -uniform float time; - -///Original MM distance estimators - -float s1 = sin(iFracAng1), c1 = cos(iFracAng1), s2 = sin(iFracAng2), c2 = cos(iFracAng2); - -//########################################## -// Space folding -//########################################## -void planeFold(inout vec4 z, vec3 n, float d) { - z.xyz -= 2.0 * min(0.0, dot(z.xyz, n) - d) * n; -} -void sierpinskiFold(inout vec4 z) { - z.xy -= min(z.x + z.y, 0.0); - z.xz -= min(z.x + z.z, 0.0); - z.yz -= min(z.y + z.z, 0.0); -} - -// Polynomial smooth minimum by iq -float smoothmin(float a, float b, float k) { - float h = clamp(0.5 + 0.5*(a-b)/k, 0.0, 1.0); - return mix(a, b, h) - k*h*(1.0-h); -} - -void mengerFold(inout vec4 z) { - float a = smoothmin(z.x - z.y, 0.0, 0.03); - z.x -= a; - z.y += a; - a = smoothmin(z.x - z.z, 0.0, 0.03); - z.x -= a; - z.z += a; - a = smoothmin(z.y - z.z, 0.0, 0.03); - z.y -= a; - z.z += a; -} -void boxFold(inout vec4 z, vec3 r) { - z.xyz = clamp(z.xyz, -r, r) * 2.0 - z.xyz; -} -void rotX(inout vec4 z, float s, float c) { - z.yz = vec2(c*z.y + s*z.z, c*z.z - s*z.y); -} -void rotY(inout vec4 z, float s, float c) { - z.xz = vec2(c*z.x - s*z.z, c*z.z + s*z.x); -} -void rotZ(inout vec4 z, float s, float c) { - z.xy = vec2(c*z.x + s*z.y, c*z.y - s*z.x); -} -void rotX(inout vec4 z, float a) { - rotX(z, sin(a), cos(a)); -} -void rotY(inout vec4 z, float a) { - rotY(z, sin(a), cos(a)); -} -void rotZ(inout vec4 z, float a) { - rotZ(z, sin(a), cos(a)); -} - -//########################################## -// Primitive DEs -//########################################## -float de_sphere(vec4 p, float r) { - return (length(p.xyz) - r) / p.w; -} -float de_box(vec4 p, vec3 s) { - vec3 a = abs(p.xyz) - s; - return (min(max(max(a.x, a.y), a.z), 0.0) + length(max(a, 0.0))) / p.w; -} -float de_tetrahedron(vec4 p, float r) { - float md = max(max(-p.x - p.y - p.z, p.x + p.y - p.z), - max(-p.x + p.y + p.z, p.x - p.y + p.z)); - return (md - r) / (p.w * sqrt(3.0)); -} -float de_capsule(vec4 p, float h, float r) { - p.y -= clamp(p.y, -h, h); - return (length(p.xyz) - r) / p.w; -} - -//########################################## -// Main DEs -//########################################## -float de_fractal(vec4 p) -{ - for (int i = 0; i < FRACTAL_ITER; ++i) { - p.xyz = abs(p.xyz); - rotZ(p, s1, c1); - mengerFold(p); - rotX(p, s2, c2); - p *= iFracScale; - p.xyz += iFracShift; - } - return de_box(p, vec3(6.0)); -} - -vec4 col_fractal(vec4 p) -{ - vec3 orbit = vec3(0.0); - for (int i = 0; i < FRACTAL_ITER; ++i) { - p.xyz = abs(p.xyz); - rotZ(p, s1, c1); - mengerFold(p); - rotX(p, s2, c2); - p *= iFracScale; - p.xyz += iFracShift; - orbit = max(orbit, p.xyz*iFracCol); - } - return vec4(orbit, de_box(p, vec3(6.0))); -} - -float de_marble(vec4 p) -{ - return de_sphere(p - vec4(iMarblePos, 0), iMarbleRad); -} - -vec4 col_marble(vec4 p) -{ - vec4 col = vec4(0, 0, 0, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); - return vec4(col.x, col.y, col.z, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); -} - -float de_flag(vec4 p) -{ - vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale; - vec4 p_s = p/iMarbleRad; - vec4 d_pos = p - vec4(f_pos, 0); - vec4 caps_pos = p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0); - //animated flag woooo - float oscillation = sin(4*p_s.x + 1*p_s.y - 10*time) + 0.4*sin(6*p_s.x - 2*p_s.y - 12*time) + 0.1*sin(16*p_s.x + 5*p_s.y - 14*time); - //scale the flag displacement amplitude by the distance from the flagpole - float d = 0.7*de_box(d_pos + caps_pos.x*vec4(0,0.005*oscillation,0.03*oscillation,0), vec3(1.5, 0.8, 0.01)*iMarbleRad); - d = min(d, de_capsule(caps_pos, iMarbleRad*2.4, iMarbleRad*0.05)); - return d; -} - -vec4 col_flag(vec4 p) -{ - vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale; - float d1 = de_box(p - vec4(f_pos, 0), vec3(1.5, 0.8, 0.08)*iMarbleRad); - float d2 = de_capsule(p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0), iMarbleRad*2.4, iMarbleRad*0.18); - if (d1 < d2) { - return vec4(1.0, 0.2, 0.1, d1); - } else { - return vec4(0.9, 0.9, 0.1, d2); - } -} - -//float DE_count = 0; - -float de_scene(vec3 pos) -{ - //DE_count = DE_count+1; - vec4 p = vec4(pos,1.f); - float d = de_fractal(p); - d = min(d, de_marble(p)); - d = min(d, de_flag(p)); - return d; -} - -vec4 col_scene(vec3 pos) -{ - //DE_count = DE_count+1; - vec4 p = vec4(pos,1.f); - vec4 col = col_fractal(p); - vec4 col_f = col_flag(p); - if (col_f.w < col.w) { col = col_f; } - vec4 col_m = col_marble(p); - if (col_m.w < col.w) { - return vec4(col_m.xyz, 1.0); - } - return vec4(min(col.xyz,1), 0.0); -} - -//A faster formula to find the gradient/normal direction of the DE -//credit to http://www.iquilezles.org/www/articles/normalsSDF/normalsSDF.htm -vec4 calcNormal(vec3 p, float dx) { - const vec3 k = vec3(1,-1,0); - return (k.xyyx*DE(p + k.xyy*dx) + - k.yyxx*DE(p + k.yyx*dx) + - k.yxyx*DE(p + k.yxy*dx) + - k.xxxx*DE(p + k.xxx*dx))/vec4(4*dx,4*dx,4*dx,4); -} - - -#define MAX_DIST 50 -#define MIN_DIST 1e-5 -#define MAX_MARCHES 512 -#define NORMARCHES 5 - - -void ray_march(inout vec4 pos, inout vec4 dir, inout vec4 var, float fov, float d0) -{ - //March the ray - for (; var.x < MAX_MARCHES; var.x += 1.0) { - //if the distance from the surface is less than the distance per pixel we stop - if(dir.w > MAX_DIST || pos.w<0) - { - break; - } - - if(pos.w < max(fov*dir.w, MIN_DIST) && var.x > 0 && var.w < 1) - { - break; - } - - dir.w += pos.w; - pos.xyz += pos.w*dir.xyz; - pos.w = DE(pos.xyz)-d0*dir.w; - var.w = 0; - } - - pos.w += d0*dir.w; -} - -// Polynomial smooth minimum by iq -float smin(float a, float b, float k) { - float h = clamp(0.5 + 0.5*(a-b)/k, 0.0, 1.0); - return mix(a, b, h) - k*h*(1.0-h); -} - -float shadow_march(vec4 pos, vec4 dir, float distance2light, float light_angle) -{ - float light_visibility = 1; - float ph = 1e5; - float dDEdt = 0; - pos.w = DE(pos.xyz); - int i = 0; - for (; i < MAX_MARCHES; i++) { - - dir.w += pos.w; - pos.xyz += pos.w*dir.xyz; - pos.w = DE(pos.xyz); - - float y = pos.w*pos.w/(2.0*ph); - float d = (pos.w+ph)*0.5*(1-dDEdt); - float angle = d/(max(MIN_DIST,dir.w-y)*light_angle); - - light_visibility = min(light_visibility, angle); - - dDEdt = dDEdt*0.75 + 0.25*(pos.w-ph)/ph; - ph = pos.w; - - if(dir.w >= distance2light) - { - break; - } - - if(dir.w > MAX_DIST || pos.w < max(fovray*dir.w, MIN_DIST)) - { - return 0; - } - } - //return light_visibility; //bad - return 0.5-cos(3.14159265*light_visibility)*0.5; //looks better and is more physically accurate(for a circular light source) -} - -float sphere_intersection(vec3 r, vec3 p, vec4 sphere) -{ - p = p - sphere.xyz; - if(p == vec3(0)) return sphere.w; - - float b = dot(p, r); - float c = sphere.w*sphere.w - dot(p,p); - float d = b*b + c; - - if((d <= 0) || (c <= 0)) //if no intersection - { - return 0; - } - else - { - return sqrt(d) - b; //use furthest solution in the direction of the ray - } -} - -float find_furthest_intersection(vec3 r, vec3 p, ivec2 id) -{ - float d = 0; - ivec2 idR = min(id+1, group_size-1); - ivec2 idL = max(id-1, 0); - for(int i = idL.x; i <= idR.x; i++) - { - for(int j = idL.y; j <= idR.y; j++) - { - d = max(d, sphere_intersection(r,p,de_sph[i][j])); - } - } - return d; -} - - -float find_furthest_intersection_all(vec3 r, vec3 p, ivec2 id) -{ - float d = 0; - for(int i = 0; i < group_size; i++) - { - for(int j = 0; j < group_size; j++) - { - d = max(d, sphere_intersection(r,p,de_sph[i][j])); - } - } - return d; -} - -void normarch(inout vec4 pos) -{ - //calculate the normal - vec4 norm = calcNormal(pos.xyz, pos.w/8); - norm.xyz = normalize(norm.xyz); - pos.w = norm.w; - - float prev_w = 0; - //march in the direction of the normal - #pragma unroll - for(int i = 0; i < NORMARCHES; i++) - { - pos.xyz += pos.w*norm.xyz; - pos.w = DE(pos.xyz); - if(pos.w < prev_w) - { - pos.xyz -= prev_w*norm.xyz; - pos.w = prev_w; - break; - } - prev_w = pos.w; - } -} - - -#define PI 3.14159265 -#define AMBIENT_MARCHES 5 -#define AMBIENT_COLOR 2*vec4(1,1,1,1) -#define LIGHT_ANGLE 0.08 - -uniform vec3 BACKGROUND_COLOR; -uniform vec3 LIGHT_DIRECTION; -uniform float PBR_METALLIC; -uniform float PBR_ROUGHNESS; -uniform vec3 LIGHT_COLOR; -uniform bool SHADOWS_ENABLED; - - -//better to use a sampler though -vec4 interp(layout (rgba32f) image2D text, vec2 coord) -{ - //coord *= 0.99; - ivec2 ci = ivec2(coord); - vec2 d = coord - floor(coord); - return imageLoad(text, ci)*(1-d.x)*(1-d.y) + - imageLoad(text, ci+ivec2(1,0))*d.x*(1-d.y) + - imageLoad(text, ci+ivec2(0,1))*(1-d.x)*d.y + - imageLoad(text, ci+ivec2(1))*d.x*d.y; -} - - -///PBR functions -vec3 fresnelSchlick(float cosTheta, vec3 F0) -{ - return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); -} - -float DistributionGGX(vec3 N, vec3 H, float roughness) -{ - float a = roughness*roughness; - float a2 = a*a; - float NdotH = max(dot(N, H), 0.0); - float NdotH2 = NdotH*NdotH; - - float num = a2; - float denom = (NdotH2 * (a2 - 1.0) + 1.0); - denom = PI * denom * denom; - - return num / denom; -} - -float GeometrySchlickGGX(float NdotV, float roughness) -{ - float r = (roughness + 1.0); - float k = (r*r) / 8.0; - - float num = NdotV; - float denom = NdotV * (1.0 - k) + k; - - return num / denom; -} - -float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) -{ - float NdotV = max(dot(N, V), 0.0); - float NdotL = max(dot(N, L), 0.0); - float ggx2 = GeometrySchlickGGX(NdotV, roughness); - float ggx1 = GeometrySchlickGGX(NdotL, roughness); - - return ggx1 * ggx2; -} -///END PBR functions - -const float Br = 0.0025; -const float Bm = 0.0003; -const float g = 0.9800; -const vec3 nitrogen = vec3(0.650, 0.570, 0.475); -const vec3 Kr = Br / pow(nitrogen, vec3(4.0)); -const vec3 Km = Bm / pow(nitrogen, vec3(0.84)); - -vec3 sky_color(in vec3 pos) -{ - // Atmosphere Scattering - vec3 fsun = LIGHT_DIRECTION; - float brightnees = exp(min(5*pos.y,0)); - if(pos.y < 0) - { - pos.y = 0; - pos.xyz = normalize(pos.xyz); - } - float mu = dot(normalize(pos), normalize(fsun)); - - vec3 extinction = mix(exp(-exp(-((pos.y + fsun.y * 4.0) * (exp(-pos.y * 16.0) + 0.1) / 80.0) / Br) * (exp(-pos.y * 16.0) + 0.1) * Kr / Br) * exp(-pos.y * exp(-pos.y * 8.0 ) * 4.0) * exp(-pos.y * 2.0) * 4.0, vec3(1.0 - exp(fsun.y)) * 0.2, -fsun.y * 0.2 + 0.5); - vec3 sky_col = brightnees* 3.0 / (8.0 * 3.14) * (1.0 + mu * mu) * (Kr + Km * (1.0 - g * g) / (2.0 + g * g) / pow(1.0 + g * g - 2.0 * g * mu, 1.5)) / (Br + Bm) * extinction; - sky_col = 0.4*clamp(sky_col,0,10); - return sky_col*sky_col; -} - -vec3 ambient_sky_color(in vec3 pos) -{ - float y = pos.y; - pos.xyz = normalize(vec3(1,0,0)); - return sky_color(pos)*exp(-abs(y)); -} - -vec4 ambient_occlusion(in vec4 pos, in vec4 norm, in vec4 dir) -{ - vec3 dir1 = normalize(cross(dir.xyz,norm.xyz)); - vec3 dir2 = normalize(cross(dir1,norm.xyz)); - pos.w = iMarbleRad/2; - - vec3 pos0 = pos.xyz; - - float shifter = 2; - float dcoef = 0.02/iMarbleRad; - float occlusion_angle = 0; - float integral = 0; - float i_coef = 0; - - vec3 ambient_color = ambient_sky_color(norm.xyz); - - //march in the direction of the normal - #pragma unroll - for(int i = 0; i < AMBIENT_MARCHES; i++) - { - //moving in a zig-zag - vec3 direction = normalize(norm.xyz + 0.6*((mod(shifter,3.f)-1)*dir1 + (mod(shifter+1,3.f)-1)*dir2)); - shifter += 1; - pos.xyz += pos.w*direction; - pos.w = DE(pos.xyz); - - norm.w = length(pos0 - pos.xyz); - i_coef = 1/(dcoef*norm.w+1);//importance - occlusion_angle += i_coef*clamp(pos.w/norm.w,0,1); - integral += i_coef; - } - - occlusion_angle /= integral; // average weighted by importance - return vec4(ambient_color,1)*(0.5-cos(3.14159265*occlusion_angle)*0.5); -} - - -vec3 refraction(vec3 rd, vec3 n, float p) { - float dot_nd = dot(rd, n); - return p * (rd - dot_nd * n) + sqrt(1.0 - (p * p) * (1.0 - dot_nd * dot_nd)) * n; -} - -vec3 lighting(vec4 color, vec4 pos, vec4 dir, vec4 norm, vec3 refl, vec3 refr, float shadow) -{ - vec3 albedo = color.xyz; - albedo *= albedo; //square it to make the fractals more colorfull - - vec4 ambient_color = ambient_occlusion(pos, norm, dir); - - float metallic = PBR_METALLIC; - vec3 F0 = vec3(0.04); - F0 = mix(F0, albedo, metallic); - - //reflectance equation - vec3 Lo = vec3(0.0); - vec3 V = -dir.xyz; - vec3 N = norm.xyz; - - { //ambient occlusion contribution - float roughness = max(PBR_ROUGHNESS,0.5); - vec3 L = normalize(N); - vec3 H = normalize(V + L); - vec3 radiance = ambient_color.xyz; - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - if(!SHADOWS_ENABLED) - { - shadow = ambient_color.w; - } - - vec3 sun_color = sky_color(LIGHT_DIRECTION); - - { //light contribution - float roughness = PBR_ROUGHNESS; - vec3 L = normalize(LIGHT_DIRECTION); - vec3 H = normalize(V + L); - vec3 radiance = sun_color*shadow*(0.6+0.4*ambient_color.w); - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - { //light reflection, GI imitation - float roughness = max(PBR_ROUGHNESS,0.5); - vec3 L = normalize(-LIGHT_DIRECTION); - vec3 H = normalize(V + L); - vec3 radiance = 0.35*sun_color*ambient_color.w*(1-ambient_color.w); - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - if(color.w>0.5) // if marble - { - vec3 n = normalize(pos.xyz - iMarblePos); - vec3 q = dir.xyz - n*(2*dot(dir.xyz,n)); - //Combine for final marble color - if(MARBLE_MODE == 0) - { - //glass - vec3 F0 = vec3(0.03); - vec3 L = normalize(q); - vec3 H = normalize(V + L); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - Lo += kS*refl + kD*refr; - } - else - { - //metal - vec3 F0 = vec3(0.6); - vec3 L = normalize(q); - vec3 H = normalize(V + L); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - Lo += kS*refl; - } - } - - return Lo; -} - -vec3 shading_simple(in vec4 pos, in vec4 dir, float fov, float shadow) -{ - - - if(pos.w < max(16*fovray*dir.w, MIN_DIST)) - { - //calculate the normal - float error = 0.5*fov*dir.w; - vec4 norm = calcNormal(pos.xyz, max(MIN_DIST, error)); - norm.xyz = normalize(norm.xyz); - if(norm.w < -error) - { - return COL(pos.xyz); - } - else - { - //optimize color sampling - vec3 cpos = pos.xyz - norm.w*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - - vec4 color = COL(cpos); - return lighting(color, pos, dir, norm, vec3(0), vec3(0), shadow); - } - } - else - { - return sky_color(dir.xyz); - } -} - - -vec3 render_ray(in vec4 pos, in vec4 dir, float fov) -{ - vec4 var = vec4(0,0,0,1); - ray_march(pos, dir, var, fov, MIN_DIST); - float shadow = shadow_march(pos, vec4(LIGHT_DIRECTION,0), MAX_DIST, LIGHT_ANGLE); - return shading_simple(pos, dir, fov, shadow); -} - -vec3 shading(in vec4 pos, in vec4 dir, float fov, float shadow) -{ - if(pos.w < max(16*fovray*dir.w, MIN_DIST)) - { - //calculate the normal - float error = 0.5*fov*dir.w; - vec4 norm = calcNormal(pos.xyz, max(MIN_DIST, error)); - norm.xyz = normalize(norm.xyz); - if(norm.w < -error) - { - return COL(pos.xyz); - } - else - { - //optimize color sampling - vec3 cpos = pos.xyz - norm.w*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - - vec4 color = COL(cpos); - vec3 refl = vec3(0); - vec3 refr = vec3(0); - if(color.w>0.5) // if marble - { - vec3 n = normalize(iMarblePos - cpos.xyz); - vec3 q = refraction(dir.xyz, n, 1.0 / 1.5); - vec3 p2 = cpos.xyz + (dot(q, n) * 2.0 * iMarbleRad) * q; - n = normalize(p2 - iMarblePos); - q = (dot(q, dir.xyz) * 2.0) * q - dir.xyz; - vec4 p_temp = vec4(p2 + n * (MIN_DIST * 10), 0); - vec4 r_temp = vec4(q, 0); - - refr = render_ray(p_temp, r_temp, fov); - - //Calculate reflection - n = normalize(cpos.xyz - iMarblePos); - q = dir.xyz - n*(2*dot(dir.xyz,n)); - p_temp = vec4(cpos.xyz + n * (MIN_DIST * 10), 0); - r_temp = vec4(q, dir.w); - - refl = render_ray(p_temp, r_temp, fov); - } - - return lighting(color, cpos, dir, norm, refl, refr, shadow); - } - } - else - { - return sky_color(dir.xyz); - } - -} - -vec3 HDRmapping(vec3 color, float exposure, float gamma) -{ - // Exposure tone mapping - vec3 mapped = vec3(1.0) - exp(-color * exposure); - // Gamma correction - return pow(mapped, vec3(1.0 / gamma)); -} - - -#define VIGNETTE_STRENGTH 0.2 - -void main() { - ivec2 global_pos = ivec2(gl_GlobalInvocationID.xy); - vec2 img_size = vec2(imageSize(color_HDR)); - - vec2 res_ratio = vec2(imageSize(bloom))/img_size; - vec3 bloom_color = interp(bloom, vec2(global_pos)*res_ratio).xyz; - - vec3 fin_color = imageLoad(color_HDR, global_pos).xyz + bloom_color; - - float vignette = 1.0 - VIGNETTE_STRENGTH * length(vec2(global_pos)/img_size - 0.5); - imageStore(final_color, global_pos, vec4(HDRmapping(fin_color, Camera.exposure, 2.2)*vignette, 1)); -} - -ERROR: 0:761: 'lighting' : no matching overloaded function found (using implicit conversion) - diff --git a/game_folder/shaders/compute/Illumination_step.glsl_error.txt b/game_folder/shaders/compute/Illumination_step.glsl_error.txt deleted file mode 100644 index 70456745..00000000 --- a/game_folder/shaders/compute/Illumination_step.glsl_error.txt +++ /dev/null @@ -1,821 +0,0 @@ -#version 430 -//4*4 ray bundle -#define group_size 8 -#define block_size 64 - -layout(local_size_x = group_size, local_size_y = group_size) in; -layout(rgba32f, binding = 0) uniform image2D illumination; -layout(rgba32f, binding = 1) uniform image2D DE_input; -layout(rgba32f, binding = 2) uniform image2D color_HDR; //calculate final color - -//make all the local distance estimator spheres shared -shared vec4 de_sph[group_size][group_size]; - - -struct ray -{ - vec3 pos; - vec3 dir; -}; - -struct gl_camera -{ - vec3 position; - vec3 dirx; - vec3 diry; - vec3 dirz; - vec2 resolution; - float aspect_ratio; - float FOV; - float focus; - float bokeh; - float exposure; - float mblur; - float speckle; - float size; - float bloomintensity; - float bloomtreshold; - float bloomradius; - int stepN; - int step; -}; - - -ivec2 getGpos(int index) -{ - int y = index/group_size; - int x = index%group_size; - return ivec2(x,y); -} - -uniform gl_camera Camera; -float fovray; - -ray get_ray(vec2 screen_pos) -{ - vec2 shift = Camera.FOV*(2.f*screen_pos - 1.f)*vec2(Camera.aspect_ratio, 1.f); - ray cray; - cray.pos = Camera.position + Camera.size*(Camera.dirx*shift.x + Camera.diry*shift.y); - cray.dir = normalize(Camera.dirx*shift.x + Camera.diry*shift.y + Camera.dirz); - float aspect_ratio_ratio = Camera.aspect_ratio/(Camera.resolution.x/Camera.resolution.y); - fovray = 1.41*Camera.FOV*max(1.f/aspect_ratio_ratio, aspect_ratio_ratio)/Camera.resolution.x; //pixel FOV - return cray; -} - -#define COL col_scene -#define DE de_scene - -uniform float iFracScale; -uniform float iFracAng1; -uniform float iFracAng2; -uniform vec3 iFracShift; -uniform vec3 iFracCol; -uniform vec3 iMarblePos; -uniform float iMarbleRad; -uniform float iFlagScale; -uniform vec3 iFlagPos; -uniform int FRACTAL_ITER; -uniform int MARBLE_MODE; -uniform float time; - -///Original MM distance estimators - -float s1 = sin(iFracAng1), c1 = cos(iFracAng1), s2 = sin(iFracAng2), c2 = cos(iFracAng2); - -//########################################## -// Space folding -//########################################## -void planeFold(inout vec4 z, vec3 n, float d) { - z.xyz -= 2.0 * min(0.0, dot(z.xyz, n) - d) * n; -} -void sierpinskiFold(inout vec4 z) { - z.xy -= min(z.x + z.y, 0.0); - z.xz -= min(z.x + z.z, 0.0); - z.yz -= min(z.y + z.z, 0.0); -} - -// Polynomial smooth minimum by iq -float smoothmin(float a, float b, float k) { - float h = clamp(0.5 + 0.5*(a-b)/k, 0.0, 1.0); - return mix(a, b, h) - k*h*(1.0-h); -} - -void mengerFold(inout vec4 z) { - float a = smoothmin(z.x - z.y, 0.0, 0.03); - z.x -= a; - z.y += a; - a = smoothmin(z.x - z.z, 0.0, 0.03); - z.x -= a; - z.z += a; - a = smoothmin(z.y - z.z, 0.0, 0.03); - z.y -= a; - z.z += a; -} -void boxFold(inout vec4 z, vec3 r) { - z.xyz = clamp(z.xyz, -r, r) * 2.0 - z.xyz; -} -void rotX(inout vec4 z, float s, float c) { - z.yz = vec2(c*z.y + s*z.z, c*z.z - s*z.y); -} -void rotY(inout vec4 z, float s, float c) { - z.xz = vec2(c*z.x - s*z.z, c*z.z + s*z.x); -} -void rotZ(inout vec4 z, float s, float c) { - z.xy = vec2(c*z.x + s*z.y, c*z.y - s*z.x); -} -void rotX(inout vec4 z, float a) { - rotX(z, sin(a), cos(a)); -} -void rotY(inout vec4 z, float a) { - rotY(z, sin(a), cos(a)); -} -void rotZ(inout vec4 z, float a) { - rotZ(z, sin(a), cos(a)); -} - -//########################################## -// Primitive DEs -//########################################## -float de_sphere(vec4 p, float r) { - return (length(p.xyz) - r) / p.w; -} -float de_box(vec4 p, vec3 s) { - vec3 a = abs(p.xyz) - s; - return (min(max(max(a.x, a.y), a.z), 0.0) + length(max(a, 0.0))) / p.w; -} -float de_tetrahedron(vec4 p, float r) { - float md = max(max(-p.x - p.y - p.z, p.x + p.y - p.z), - max(-p.x + p.y + p.z, p.x - p.y + p.z)); - return (md - r) / (p.w * sqrt(3.0)); -} -float de_capsule(vec4 p, float h, float r) { - p.y -= clamp(p.y, -h, h); - return (length(p.xyz) - r) / p.w; -} - -//########################################## -// Main DEs -//########################################## -float de_fractal(vec4 p) -{ - for (int i = 0; i < FRACTAL_ITER; ++i) { - p.xyz = abs(p.xyz); - rotZ(p, s1, c1); - mengerFold(p); - rotX(p, s2, c2); - p *= iFracScale; - p.xyz += iFracShift; - } - return de_box(p, vec3(6.0)); -} - -vec4 col_fractal(vec4 p) -{ - vec3 orbit = vec3(0.0); - for (int i = 0; i < FRACTAL_ITER; ++i) { - p.xyz = abs(p.xyz); - rotZ(p, s1, c1); - mengerFold(p); - rotX(p, s2, c2); - p *= iFracScale; - p.xyz += iFracShift; - orbit = max(orbit, p.xyz*iFracCol); - } - return vec4(orbit, de_box(p, vec3(6.0))); -} - -float de_marble(vec4 p) -{ - return de_sphere(p - vec4(iMarblePos, 0), iMarbleRad); -} - -vec4 col_marble(vec4 p) -{ - vec4 col = vec4(0, 0, 0, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); - return vec4(col.x, col.y, col.z, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); -} - -float de_flag(vec4 p) -{ - vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale; - vec4 p_s = p/iMarbleRad; - vec4 d_pos = p - vec4(f_pos, 0); - vec4 caps_pos = p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0); - //animated flag woooo - float oscillation = sin(4*p_s.x + 1*p_s.y - 10*time) + 0.4*sin(6*p_s.x - 2*p_s.y - 12*time) + 0.1*sin(16*p_s.x + 5*p_s.y - 14*time); - //scale the flag displacement amplitude by the distance from the flagpole - float d = 0.7*de_box(d_pos + caps_pos.x*vec4(0,0.005*oscillation,0.03*oscillation,0), vec3(1.5, 0.8, 0.01)*iMarbleRad); - d = min(d, de_capsule(caps_pos, iMarbleRad*2.4, iMarbleRad*0.05)); - return d; -} - -vec4 col_flag(vec4 p) -{ - vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale; - float d1 = de_box(p - vec4(f_pos, 0), vec3(1.5, 0.8, 0.08)*iMarbleRad); - float d2 = de_capsule(p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0), iMarbleRad*2.4, iMarbleRad*0.18); - if (d1 < d2) { - return vec4(1.0, 0.2, 0.1, d1); - } else { - return vec4(0.9, 0.9, 0.1, d2); - } -} - -//float DE_count = 0; - -float de_scene(vec3 pos) -{ - //DE_count = DE_count+1; - vec4 p = vec4(pos,1.f); - float d = de_fractal(p); - d = min(d, de_marble(p)); - d = min(d, de_flag(p)); - return d; -} - -vec4 col_scene(vec3 pos) -{ - //DE_count = DE_count+1; - vec4 p = vec4(pos,1.f); - vec4 col = col_fractal(p); - vec4 col_f = col_flag(p); - if (col_f.w < col.w) { col = col_f; } - vec4 col_m = col_marble(p); - if (col_m.w < col.w) { - return vec4(col_m.xyz, 1.0); - } - return vec4(min(col.xyz,1), 0.0); -} - -//A faster formula to find the gradient/normal direction of the DE -//credit to http://www.iquilezles.org/www/articles/normalsSDF/normalsSDF.htm -vec4 calcNormal(vec3 p, float dx) { - const vec3 k = vec3(1,-1,0); - return (k.xyyx*DE(p + k.xyy*dx) + - k.yyxx*DE(p + k.yyx*dx) + - k.yxyx*DE(p + k.yxy*dx) + - k.xxxx*DE(p + k.xxx*dx))/vec4(4*dx,4*dx,4*dx,4); -} - - -#define MAX_DIST 50 -#define MIN_DIST 1e-5 -#define MAX_MARCHES 512 -#define NORMARCHES 5 - - -void ray_march(inout vec4 pos, inout vec4 dir, inout vec4 var, float fov, float d0) -{ - //March the ray - for (; var.x < MAX_MARCHES; var.x += 1.0) { - //if the distance from the surface is less than the distance per pixel we stop - if(dir.w > MAX_DIST || pos.w<0) - { - break; - } - - if(pos.w < max(fov*dir.w, MIN_DIST) && var.x > 0 && var.w < 1) - { - break; - } - - dir.w += pos.w; - pos.xyz += pos.w*dir.xyz; - pos.w = DE(pos.xyz)-d0*dir.w; - var.w = 0; - } - - pos.w += d0*dir.w; -} - -// Polynomial smooth minimum by iq -float smin(float a, float b, float k) { - float h = clamp(0.5 + 0.5*(a-b)/k, 0.0, 1.0); - return mix(a, b, h) - k*h*(1.0-h); -} - -float shadow_march(vec4 pos, vec4 dir, float distance2light, float light_angle) -{ - float light_visibility = 1; - float ph = 1e5; - float dDEdt = 0; - pos.w = DE(pos.xyz); - int i = 0; - for (; i < MAX_MARCHES; i++) { - - dir.w += pos.w; - pos.xyz += pos.w*dir.xyz; - pos.w = DE(pos.xyz); - - float y = pos.w*pos.w/(2.0*ph); - float d = (pos.w+ph)*0.5*(1-dDEdt); - float angle = d/(max(MIN_DIST,dir.w-y)*light_angle); - - light_visibility = min(light_visibility, angle); - - dDEdt = dDEdt*0.75 + 0.25*(pos.w-ph)/ph; - ph = pos.w; - - if(dir.w >= distance2light) - { - break; - } - - if(dir.w > MAX_DIST || pos.w < max(fovray*dir.w, MIN_DIST)) - { - return 0; - } - } - //return light_visibility; //bad - return 0.5-cos(3.14159265*light_visibility)*0.5; //looks better and is more physically accurate(for a circular light source) -} - -float sphere_intersection(vec3 r, vec3 p, vec4 sphere) -{ - p = p - sphere.xyz; - if(p == vec3(0)) return sphere.w; - - float b = dot(p, r); - float c = sphere.w*sphere.w - dot(p,p); - float d = b*b + c; - - if((d <= 0) || (c <= 0)) //if no intersection - { - return 0; - } - else - { - return sqrt(d) - b; //use furthest solution in the direction of the ray - } -} - -float find_furthest_intersection(vec3 r, vec3 p, ivec2 id) -{ - float d = 0; - ivec2 idR = min(id+1, group_size-1); - ivec2 idL = max(id-1, 0); - for(int i = idL.x; i <= idR.x; i++) - { - for(int j = idL.y; j <= idR.y; j++) - { - d = max(d, sphere_intersection(r,p,de_sph[i][j])); - } - } - return d; -} - - -float find_furthest_intersection_all(vec3 r, vec3 p, ivec2 id) -{ - float d = 0; - for(int i = 0; i < group_size; i++) - { - for(int j = 0; j < group_size; j++) - { - d = max(d, sphere_intersection(r,p,de_sph[i][j])); - } - } - return d; -} - -void normarch(inout vec4 pos) -{ - //calculate the normal - vec4 norm = calcNormal(pos.xyz, pos.w/8); - norm.xyz = normalize(norm.xyz); - pos.w = norm.w; - - float prev_w = 0; - //march in the direction of the normal - #pragma unroll - for(int i = 0; i < NORMARCHES; i++) - { - pos.xyz += pos.w*norm.xyz; - pos.w = DE(pos.xyz); - if(pos.w < prev_w) - { - pos.xyz -= prev_w*norm.xyz; - pos.w = prev_w; - break; - } - prev_w = pos.w; - } -} - - -#define PI 3.14159265 -#define AMBIENT_MARCHES 5 -#define AMBIENT_COLOR 2*vec4(1,1,1,1) -#define LIGHT_ANGLE 0.08 - -uniform vec3 BACKGROUND_COLOR; -uniform vec3 LIGHT_DIRECTION; -uniform float PBR_METALLIC; -uniform float PBR_ROUGHNESS; -uniform vec3 LIGHT_COLOR; -uniform bool SHADOWS_ENABLED; - - -//better to use a sampler though -vec4 interp(layout (rgba32f) image2D text, vec2 coord) -{ - //coord *= 0.99; - ivec2 ci = ivec2(coord); - vec2 d = coord - floor(coord); - return imageLoad(text, ci)*(1-d.x)*(1-d.y) + - imageLoad(text, ci+ivec2(1,0))*d.x*(1-d.y) + - imageLoad(text, ci+ivec2(0,1))*(1-d.x)*d.y + - imageLoad(text, ci+ivec2(1))*d.x*d.y; -} - - -///PBR functions -vec3 fresnelSchlick(float cosTheta, vec3 F0) -{ - return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); -} - -float DistributionGGX(vec3 N, vec3 H, float roughness) -{ - float a = roughness*roughness; - float a2 = a*a; - float NdotH = max(dot(N, H), 0.0); - float NdotH2 = NdotH*NdotH; - - float num = a2; - float denom = (NdotH2 * (a2 - 1.0) + 1.0); - denom = PI * denom * denom; - - return num / denom; -} - -float GeometrySchlickGGX(float NdotV, float roughness) -{ - float r = (roughness + 1.0); - float k = (r*r) / 8.0; - - float num = NdotV; - float denom = NdotV * (1.0 - k) + k; - - return num / denom; -} - -float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) -{ - float NdotV = max(dot(N, V), 0.0); - float NdotL = max(dot(N, L), 0.0); - float ggx2 = GeometrySchlickGGX(NdotV, roughness); - float ggx1 = GeometrySchlickGGX(NdotL, roughness); - - return ggx1 * ggx2; -} -///END PBR functions - -const float Br = 0.0025; -const float Bm = 0.0003; -const float g = 0.9800; -const vec3 nitrogen = vec3(0.650, 0.570, 0.475); -const vec3 Kr = Br / pow(nitrogen, vec3(4.0)); -const vec3 Km = Bm / pow(nitrogen, vec3(0.84)); - -vec3 sky_color(in vec3 pos) -{ - // Atmosphere Scattering - vec3 fsun = LIGHT_DIRECTION; - float brightnees = exp(min(5*pos.y,0)); - if(pos.y < 0) - { - pos.y = 0; - pos.xyz = normalize(pos.xyz); - } - float mu = dot(normalize(pos), normalize(fsun)); - - vec3 extinction = mix(exp(-exp(-((pos.y + fsun.y * 4.0) * (exp(-pos.y * 16.0) + 0.1) / 80.0) / Br) * (exp(-pos.y * 16.0) + 0.1) * Kr / Br) * exp(-pos.y * exp(-pos.y * 8.0 ) * 4.0) * exp(-pos.y * 2.0) * 4.0, vec3(1.0 - exp(fsun.y)) * 0.2, -fsun.y * 0.2 + 0.5); - vec3 sky_col = brightnees* 3.0 / (8.0 * 3.14) * (1.0 + mu * mu) * (Kr + Km * (1.0 - g * g) / (2.0 + g * g) / pow(1.0 + g * g - 2.0 * g * mu, 1.5)) / (Br + Bm) * extinction; - sky_col = 0.4*clamp(sky_col,0,10); - return sky_col*sky_col; -} - -vec3 ambient_sky_color(in vec3 pos) -{ - float y = pos.y; - pos.xyz = normalize(vec3(1,0,0)); - return sky_color(pos)*exp(-abs(y)); -} - -vec4 ambient_occlusion(in vec4 pos, in vec4 norm, in vec4 dir) -{ - vec3 dir1 = normalize(cross(dir.xyz,norm.xyz)); - vec3 dir2 = normalize(cross(dir1,norm.xyz)); - pos.w = iMarbleRad/2; - - vec3 pos0 = pos.xyz; - - float shifter = 2; - float dcoef = 0.02/iMarbleRad; - float occlusion_angle = 0; - float integral = 0; - float i_coef = 0; - - vec3 ambient_color = ambient_sky_color(norm.xyz); - - //march in the direction of the normal - #pragma unroll - for(int i = 0; i < AMBIENT_MARCHES; i++) - { - //moving in a zig-zag - vec3 direction = normalize(norm.xyz + 0.6*((mod(shifter,3.f)-1)*dir1 + (mod(shifter+1,3.f)-1)*dir2)); - shifter += 1; - pos.xyz += pos.w*direction; - pos.w = DE(pos.xyz); - - norm.w = length(pos0 - pos.xyz); - i_coef = 1/(dcoef*norm.w+1);//importance - occlusion_angle += i_coef*clamp(pos.w/norm.w,0,1); - integral += i_coef; - } - - occlusion_angle /= integral; // average weighted by importance - return vec4(ambient_color,1)*(0.5-cos(3.14159265*occlusion_angle)*0.5); -} - - -vec3 refraction(vec3 rd, vec3 n, float p) { - float dot_nd = dot(rd, n); - return p * (rd - dot_nd * n) + sqrt(1.0 - (p * p) * (1.0 - dot_nd * dot_nd)) * n; -} - -vec3 lighting(vec4 color, vec4 pos, vec4 dir, vec4 norm, vec3 refl, vec3 refr, float shadow) -{ - vec3 albedo = color.xyz; - albedo *= albedo; //square it to make the fractals more colorfull - - vec4 ambient_color = ambient_occlusion(pos, norm, dir); - - float metallic = PBR_METALLIC; - vec3 F0 = vec3(0.04); - F0 = mix(F0, albedo, metallic); - - //reflectance equation - vec3 Lo = vec3(0.0); - vec3 V = -dir.xyz; - vec3 N = norm.xyz; - - { //ambient occlusion contribution - float roughness = max(PBR_ROUGHNESS,0.5); - vec3 L = normalize(N); - vec3 H = normalize(V + L); - vec3 radiance = ambient_color.xyz; - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - if(!SHADOWS_ENABLED) - { - shadow = ambient_color.w; - } - - vec3 sun_color = sky_color(LIGHT_DIRECTION); - - { //light contribution - float roughness = PBR_ROUGHNESS; - vec3 L = normalize(LIGHT_DIRECTION); - vec3 H = normalize(V + L); - vec3 radiance = sun_color*shadow*(0.6+0.4*ambient_color.w); - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - { //light reflection, GI imitation - float roughness = max(PBR_ROUGHNESS,0.5); - vec3 L = normalize(-LIGHT_DIRECTION); - vec3 H = normalize(V + L); - vec3 radiance = 0.35*sun_color*ambient_color.w*(1-ambient_color.w); - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - if(color.w>0.5) // if marble - { - vec3 n = normalize(pos.xyz - iMarblePos); - vec3 q = dir.xyz - n*(2*dot(dir.xyz,n)); - //Combine for final marble color - if(MARBLE_MODE == 0) - { - //glass - vec3 F0 = vec3(0.03); - vec3 L = normalize(q); - vec3 H = normalize(V + L); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - Lo += kS*refl + kD*refr; - } - else - { - //metal - vec3 F0 = vec3(0.6); - vec3 L = normalize(q); - vec3 H = normalize(V + L); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - Lo += kS*refl; - } - } - - return Lo; -} - -vec3 shading_simple(in vec4 pos, in vec4 dir, float fov, float shadow) -{ - - - if(pos.w < max(16*fovray*dir.w, MIN_DIST)) - { - //calculate the normal - float error = 0.5*fov*dir.w; - vec4 norm = calcNormal(pos.xyz, max(MIN_DIST, error)); - norm.xyz = normalize(norm.xyz); - if(norm.w < -error) - { - return COL(pos.xyz); - } - else - { - //optimize color sampling - vec3 cpos = pos.xyz - norm.w*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - - vec4 color = COL(cpos); - return lighting(color, pos, dir, norm, vec3(0), vec3(0), shadow); - } - } - else - { - return sky_color(dir.xyz); - } -} - - -vec3 render_ray(in vec4 pos, in vec4 dir, float fov) -{ - vec4 var = vec4(0,0,0,1); - ray_march(pos, dir, var, fov, MIN_DIST); - float shadow = shadow_march(pos, vec4(LIGHT_DIRECTION,0), MAX_DIST, LIGHT_ANGLE); - return shading_simple(pos, dir, fov, shadow); -} - -vec3 shading(in vec4 pos, in vec4 dir, float fov, float shadow) -{ - if(pos.w < max(16*fovray*dir.w, MIN_DIST)) - { - //calculate the normal - float error = 0.5*fov*dir.w; - vec4 norm = calcNormal(pos.xyz, max(MIN_DIST, error)); - norm.xyz = normalize(norm.xyz); - if(norm.w < -error) - { - return COL(pos.xyz); - } - else - { - //optimize color sampling - vec3 cpos = pos.xyz - norm.w*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - - vec4 color = COL(cpos); - vec3 refl = vec3(0); - vec3 refr = vec3(0); - if(color.w>0.5) // if marble - { - vec3 n = normalize(iMarblePos - cpos.xyz); - vec3 q = refraction(dir.xyz, n, 1.0 / 1.5); - vec3 p2 = cpos.xyz + (dot(q, n) * 2.0 * iMarbleRad) * q; - n = normalize(p2 - iMarblePos); - q = (dot(q, dir.xyz) * 2.0) * q - dir.xyz; - vec4 p_temp = vec4(p2 + n * (MIN_DIST * 10), 0); - vec4 r_temp = vec4(q, 0); - - refr = render_ray(p_temp, r_temp, fov); - - //Calculate reflection - n = normalize(cpos.xyz - iMarblePos); - q = dir.xyz - n*(2*dot(dir.xyz,n)); - p_temp = vec4(cpos.xyz + n * (MIN_DIST * 10), 0); - r_temp = vec4(q, dir.w); - - refl = render_ray(p_temp, r_temp, fov); - } - - return lighting(color, cpos, dir, norm, refl, refr, shadow); - } - } - else - { - return sky_color(dir.xyz); - } - -} - -vec3 HDRmapping(vec3 color, float exposure, float gamma) -{ - // Exposure tone mapping - vec3 mapped = vec3(1.0) - exp(-color * exposure); - // Gamma correction - return pow(mapped, vec3(1.0 / gamma)); -} - - -///Half-resolution illumination step - - -void main() { - - ivec2 global_pos = ivec2(gl_GlobalInvocationID.xy); - ivec2 local_indx = ivec2(gl_LocalInvocationID.xy); - - vec2 img_size = vec2(imageSize(illumination)); - vec2 pimg_size = vec2(imageSize(DE_input)); - vec2 step_scale = img_size/pimg_size; - - ivec2 prev_pos = min(ivec2((vec2(global_pos)/step_scale) + 0.5),ivec2(pimg_size)-1); - - vec4 sph = imageLoad(DE_input, prev_pos); - - ray rr = get_ray(vec2(global_pos)/img_size); - vec4 pos = vec4(rr.pos,0); - vec4 dir = vec4(rr.dir,0); - vec4 var = vec4(0); - - float td = dot(dir.xyz, sph.xyz - pos.xyz);//traveled distance - - pos = sph; - dir.w += td; - - vec4 illum = vec4(0); - - if(pos.w < max(2*fovray*td, MIN_DIST) && SHADOWS_ENABLED) - { - vec4 norm = calcNormal(pos.xyz, max(2*fovray*td, MIN_DIST)); - norm.xyz = normalize(norm.xyz); - pos.xyz += norm.xyz*max(2*fovray*td, MIN_DIST); - illum.x = shadow_march(pos, normalize(vec4(LIGHT_DIRECTION,0)), MAX_DIST, LIGHT_ANGLE); - - //illum.y = ambient_occlusion(pos, norm); - } - - imageStore(illumination, global_pos, illum); -} - -ERROR: 0:760: 'lighting' : no matching overloaded function found (using implicit conversion) - diff --git a/game_folder/shaders/compute/MRRM1.glsl_error.txt b/game_folder/shaders/compute/MRRM1.glsl_error.txt deleted file mode 100644 index bba2dd06..00000000 --- a/game_folder/shaders/compute/MRRM1.glsl_error.txt +++ /dev/null @@ -1,438 +0,0 @@ -#version 430 -#define group_size 8 -#define block_size 64 - -layout(local_size_x = group_size, local_size_y = group_size) in; -layout(rgba32f, binding = 0) uniform image2D DE_output; //calculate final DE spheres -layout(rgba32f, binding = 1) uniform image2D DE2_output; -layout(rgba32f, binding = 2) uniform image2D var_output; -layout(rgba32f, binding = 3) uniform image2D DE_input; -layout(rgba32f, binding = 4) uniform image2D color_HDR; //calculate final color - -//make all the local distance estimator spheres shared -shared vec4 de_sph[group_size][group_size]; - - -struct ray -{ - vec3 pos; - vec3 dir; -}; - -struct gl_camera -{ - vec3 position; - vec3 dirx; - vec3 diry; - vec3 dirz; - vec2 resolution; - float aspect_ratio; - float FOV; - float focus; - float bokeh; - float exposure; - float mblur; - float speckle; - float size; - float bloomintensity; - float bloomtreshold; - float bloomradius; - int stepN; - int step; -}; - - -ivec2 getGpos(int index) -{ - int y = index/group_size; - int x = index%group_size; - return ivec2(x,y); -} - -uniform gl_camera Camera; -float fovray; - -ray get_ray(vec2 screen_pos) -{ - vec2 shift = Camera.FOV*(2.f*screen_pos - 1.f)*vec2(Camera.aspect_ratio, 1.f); - ray cray; - cray.pos = Camera.position + Camera.size*(Camera.dirx*shift.x + Camera.diry*shift.y); - cray.dir = normalize(Camera.dirx*shift.x + Camera.diry*shift.y + Camera.dirz); - float aspect_ratio_ratio = Camera.aspect_ratio/(Camera.resolution.x/Camera.resolution.y); - fovray = 1.41*Camera.FOV*max(1.f/aspect_ratio_ratio, aspect_ratio_ratio)/Camera.resolution.x; //pixel FOV - return cray; -} - -#define COL col_scene -#define DE de_scene - -uniform float iFracScale; -uniform float iFracAng1; -uniform float iFracAng2; -uniform vec3 iFracShift; -uniform vec3 iFracCol; -uniform vec3 iMarblePos; -uniform float iMarbleRad; -uniform float iFlagScale; -uniform vec3 iFlagPos; -uniform int FRACTAL_ITER; -uniform int MARBLE_MODE; -uniform float time; - -layout(rgba8, binding = 3) uniform image2D color_flag; - -///Original MM distance estimators - -float s1 = sin(iFracAng1), c1 = cos(iFracAng1), s2 = sin(iFracAng2), c2 = cos(iFracAng2); - -//########################################## -// Space folding -//########################################## -void planeFold(inout vec4 z, vec3 n, float d) { - z.xyz -= 2.0 * min(0.0, dot(z.xyz, n) - d) * n; -} -void sierpinskiFold(inout vec4 z) { - z.xy -= min(z.x + z.y, 0.0); - z.xz -= min(z.x + z.z, 0.0); - z.yz -= min(z.y + z.z, 0.0); -} - -// Polynomial smooth minimum by iq -float smoothmin(float a, float b, float k) { - float h = clamp(0.5 + 0.5*(a-b)/k, 0.0, 1.0); - return mix(a, b, h) - k*h*(1.0-h); -} - -/*void mengerFold(inout vec4 z) { - float a = smoothmin(z.x - z.y, 0.0, 0.03); - z.x -= a; - z.y += a; - a = smoothmin(z.x - z.z, 0.0, 0.03); - z.x -= a; - z.z += a; - a = smoothmin(z.y - z.z, 0.0, 0.03); - z.y -= a; - z.z += a; -}*/ - - -void mengerFold(inout vec4 z) { - float a = min(z.x - z.y, 0.0); - z.x -= a; - z.y += a; - a = min(z.x - z.z, 0.0); - z.x -= a; - z.z += a; - a = min(z.y - z.z, 0.0); - z.y -= a; - z.z += a; -} -void boxFold(inout vec4 z, vec3 r) { - z.xyz = clamp(z.xyz, -r, r) * 2.0 - z.xyz; -} -void rotX(inout vec4 z, float s, float c) { - z.yz = vec2(c*z.y + s*z.z, c*z.z - s*z.y); -} -void rotY(inout vec4 z, float s, float c) { - z.xz = vec2(c*z.x - s*z.z, c*z.z + s*z.x); -} -void rotZ(inout vec4 z, float s, float c) { - z.xy = vec2(c*z.x + s*z.y, c*z.y - s*z.x); -} -void rotX(inout vec4 z, float a) { - rotX(z, sin(a), cos(a)); -} -void rotY(inout vec4 z, float a) { - rotY(z, sin(a), cos(a)); -} -void rotZ(inout vec4 z, float a) { - rotZ(z, sin(a), cos(a)); -} - -//########################################## -// Primitive DEs -//########################################## -float de_sphere(vec4 p, float r) { - return (length(p.xyz) - r) / p.w; -} -float de_box(vec4 p, vec3 s) { - vec3 a = abs(p.xyz) - s; - return (min(max(max(a.x, a.y), a.z), 0.0) + length(max(a, 0.0))) / p.w; -} -float de_tetrahedron(vec4 p, float r) { - float md = max(max(-p.x - p.y - p.z, p.x + p.y - p.z), - max(-p.x + p.y + p.z, p.x - p.y + p.z)); - return (md - r) / (p.w * sqrt(3.0)); -} -float de_capsule(vec4 p, float h, float r) { - p.y -= clamp(p.y, -h, h); - return (length(p.xyz) - r) / p.w; -} - -//########################################## -// Main DEs -//########################################## -float de_fractal(vec4 p) -{ - for (int i = 0; i < FRACTAL_ITER; ++i) { - p.xyz = abs(p.xyz); - rotZ(p, s1, c1); - mengerFold(p); - rotX(p, s2, c2); - p *= iFracScale; - p.xyz += iFracShift; - } - return de_box(p, vec3(6.0)); -} - -vec4 col_fractal(vec4 p) -{ - vec3 orbit = vec3(0.0); - for (int i = 0; i < FRACTAL_ITER; ++i) { - p.xyz = abs(p.xyz); - rotZ(p, s1, c1); - mengerFold(p); - rotX(p, s2, c2); - p *= iFracScale; - p.xyz += iFracShift; - orbit = max(orbit, p.xyz*iFracCol); - } - return vec4(orbit, de_box(p, vec3(6.0))); -} - -float de_marble(vec4 p) -{ - return de_sphere(p - vec4(iMarblePos, 0), iMarbleRad); -} - -vec4 col_marble(vec4 p) -{ - vec4 col = vec4(0, 0, 0, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); - return vec4(col.x, col.y, col.z, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); -} - -float de_flag(vec4 p) -{ - vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale; - vec4 p_s = p/iMarbleRad; - vec4 d_pos = p - vec4(f_pos, 0); - vec4 caps_pos = p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0); - //animated flag woooo - float oscillation = sin(8*p_s.x - 1*p_s.y - 20*time) + 0.4*sin(11*p_s.x + 2*p_s.y - 25*time) + 0.15*sin(20*p_s.x - 5*p_s.y - 27*time); - //scale the flag displacement amplitude by the distance from the flagpole - float d = 0.4*de_box(d_pos + caps_pos.x*vec4(0,0.02+ caps_pos.x* 0.5+0.01*oscillation,0.04*oscillation,0), vec3(1.5, 0.8, 0.005)*iMarbleRad); - d = min(d, de_capsule(caps_pos, iMarbleRad*2.4, iMarbleRad*0.05)); - return d; -} - -vec4 col_flag(vec4 p) -{ - vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale; - float d1 = de_box(p - vec4(f_pos, 0), vec3(1.5, 0.8, 0.08)*iMarbleRad); - float d2 = de_capsule(p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0), iMarbleRad*2.4, iMarbleRad*0.18); - if (d1 < d2) { - vec2 color_flag_s = vec2(imageLoad(color_flag)); - return vec4(1.0, 0.2, 0.1, d1); - } else { - return vec4(0.9, 0.9, 0.1, d2); - } -} - -//float DE_count = 0; - -float de_scene(vec3 pos) -{ - //DE_count = DE_count+1; - vec4 p = vec4(pos,1.f); - float d = de_fractal(p); - d = min(d, de_marble(p)); - d = min(d, de_flag(p)); - return d; -} - -vec4 col_scene(vec3 pos) -{ - //DE_count = DE_count+1; - vec4 p = vec4(pos,1.f); - vec4 col = col_fractal(p); - vec4 col_f = col_flag(p); - if (col_f.w < col.w) { col = col_f; } - vec4 col_m = col_marble(p); - if (col_m.w < col.w) { - return vec4(col_m.xyz, 1.0); - } - return vec4(min(col.xyz,1), 0.0); -} - -//A faster formula to find the gradient/normal direction of the DE -//credit to http://www.iquilezles.org/www/articles/normalsSDF/normalsSDF.htm -vec4 calcNormal(vec3 p, float dx) { - const vec3 k = vec3(1,-1,0); - return (k.xyyx*DE(p + k.xyy*dx) + - k.yyxx*DE(p + k.yyx*dx) + - k.yxyx*DE(p + k.yxy*dx) + - k.xxxx*DE(p + k.xxx*dx))/vec4(4*dx,4*dx,4*dx,4); -} - - -#define MAX_DIST 50 -#define MIN_DIST 1e-7 -#define MAX_MARCHES 512 -#define NORMARCHES 2 - - -void ray_march(inout vec4 pos, inout vec4 dir, inout vec4 var, float fov, float d0) -{ - //March the ray - for (; var.x < MAX_MARCHES; var.x += 1.0) { - //if the distance from the surface is less than the distance per pixel we stop - if(dir.w > MAX_DIST || pos.w<0) - { - break; - } - - if(pos.w < max(fov*dir.w, MIN_DIST) && var.x > 0 && var.w < 1) - { - break; - } - - dir.w += pos.w; - pos.xyz += pos.w*dir.xyz; - pos.w = DE(pos.xyz)-d0*dir.w; - var.w = 0; - } - - pos.w += d0*dir.w; -} - -float shadow_march(vec4 pos, vec4 dir, float distance2light, float light_angle) -{ - float light_visibility = 1; - float ph = 1e5; - float dDEdt = 0; - pos.w = DE(pos.xyz); - int i = 0; - for (; i < MAX_MARCHES; i++) { - - dir.w += pos.w; - pos.xyz += pos.w*dir.xyz; - pos.w = DE(pos.xyz); - - float y = pos.w*pos.w/(2.0*ph); - float d = (pos.w+ph)*0.5*(1-dDEdt); - float angle = d/(max(MIN_DIST,dir.w-y)*light_angle); - - light_visibility = min(light_visibility, angle); - - dDEdt = dDEdt*0.75 + 0.25*(pos.w-ph)/ph; - ph = pos.w; - - if(dir.w >= distance2light) - { - break; - } - - if(dir.w > MAX_DIST || pos.w < max(fovray*dir.w, MIN_DIST)) - { - return 0; - } - } - //return light_visibility; //bad - return 0.5-cos(3.14159265*light_visibility)*0.5; //looks better and is more physically accurate(for a circular light source) -} - -float sphere_intersection(vec3 r, vec3 p, vec4 sphere) -{ - p = p - sphere.xyz; - if(p == vec3(0)) return sphere.w; - - float b = dot(p, r); - float c = sphere.w*sphere.w - dot(p,p); - float d = b*b + c; - - if((d <= 0) || (c <= 0)) //if no intersection - { - return 0; - } - else - { - return sqrt(d) - b; //use furthest solution in the direction of the ray - } -} - -float find_furthest_intersection(vec3 r, vec3 p, ivec2 id) -{ - float d = 0; - ivec2 idR = min(id+1, group_size-1); - ivec2 idL = max(id-1, 0); - for(int i = idL.x; i <= idR.x; i++) - { - for(int j = idL.y; j <= idR.y; j++) - { - d = max(d, sphere_intersection(r,p,de_sph[i][j])); - } - } - return d; -} - - -float find_furthest_intersection_all(vec3 r, vec3 p, ivec2 id) -{ - float d = 0; - for(int i = 0; i < group_size; i++) - { - for(int j = 0; j < group_size; j++) - { - d = max(d, sphere_intersection(r,p,de_sph[i][j])); - } - } - return d; -} - -void normarch(inout vec4 pos) -{ - //calculate the normal - vec4 norm = calcNormal(pos.xyz, pos.w/8); - norm.xyz = normalize(norm.xyz); - pos.w = norm.w; - - //march in the direction of the normal - #pragma unroll - for(int i = 0; i < NORMARCHES; i++) - { - pos.xyz += pos.w*norm.xyz; - pos.w = DE(pos.xyz); - } -} - - -///The first step of multi resolution ray marching - -void main() { - ivec2 global_pos = ivec2(gl_GlobalInvocationID.x,gl_GlobalInvocationID.y); - int local_indx = int(gl_LocalInvocationIndex); - vec2 img_size = vec2(imageSize(DE_output)); - //if within the texture - - //initialize the ray - ray rr = get_ray(vec2(global_pos)/img_size); - vec4 pos = vec4(rr.pos,0); - vec4 dir = vec4(rr.dir,0); - vec4 var = vec4(0); - float res_ratio = float(imageSize(color_HDR).x/imageSize(DE_output).x);; - fovray *= res_ratio; - dir.w = 4*Camera.size; - ray_march(pos, dir, var, fovray, fovray); - - vec4 pos1 = pos; - - normarch(pos1); - - //save the DE spheres - imageStore(DE_output, global_pos, pos); - imageStore(DE2_output, global_pos, pos1); - imageStore(var_output, global_pos, var); -} - -ERROR: 0:235: 'imageLoad' : no matching overloaded function found (using implicit conversion) - diff --git a/game_folder/shaders/compute/MRRM3.glsl_error.txt b/game_folder/shaders/compute/MRRM3.glsl_error.txt deleted file mode 100644 index be29072e..00000000 --- a/game_folder/shaders/compute/MRRM3.glsl_error.txt +++ /dev/null @@ -1,833 +0,0 @@ -#version 430 -//4*4 ray bundle -#define group_size 8 -#define block_size 64 -#define RBM1 0 - -layout(local_size_x = group_size, local_size_y = group_size) in; -layout(rgba32f, binding = 0) uniform image2D DE_input; -layout(rgba32f, binding = 1) uniform image2D DE2_input; -layout(rgba32f, binding = 2) uniform image2D var_input; -layout(rgba32f, binding = 3) uniform image2D DE_output; //calculate final DE spheres - -//make all the local distance estimator spheres shared -shared vec4 de_sph[group_size][group_size]; - - -struct ray -{ - vec3 pos; - vec3 dir; -}; - -struct gl_camera -{ - vec3 position; - vec3 dirx; - vec3 diry; - vec3 dirz; - vec2 resolution; - float aspect_ratio; - float FOV; - float focus; - float bokeh; - float exposure; - float mblur; - float speckle; - float size; - float bloomintensity; - float bloomtreshold; - float bloomradius; - int stepN; - int step; -}; - - -ivec2 getGpos(int index) -{ - int y = index/group_size; - int x = index%group_size; - return ivec2(x,y); -} - -uniform gl_camera Camera; -float fovray; - -ray get_ray(vec2 screen_pos) -{ - vec2 shift = Camera.FOV*(2.f*screen_pos - 1.f)*vec2(Camera.aspect_ratio, 1.f); - ray cray; - cray.pos = Camera.position + Camera.size*(Camera.dirx*shift.x + Camera.diry*shift.y); - cray.dir = normalize(Camera.dirx*shift.x + Camera.diry*shift.y + Camera.dirz); - float aspect_ratio_ratio = Camera.aspect_ratio/(Camera.resolution.x/Camera.resolution.y); - fovray = 1.41*Camera.FOV*max(1.f/aspect_ratio_ratio, aspect_ratio_ratio)/Camera.resolution.x; //pixel FOV - return cray; -} - -#define COL col_scene -#define DE de_scene - -uniform float iFracScale; -uniform float iFracAng1; -uniform float iFracAng2; -uniform vec3 iFracShift; -uniform vec3 iFracCol; -uniform vec3 iMarblePos; -uniform float iMarbleRad; -uniform float iFlagScale; -uniform vec3 iFlagPos; -uniform int FRACTAL_ITER; -uniform int MARBLE_MODE; -uniform float time; - -///Original MM distance estimators - -float s1 = sin(iFracAng1), c1 = cos(iFracAng1), s2 = sin(iFracAng2), c2 = cos(iFracAng2); - -//########################################## -// Space folding -//########################################## -void planeFold(inout vec4 z, vec3 n, float d) { - z.xyz -= 2.0 * min(0.0, dot(z.xyz, n) - d) * n; -} -void sierpinskiFold(inout vec4 z) { - z.xy -= min(z.x + z.y, 0.0); - z.xz -= min(z.x + z.z, 0.0); - z.yz -= min(z.y + z.z, 0.0); -} - -// Polynomial smooth minimum by iq -float smoothmin(float a, float b, float k) { - float h = clamp(0.5 + 0.5*(a-b)/k, 0.0, 1.0); - return mix(a, b, h) - k*h*(1.0-h); -} - -void mengerFold(inout vec4 z) { - float a = smoothmin(z.x - z.y, 0.0, 0.03); - z.x -= a; - z.y += a; - a = smoothmin(z.x - z.z, 0.0, 0.03); - z.x -= a; - z.z += a; - a = smoothmin(z.y - z.z, 0.0, 0.03); - z.y -= a; - z.z += a; -} -void boxFold(inout vec4 z, vec3 r) { - z.xyz = clamp(z.xyz, -r, r) * 2.0 - z.xyz; -} -void rotX(inout vec4 z, float s, float c) { - z.yz = vec2(c*z.y + s*z.z, c*z.z - s*z.y); -} -void rotY(inout vec4 z, float s, float c) { - z.xz = vec2(c*z.x - s*z.z, c*z.z + s*z.x); -} -void rotZ(inout vec4 z, float s, float c) { - z.xy = vec2(c*z.x + s*z.y, c*z.y - s*z.x); -} -void rotX(inout vec4 z, float a) { - rotX(z, sin(a), cos(a)); -} -void rotY(inout vec4 z, float a) { - rotY(z, sin(a), cos(a)); -} -void rotZ(inout vec4 z, float a) { - rotZ(z, sin(a), cos(a)); -} - -//########################################## -// Primitive DEs -//########################################## -float de_sphere(vec4 p, float r) { - return (length(p.xyz) - r) / p.w; -} -float de_box(vec4 p, vec3 s) { - vec3 a = abs(p.xyz) - s; - return (min(max(max(a.x, a.y), a.z), 0.0) + length(max(a, 0.0))) / p.w; -} -float de_tetrahedron(vec4 p, float r) { - float md = max(max(-p.x - p.y - p.z, p.x + p.y - p.z), - max(-p.x + p.y + p.z, p.x - p.y + p.z)); - return (md - r) / (p.w * sqrt(3.0)); -} -float de_capsule(vec4 p, float h, float r) { - p.y -= clamp(p.y, -h, h); - return (length(p.xyz) - r) / p.w; -} - -//########################################## -// Main DEs -//########################################## -float de_fractal(vec4 p) -{ - for (int i = 0; i < FRACTAL_ITER; ++i) { - p.xyz = abs(p.xyz); - rotZ(p, s1, c1); - mengerFold(p); - rotX(p, s2, c2); - p *= iFracScale; - p.xyz += iFracShift; - } - return de_box(p, vec3(6.0)); -} - -vec4 col_fractal(vec4 p) -{ - vec3 orbit = vec3(0.0); - for (int i = 0; i < FRACTAL_ITER; ++i) { - p.xyz = abs(p.xyz); - rotZ(p, s1, c1); - mengerFold(p); - rotX(p, s2, c2); - p *= iFracScale; - p.xyz += iFracShift; - orbit = max(orbit, p.xyz*iFracCol); - } - return vec4(orbit, de_box(p, vec3(6.0))); -} - -float de_marble(vec4 p) -{ - return de_sphere(p - vec4(iMarblePos, 0), iMarbleRad); -} - -vec4 col_marble(vec4 p) -{ - vec4 col = vec4(0, 0, 0, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); - return vec4(col.x, col.y, col.z, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); -} - -float de_flag(vec4 p) -{ - vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale; - vec4 p_s = p/iMarbleRad; - vec4 d_pos = p - vec4(f_pos, 0); - vec4 caps_pos = p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0); - //animated flag woooo - float oscillation = sin(4*p_s.x + 1*p_s.y - 10*time) + 0.4*sin(6*p_s.x - 2*p_s.y - 12*time) + 0.1*sin(16*p_s.x + 5*p_s.y - 14*time); - //scale the flag displacement amplitude by the distance from the flagpole - float d = 0.7*de_box(d_pos + caps_pos.x*vec4(0,0.005*oscillation,0.03*oscillation,0), vec3(1.5, 0.8, 0.01)*iMarbleRad); - d = min(d, de_capsule(caps_pos, iMarbleRad*2.4, iMarbleRad*0.05)); - return d; -} - -vec4 col_flag(vec4 p) -{ - vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale; - float d1 = de_box(p - vec4(f_pos, 0), vec3(1.5, 0.8, 0.08)*iMarbleRad); - float d2 = de_capsule(p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0), iMarbleRad*2.4, iMarbleRad*0.18); - if (d1 < d2) { - return vec4(1.0, 0.2, 0.1, d1); - } else { - return vec4(0.9, 0.9, 0.1, d2); - } -} - -//float DE_count = 0; - -float de_scene(vec3 pos) -{ - //DE_count = DE_count+1; - vec4 p = vec4(pos,1.f); - float d = de_fractal(p); - d = min(d, de_marble(p)); - d = min(d, de_flag(p)); - return d; -} - -vec4 col_scene(vec3 pos) -{ - //DE_count = DE_count+1; - vec4 p = vec4(pos,1.f); - vec4 col = col_fractal(p); - vec4 col_f = col_flag(p); - if (col_f.w < col.w) { col = col_f; } - vec4 col_m = col_marble(p); - if (col_m.w < col.w) { - return vec4(col_m.xyz, 1.0); - } - return vec4(min(col.xyz,1), 0.0); -} - -//A faster formula to find the gradient/normal direction of the DE -//credit to http://www.iquilezles.org/www/articles/normalsSDF/normalsSDF.htm -vec4 calcNormal(vec3 p, float dx) { - const vec3 k = vec3(1,-1,0); - return (k.xyyx*DE(p + k.xyy*dx) + - k.yyxx*DE(p + k.yyx*dx) + - k.yxyx*DE(p + k.yxy*dx) + - k.xxxx*DE(p + k.xxx*dx))/vec4(4*dx,4*dx,4*dx,4); -} - - -#define MAX_DIST 50 -#define MIN_DIST 1e-5 -#define MAX_MARCHES 512 -#define NORMARCHES 5 - - -void ray_march(inout vec4 pos, inout vec4 dir, inout vec4 var, float fov, float d0) -{ - //March the ray - for (; var.x < MAX_MARCHES; var.x += 1.0) { - //if the distance from the surface is less than the distance per pixel we stop - if(dir.w > MAX_DIST || pos.w<0) - { - break; - } - - if(pos.w < max(fov*dir.w, MIN_DIST) && var.x > 0 && var.w < 1) - { - break; - } - - dir.w += pos.w; - pos.xyz += pos.w*dir.xyz; - pos.w = DE(pos.xyz)-d0*dir.w; - var.w = 0; - } - - pos.w += d0*dir.w; -} - -// Polynomial smooth minimum by iq -float smin(float a, float b, float k) { - float h = clamp(0.5 + 0.5*(a-b)/k, 0.0, 1.0); - return mix(a, b, h) - k*h*(1.0-h); -} - -float shadow_march(vec4 pos, vec4 dir, float distance2light, float light_angle) -{ - float light_visibility = 1; - float ph = 1e5; - float dDEdt = 0; - pos.w = DE(pos.xyz); - int i = 0; - for (; i < MAX_MARCHES; i++) { - - dir.w += pos.w; - pos.xyz += pos.w*dir.xyz; - pos.w = DE(pos.xyz); - - float y = pos.w*pos.w/(2.0*ph); - float d = (pos.w+ph)*0.5*(1-dDEdt); - float angle = d/(max(MIN_DIST,dir.w-y)*light_angle); - - light_visibility = min(light_visibility, angle); - - dDEdt = dDEdt*0.75 + 0.25*(pos.w-ph)/ph; - ph = pos.w; - - if(dir.w >= distance2light) - { - break; - } - - if(dir.w > MAX_DIST || pos.w < max(fovray*dir.w, MIN_DIST)) - { - return 0; - } - } - //return light_visibility; //bad - return 0.5-cos(3.14159265*light_visibility)*0.5; //looks better and is more physically accurate(for a circular light source) -} - -float sphere_intersection(vec3 r, vec3 p, vec4 sphere) -{ - p = p - sphere.xyz; - if(p == vec3(0)) return sphere.w; - - float b = dot(p, r); - float c = sphere.w*sphere.w - dot(p,p); - float d = b*b + c; - - if((d <= 0) || (c <= 0)) //if no intersection - { - return 0; - } - else - { - return sqrt(d) - b; //use furthest solution in the direction of the ray - } -} - -float find_furthest_intersection(vec3 r, vec3 p, ivec2 id) -{ - float d = 0; - ivec2 idR = min(id+1, group_size-1); - ivec2 idL = max(id-1, 0); - for(int i = idL.x; i <= idR.x; i++) - { - for(int j = idL.y; j <= idR.y; j++) - { - d = max(d, sphere_intersection(r,p,de_sph[i][j])); - } - } - return d; -} - - -float find_furthest_intersection_all(vec3 r, vec3 p, ivec2 id) -{ - float d = 0; - for(int i = 0; i < group_size; i++) - { - for(int j = 0; j < group_size; j++) - { - d = max(d, sphere_intersection(r,p,de_sph[i][j])); - } - } - return d; -} - -void normarch(inout vec4 pos) -{ - //calculate the normal - vec4 norm = calcNormal(pos.xyz, pos.w/8); - norm.xyz = normalize(norm.xyz); - pos.w = norm.w; - - float prev_w = 0; - //march in the direction of the normal - #pragma unroll - for(int i = 0; i < NORMARCHES; i++) - { - pos.xyz += pos.w*norm.xyz; - pos.w = DE(pos.xyz); - if(pos.w < prev_w) - { - pos.xyz -= prev_w*norm.xyz; - pos.w = prev_w; - break; - } - prev_w = pos.w; - } -} - - -#define PI 3.14159265 -#define AMBIENT_MARCHES 5 -#define AMBIENT_COLOR 2*vec4(1,1,1,1) -#define LIGHT_ANGLE 0.08 - -uniform vec3 BACKGROUND_COLOR; -uniform vec3 LIGHT_DIRECTION; -uniform float PBR_METALLIC; -uniform float PBR_ROUGHNESS; -uniform vec3 LIGHT_COLOR; -uniform bool SHADOWS_ENABLED; - - -//better to use a sampler though -vec4 interp(layout (rgba32f) image2D text, vec2 coord) -{ - //coord *= 0.99; - ivec2 ci = ivec2(coord); - vec2 d = coord - floor(coord); - return imageLoad(text, ci)*(1-d.x)*(1-d.y) + - imageLoad(text, ci+ivec2(1,0))*d.x*(1-d.y) + - imageLoad(text, ci+ivec2(0,1))*(1-d.x)*d.y + - imageLoad(text, ci+ivec2(1))*d.x*d.y; -} - - -///PBR functions -vec3 fresnelSchlick(float cosTheta, vec3 F0) -{ - return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); -} - -float DistributionGGX(vec3 N, vec3 H, float roughness) -{ - float a = roughness*roughness; - float a2 = a*a; - float NdotH = max(dot(N, H), 0.0); - float NdotH2 = NdotH*NdotH; - - float num = a2; - float denom = (NdotH2 * (a2 - 1.0) + 1.0); - denom = PI * denom * denom; - - return num / denom; -} - -float GeometrySchlickGGX(float NdotV, float roughness) -{ - float r = (roughness + 1.0); - float k = (r*r) / 8.0; - - float num = NdotV; - float denom = NdotV * (1.0 - k) + k; - - return num / denom; -} - -float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) -{ - float NdotV = max(dot(N, V), 0.0); - float NdotL = max(dot(N, L), 0.0); - float ggx2 = GeometrySchlickGGX(NdotV, roughness); - float ggx1 = GeometrySchlickGGX(NdotL, roughness); - - return ggx1 * ggx2; -} -///END PBR functions - -const float Br = 0.0025; -const float Bm = 0.0003; -const float g = 0.9800; -const vec3 nitrogen = vec3(0.650, 0.570, 0.475); -const vec3 Kr = Br / pow(nitrogen, vec3(4.0)); -const vec3 Km = Bm / pow(nitrogen, vec3(0.84)); - -vec3 sky_color(in vec3 pos) -{ - // Atmosphere Scattering - vec3 fsun = LIGHT_DIRECTION; - float brightnees = exp(min(5*pos.y,0)); - if(pos.y < 0) - { - pos.y = 0; - pos.xyz = normalize(pos.xyz); - } - float mu = dot(normalize(pos), normalize(fsun)); - - vec3 extinction = mix(exp(-exp(-((pos.y + fsun.y * 4.0) * (exp(-pos.y * 16.0) + 0.1) / 80.0) / Br) * (exp(-pos.y * 16.0) + 0.1) * Kr / Br) * exp(-pos.y * exp(-pos.y * 8.0 ) * 4.0) * exp(-pos.y * 2.0) * 4.0, vec3(1.0 - exp(fsun.y)) * 0.2, -fsun.y * 0.2 + 0.5); - vec3 sky_col = brightnees* 3.0 / (8.0 * 3.14) * (1.0 + mu * mu) * (Kr + Km * (1.0 - g * g) / (2.0 + g * g) / pow(1.0 + g * g - 2.0 * g * mu, 1.5)) / (Br + Bm) * extinction; - sky_col = 0.4*clamp(sky_col,0,10); - return sky_col*sky_col; -} - -vec3 ambient_sky_color(in vec3 pos) -{ - float y = pos.y; - pos.xyz = normalize(vec3(1,0,0)); - return sky_color(pos)*exp(-abs(y)); -} - -vec4 ambient_occlusion(in vec4 pos, in vec4 norm, in vec4 dir) -{ - vec3 dir1 = normalize(cross(dir.xyz,norm.xyz)); - vec3 dir2 = normalize(cross(dir1,norm.xyz)); - pos.w = iMarbleRad/2; - - vec3 pos0 = pos.xyz; - - float shifter = 2; - float dcoef = 0.02/iMarbleRad; - float occlusion_angle = 0; - float integral = 0; - float i_coef = 0; - - vec3 ambient_color = ambient_sky_color(norm.xyz); - - //march in the direction of the normal - #pragma unroll - for(int i = 0; i < AMBIENT_MARCHES; i++) - { - //moving in a zig-zag - vec3 direction = normalize(norm.xyz + 0.6*((mod(shifter,3.f)-1)*dir1 + (mod(shifter+1,3.f)-1)*dir2)); - shifter += 1; - pos.xyz += pos.w*direction; - pos.w = DE(pos.xyz); - - norm.w = length(pos0 - pos.xyz); - i_coef = 1/(dcoef*norm.w+1);//importance - occlusion_angle += i_coef*clamp(pos.w/norm.w,0,1); - integral += i_coef; - } - - occlusion_angle /= integral; // average weighted by importance - return vec4(ambient_color,1)*(0.5-cos(3.14159265*occlusion_angle)*0.5); -} - - -vec3 refraction(vec3 rd, vec3 n, float p) { - float dot_nd = dot(rd, n); - return p * (rd - dot_nd * n) + sqrt(1.0 - (p * p) * (1.0 - dot_nd * dot_nd)) * n; -} - -vec3 lighting(vec4 color, vec4 pos, vec4 dir, vec4 norm, vec3 refl, vec3 refr, float shadow) -{ - vec3 albedo = color.xyz; - albedo *= albedo; //square it to make the fractals more colorfull - - vec4 ambient_color = ambient_occlusion(pos, norm, dir); - - float metallic = PBR_METALLIC; - vec3 F0 = vec3(0.04); - F0 = mix(F0, albedo, metallic); - - //reflectance equation - vec3 Lo = vec3(0.0); - vec3 V = -dir.xyz; - vec3 N = norm.xyz; - - { //ambient occlusion contribution - float roughness = max(PBR_ROUGHNESS,0.5); - vec3 L = normalize(N); - vec3 H = normalize(V + L); - vec3 radiance = ambient_color.xyz; - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - if(!SHADOWS_ENABLED) - { - shadow = ambient_color.w; - } - - vec3 sun_color = sky_color(LIGHT_DIRECTION); - - { //light contribution - float roughness = PBR_ROUGHNESS; - vec3 L = normalize(LIGHT_DIRECTION); - vec3 H = normalize(V + L); - vec3 radiance = sun_color*shadow*(0.6+0.4*ambient_color.w); - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - { //light reflection, GI imitation - float roughness = max(PBR_ROUGHNESS,0.5); - vec3 L = normalize(-LIGHT_DIRECTION); - vec3 H = normalize(V + L); - vec3 radiance = 0.35*sun_color*ambient_color.w*(1-ambient_color.w); - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - if(color.w>0.5) // if marble - { - vec3 n = normalize(pos.xyz - iMarblePos); - vec3 q = dir.xyz - n*(2*dot(dir.xyz,n)); - //Combine for final marble color - if(MARBLE_MODE == 0) - { - //glass - vec3 F0 = vec3(0.03); - vec3 L = normalize(q); - vec3 H = normalize(V + L); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - Lo += kS*refl + kD*refr; - } - else - { - //metal - vec3 F0 = vec3(0.6); - vec3 L = normalize(q); - vec3 H = normalize(V + L); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - Lo += kS*refl; - } - } - - return Lo; -} - -vec3 shading_simple(in vec4 pos, in vec4 dir, float fov, float shadow) -{ - - - if(pos.w < max(16*fovray*dir.w, MIN_DIST)) - { - //calculate the normal - float error = 0.5*fov*dir.w; - vec4 norm = calcNormal(pos.xyz, max(MIN_DIST, error)); - norm.xyz = normalize(norm.xyz); - if(norm.w < -error) - { - return COL(pos.xyz); - } - else - { - //optimize color sampling - vec3 cpos = pos.xyz - norm.w*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - - vec4 color = COL(cpos); - return lighting(color, pos, dir, norm, vec3(0), vec3(0), shadow); - } - } - else - { - return sky_color(dir.xyz); - } -} - - -vec3 render_ray(in vec4 pos, in vec4 dir, float fov) -{ - vec4 var = vec4(0,0,0,1); - ray_march(pos, dir, var, fov, MIN_DIST); - float shadow = shadow_march(pos, vec4(LIGHT_DIRECTION,0), MAX_DIST, LIGHT_ANGLE); - return shading_simple(pos, dir, fov, shadow); -} - -vec3 shading(in vec4 pos, in vec4 dir, float fov, float shadow) -{ - if(pos.w < max(16*fovray*dir.w, MIN_DIST)) - { - //calculate the normal - float error = 0.5*fov*dir.w; - vec4 norm = calcNormal(pos.xyz, max(MIN_DIST, error)); - norm.xyz = normalize(norm.xyz); - if(norm.w < -error) - { - return COL(pos.xyz); - } - else - { - //optimize color sampling - vec3 cpos = pos.xyz - norm.w*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - - vec4 color = COL(cpos); - vec3 refl = vec3(0); - vec3 refr = vec3(0); - if(color.w>0.5) // if marble - { - vec3 n = normalize(iMarblePos - cpos.xyz); - vec3 q = refraction(dir.xyz, n, 1.0 / 1.5); - vec3 p2 = cpos.xyz + (dot(q, n) * 2.0 * iMarbleRad) * q; - n = normalize(p2 - iMarblePos); - q = (dot(q, dir.xyz) * 2.0) * q - dir.xyz; - vec4 p_temp = vec4(p2 + n * (MIN_DIST * 10), 0); - vec4 r_temp = vec4(q, 0); - - refr = render_ray(p_temp, r_temp, fov); - - //Calculate reflection - n = normalize(cpos.xyz - iMarblePos); - q = dir.xyz - n*(2*dot(dir.xyz,n)); - p_temp = vec4(cpos.xyz + n * (MIN_DIST * 10), 0); - r_temp = vec4(q, dir.w); - - refl = render_ray(p_temp, r_temp, fov); - } - - return lighting(color, cpos, dir, norm, refl, refr, shadow); - } - } - else - { - return sky_color(dir.xyz); - } - -} - -vec3 HDRmapping(vec3 color, float exposure, float gamma) -{ - // Exposure tone mapping - vec3 mapped = vec3(1.0) - exp(-color * exposure); - // Gamma correction - return pow(mapped, vec3(1.0 / gamma)); -} - - -///The second step of multi resolution ray marching - -void main() { - ivec2 global_pos = ivec2(gl_GlobalInvocationID.xy); - ivec2 local_indx = ivec2(gl_LocalInvocationID.xy); - vec2 img_size = vec2(imageSize(DE_output)); - vec2 pimg_size = vec2(imageSize(DE_input)); - vec2 MRRM_step_scale = img_size/pimg_size; - //if within the texture - - ivec2 prev_pos = min(ivec2((vec2(global_pos)/MRRM_step_scale) + 0.5),ivec2(pimg_size)-1); - //initialize the ray - vec4 sph = imageLoad(DE_input, prev_pos); - vec4 sph_norm = imageLoad(DE2_input, prev_pos); - - #if(RBM1) - de_sph[local_indx.x][local_indx.y] = sph; - memoryBarrierShared(); - #endif - - ray rr = get_ray(vec2(global_pos)/img_size); - vec4 pos = vec4(rr.pos,0); - vec4 dir = vec4(rr.dir,0); - vec4 var = imageLoad(var_input, prev_pos); - - float td = dot(dir.xyz, sph.xyz - pos.xyz);//traveled distance - - //first order, MRRM - pos.xyz += dir.xyz*td;//move local ray beginning inside the DE sphere - dir.w += td; - - //calculate new best pos, second order, MRRBM - #if(RBM1) - barrier(); - float d = find_furthest_intersection(dir.xyz, pos.xyz, local_indx); - #else - float d = sphere_intersection(dir.xyz, pos.xyz, sph); - d = max(d, sphere_intersection(dir.xyz, pos.xyz, sph_norm)); - #endif - - pos.w = d; - var.w = 1; - - //pos.xyz += d*dir.xyz; - //pos.w = sph.w; - ray_march(pos, dir, var, fovray, 0); - - //save the DE spheres - imageStore(DE_output, global_pos, pos); -} - -ERROR: 0:762: 'lighting' : no matching overloaded function found (using implicit conversion) - diff --git a/game_folder/shaders/compute/Shading_step.glsl_error.txt b/game_folder/shaders/compute/Shading_step.glsl_error.txt deleted file mode 100644 index 740a03d1..00000000 --- a/game_folder/shaders/compute/Shading_step.glsl_error.txt +++ /dev/null @@ -1,809 +0,0 @@ -#version 430 -//4*4 ray bundle -#define group_size 8 -#define block_size 64 - -layout(local_size_x = group_size, local_size_y = group_size) in; -layout(rgba32f, binding = 0) uniform image2D illumination; //shadows -layout(rgba32f, binding = 1) uniform image2D DE_input; -layout(rgba32f, binding = 2) uniform image2D color_HDR; //calculate final color - - -//make all the local distance estimator spheres shared -shared vec4 de_sph[group_size][group_size]; - - -struct ray -{ - vec3 pos; - vec3 dir; -}; - -struct gl_camera -{ - vec3 position; - vec3 dirx; - vec3 diry; - vec3 dirz; - vec2 resolution; - float aspect_ratio; - float FOV; - float focus; - float bokeh; - float exposure; - float mblur; - float speckle; - float size; - float bloomintensity; - float bloomtreshold; - float bloomradius; - int stepN; - int step; -}; - - -ivec2 getGpos(int index) -{ - int y = index/group_size; - int x = index%group_size; - return ivec2(x,y); -} - -uniform gl_camera Camera; -float fovray; - -ray get_ray(vec2 screen_pos) -{ - vec2 shift = Camera.FOV*(2.f*screen_pos - 1.f)*vec2(Camera.aspect_ratio, 1.f); - ray cray; - cray.pos = Camera.position + Camera.size*(Camera.dirx*shift.x + Camera.diry*shift.y); - cray.dir = normalize(Camera.dirx*shift.x + Camera.diry*shift.y + Camera.dirz); - float aspect_ratio_ratio = Camera.aspect_ratio/(Camera.resolution.x/Camera.resolution.y); - fovray = 1.41*Camera.FOV*max(1.f/aspect_ratio_ratio, aspect_ratio_ratio)/Camera.resolution.x; //pixel FOV - return cray; -} - -#define COL col_scene -#define DE de_scene - -uniform float iFracScale; -uniform float iFracAng1; -uniform float iFracAng2; -uniform vec3 iFracShift; -uniform vec3 iFracCol; -uniform vec3 iMarblePos; -uniform float iMarbleRad; -uniform float iFlagScale; -uniform vec3 iFlagPos; -uniform int FRACTAL_ITER; -uniform int MARBLE_MODE; -uniform float time; - -///Original MM distance estimators - -float s1 = sin(iFracAng1), c1 = cos(iFracAng1), s2 = sin(iFracAng2), c2 = cos(iFracAng2); - -//########################################## -// Space folding -//########################################## -void planeFold(inout vec4 z, vec3 n, float d) { - z.xyz -= 2.0 * min(0.0, dot(z.xyz, n) - d) * n; -} -void sierpinskiFold(inout vec4 z) { - z.xy -= min(z.x + z.y, 0.0); - z.xz -= min(z.x + z.z, 0.0); - z.yz -= min(z.y + z.z, 0.0); -} - -// Polynomial smooth minimum by iq -float smoothmin(float a, float b, float k) { - float h = clamp(0.5 + 0.5*(a-b)/k, 0.0, 1.0); - return mix(a, b, h) - k*h*(1.0-h); -} - -void mengerFold(inout vec4 z) { - float a = smoothmin(z.x - z.y, 0.0, 0.03); - z.x -= a; - z.y += a; - a = smoothmin(z.x - z.z, 0.0, 0.03); - z.x -= a; - z.z += a; - a = smoothmin(z.y - z.z, 0.0, 0.03); - z.y -= a; - z.z += a; -} -void boxFold(inout vec4 z, vec3 r) { - z.xyz = clamp(z.xyz, -r, r) * 2.0 - z.xyz; -} -void rotX(inout vec4 z, float s, float c) { - z.yz = vec2(c*z.y + s*z.z, c*z.z - s*z.y); -} -void rotY(inout vec4 z, float s, float c) { - z.xz = vec2(c*z.x - s*z.z, c*z.z + s*z.x); -} -void rotZ(inout vec4 z, float s, float c) { - z.xy = vec2(c*z.x + s*z.y, c*z.y - s*z.x); -} -void rotX(inout vec4 z, float a) { - rotX(z, sin(a), cos(a)); -} -void rotY(inout vec4 z, float a) { - rotY(z, sin(a), cos(a)); -} -void rotZ(inout vec4 z, float a) { - rotZ(z, sin(a), cos(a)); -} - -//########################################## -// Primitive DEs -//########################################## -float de_sphere(vec4 p, float r) { - return (length(p.xyz) - r) / p.w; -} -float de_box(vec4 p, vec3 s) { - vec3 a = abs(p.xyz) - s; - return (min(max(max(a.x, a.y), a.z), 0.0) + length(max(a, 0.0))) / p.w; -} -float de_tetrahedron(vec4 p, float r) { - float md = max(max(-p.x - p.y - p.z, p.x + p.y - p.z), - max(-p.x + p.y + p.z, p.x - p.y + p.z)); - return (md - r) / (p.w * sqrt(3.0)); -} -float de_capsule(vec4 p, float h, float r) { - p.y -= clamp(p.y, -h, h); - return (length(p.xyz) - r) / p.w; -} - -//########################################## -// Main DEs -//########################################## -float de_fractal(vec4 p) -{ - for (int i = 0; i < FRACTAL_ITER; ++i) { - p.xyz = abs(p.xyz); - rotZ(p, s1, c1); - mengerFold(p); - rotX(p, s2, c2); - p *= iFracScale; - p.xyz += iFracShift; - } - return de_box(p, vec3(6.0)); -} - -vec4 col_fractal(vec4 p) -{ - vec3 orbit = vec3(0.0); - for (int i = 0; i < FRACTAL_ITER; ++i) { - p.xyz = abs(p.xyz); - rotZ(p, s1, c1); - mengerFold(p); - rotX(p, s2, c2); - p *= iFracScale; - p.xyz += iFracShift; - orbit = max(orbit, p.xyz*iFracCol); - } - return vec4(orbit, de_box(p, vec3(6.0))); -} - -float de_marble(vec4 p) -{ - return de_sphere(p - vec4(iMarblePos, 0), iMarbleRad); -} - -vec4 col_marble(vec4 p) -{ - vec4 col = vec4(0, 0, 0, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); - return vec4(col.x, col.y, col.z, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); -} - -float de_flag(vec4 p) -{ - vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale; - vec4 p_s = p/iMarbleRad; - vec4 d_pos = p - vec4(f_pos, 0); - vec4 caps_pos = p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0); - //animated flag woooo - float oscillation = sin(4*p_s.x + 1*p_s.y - 10*time) + 0.4*sin(6*p_s.x - 2*p_s.y - 12*time) + 0.1*sin(16*p_s.x + 5*p_s.y - 14*time); - //scale the flag displacement amplitude by the distance from the flagpole - float d = 0.7*de_box(d_pos + caps_pos.x*vec4(0,0.005*oscillation,0.03*oscillation,0), vec3(1.5, 0.8, 0.01)*iMarbleRad); - d = min(d, de_capsule(caps_pos, iMarbleRad*2.4, iMarbleRad*0.05)); - return d; -} - -vec4 col_flag(vec4 p) -{ - vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale; - float d1 = de_box(p - vec4(f_pos, 0), vec3(1.5, 0.8, 0.08)*iMarbleRad); - float d2 = de_capsule(p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0), iMarbleRad*2.4, iMarbleRad*0.18); - if (d1 < d2) { - return vec4(1.0, 0.2, 0.1, d1); - } else { - return vec4(0.9, 0.9, 0.1, d2); - } -} - -//float DE_count = 0; - -float de_scene(vec3 pos) -{ - //DE_count = DE_count+1; - vec4 p = vec4(pos,1.f); - float d = de_fractal(p); - d = min(d, de_marble(p)); - d = min(d, de_flag(p)); - return d; -} - -vec4 col_scene(vec3 pos) -{ - //DE_count = DE_count+1; - vec4 p = vec4(pos,1.f); - vec4 col = col_fractal(p); - vec4 col_f = col_flag(p); - if (col_f.w < col.w) { col = col_f; } - vec4 col_m = col_marble(p); - if (col_m.w < col.w) { - return vec4(col_m.xyz, 1.0); - } - return vec4(min(col.xyz,1), 0.0); -} - -//A faster formula to find the gradient/normal direction of the DE -//credit to http://www.iquilezles.org/www/articles/normalsSDF/normalsSDF.htm -vec4 calcNormal(vec3 p, float dx) { - const vec3 k = vec3(1,-1,0); - return (k.xyyx*DE(p + k.xyy*dx) + - k.yyxx*DE(p + k.yyx*dx) + - k.yxyx*DE(p + k.yxy*dx) + - k.xxxx*DE(p + k.xxx*dx))/vec4(4*dx,4*dx,4*dx,4); -} - - -#define MAX_DIST 50 -#define MIN_DIST 1e-5 -#define MAX_MARCHES 512 -#define NORMARCHES 5 - - -void ray_march(inout vec4 pos, inout vec4 dir, inout vec4 var, float fov, float d0) -{ - //March the ray - for (; var.x < MAX_MARCHES; var.x += 1.0) { - //if the distance from the surface is less than the distance per pixel we stop - if(dir.w > MAX_DIST || pos.w<0) - { - break; - } - - if(pos.w < max(fov*dir.w, MIN_DIST) && var.x > 0 && var.w < 1) - { - break; - } - - dir.w += pos.w; - pos.xyz += pos.w*dir.xyz; - pos.w = DE(pos.xyz)-d0*dir.w; - var.w = 0; - } - - pos.w += d0*dir.w; -} - -// Polynomial smooth minimum by iq -float smin(float a, float b, float k) { - float h = clamp(0.5 + 0.5*(a-b)/k, 0.0, 1.0); - return mix(a, b, h) - k*h*(1.0-h); -} - -float shadow_march(vec4 pos, vec4 dir, float distance2light, float light_angle) -{ - float light_visibility = 1; - float ph = 1e5; - float dDEdt = 0; - pos.w = DE(pos.xyz); - int i = 0; - for (; i < MAX_MARCHES; i++) { - - dir.w += pos.w; - pos.xyz += pos.w*dir.xyz; - pos.w = DE(pos.xyz); - - float y = pos.w*pos.w/(2.0*ph); - float d = (pos.w+ph)*0.5*(1-dDEdt); - float angle = d/(max(MIN_DIST,dir.w-y)*light_angle); - - light_visibility = min(light_visibility, angle); - - dDEdt = dDEdt*0.75 + 0.25*(pos.w-ph)/ph; - ph = pos.w; - - if(dir.w >= distance2light) - { - break; - } - - if(dir.w > MAX_DIST || pos.w < max(fovray*dir.w, MIN_DIST)) - { - return 0; - } - } - //return light_visibility; //bad - return 0.5-cos(3.14159265*light_visibility)*0.5; //looks better and is more physically accurate(for a circular light source) -} - -float sphere_intersection(vec3 r, vec3 p, vec4 sphere) -{ - p = p - sphere.xyz; - if(p == vec3(0)) return sphere.w; - - float b = dot(p, r); - float c = sphere.w*sphere.w - dot(p,p); - float d = b*b + c; - - if((d <= 0) || (c <= 0)) //if no intersection - { - return 0; - } - else - { - return sqrt(d) - b; //use furthest solution in the direction of the ray - } -} - -float find_furthest_intersection(vec3 r, vec3 p, ivec2 id) -{ - float d = 0; - ivec2 idR = min(id+1, group_size-1); - ivec2 idL = max(id-1, 0); - for(int i = idL.x; i <= idR.x; i++) - { - for(int j = idL.y; j <= idR.y; j++) - { - d = max(d, sphere_intersection(r,p,de_sph[i][j])); - } - } - return d; -} - - -float find_furthest_intersection_all(vec3 r, vec3 p, ivec2 id) -{ - float d = 0; - for(int i = 0; i < group_size; i++) - { - for(int j = 0; j < group_size; j++) - { - d = max(d, sphere_intersection(r,p,de_sph[i][j])); - } - } - return d; -} - -void normarch(inout vec4 pos) -{ - //calculate the normal - vec4 norm = calcNormal(pos.xyz, pos.w/8); - norm.xyz = normalize(norm.xyz); - pos.w = norm.w; - - float prev_w = 0; - //march in the direction of the normal - #pragma unroll - for(int i = 0; i < NORMARCHES; i++) - { - pos.xyz += pos.w*norm.xyz; - pos.w = DE(pos.xyz); - if(pos.w < prev_w) - { - pos.xyz -= prev_w*norm.xyz; - pos.w = prev_w; - break; - } - prev_w = pos.w; - } -} - - -#define PI 3.14159265 -#define AMBIENT_MARCHES 5 -#define AMBIENT_COLOR 2*vec4(1,1,1,1) -#define LIGHT_ANGLE 0.08 - -uniform vec3 BACKGROUND_COLOR; -uniform vec3 LIGHT_DIRECTION; -uniform float PBR_METALLIC; -uniform float PBR_ROUGHNESS; -uniform vec3 LIGHT_COLOR; -uniform bool SHADOWS_ENABLED; - - -//better to use a sampler though -vec4 interp(layout (rgba32f) image2D text, vec2 coord) -{ - //coord *= 0.99; - ivec2 ci = ivec2(coord); - vec2 d = coord - floor(coord); - return imageLoad(text, ci)*(1-d.x)*(1-d.y) + - imageLoad(text, ci+ivec2(1,0))*d.x*(1-d.y) + - imageLoad(text, ci+ivec2(0,1))*(1-d.x)*d.y + - imageLoad(text, ci+ivec2(1))*d.x*d.y; -} - - -///PBR functions -vec3 fresnelSchlick(float cosTheta, vec3 F0) -{ - return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); -} - -float DistributionGGX(vec3 N, vec3 H, float roughness) -{ - float a = roughness*roughness; - float a2 = a*a; - float NdotH = max(dot(N, H), 0.0); - float NdotH2 = NdotH*NdotH; - - float num = a2; - float denom = (NdotH2 * (a2 - 1.0) + 1.0); - denom = PI * denom * denom; - - return num / denom; -} - -float GeometrySchlickGGX(float NdotV, float roughness) -{ - float r = (roughness + 1.0); - float k = (r*r) / 8.0; - - float num = NdotV; - float denom = NdotV * (1.0 - k) + k; - - return num / denom; -} - -float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) -{ - float NdotV = max(dot(N, V), 0.0); - float NdotL = max(dot(N, L), 0.0); - float ggx2 = GeometrySchlickGGX(NdotV, roughness); - float ggx1 = GeometrySchlickGGX(NdotL, roughness); - - return ggx1 * ggx2; -} -///END PBR functions - -const float Br = 0.0025; -const float Bm = 0.0003; -const float g = 0.9800; -const vec3 nitrogen = vec3(0.650, 0.570, 0.475); -const vec3 Kr = Br / pow(nitrogen, vec3(4.0)); -const vec3 Km = Bm / pow(nitrogen, vec3(0.84)); - -vec3 sky_color(in vec3 pos) -{ - // Atmosphere Scattering - vec3 fsun = LIGHT_DIRECTION; - float brightnees = exp(min(5*pos.y,0)); - if(pos.y < 0) - { - pos.y = 0; - pos.xyz = normalize(pos.xyz); - } - float mu = dot(normalize(pos), normalize(fsun)); - - vec3 extinction = mix(exp(-exp(-((pos.y + fsun.y * 4.0) * (exp(-pos.y * 16.0) + 0.1) / 80.0) / Br) * (exp(-pos.y * 16.0) + 0.1) * Kr / Br) * exp(-pos.y * exp(-pos.y * 8.0 ) * 4.0) * exp(-pos.y * 2.0) * 4.0, vec3(1.0 - exp(fsun.y)) * 0.2, -fsun.y * 0.2 + 0.5); - vec3 sky_col = brightnees* 3.0 / (8.0 * 3.14) * (1.0 + mu * mu) * (Kr + Km * (1.0 - g * g) / (2.0 + g * g) / pow(1.0 + g * g - 2.0 * g * mu, 1.5)) / (Br + Bm) * extinction; - sky_col = 0.4*clamp(sky_col,0,10); - return sky_col*sky_col; -} - -vec3 ambient_sky_color(in vec3 pos) -{ - float y = pos.y; - pos.xyz = normalize(vec3(1,0,0)); - return sky_color(pos)*exp(-abs(y)); -} - -vec4 ambient_occlusion(in vec4 pos, in vec4 norm, in vec4 dir) -{ - vec3 dir1 = normalize(cross(dir.xyz,norm.xyz)); - vec3 dir2 = normalize(cross(dir1,norm.xyz)); - pos.w = iMarbleRad/2; - - vec3 pos0 = pos.xyz; - - float shifter = 2; - float dcoef = 0.02/iMarbleRad; - float occlusion_angle = 0; - float integral = 0; - float i_coef = 0; - - vec3 ambient_color = ambient_sky_color(norm.xyz); - - //march in the direction of the normal - #pragma unroll - for(int i = 0; i < AMBIENT_MARCHES; i++) - { - //moving in a zig-zag - vec3 direction = normalize(norm.xyz + 0.6*((mod(shifter,3.f)-1)*dir1 + (mod(shifter+1,3.f)-1)*dir2)); - shifter += 1; - pos.xyz += pos.w*direction; - pos.w = DE(pos.xyz); - - norm.w = length(pos0 - pos.xyz); - i_coef = 1/(dcoef*norm.w+1);//importance - occlusion_angle += i_coef*clamp(pos.w/norm.w,0,1); - integral += i_coef; - } - - occlusion_angle /= integral; // average weighted by importance - return vec4(ambient_color,1)*(0.5-cos(3.14159265*occlusion_angle)*0.5); -} - - -vec3 refraction(vec3 rd, vec3 n, float p) { - float dot_nd = dot(rd, n); - return p * (rd - dot_nd * n) + sqrt(1.0 - (p * p) * (1.0 - dot_nd * dot_nd)) * n; -} - -vec3 lighting(vec4 color, vec4 pos, vec4 dir, vec4 norm, vec3 refl, vec3 refr, float shadow) -{ - vec3 albedo = color.xyz; - albedo *= albedo; //square it to make the fractals more colorfull - - vec4 ambient_color = ambient_occlusion(pos, norm, dir); - - float metallic = PBR_METALLIC; - vec3 F0 = vec3(0.04); - F0 = mix(F0, albedo, metallic); - - //reflectance equation - vec3 Lo = vec3(0.0); - vec3 V = -dir.xyz; - vec3 N = norm.xyz; - - { //ambient occlusion contribution - float roughness = max(PBR_ROUGHNESS,0.5); - vec3 L = normalize(N); - vec3 H = normalize(V + L); - vec3 radiance = ambient_color.xyz; - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - if(!SHADOWS_ENABLED) - { - shadow = ambient_color.w; - } - - vec3 sun_color = sky_color(LIGHT_DIRECTION); - - { //light contribution - float roughness = PBR_ROUGHNESS; - vec3 L = normalize(LIGHT_DIRECTION); - vec3 H = normalize(V + L); - vec3 radiance = sun_color*shadow*(0.6+0.4*ambient_color.w); - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - { //light reflection, GI imitation - float roughness = max(PBR_ROUGHNESS,0.5); - vec3 L = normalize(-LIGHT_DIRECTION); - vec3 H = normalize(V + L); - vec3 radiance = 0.35*sun_color*ambient_color.w*(1-ambient_color.w); - - // cook-torrance brdf - float NDF = DistributionGGX(N, H, roughness); - float G = GeometrySmith(N, V, L, roughness); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - kD *= 1.0 - metallic; - - vec3 numerator = NDF * G * F; - float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0); - vec3 specular = numerator / max(denominator, 0.001); - - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); - Lo += (kD * albedo / PI + specular) * radiance * NdotL; - } - - if(color.w>0.5) // if marble - { - vec3 n = normalize(pos.xyz - iMarblePos); - vec3 q = dir.xyz - n*(2*dot(dir.xyz,n)); - //Combine for final marble color - if(MARBLE_MODE == 0) - { - //glass - vec3 F0 = vec3(0.03); - vec3 L = normalize(q); - vec3 H = normalize(V + L); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - Lo += kS*refl + kD*refr; - } - else - { - //metal - vec3 F0 = vec3(0.6); - vec3 L = normalize(q); - vec3 H = normalize(V + L); - vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); - - vec3 kS = F; - vec3 kD = vec3(1.0) - kS; - Lo += kS*refl; - } - } - - return Lo; -} - -vec3 shading_simple(in vec4 pos, in vec4 dir, float fov, float shadow) -{ - - - if(pos.w < max(16*fovray*dir.w, MIN_DIST)) - { - //calculate the normal - float error = 0.5*fov*dir.w; - vec4 norm = calcNormal(pos.xyz, max(MIN_DIST, error)); - norm.xyz = normalize(norm.xyz); - if(norm.w < -error) - { - return COL(pos.xyz); - } - else - { - //optimize color sampling - vec3 cpos = pos.xyz - norm.w*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - - vec4 color = COL(cpos); - return lighting(color, pos, dir, norm, vec3(0), vec3(0), shadow); - } - } - else - { - return sky_color(dir.xyz); - } -} - - -vec3 render_ray(in vec4 pos, in vec4 dir, float fov) -{ - vec4 var = vec4(0,0,0,1); - ray_march(pos, dir, var, fov, MIN_DIST); - float shadow = shadow_march(pos, vec4(LIGHT_DIRECTION,0), MAX_DIST, LIGHT_ANGLE); - return shading_simple(pos, dir, fov, shadow); -} - -vec3 shading(in vec4 pos, in vec4 dir, float fov, float shadow) -{ - if(pos.w < max(16*fovray*dir.w, MIN_DIST)) - { - //calculate the normal - float error = 0.5*fov*dir.w; - vec4 norm = calcNormal(pos.xyz, max(MIN_DIST, error)); - norm.xyz = normalize(norm.xyz); - if(norm.w < -error) - { - return COL(pos.xyz); - } - else - { - //optimize color sampling - vec3 cpos = pos.xyz - norm.w*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - cpos = cpos - DE(cpos)*norm.xyz; - - vec4 color = COL(cpos); - vec3 refl = vec3(0); - vec3 refr = vec3(0); - if(color.w>0.5) // if marble - { - vec3 n = normalize(iMarblePos - cpos.xyz); - vec3 q = refraction(dir.xyz, n, 1.0 / 1.5); - vec3 p2 = cpos.xyz + (dot(q, n) * 2.0 * iMarbleRad) * q; - n = normalize(p2 - iMarblePos); - q = (dot(q, dir.xyz) * 2.0) * q - dir.xyz; - vec4 p_temp = vec4(p2 + n * (MIN_DIST * 10), 0); - vec4 r_temp = vec4(q, 0); - - refr = render_ray(p_temp, r_temp, fov); - - //Calculate reflection - n = normalize(cpos.xyz - iMarblePos); - q = dir.xyz - n*(2*dot(dir.xyz,n)); - p_temp = vec4(cpos.xyz + n * (MIN_DIST * 10), 0); - r_temp = vec4(q, dir.w); - - refl = render_ray(p_temp, r_temp, fov); - } - - return lighting(color, cpos, dir, norm, refl, refr, shadow); - } - } - else - { - return sky_color(dir.xyz); - } - -} - -vec3 HDRmapping(vec3 color, float exposure, float gamma) -{ - // Exposure tone mapping - vec3 mapped = vec3(1.0) - exp(-color * exposure); - // Gamma correction - return pow(mapped, vec3(1.0 / gamma)); -} - - -void main() { - ivec2 global_pos = ivec2(gl_GlobalInvocationID.xy); - ivec2 local_indx = ivec2(gl_LocalInvocationID.xy); - vec2 img_size = vec2(imageSize(color_HDR)); - vec2 res_ratio = vec2(imageSize(illumination))/img_size; - vec4 sph = imageLoad(DE_input, global_pos); - vec4 illum = interp(illumination, vec2(global_pos)*res_ratio); - - ray rr = get_ray(vec2(global_pos)/img_size); - vec4 pos = vec4(rr.pos,0); - vec4 dir = vec4(rr.dir,0); - vec4 var = vec4(0); - - float td = dot(dir.xyz, sph.xyz - pos.xyz);//traveled distance - - pos = sph; - dir.w += td; - - vec3 color = shading(pos, dir, fovray, illum.x); - - vec3 prev_color = imageLoad(color_HDR, global_pos).xyz; - if(!isnan(color.x) && !isnan(color.y) && !isnan(color.z)) - { - color = prev_color*Camera.mblur + (1-Camera.mblur)*color; //blur - imageStore(color_HDR, global_pos, vec4(color.xyz, 1)); - } -} - -ERROR: 0:761: 'lighting' : no matching overloaded function found (using implicit conversion) - diff --git a/game_folder/shaders/compute/camera.glsl b/game_folder/shaders/compute/camera.glsl index dbf2ba4c..fe1d65c3 100644 --- a/game_folder/shaders/compute/camera.glsl +++ b/game_folder/shaders/compute/camera.glsl @@ -5,7 +5,7 @@ struct ray vec3 dir; }; -struct gl_camera +struct glcamera { vec3 position; vec3 dirx; @@ -23,8 +23,6 @@ struct gl_camera float bloomintensity; float bloomtreshold; float bloomradius; - int stepN; - int step; }; @@ -35,7 +33,7 @@ ivec2 getGpos(int index) return ivec2(x,y); } -uniform gl_camera Camera; +uniform glcamera Camera; float fovray; ray get_ray(vec2 screen_pos) diff --git a/game_folder/shaders/compute/distance_estimators.glsl b/game_folder/shaders/compute/distance_estimators.glsl index 1aa68afd..3847626e 100644 --- a/game_folder/shaders/compute/distance_estimators.glsl +++ b/game_folder/shaders/compute/distance_estimators.glsl @@ -142,8 +142,8 @@ float de_marble(vec4 p) vec4 col_marble(vec4 p) { - vec4 col = vec4(0, 0, 0, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); - return vec4(col.x, col.y, col.z, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); + vec4 col = vec4(0.5, 0.5, 0.5, de_sphere(p - vec4(iMarblePos, 0), iMarbleRad)); + return col; } float de_flag(vec4 p) diff --git a/game_folder/shaders/compute/shading.glsl b/game_folder/shaders/compute/shading.glsl index 67d3f2ba..8c109d03 100644 --- a/game_folder/shaders/compute/shading.glsl +++ b/game_folder/shaders/compute/shading.glsl @@ -1,7 +1,7 @@ #include #define PI 3.14159265 -#define AMBIENT_MARCHES 5 +#define AMBIENT_MARCHES 7 #define AMBIENT_COLOR 2*vec4(1,1,1,1) #define LIGHT_ANGLE 0.08 @@ -16,7 +16,6 @@ uniform bool SHADOWS_ENABLED; //better to use a sampler though vec4 interp(layout (rgba32f) image2D text, vec2 coord) { - //coord *= 0.99; ivec2 ci = ivec2(coord); vec2 d = coord - floor(coord); return imageLoad(text, ci)*(1-d.x)*(1-d.y) + @@ -121,7 +120,7 @@ vec4 ambient_occlusion(in vec4 pos, in vec4 norm, in vec4 dir) for(int i = 0; i < AMBIENT_MARCHES; i++) { //moving in a zig-zag - vec3 direction = normalize(norm.xyz + 0.6*((mod(shifter,3.f)-1)*dir1 + (mod(shifter+1,3.f)-1)*dir2)); + vec3 direction = normalize(norm.xyz + 0.8*((mod(shifter,3.f)-1)*dir1 + (mod(shifter+1,3.f)-1)*dir2)); shifter += 1; pos.xyz += pos.w*direction; pos.w = DE(pos.xyz); @@ -193,7 +192,7 @@ vec3 lighting(vec4 color, vec4 pos, vec4 dir, vec4 norm, vec3 refl, vec3 refr, f float roughness = PBR_ROUGHNESS; vec3 L = normalize(LIGHT_DIRECTION); vec3 H = normalize(V + L); - vec3 radiance = sun_color*shadow*(0.6+0.4*ambient_color.w); + vec3 radiance = sun_color*shadow*(0.8+0.2*ambient_color.w); // cook-torrance brdf float NDF = DistributionGGX(N, H, roughness); diff --git a/src/Gamemodes.cpp b/src/Gamemodes.cpp index 9495ace8..690a7688 100644 --- a/src/Gamemodes.cpp +++ b/src/Gamemodes.cpp @@ -1,4 +1,5 @@ #include "Gamemodes.h" +#include "Gamemodes.h" @@ -11,9 +12,7 @@ bool mouse_clicked = false; bool show_cheats = false; //Constants -float mouse_sensitivity = 0.005f; -float wheel_sensitivity = 0.2f; -float music_vol = 75.0f; + float target_fps = 60.0f; GameMode game_mode = MAIN_MENU; @@ -23,13 +22,7 @@ void OpenMainMenu(Scene * scene, Overlays * overlays) RemoveAllObjects(); game_mode = MAIN_MENU; - if (current_music != scene->levels.GetMusic("menu.ogg")) - { - if (current_music != nullptr) - current_music->stop(); - current_music = scene->levels.GetMusic("menu.ogg"); - current_music->play(); - } + scene->SetCurrentMusic(scene->levels.GetMusic("menu.ogg")); scene->SetExposure(1.0f); scene->SetMode(Scene::INTRO); @@ -148,6 +141,7 @@ void OpenMainMenu(Scene * scene, Overlays * overlays) void OpenEditor(Scene * scene, Overlays * overlays, int level) { + scene->StopMusic(); RemoveAllObjects(); //go to level editor game_mode = LEVEL_EDITOR; @@ -217,7 +211,7 @@ void OpenPauseMenu(Scene * scene, Overlays * overlays) margin.SetBackgroundColor(sf::Color::Transparent); pausemenu.AddObject(&margin, Object::Allign::LEFT); - //PLAY + Box resumebtn(600, 50); Text button1(LOCAL["Resume"], LOCAL("default"), 40, sf::Color::White); button1.SetBorderColor(sf::Color::Black); @@ -228,7 +222,6 @@ void OpenPauseMenu(Scene * scene, Overlays * overlays) { RemoveAllObjects(); game_mode = PLAYING; - scene->GetCurMusic().setVolume(GetVol()); scene->SetExposure(1.0f); LockMouse(*window); overlays->sound_click.play(); @@ -236,7 +229,7 @@ void OpenPauseMenu(Scene * scene, Overlays * overlays) resumebtn.AddObject(&button1, Object::Allign::CENTER); pausemenu.AddObject(&resumebtn, Object::Allign::LEFT); - //LEVELS + Box rstbtn(600, 50); Text button2(LOCAL["Restart"], LOCAL("default"), 40, sf::Color::White); button2.SetBorderColor(sf::Color::Black); @@ -248,7 +241,6 @@ void OpenPauseMenu(Scene * scene, Overlays * overlays) RemoveAllObjects(); game_mode = PLAYING; scene->ResetLevel(); - scene->GetCurMusic().setVolume(GetVol()); scene->SetExposure(1.0f); LockMouse(*window); overlays->sound_click.play(); @@ -256,7 +248,7 @@ void OpenPauseMenu(Scene * scene, Overlays * overlays) rstbtn.AddObject(&button2, Object::Allign::CENTER); pausemenu.AddObject(&rstbtn, Object::Allign::LEFT); - //Settings + Box sttbtn(600, 50); Text buttonstt(LOCAL["Settings"], LOCAL("default"), 40, sf::Color::White); buttonstt.SetBorderColor(sf::Color::Black); @@ -271,7 +263,7 @@ void OpenPauseMenu(Scene * scene, Overlays * overlays) sttbtn.AddObject(&buttonstt, Object::Allign::CENTER); pausemenu.AddObject(&sttbtn, Object::Allign::LEFT); - //Exit + Box exitbtn(600, 50); Text button5(LOCAL["Quit"], LOCAL("default"), 40, sf::Color::White); button5.SetBorderColor(sf::Color::Black); @@ -290,7 +282,6 @@ void OpenPauseMenu(Scene * scene, Overlays * overlays) OpenMainMenu(scene, overlays); } scene->SetMode(Scene::INTRO); - scene->StopAllMusic(); }, true); exitbtn.AddObject(&button5, Object::Allign::CENTER); pausemenu.AddObject(&exitbtn, Object::Allign::LEFT); @@ -300,7 +291,6 @@ void OpenPauseMenu(Scene * scene, Overlays * overlays) void PauseGame(sf::RenderWindow& window, Overlays * overlays, Scene * scene) { game_mode = PAUSED; - scene->GetCurMusic().setVolume(GetVol()); UnlockMouse(window); OpenPauseMenu(scene, overlays); scene->SetExposure(0.5f); @@ -347,6 +337,9 @@ void OpenTestWindow() void OpenLevelMenu(Scene* scene, Overlays* overlays) { RemoveAllObjects(); + + scene->SetCurrentMusic(scene->levels.GetMusic("menu.ogg")); + sf::Vector2f wsize = default_size; sf::Vector2f vsize = default_view.getSize(); MenuBox levels(wsize.x*0.95f, vsize.y*0.95f, (vsize.x - wsize.x*0.95f)/2, vsize.y*0.025f); @@ -567,16 +560,6 @@ void ConfirmEditorExit(Scene* scene, Overlays* overlays) }); } - -float GetVol() { - if (game_mode == PAUSED) { - return music_vol / 4; - } - else { - return music_vol; - } -} - void LockMouse(sf::RenderWindow& window) { window.setMouseCursorVisible(false); const sf::Vector2u size = window.getSize(); @@ -601,20 +584,83 @@ int DirExists(const char *path) { void FirstStart(Overlays* overlays) { - TwDefine("First_launch visible=true"); + TwDefine("First_launch visible=true color='0 0 0' alpha=255 size='500 200' valueswidth=300 position='500 500'"); TwDefine("Statistics visible=false"); TwDefine("Settings visible=false"); game_mode = FIRST_START; overlays->TWBAR_ENABLED = true; + + RemoveAllObjects(); + + sf::Vector2f wsize = default_size; + sf::Vector2f vsize = default_view.getSize(); + MenuBox mainmenu(1000, vsize.y*0.95f, wsize.x*0.025, wsize.y*0.025f); + mainmenu.SetBackgroundColor(sf::Color::Transparent); + //make the menu static + mainmenu.static_object = true; + + //TITLE + Text ttl("Marble\nMarcher", LOCAL("default"), 120, sf::Color::White); + ttl.SetBorderColor(sf::Color::Black); + ttl.SetBorderWidth(4); + mainmenu.AddObject(&ttl, Object::Allign::LEFT); + + Box margin1(800, 5); + margin1.SetBackgroundColor(sf::Color::Transparent); + mainmenu.AddObject(&margin1, Object::Allign::LEFT); + + Text CE("Community Edition", LOCAL("default"), 60, sf::Color::White); + CE.SetBorderColor(sf::Color::Black); + CE.SetBorderWidth(4); + mainmenu.AddObject(&CE, Object::Allign::LEFT); + + AddGlobalObject(mainmenu); } -//ANTTWEAKBAR +//ANTTWEAKBAR stuff + + +sf::Vector2i getResolution(int i) +{ + switch (i) + { + case 0: + return sf::Vector2i(320, 240); + case 1: + return sf::Vector2i(480, 320); + case 2: + return sf::Vector2i(640, 480); + case 3: + return sf::Vector2i(800, 480); + case 4: + return sf::Vector2i(960, 540); + case 5: + return sf::Vector2i(1136, 640); + case 6: + return sf::Vector2i(1280, 720); + case 7: + return sf::Vector2i(1600, 900); + case 8: + return sf::Vector2i(1920, 1080); + case 9: + return sf::Vector2i(2048, 1152); + case 10: + return sf::Vector2i(2560, 1440); + case 11: + return sf::Vector2i(3840, 2160); + case 12: + return sf::Vector2i(7680, 4320); + case 13: + return sf::Vector2i(10240, 4320); + } +} Scene *scene_ptr; Overlays *overlays_ptr; Renderer *renderer_ptr; sf::Shader *shader_ptr; +sf::RenderWindow *window; sf::RenderTexture *renderTexture; sf::RenderTexture *screenshotTexture; sf::Texture *main_txt; @@ -622,9 +668,12 @@ sf::Texture *screenshot_txt; sf::RectangleShape *rectmain; sf::RectangleShape *rectscr; - -void SetPointers(sf::RenderTexture *render, sf::RenderTexture *screenshot, sf::Texture *main, sf::Texture *screensht, sf::RectangleShape *rmain, sf::RectangleShape *rscr, sf::Shader *shader) +void SetPointers(sf::RenderWindow *w, Scene* scene, Overlays* overlays, Renderer* rd, sf::RenderTexture *render, sf::RenderTexture *screenshot, sf::Texture *main, sf::Texture *screensht, sf::RectangleShape *rmain, sf::RectangleShape *rscr, sf::Shader *shader) { + window = w; + scene_ptr = scene; + overlays_ptr = overlays; + renderer_ptr = rd; renderTexture = render; screenshotTexture = screenshot; shader_ptr = shader; @@ -634,17 +683,63 @@ void SetPointers(sf::RenderTexture *render, sf::RenderTexture *screenshot, sf::T rectscr = rscr; } + +void TakeScreenshot() +{ + sf::Vector2i rendering_resolution = getResolution(SETTINGS.stg.rendering_resolution); + sf::Vector2i screenshot_resolution = getResolution(SETTINGS.stg.screenshot_resolution); + + scene_ptr->SetResolution(*shader_ptr, screenshot_resolution.x, screenshot_resolution.y); + renderer_ptr->ReInitialize(screenshot_resolution.x, screenshot_resolution.y); + scene_ptr->WriteRenderer(*renderer_ptr); + + shader_ptr->setUniform("render_texture", *screenshot_txt); + renderer_ptr->SetOutputTexture(*screenshot_txt); + scene_ptr->Write(*shader_ptr); + + //Setup full-screen shader + sf::RenderStates states = sf::RenderStates::Default; + states.shader = shader_ptr; + + window->setActive(false); + screenshotTexture->setActive(true); + + renderer_ptr->camera.SetMotionBlur(0); + renderer_ptr->Render(); + + screenshotTexture->draw(*rectscr, states); + screenshotTexture->display(); + screenshotTexture->getTexture().copyToImage().saveToFile((std::string)"screenshots/screenshot" + (std::string)num2str(time(NULL)) + ".jpg"); + + screenshotTexture->setActive(false); + window->setActive(true); + + scene_ptr->SetResolution(*shader_ptr, rendering_resolution.x, rendering_resolution.y); + renderer_ptr->ReInitialize(rendering_resolution.x, rendering_resolution.y); + scene_ptr->Write(*shader_ptr); +} + void InitializeRendering(std::string config) { - scene_ptr->SetResolution(*shader_ptr, SETTINGS.stg.rendering_resolution.x, SETTINGS.stg.rendering_resolution.y); - renderer_ptr->Initialize(SETTINGS.stg.rendering_resolution.x, SETTINGS.stg.rendering_resolution.y, renderer_ptr->GetConfigFolder() + "/" + config); + + sf::Vector2i rendering_resolution = getResolution(SETTINGS.stg.rendering_resolution); + sf::Vector2i screenshot_resolution = getResolution(SETTINGS.stg.screenshot_resolution); + + scene_ptr->SetResolution(*shader_ptr, rendering_resolution.x, rendering_resolution.y); + renderer_ptr->Initialize(rendering_resolution.x, rendering_resolution.y, renderer_ptr->GetConfigFolder() + "/" + config); renderer_ptr->variables["MRRM_scale"] = SETTINGS.stg.MRRM_scale; renderer_ptr->variables["shadow_scale"] = SETTINGS.stg.shadow_resolution; renderer_ptr->variables["bloom_scale"] = SETTINGS.stg.bloom_resolution; renderer_ptr->camera.bloomintensity = SETTINGS.stg.bloom_intensity; - renderer_ptr->camera.bloomradius = SETTINGS.stg.bloom_intensity; - renderer_ptr->camera.bloomtreshold = SETTINGS.stg.bloom_intensity; + renderer_ptr->camera.bloomradius = SETTINGS.stg.bloom_radius; + renderer_ptr->camera.bloomtreshold = SETTINGS.stg.bloom_treshold; + renderer_ptr->camera.SetMotionBlur(SETTINGS.stg.motion_blur); renderer_ptr->camera.SetFOV(SETTINGS.stg.FOV); + renderer_ptr->camera.SetExposure(SETTINGS.stg.exposure); + + scene_ptr->Refl_Refr_Enabled = SETTINGS.stg.refl_refr; + scene_ptr->Shadows_Enabled = SETTINGS.stg.shadows; + scene_ptr->Fog_Enabled = SETTINGS.stg.fog; //GL settings sf::ContextSettings settings; @@ -652,18 +747,18 @@ void InitializeRendering(std::string config) settings.minorVersion = 3; renderTexture->clear(); - renderTexture->create(SETTINGS.stg.rendering_resolution.x, SETTINGS.stg.rendering_resolution.y, settings); - main_txt->create(SETTINGS.stg.rendering_resolution.x, SETTINGS.stg.rendering_resolution.y); + renderTexture->create(rendering_resolution.x, rendering_resolution.y, settings); + main_txt->create(rendering_resolution.x, rendering_resolution.y); renderTexture->setSmooth(false); renderer_ptr->SetOutputTexture(*main_txt); screenshotTexture->clear(); - screenshotTexture->create(SETTINGS.stg.screenshot_resolution.x, SETTINGS.stg.screenshot_resolution.y, settings); - screenshot_txt->create(SETTINGS.stg.screenshot_resolution.x, SETTINGS.stg.screenshot_resolution.y); + screenshotTexture->create(screenshot_resolution.x, screenshot_resolution.y, settings); + screenshot_txt->create(screenshot_resolution.x, screenshot_resolution.y); screenshotTexture->setSmooth(false); - const sf::Glsl::Vec2 window_res((float)SETTINGS.stg.rendering_resolution.x, (float)SETTINGS.stg.rendering_resolution.y); - const sf::Glsl::Vec2 sres_res((float)SETTINGS.stg.screenshot_resolution.x, (float)SETTINGS.stg.screenshot_resolution.y); + const sf::Glsl::Vec2 window_res((float)rendering_resolution.x, (float)rendering_resolution.y); + const sf::Glsl::Vec2 sres_res((float)screenshot_resolution.x, (float)screenshot_resolution.y); //Create screen rectangle rectmain->setSize(window_res); rectscr->setSize(sres_res); @@ -720,52 +815,73 @@ void TW_CALL CopyStdStringToClient(std::string& destinationClientString, const s destinationClientString = sourceLibraryString; } -int render_resolution = 3; -int screenshot_resolution = 10; -int language_choise = 0; -int shader_config = 0; -sf::Vector2i getResolution(int i) + + +void TW_CALL ApplySettings(void *data) { - switch (i) + if (!window->isOpen() || SETTINGS.first_start) { - case 0: - return sf::Vector2i(320, 240); - case 1: - return sf::Vector2i(480, 320); - case 2: - return sf::Vector2i(640, 480); - case 3: - return sf::Vector2i(800, 480); - case 4: - return sf::Vector2i(960, 540); - case 5: - return sf::Vector2i(1136, 640); - case 6: - return sf::Vector2i(1280, 720); - case 7: - return sf::Vector2i(1600, 900); - case 8: - return sf::Vector2i(1920, 1080); - case 9: - return sf::Vector2i(2048, 1152); - case 10: - return sf::Vector2i(2560, 1440); - case 11: - return sf::Vector2i(3840, 2160); - case 12: - return sf::Vector2i(7680, 4320); - case 13: - return sf::Vector2i(10240, 4320); + sf::VideoMode screen_size; + sf::Uint32 window_style; + bool fullscreen = SETTINGS.stg.fullscreen; + if (fullscreen) { + screen_size = sf::VideoMode::getDesktopMode(); + window_style = sf::Style::Fullscreen; + } + else { + screen_size = sf::VideoMode::getDesktopMode(); + window_style = sf::Style::Default; + } + + //GL settings + sf::ContextSettings settings; + settings.majorVersion = 4; + settings.minorVersion = 3; + + window->create(screen_size, "Marble Marcher Community Edition", window_style, settings); + window->setVerticalSyncEnabled(SETTINGS.stg.VSYNC); + window->setKeyRepeatEnabled(false); + + INIT(); + + if (!fullscreen) + { + sf::VideoMode fs_size = sf::VideoMode::getDesktopMode(); + window->setSize(sf::Vector2u(fs_size.width, fs_size.height - 100.f)); + window->setPosition(sf::Vector2i(0, 0)); + } + + SETTINGS.first_start = false; + + overlays_ptr->SetAntTweakBar(window->getSize().x, window->getSize().y); } + + std::vector langs = LOCAL.GetLanguages(); + LOCAL.SetLanguage(langs[SETTINGS.stg.language]); + + std::vector configs = renderer_ptr->GetConfigurationsList(); + + InitializeRendering(configs[SETTINGS.stg.shader_config]); + + if (current_music != nullptr) + current_music->setVolume(SETTINGS.stg.music_volume); + + scene_ptr->sound_goal.setVolume(SETTINGS.stg.fx_volume); + scene_ptr->sound_bounce1.setVolume(SETTINGS.stg.fx_volume); + scene_ptr->sound_bounce2.setVolume(SETTINGS.stg.fx_volume); + scene_ptr->sound_bounce3.setVolume(SETTINGS.stg.fx_volume); + scene_ptr->sound_shatter.setVolume(SETTINGS.stg.fx_volume); + + overlays_ptr->sound_hover.setVolume(SETTINGS.stg.fx_volume); + overlays_ptr->sound_click.setVolume(SETTINGS.stg.fx_volume); + overlays_ptr->sound_count.setVolume(SETTINGS.stg.fx_volume); + overlays_ptr->sound_go.setVolume(SETTINGS.stg.fx_volume); } void TW_CALL InitialOK(void *data) { - std::vector langs = LOCAL.GetLanguages(); - LOCAL.SetLanguage(langs[language_choise]); - SETTINGS.stg.rendering_resolution = getResolution(render_resolution); - SETTINGS.stg.screenshot_resolution = getResolution(screenshot_resolution); + ApplySettings(nullptr); TwDefine("First_launch visible=false"); TwDefine("Statistics visible=true"); TwDefine("Settings visible=true"); @@ -773,33 +889,13 @@ void TW_CALL InitialOK(void *data) OpenMainMenu(scene_ptr, overlays_ptr); } -void TW_CALL ApplySettings(void *data) -{ - std::vector langs = LOCAL.GetLanguages(); - LOCAL.SetLanguage(langs[language_choise]); - SETTINGS.stg.rendering_resolution = getResolution(render_resolution); - SETTINGS.stg.screenshot_resolution = getResolution(screenshot_resolution); - std::vector configs = renderer_ptr->GetConfigurationsList(); - - InitializeRendering(configs[shader_config]); - - if(current_music != nullptr) - current_music->setVolume(SETTINGS.stg.music_volume); -} - - - -void InitializeATBWindows(Scene* scene, Overlays* overlays, Renderer* rd, float* fps, bool *vsync, float *mouse_sensitivity, float *wheel_sensitivity, float *music_vol, float *target_fps) +void InitializeATBWindows(float* fps, float *target_fps) { - scene_ptr = scene; - overlays_ptr = overlays; - renderer_ptr = rd; - overlays_ptr->stats = TwNewBar("Statistics"); TwDefine(" GLOBAL help='Marble Marcher: Community Edition. Use F5 to take screenshots. F4 to open or close settings windows.' "); - std::map level_list = scene->levels.getLevelNames(); + std::map level_list = scene_ptr->levels.getLevelNames(); TwEnumVal *level_enums = new TwEnumVal[level_list.size() + 1]; TwEnumVal enumval; enumval.Label = "None"; @@ -816,24 +912,9 @@ void InitializeATBWindows(Scene* scene, Overlays* overlays, Renderer* rd, float* TwType Levels = TwDefineEnum("levels", level_enums, level_list.size() + 1); - TwEnumVal resolutions[] = { { 0, "320x240" }, - { 1, "480x320" }, - { 2, "640x480" }, - { 3, "800x480" }, - { 4, "960x540" }, - { 5, "1136x640" }, - { 6, "1280x720" }, - { 7, "1600x900" }, - { 8, "1920x1080" }, - { 9, "2048x1152" }, - { 10, "2560x1440" }, - { 11, "3840x2160" }, - { 12, "7680x4320" }, - { 13, "10240x4320" } }; - TwType Resolutions = TwDefineEnum("Resolutions", resolutions, 14); - std::vector music_list = scene->levels.GetMusicNames(); + std::vector music_list = scene_ptr->levels.GetMusicNames(); TwEnumVal *music_enums = new TwEnumVal[music_list.size()]; for (int i = 0; i < music_list.size(); i++) { @@ -857,7 +938,7 @@ void InitializeATBWindows(Scene* scene, Overlays* overlays, Renderer* rd, float* TwType Languages = TwDefineEnum("Languages", language_enums, langs.size()); - std::vector configs = rd->GetConfigurationsList(); + std::vector configs = renderer_ptr->GetConfigurationsList(); TwEnumVal *config_enums = new TwEnumVal[configs.size()]; for (int j = 0; j < configs.size(); j++) @@ -873,21 +954,22 @@ void InitializeATBWindows(Scene* scene, Overlays* overlays, Renderer* rd, float* int barPos[2] = { 16, 60 }; TwSetParam(overlays_ptr->stats, NULL, "position", TW_PARAM_INT32, 2, &barPos); TwAddVarRO(overlays_ptr->stats, "FPS", TW_TYPE_FLOAT, fps, " label='FPS' "); - TwAddVarRO(overlays_ptr->stats, "Marble velocity", TW_TYPE_DIR3F, scene->marble_vel.data(), " "); - TwAddVarRO(overlays_ptr->stats, "Marble position", TW_TYPE_DIR3F, scene->marble_pos.data(), " "); + TwAddVarRO(overlays_ptr->stats, "Marble velocity", TW_TYPE_DIR3F, scene_ptr->marble_vel.data(), " "); + TwAddVarRO(overlays_ptr->stats, "Marble position", TW_TYPE_DIR3F, scene_ptr->marble_pos.data(), " "); overlays_ptr->settings = TwNewBar("Settings"); - TwAddVarRW(overlays_ptr->settings, "Rendering resolution", Resolutions, &render_resolution, "group='Rendering settings'"); - TwAddVarRW(overlays_ptr->settings, "Screenshot resolution", Resolutions, &screenshot_resolution, "group='Rendering settings'"); - TwAddVarRW(overlays_ptr->settings, "Shader configuration", Configurations, &shader_config, "group='Rendering settings'"); + TwAddVarRW(overlays_ptr->settings, "Rendering resolution", Resolutions, &SETTINGS.stg.rendering_resolution, "group='Rendering settings'"); + TwAddVarRW(overlays_ptr->settings, "Fullscreen", TW_TYPE_BOOLCPP, &SETTINGS.stg.fullscreen, "group='Graphics settings' help='You need to restart the game for chages to take effect'"); + TwAddVarRW(overlays_ptr->settings, "Screenshot resolution", Resolutions, &SETTINGS.stg.screenshot_resolution, "group='Rendering settings'"); + TwAddVarRW(overlays_ptr->settings, "Shader configuration", Configurations, &SETTINGS.stg.shader_config, "group='Rendering settings'"); TwAddVarRW(overlays_ptr->settings, "MRRM scaling", TW_TYPE_INT32, &SETTINGS.stg.MRRM_scale, "min=2 max=8 group='Rendering settings'"); TwAddVarRW(overlays_ptr->settings, "Shadow downscaling", TW_TYPE_INT32, &SETTINGS.stg.shadow_resolution, "min=1 max=8 group='Rendering settings'"); TwAddVarRW(overlays_ptr->settings, "Bloom downscaling", TW_TYPE_INT32, &SETTINGS.stg.bloom_resolution, "min=1 max=8 group='Rendering settings'"); TwAddVarRW(overlays_ptr->settings, "FOV", TW_TYPE_FLOAT, &SETTINGS.stg.FOV, "min=30 step=1 max=180 group='Graphics settings'"); - TwAddVarRW(overlays_ptr->settings, "VSYNC", TW_TYPE_BOOLCPP, vsync, "group='Graphics settings'"); + TwAddVarRW(overlays_ptr->settings, "VSYNC", TW_TYPE_BOOLCPP, &SETTINGS.stg.VSYNC, "group='Graphics settings'"); TwAddVarRW(overlays_ptr->settings, "Shadows", TW_TYPE_BOOLCPP, &SETTINGS.stg.shadows, "group='Graphics settings'"); TwAddVarRW(overlays_ptr->settings, "Reflection and Refraction", TW_TYPE_BOOLCPP, &SETTINGS.stg.refl_refr, "group='Graphics settings'"); TwAddVarRW(overlays_ptr->settings, "Volumetric fog", TW_TYPE_BOOLCPP, &SETTINGS.stg.fog, "group='Graphics settings'"); @@ -898,19 +980,19 @@ void InitializeATBWindows(Scene* scene, Overlays* overlays, Renderer* rd, float* TwAddVarRW(overlays_ptr->settings, "Bloom Radius", TW_TYPE_FLOAT, &SETTINGS.stg.bloom_radius, "min=1 max=10 step=0.1 group='Graphics settings'"); - TwAddVarRW(overlays_ptr->settings, "Language", Languages, &language_choise, "group='Gameplay settings'"); + TwAddVarRW(overlays_ptr->settings, "Language", Languages, &SETTINGS.stg.language, "group='Gameplay settings'"); TwEnumVal marble_type[] = { { 0, "Glass" }, { 1, "Metal" } }; TwType Marble_type = TwDefineEnum("Marble type", marble_type, 2); - TwAddVarRW(overlays_ptr->settings, "Marble type", Marble_type, &scene->MarbleType, "group='Gameplay settings'"); + TwAddVarRW(overlays_ptr->settings, "Marble type", Marble_type, &scene_ptr->MarbleType, "group='Gameplay settings'"); TwAddVarRW(overlays_ptr->settings, "Mouse sensitivity", TW_TYPE_FLOAT, &SETTINGS.stg.mouse_sensitivity, "min=0.001 max=0.02 step=0.001 group='Gameplay settings'"); TwAddVarRW(overlays_ptr->settings, "Wheel sensitivity", TW_TYPE_FLOAT, &SETTINGS.stg.wheel_sensitivity, "min=0.01 max=0.5 step=0.01 group='Gameplay settings'"); TwAddVarRW(overlays_ptr->settings, "Music volume", TW_TYPE_FLOAT, &SETTINGS.stg.music_volume, "min=0 max=100 step=1 group='Gameplay settings'"); TwAddVarRW(overlays_ptr->settings, "FX volume", TW_TYPE_FLOAT, &SETTINGS.stg.fx_volume, "min=0 max=100 step=1 group='Gameplay settings'"); TwAddVarRW(overlays_ptr->settings, "Target FPS", TW_TYPE_FLOAT, target_fps, "min=24 max=144 step=1 group='Gameplay settings'"); - TwAddVarRW(overlays_ptr->settings, "Camera size", TW_TYPE_FLOAT, &scene->camera_size, "min=0 max=10 step=0.001 group='Gameplay settings'"); - TwAddVarRW(overlays_ptr->settings, "Camera speed(Free mode)", TW_TYPE_FLOAT, &scene->free_camera_speed, "min=0 max=10 step=0.001 group='Gameplay settings'"); + TwAddVarRW(overlays_ptr->settings, "Camera size", TW_TYPE_FLOAT, &scene_ptr->camera_size, "min=0 max=10 step=0.001 group='Gameplay settings'"); + TwAddVarRW(overlays_ptr->settings, "Camera speed(Free mode)", TW_TYPE_FLOAT, &scene_ptr->free_camera_speed, "min=0 max=100 step=0.001 group='Gameplay settings'"); TwAddButton(overlays_ptr->settings, "Apply", ApplySettings, NULL, " label='Apply settings' "); @@ -922,7 +1004,7 @@ void InitializeATBWindows(Scene* scene, Overlays* overlays, Renderer* rd, float* TwCopyStdStringToClientFunc(CopyStdStringToClient); overlays_ptr->level_editor = TwNewBar("LevelEditor"); - Level *copy = &scene->level_copy; + Level *copy = &scene_ptr->level_copy; TwAddVarRW(overlays_ptr->level_editor, "Level Name", TW_TYPE_STDSTRING, ©->txt, ""); TwAddVarRW(overlays_ptr->level_editor, "Level Description", TW_TYPE_STDSTRING, ©->desc, ""); @@ -961,7 +1043,7 @@ void InitializeATBWindows(Scene* scene, Overlays* overlays, Renderer* rd, float* TwAddVarRW(overlays_ptr->fractal_editor, "PBR roughness", TW_TYPE_FLOAT, ©->PBR_roughness, "min=0 max=1 step=0.001 group='Fractal Material'"); TwAddVarRW(overlays_ptr->fractal_editor, "PBR metallic", TW_TYPE_FLOAT, ©->PBR_metal, "min=0 max=1 step=0.001 group='Fractal Material'"); float *p = copy->params.data(); - TwAddVarRW(overlays_ptr->fractal_editor, "Fractal Iterations", TW_TYPE_INT32, ©->FractalIter, "min=1 max=20 step=1 group='Fractal Coefficients'"); + TwAddVarRW(overlays_ptr->fractal_editor, "Fractal Iterations", TW_TYPE_INT32, ©->FractalIter, "min=1 max=32 step=1 group='Fractal Coefficients'"); TwAddVarRW(overlays_ptr->fractal_editor, "Fractal Scale", TW_TYPE_FLOAT, p, "min=0 max=5 step=0.0001 group='Fractal Coefficients'"); TwAddVarRW(overlays_ptr->fractal_editor, "Fractal Angle1", TW_TYPE_FLOAT, p + 1, "min=-10 max=10 step=0.0001 group='Fractal Coefficients'"); TwAddVarRW(overlays_ptr->fractal_editor, "Fractal Angle2", TW_TYPE_FLOAT, p + 2, "min=-10 max=10 step=0.0001 group='Fractal Coefficients'"); @@ -974,9 +1056,10 @@ void InitializeATBWindows(Scene* scene, Overlays* overlays, Renderer* rd, float* overlays_ptr->flaunch = TwNewBar("First_launch"); - TwAddVarRW(overlays_ptr->flaunch, "Rendering resolution", Resolutions, &render_resolution, ""); - TwAddVarRW(overlays_ptr->flaunch, "Screenshot resolution", Resolutions, &screenshot_resolution, ""); - TwAddVarRW(overlays_ptr->flaunch, "Language", Languages, &language_choise, ""); + TwAddVarRW(overlays_ptr->flaunch, "Rendering resolution", Resolutions, &SETTINGS.stg.rendering_resolution, ""); + TwAddVarRW(overlays_ptr->flaunch, "Fullscreen", TW_TYPE_BOOLCPP, &SETTINGS.stg.fullscreen, " help='You need to restart the game for chages to take effect'"); + TwAddVarRW(overlays_ptr->flaunch, "Screenshot resolution", Resolutions, &SETTINGS.stg.screenshot_resolution, ""); + TwAddVarRW(overlays_ptr->flaunch, "Language", Languages, &SETTINGS.stg.language, ""); TwAddButton(overlays_ptr->flaunch, "OK", InitialOK, NULL, " label='OK' "); TwSetParam(overlays_ptr->flaunch, NULL, "position", TW_PARAM_INT32, 2, &barPos1); diff --git a/src/Gamemodes.h b/src/Gamemodes.h index 1b28b400..e9c7117f 100644 --- a/src/Gamemodes.h +++ b/src/Gamemodes.h @@ -5,7 +5,6 @@ #include #include -#include #include enum GameMode { @@ -32,9 +31,6 @@ extern bool show_cheats; extern InputState io_state; //Constants -extern float mouse_sensitivity; -extern float wheel_sensitivity; -extern float music_vol; extern float target_fps; extern GameMode game_mode; @@ -58,8 +54,6 @@ void OpenLevelMenu(Scene* scene, Overlays* overlays); void ConfirmLevelDeletion(int lvl, Scene* scene, Overlays* overlays); void ConfirmEditorExit(Scene * scene, Overlays * overlays); - -float GetVol(); void LockMouse(sf::RenderWindow& window); void UnlockMouse(sf::RenderWindow& window); void PauseGame(sf::RenderWindow& window, Overlays * overlays, Scene * scene); @@ -67,9 +61,12 @@ int DirExists(const char *path); void FirstStart(Overlays* overlays); -void SetPointers(sf::RenderTexture * render, sf::RenderTexture * screenshot, sf::Texture * main, sf::Texture * screensht, sf::RectangleShape * rmain, sf::RectangleShape * rscr, sf::Shader * shader); +void SetPointers(sf::RenderWindow *w, Scene* scene, Overlays* overlays, Renderer* rd, sf::RenderTexture *render, sf::RenderTexture *screenshot, sf::Texture *main, sf::Texture *screensht, sf::RectangleShape *rmain, sf::RectangleShape *rscr, sf::Shader *shader); +void TakeScreenshot(); + +void TW_CALL ApplySettings(void * data); -void InitializeATBWindows(Scene* scene, Overlays* overlays, Renderer* rd, float* fps, bool *vsync, float *mouse_sensitivity, float *wheel_sensitivity, float *music_vol, float *target_fps); +void InitializeATBWindows(float * fps, float * target_fps); template < typename T > std::string num2str(const T& n) { diff --git a/src/Main.cpp b/src/Main.cpp index cc5e18ee..5ceaa09e 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -70,19 +70,6 @@ int main(int argc, char *argv[]) { return 1; } - //Load the font - sf::Font font; - if (!font.loadFromFile(Orbitron_Bold_ttf)) { - ERROR_MSG("Unable to load font"); - return 1; - } - //Load the mono font - sf::Font font_mono; - if (!font_mono.loadFromFile(Inconsolata_Bold_ttf)) { - ERROR_MSG("Unable to load mono font"); - return 1; - } - //Load the music sf::Music menu_music; menu_music.openFromFile(menu_ogg); @@ -100,73 +87,34 @@ int main(int argc, char *argv[]) { credits_music.openFromFile(credits_ogg); credits_music.setLoop(true); - //Get the directory for saving and loading high scores -#ifdef _WIN32 - const std::string save_dir = std::string(std::getenv("APPDATA")) + "\\MarbleMarcher"; -#else - const std::string save_dir = std::string(std::getenv("HOME")) + "/.MarbleMarcher"; -#endif - - if (!DirExists(save_dir.c_str())) { -#if defined(_WIN32) - bool success = CreateDirectory(save_dir.c_str(), NULL) != 0 || GetLastError() == ERROR_ALREADY_EXISTS; -#else - bool success = mkdir(save_dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0; -#endif - if (!success) { - ERROR_MSG("Failed to create save directory"); - return 1; - } - } - const std::string save_file = save_dir + "/scores.bin"; - const std::string settings_file = save_dir + "/settings.bin"; - - game_settings.Load(settings_file); - - //Have user select the resolution - SelectRes select_res(&font_mono); - const Resolution* resolution = select_res.Run(); - bool fullscreen = select_res.FullScreen(); - if (resolution == nullptr) { - return 0; - } - - //GL settings - sf::ContextSettings settings; - settings.majorVersion = 4; - settings.minorVersion = 3; - - //Create the window - sf::VideoMode screen_size; - sf::Uint32 window_style; - const sf::Vector2i screen_center(resolution->width / 2, resolution->height / 2); - if (fullscreen) { - screen_size = sf::VideoMode::getDesktopMode(); - window_style = sf::Style::Fullscreen; - } else { - screen_size = sf::VideoMode(resolution->width, resolution->height, 24); - window_style = sf::Style::Default; - } + bool first_start = SETTINGS.Load("assets/settings.bin"); - AdditionalSettings addsett; - addsett.Load("assets/config.txt"); LOCAL.LoadLocalsFromFolder(local_folder); - LOCAL.SetLanguage(addsett.lang); + sf::RenderWindow window; + Renderer rend("shaders/compute/MAIN.cfg"); + sf::RenderTexture renderTexture; + sf::RenderTexture screenshotTexture; + sf::Texture main_txt, screenshot_txt; + sf::RectangleShape rect; + sf::RectangleShape rect_scrshot; + //Create the fractal scene + Scene scene(level_music); + //Create the old menus + Overlays overlays(&LOCAL("default"), &LOCAL("mono"), &scene); + + //Main loop + sf::Clock clock; + float smooth_fps = target_fps; + float lag_ms = 0.0f; + mouse_pos = sf::Vector2i(0, 0); + mouse_prev_pos = sf::Vector2i(0, 0); + + SetPointers(&window, &scene, &overlays, &rend, &renderTexture, &screenshotTexture, &main_txt, &screenshot_txt, &rect, &rect_scrshot, &shader); - sf::Vector2f screenshot_size = sf::Vector2f(addsett.screenshot_width, addsett.screenshot_height); + ApplySettings(nullptr); - sf::RenderWindow window(screen_size, "Marble Marcher Community Edition", window_style, settings); - window.setVerticalSyncEnabled(VSYNC); - window.setKeyRepeatEnabled(false); + InitializeATBWindows(&smooth_fps, &target_fps); - INIT(); - if (!fullscreen) - { - sf::VideoMode fs_size = sf::VideoMode::getDesktopMode(); - window.setSize(sf::Vector2u(fs_size.width, fs_size.height-100.f)); - window.setPosition(sf::Vector2i(0, 0)); - } - window.requestFocus(); UpdateAspectRatio(window.getSize().x, window.getSize().y); //set window icon @@ -174,72 +122,17 @@ int main(int argc, char *argv[]) { icon.loadFromFile(icon_png); window.setIcon(icon.getSize().x, icon.getSize().y, icon.getPixelsPtr()); - //If native resolution is the same, then we don't need a render texture - if (resolution->width == screen_size.width && resolution->height == screen_size.height) { - fullscreen = false; - } - //force fullscreen mode - fullscreen = true; + bool fullscreen = true; - Renderer rend(resolution->width, resolution->height, "shaders/compute/MAIN.cfg"); rend.LoadExternalTextures("shaders/textures/"); - - rend.camera.SetAspectRatio((float)window.getSize().x / (float)window.getSize().y); - sf::RenderTexture renderTexture; - sf::RenderTexture screenshotTexture; - sf::Texture main_txt, screenshot_txt; - const sf::Glsl::Vec2 window_res((float)resolution->width, (float)resolution->height); - const sf::Glsl::Vec2 sres_res((float)screenshot_size.x, (float)screenshot_size.y); - //Create screen rectangle - sf::RectangleShape rect; - rect.setSize(window_res); - rect.setPosition(0, 0); - - sf::RectangleShape rect_scrshot; - rect_scrshot.setSize(sres_res); - rect_scrshot.setPosition(0, 0); - - SetPointers(&renderTexture, &screenshotTexture, &main_txt, &screenshot_txt, &rect, &rect_scrshot, &shader); - - //screenshot number - int screenshot_i = 0; - //new rendering textures - sf::Image mimg, simg; - mimg.create(resolution->width, resolution->height, sf::Color::Blue); - - main_txt.loadFromImage(mimg); - screenshot_txt.create(screenshot_size.x, screenshot_size.y); - - screenshotTexture.create(screenshot_size.x, screenshot_size.y, settings); - screenshotTexture.setSmooth(false); - - if (fullscreen) { - renderTexture.create(resolution->width, resolution->height, settings); - renderTexture.setSmooth(false); - } - sf::View default_window_view = window.getDefaultView(); - - //Create the fractal scene - Scene scene(level_music); scene.Write(shader); - scene.SetResolution(shader, window_res.x, window_res.y); scene.SetWindowResolution(window.getSize().x, window.getSize().y); - - - - menu_music.setVolume(GetVol()); - //menu_music.play(); - //Main loop - sf::Clock clock; - float smooth_fps = target_fps; - float lag_ms = 0.0f; - mouse_pos = sf::Vector2i(0, 0); - mouse_prev_pos = sf::Vector2i(0, 0); + //temporary level generation code /*for (int i = 0; i < 24; i++) @@ -251,23 +144,26 @@ int main(int argc, char *argv[]) { scene.levels.LoadLevelsFromFolder(level_folder); scene.levels.LoadMusicFromFolder(music_folder); - //Create the menus - Overlays overlays(&font, &font_mono, &scene); - overlays.SetScale(float(screen_size.width) / 1280.0f); - + overlays.SetScale(float(window.getSize().x) / 1280.0f); scene.StartDefault(); - overlays.SetAntTweakBar(window.getSize().x, window.getSize().y); - InitializeATBWindows(&scene, &overlays, &rend, &smooth_fps, &VSYNC, &mouse_sensitivity, &wheel_sensitivity, &music_vol, &target_fps); - + io_state.window_size = sf::Vector2f(window.getSize().x, window.getSize().y); float prev_s = 0; - OpenMainMenu(&scene, &overlays); - - while (window.isOpen()) { + if (first_start) + { + FirstStart(&overlays); + } + else + { + OpenMainMenu(&scene, &overlays); + } + + while (window.isOpen()) + { sf::Event event; - + window.clear(sf::Color::White); float mouse_wheel = 0.0f; mouse_prev_pos = mouse_pos; io_state.mouse_prev = sf::Vector2f(mouse_prev_pos.x, mouse_prev_pos.y); @@ -287,9 +183,7 @@ int main(int argc, char *argv[]) { } } else if (event.type == sf::Event::Resized) { - screen_size.width = event.size.width; - screen_size.height = event.size.height; - overlays.SetScale( std::max(float(screen_size.width), float(screen_size.height))/ 1280.0f); + overlays.SetScale( std::max(float(event.size.width), float(event.size.height))/ 1280.0f); sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height); default_window_view = sf::View(visibleArea); window.setView(default_window_view); @@ -314,8 +208,6 @@ int main(int argc, char *argv[]) { scene.SetExposure(1.0f); credits_music.stop(); scene.levels.StopAllMusic(); - menu_music.setVolume(GetVol()); - //menu_music.play(); } else if (game_mode == MIDPOINT) { game_mode = PLAYING; @@ -337,8 +229,6 @@ int main(int argc, char *argv[]) { else if (game_mode == PAUSED) { RemoveAllObjects(); game_mode = PLAYING; - scene.GetCurMusic().setVolume(GetVol()); - scene.SetExposure(1.0f); LockMouse(window); } else if (game_mode == PLAYING) { @@ -361,39 +251,7 @@ int main(int argc, char *argv[]) { scene.EnbaleCheats(); } } else if (keycode == sf::Keyboard::F5) { - ///Screenshot - screenshot_i++; - //Update the shader values - scene.SetResolution(shader, SETTINGS.stg.screenshot_resolution.x, SETTINGS.stg.screenshot_resolution.y); - rend.ReInitialize(SETTINGS.stg.screenshot_resolution.x, SETTINGS.stg.screenshot_resolution.y); - scene.WriteRenderer(rend); - shader.setUniform("render_texture", screenshot_txt); - rend.SetOutputTexture(screenshot_txt); - scene.Write(shader); - - //Setup full-screen shader - sf::RenderStates states = sf::RenderStates::Default; - states.shader = &shader; - //shader.setUniform("render_texture", screenshot_txt); - - window.setActive(false); - //Draw the fractal - //Draw to the render texture - screenshotTexture.setActive(true); - - rend.camera.SetMotionBlur(0); - rend.Render(); - - screenshotTexture.draw(rect_scrshot, states); - screenshotTexture.display(); - screenshotTexture.getTexture().copyToImage().saveToFile((std::string)"screenshots/screenshot"+(std::string)num2str(time(NULL))+".jpg"); - - screenshotTexture.setActive(false); - window.setActive(true); - - scene.SetResolution(shader, SETTINGS.stg.rendering_resolution.x, SETTINGS.stg.rendering_resolution.y); - rend.ReInitialize(SETTINGS.stg.rendering_resolution.x, SETTINGS.stg.rendering_resolution.y); - scene.Write(shader); + TakeScreenshot(); } else if (keycode == sf::Keyboard::F4) { overlays.TWBAR_ENABLED = !overlays.TWBAR_ENABLED; } else if (keycode == sf::Keyboard::C) { @@ -457,43 +315,6 @@ int main(int argc, char *argv[]) { } else if (game_mode == PAUSED) { - const Overlays::Texts selected = overlays.GetOption(Overlays::CONTINUE, Overlays::MOUSE); - if (selected == Overlays::CONTINUE) { - game_mode = PLAYING; - scene.GetCurMusic().setVolume(GetVol()); - scene.SetExposure(1.0f); - LockMouse(window); - } - else if (selected == Overlays::RESTART) { - game_mode = PLAYING; - scene.ResetLevel(); - scene.GetCurMusic().setVolume(GetVol()); - scene.SetExposure(1.0f); - LockMouse(window); - } - else if (selected == Overlays::QUIT) { - if (scene.IsSinglePlay()) - { - OpenLevelMenu(&scene, &overlays); - } - else - { - OpenMainMenu(&scene, &overlays); - } - scene.SetMode(Scene::INTRO); - scene.StopAllMusic(); - menu_music.setVolume(GetVol()); - //menu_music.play(); - } - else if (selected == Overlays::MUSIC) { - game_settings.mute = !game_settings.mute; - for (int i = 0; i < num_level_music; ++i) { - level_music[i].setVolume(GetVol()); - } - } - else if (selected == Overlays::MOUSE) { - game_settings.mouse_sensitivity = (game_settings.mouse_sensitivity + 1) % 3; - } } if (game_mode == LEVEL_EDITOR) { @@ -542,6 +363,7 @@ int main(int argc, char *argv[]) { } } } + //Check if the game was beat if (scene.GetMode() == Scene::FINAL && game_mode != CREDITS) { game_mode = CREDITS; @@ -555,166 +377,169 @@ int main(int argc, char *argv[]) { credits_music.play(); } - //Main game update - if (game_mode == MAIN_MENU) { - scene.UpdateCamera(); - overlays.UpdateMenu((float)mouse_pos.x, (float)mouse_pos.y); - } else if (game_mode == CONTROLS) { - scene.UpdateCamera(); - overlays.UpdateControls((float)mouse_pos.x, (float)mouse_pos.y); - } else if (game_mode == LEVELS) { - scene.UpdateCamera(); - } else if (game_mode == SCREEN_SAVER) { - scene.UpdateCamera(); - } else if (game_mode == PLAYING || game_mode == CREDITS || game_mode == MIDPOINT || game_mode == LEVEL_EDITOR) { - //Collect keyboard input - const float force_lr = - (all_keys[sf::Keyboard::Left] || all_keys[sf::Keyboard::A] ? -1.0f : 0.0f) + - (all_keys[sf::Keyboard::Right] || all_keys[sf::Keyboard::D] ? 1.0f : 0.0f); - const float force_ud = - (all_keys[sf::Keyboard::Down] || all_keys[sf::Keyboard::S] ? -1.0f : 0.0f) + - (all_keys[sf::Keyboard::Up] || all_keys[sf::Keyboard::W] ? 1.0f : 0.0f); - - //Apply forces to marble and camera - scene.UpdateMarble(force_lr, force_ud); - - - scene.free_camera_speed *= 1 + mouse_wheel * 0.05; - - //make ATB impossible to use while playing - if (game_mode == PLAYING) - { - overlays.TWBAR_ENABLED = false; - } - - //Collect mouse input - if (overlays.TWBAR_ENABLED) - { - - sf::Vector2i mouse_delta = sf::Vector2i(0, 0); - window.setMouseCursorVisible(true); - if (mouse_clicked) - { - mouse_delta = mouse_pos - mouse_prev_pos; - } - - float ms = mouse_sensitivity; - if (game_settings.mouse_sensitivity == 1) { - ms *= 0.5f; - } - else if (game_settings.mouse_sensitivity == 2) { - ms *= 0.25f; - } - const float cam_lr = float(-mouse_delta.x) * ms; - const float cam_ud = float(-mouse_delta.y) * ms; - const float cam_z = mouse_wheel * wheel_sensitivity; - - scene.UpdateCamera(cam_lr, cam_ud, cam_z, mouse_clicked); - } - else - { - window.setMouseCursorVisible(false); - const sf::Vector2i mouse_delta = mouse_pos - screen_center; - sf::Mouse::setPosition(screen_center, window); - float ms = mouse_sensitivity; - if (game_settings.mouse_sensitivity == 1) { - ms *= 0.5f; - } - else if (game_settings.mouse_sensitivity == 2) { - ms *= 0.25f; - } - const float cam_lr = float(-mouse_delta.x) * ms; - const float cam_ud = float(-mouse_delta.y) * ms; - const float cam_z = mouse_wheel * wheel_sensitivity; - - scene.UpdateCamera(cam_lr, cam_ud, cam_z, mouse_clicked); - } + + //Main game update + if (game_mode == MAIN_MENU) { + scene.UpdateCamera(); + overlays.UpdateMenu((float)mouse_pos.x, (float)mouse_pos.y); + } + else if (game_mode == CONTROLS) { + scene.UpdateCamera(); + overlays.UpdateControls((float)mouse_pos.x, (float)mouse_pos.y); + } + else if (game_mode == LEVELS) { + scene.UpdateCamera(); + } + else if (game_mode == SCREEN_SAVER) { + scene.UpdateCamera(); + } + else if (game_mode == PLAYING || game_mode == CREDITS || game_mode == MIDPOINT || game_mode == LEVEL_EDITOR) { + //Collect keyboard input + const float force_lr = + (all_keys[sf::Keyboard::Left] || all_keys[sf::Keyboard::A] ? -1.0f : 0.0f) + + (all_keys[sf::Keyboard::Right] || all_keys[sf::Keyboard::D] ? 1.0f : 0.0f); + const float force_ud = + (all_keys[sf::Keyboard::Down] || all_keys[sf::Keyboard::S] ? -1.0f : 0.0f) + + (all_keys[sf::Keyboard::Up] || all_keys[sf::Keyboard::W] ? 1.0f : 0.0f); - - } else if (game_mode == PAUSED) { - - } + //Apply forces to marble and camera + scene.UpdateMarble(force_lr, force_ud); - bool skip_frame = false; - if (lag_ms >= 1000.0f / target_fps) { - //If there is too much lag, just do another frame of physics and skip the draw - lag_ms -= 1000.0f / target_fps; - skip_frame = true; - } else { - window.setVerticalSyncEnabled(VSYNC); - //Update the shader values - scene.Write(shader); - scene.WriteRenderer(rend); - rend.camera.SetAspectRatio((float)window.getSize().x / (float)window.getSize().y); - shader.setUniform("render_texture", main_txt); - rend.SetOutputTexture(main_txt); - - //Setup full-screen shader - sf::RenderStates states = sf::RenderStates::Default; - states.shader = &shader; - - //Draw the fractal - if (fullscreen) { - window.setActive(false); - renderTexture.setActive(true); - //Draw to the render texture - rend.Render(); - renderTexture.draw(rect, states); - renderTexture.display(); - - //Draw render texture to main window - sf::Sprite sprite(renderTexture.getTexture()); - sprite.setScale(float(window.getSize().x) / float(rend.variables["width"]), - float(window.getSize().y) / float(rend.variables["height"])); - window.draw(sprite); - renderTexture.setActive(false); - window.setActive(true); - } else { - window.setActive(true); - //Draw directly to the main window - window.draw(rect, states); - } - } - //Draw text overlays to the window - if (game_mode == MAIN_MENU) { - overlays.DrawMenu(window); - } else if (game_mode == CONTROLS) { - overlays.DrawControls(window); - } else if (game_mode == LEVELS) { - overlays.DrawLevels(window); - } else if (game_mode == PLAYING) { - if (scene.GetMode() == Scene::ORBIT && scene.GetMarble().x() < 998.0f) { - overlays.DrawLevelDesc(window, scene.level_copy.txt); - } else if (scene.GetMode() == Scene::MARBLE && !scene.IsFreeCamera()) { - overlays.DrawArrow(window, scene.GetGoalDirection()); - } - if (!scene.HasCheats() || scene.GetCountdownTime() < 4 * 60) { - overlays.DrawTimer(window, scene.GetCountdownTime(), scene.IsHighScore()); - } - if (!scene.HasCheats() && scene.IsFullRun() && !scene.IsFreeCamera()) { - overlays.DrawSumTime(window, scene.GetSumTime()); - } - if (scene.HasCheats() && !scene.IsFreeCamera()) { - overlays.DrawCheatsEnabled(window); - } - if (show_cheats) { - overlays.DrawCheats(window); - } - } else if (game_mode == PAUSED) { - // overlays.DrawPaused(window); - if (scene.HasCheats()) { - overlays.DrawCheatsEnabled(window); - } - } else if (game_mode == CREDITS) { - overlays.DrawCredits(window, scene.IsFullRun(), scene.GetSumTime()); - } else if (game_mode == MIDPOINT) { - overlays.DrawMidPoint(window, scene.IsFullRun(), scene.GetSumTime()); - } - if (!scene.IsFreeCamera() || game_mode == LEVEL_EDITOR) { - // overlays.DrawFPS(window, int(smooth_fps + 0.5f)); - } + scene.free_camera_speed *= 1 + mouse_wheel * 0.05; + + //make ATB impossible to use while playing + if (game_mode == PLAYING) + { + overlays.TWBAR_ENABLED = false; + } + + //Collect mouse input + if (overlays.TWBAR_ENABLED) + { + + sf::Vector2i mouse_delta = sf::Vector2i(0, 0); + window.setMouseCursorVisible(true); + if (mouse_clicked) + { + mouse_delta = mouse_pos - mouse_prev_pos; + } + + float ms = SETTINGS.stg.mouse_sensitivity; + + const float cam_lr = float(-mouse_delta.x) * ms; + const float cam_ud = float(-mouse_delta.y) * ms; + const float cam_z = mouse_wheel * SETTINGS.stg.wheel_sensitivity; + + scene.UpdateCamera(cam_lr, cam_ud, cam_z, mouse_clicked); + } + else + { + window.setMouseCursorVisible(false); + const sf::Vector2i mouse_delta = mouse_pos - sf::Vector2i(window.getSize().x*0.5, window.getSize().x*0.5); + sf::Mouse::setPosition(sf::Vector2i(window.getSize().x*0.5, window.getSize().x*0.5), window); + + float ms = SETTINGS.stg.mouse_sensitivity; + + const float cam_lr = float(-mouse_delta.x) * ms; + const float cam_ud = float(-mouse_delta.y) * ms; + const float cam_z = mouse_wheel * SETTINGS.stg.wheel_sensitivity; + + scene.UpdateCamera(cam_lr, cam_ud, cam_z, mouse_clicked); + } + + + } + + bool skip_frame = false; + if (lag_ms >= 1000.0f / target_fps) { + //If there is too much lag, just do another frame of physics and skip the draw + lag_ms -= 1000.0f / target_fps; + skip_frame = true; + } + else { + window.setVerticalSyncEnabled(VSYNC); + //Update the shader values + if (game_mode != FIRST_START) + { + scene.Write(shader); + scene.WriteRenderer(rend); + rend.camera.SetAspectRatio((float)window.getSize().x / (float)window.getSize().y); + shader.setUniform("render_texture", main_txt); + rend.SetOutputTexture(main_txt); + } + //Setup full-screen shader + sf::RenderStates states = sf::RenderStates::Default; + states.shader = &shader; + + //Draw the fractal + + if (game_mode != FIRST_START) + { + window.setActive(false); + renderTexture.setActive(true); + //Draw to the render texture + rend.Render(); + renderTexture.draw(rect, states); + renderTexture.display(); + + //Draw render texture to main window + sf::Sprite sprite(renderTexture.getTexture()); + sprite.setScale(float(window.getSize().x) / float(rend.variables["width"]), + float(window.getSize().y) / float(rend.variables["height"])); + window.draw(sprite); + renderTexture.setActive(false); + } + window.setActive(true); + + } + + //Draw text overlays to the window + if (game_mode == MAIN_MENU) { + overlays.DrawMenu(window); + } + else if (game_mode == CONTROLS) { + overlays.DrawControls(window); + } + else if (game_mode == LEVELS) { + overlays.DrawLevels(window); + } + else if (game_mode == PLAYING) { + if (scene.GetMode() == Scene::ORBIT && scene.GetMarble().x() < 998.0f) { + overlays.DrawLevelDesc(window, scene.level_copy.txt); + } + else if (scene.GetMode() == Scene::MARBLE && !scene.IsFreeCamera()) { + overlays.DrawArrow(window, scene.GetGoalDirection()); + } + if (!scene.HasCheats() || scene.GetCountdownTime() < 4 * 60) { + overlays.DrawTimer(window, scene.GetCountdownTime(), scene.IsHighScore()); + } + if (!scene.HasCheats() && scene.IsFullRun() && !scene.IsFreeCamera()) { + overlays.DrawSumTime(window, scene.GetSumTime()); + } + if (scene.HasCheats() && !scene.IsFreeCamera()) { + overlays.DrawCheatsEnabled(window); + } + if (show_cheats) { + overlays.DrawCheats(window); + } + } + else if (game_mode == PAUSED) { + // overlays.DrawPaused(window); + if (scene.HasCheats()) { + overlays.DrawCheatsEnabled(window); + } + } + else if (game_mode == CREDITS) { + overlays.DrawCredits(window, scene.IsFullRun(), scene.GetSumTime()); + } + else if (game_mode == MIDPOINT) { + overlays.DrawMidPoint(window, scene.IsFullRun(), scene.GetSumTime()); + } + if (!scene.IsFreeCamera() || game_mode == LEVEL_EDITOR) { + // overlays.DrawFPS(window, int(smooth_fps + 0.5f)); + } //new interface render stuff io_state.dt = prev_s; @@ -722,43 +547,40 @@ int main(int argc, char *argv[]) { UpdateAllObjects(&window, io_state); window.setView(default_window_view); - if (!skip_frame) { - //Finally display to the screen - - if(overlays.TWBAR_ENABLED) - scene.Synchronize(); - overlays.DrawAntTweakBar(); - - window.display(); - - //If V-Sync is running higher than desired fps, slow down! - const float s = clock.restart().asSeconds(); - prev_s = s; - if (s > 0.0f) { - smooth_fps = smooth_fps*0.9f + std::min(1.0f / s, target_fps)*0.1f; - } - const float time_diff_ms = 1000.0f * (1.0f / target_fps - s); - if (time_diff_ms > 0) { - sf::sleep(sf::seconds(time_diff_ms / 1000.0f)); - lag_ms = std::max(lag_ms - time_diff_ms, 0.0f); - } else if (time_diff_ms < 0) { - lag_ms += std::max(-time_diff_ms, 0.0f); - } - } + + + if (!skip_frame) { + if (overlays.TWBAR_ENABLED) + scene.Synchronize(); + overlays.DrawAntTweakBar(); + + window.display(); + + //If V-Sync is running higher than desired fps, slow down! + const float s = clock.restart().asSeconds(); + prev_s = s; + if (s > 0.0f) { + smooth_fps = smooth_fps * 0.9f + std::min(1.0f / s, target_fps)*0.1f; + } + const float time_diff_ms = 1000.0f * (1.0f / target_fps - s); + if (time_diff_ms > 0) { + sf::sleep(sf::seconds(time_diff_ms / 1000.0f)); + lag_ms = std::max(lag_ms - time_diff_ms, 0.0f); + } + else if (time_diff_ms < 0) { + lag_ms += std::max(-time_diff_ms, 0.0f); + } + } + } - // RemoveAllObjects(); - //UpdateAllObjects(&window, io_state); - //Stop all music - menu_music.stop(); - scene.StopAllMusic(); - credits_music.stop(); + RemoveAllObjects(); + scene.StopMusic(); scene.levels.SaveScoresToFile(); - game_settings.Save(settings_file); TwTerminate(); #ifdef _DEBUG - system("pause"); + system("pause"); #endif return 0; } diff --git a/src/Renderer.cpp b/src/Renderer.cpp index eac92a08..d6407410 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -1,7 +1,25 @@ #include "Renderer.h" +#include "Renderer.h" +#include "Renderer.h" + + +Renderer::Renderer(int w, int h, std::string config_file) +{ + LoadConfigs(config_file); + Initialize(w, h, config_file); +} + +Renderer::Renderer(std::string config_file) +{ + LoadConfigs(config_file); +} + +Renderer::Renderer() +{ +} -Renderer::Renderer(int w, int h,std::string config_file) +void Renderer::LoadConfigs(std::string config_file) { std::vector configs = GetFilesInFolder(fs::path(config_file).parent_path().string(), ".cfg"); for (auto &file : configs) @@ -9,14 +27,6 @@ Renderer::Renderer(int w, int h,std::string config_file) rendering_configurations.push_back(file.filename().string()); } config_folder = fs::path(config_file).parent_path().string(); - Initialize(w, h, config_file); -} - -Renderer::Renderer() -{ - main_textures.clear(); - shader_textures.clear(); - global_size.clear(); } void Renderer::Initialize(int w, int h, std::string config_f) diff --git a/src/Renderer.h b/src/Renderer.h index 45b5cfb7..6362fa7a 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -22,8 +22,11 @@ class Renderer { public: Renderer(int w, int h, std::string config); + Renderer(std::string config_file); Renderer(); + void LoadConfigs(std::string config_file); + void Initialize(int w, int h, std::string config); void ReInitialize(int w, int h); diff --git a/src/Scene.cpp b/src/Scene.cpp index 4d956444..4fc64c73 100644 --- a/src/Scene.cpp +++ b/src/Scene.cpp @@ -36,13 +36,29 @@ static const int frame_orbit = 600; static const int frame_deorbit = 800; static const int frame_countdown = frame_deorbit + 3*60; static const float default_zoom = 15.0f; -static const int fractal_iters = 16; static const float ground_ratio = 1.15f; static const int mus_switches[num_level_music] = {9, 15, 21, 24}; static const int num_levels_midpoint = 15; sf::Music *current_music = nullptr; +void Scene::SetCurrentMusic(sf::Music *new_music) +{ + if (current_music != new_music) + { + StopMusic(); + current_music = new_music; + current_music->play(); + current_music->setVolume(SETTINGS.stg.music_volume); + } +} + +void Scene::StopMusic() +{ + if (current_music != nullptr) + current_music->stop(); +} + static void ModPi(float& a, float b) { if (a - b > PI) { a -= 2 * PI; @@ -129,13 +145,7 @@ void Scene::SetFlag(float x, float y, float z) { void Scene::SetLevel(int level) { cur_level = level; level_copy = levels.GetLevel(level); - if (current_music != levels.GetLevelMusic(level)) - { - if (current_music != nullptr) - current_music->stop(); - current_music = levels.GetLevelMusic(level); - current_music->play(); - } + SetCurrentMusic(levels.GetLevelMusic(level)); } void Scene::SetMode(CamMode mode) { @@ -214,6 +224,7 @@ void Scene::StartNewGame() { sum_time = 0; play_single = false; ResetCheats(); + is_fullrun = true; SetLevel(0); HideObjects(); SetMode(ORBIT); @@ -231,12 +242,6 @@ void Scene::StartNextLevel() { SetLevel(cur_level + 1); HideObjects(); SetMode(ORBIT); - for (int i = 0; i < num_level_music; ++i) { - if (cur_level == mus_switches[i]) { - StopAllMusic(); - GetCurMusic().play(); - } - } } } @@ -395,7 +400,7 @@ void Scene::UpdateMarble(float dx, float dy) { } else if (bounce_delta_v > 0.25f) { sound_bounce2.play(); } else if (bounce_delta_v > 0.1f) { - sound_bounce3.setVolume(100.0f * (bounce_delta_v / 0.25f)); + sound_bounce3.setVolume(SETTINGS.stg.fx_volume * (bounce_delta_v / 0.25f)); sound_bounce3.play(); } @@ -845,6 +850,7 @@ void Scene::WriteShader(ComputeShader& shader) shader.setUniform("SHADOWS_ENABLED", Shadows_Enabled); + shader.setUniform("FOG_ENABLED", Fog_Enabled); shader.setUniform("CAMERA_SIZE", camera_size*level_copy.marble_rad / 0.035f); shader.setUniform("FRACTAL_ITER", level_copy.FractalIter); shader.setUniform("REFL_REFR_ENABLED", Refl_Refr_Enabled); @@ -864,7 +870,7 @@ float Scene::DE(const Eigen::Vector3f& pt) const { Eigen::Vector4f p; p << pt, 1.0f; - for (int i = 0; i < fractal_iters; ++i) { + for (int i = 0; i < level_copy.FractalIter; ++i) { //absFold p.segment<3>(0) = p.segment<3>(0).cwiseAbs(); //rotZ @@ -908,7 +914,7 @@ Eigen::Vector3f Scene::NP(const Eigen::Vector3f& pt) const { Eigen::Vector4f p; p << pt, 1.0f; //Fold the point, keeping history - for (int i = 0; i < fractal_iters; ++i) { + for (int i = 0; i < level_copy.FractalIter; ++i) { //absFold p_hist.push_back(p); p.segment<3>(0) = p.segment<3>(0).cwiseAbs(); @@ -939,7 +945,7 @@ Eigen::Vector3f Scene::NP(const Eigen::Vector3f& pt) const { //Get the nearest point Eigen::Vector3f n = p.segment<3>(0).cwiseMax(-6.0f).cwiseMin(6.0f); //Then unfold the nearest point (reverse order) - for (int i = 0; i < fractal_iters; ++i) { + for (int i = 0; i < level_copy.FractalIter; ++i) { //scaleTrans n.segment<3>(0) -= frac_shift; n /= frac_scale; diff --git a/src/Scene.h b/src/Scene.h index e4758d28..1e5de02f 100644 --- a/src/Scene.h +++ b/src/Scene.h @@ -20,7 +20,7 @@ #include #include #include - +#include #define MAX_DIST 20.f #define MAX_MARCHES 1000 @@ -59,6 +59,7 @@ class Scene { bool PBR_Enabled; bool Refl_Refr_Enabled; bool Shadows_Enabled; + bool Fog_Enabled; int Fractal_Iterations; float camera_size; float free_camera_speed; @@ -73,6 +74,10 @@ class Scene { Eigen::Vector3f marble_vel; Eigen::Matrix3f marble_mat; + void SetCurrentMusic(sf::Music * new_music); + + void StopMusic(); + Scene(sf::Music* level_music); void LoadLevel(int level); @@ -150,6 +155,17 @@ class Scene { Eigen::Vector3f MouseRayCast(int mousex, int mousey, float min_dist = MIN_DIST); Eigen::Vector3f RayMarch(const Eigen::Vector3f& pt, const Eigen::Vector3f& ray, float min_dist = MIN_DIST); + sf::Sound sound_goal; + sf::SoundBuffer buff_goal; + sf::Sound sound_bounce1; + sf::SoundBuffer buff_bounce1; + sf::Sound sound_bounce2; + sf::SoundBuffer buff_bounce2; + sf::Sound sound_bounce3; + sf::SoundBuffer buff_bounce3; + sf::Sound sound_shatter; + sf::SoundBuffer buff_shatter; + protected: void SetLevel(int level); @@ -191,16 +207,7 @@ class Scene { int sum_time; float exposure; - sf::Sound sound_goal; - sf::SoundBuffer buff_goal; - sf::Sound sound_bounce1; - sf::SoundBuffer buff_bounce1; - sf::Sound sound_bounce2; - sf::SoundBuffer buff_bounce2; - sf::Sound sound_bounce3; - sf::SoundBuffer buff_bounce3; - sf::Sound sound_shatter; - sf::SoundBuffer buff_shatter; + sf::Music* music; diff --git a/src/Settings.cpp b/src/Settings.cpp index dead2135..902609a1 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -1,3 +1,18 @@ #include -AllSettings SETTINGS; \ No newline at end of file +AllSettings SETTINGS; + +TwEnumVal resolutions[] = { { 0, "320x240" }, + { 1, "480x320" }, + { 2, "640x480" }, + { 3, "800x480" }, + { 4, "960x540" }, + { 5, "1136x640" }, + { 6, "1280x720" }, + { 7, "1600x900" }, + { 8, "1920x1080" }, + { 9, "2048x1152" }, + { 10, "2560x1440" }, + { 11, "3840x2160" }, + { 12, "7680x4320" }, + { 13, "10240x4320" } }; \ No newline at end of file diff --git a/src/Settings.h b/src/Settings.h index 58e83a1d..b4f9db6f 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -19,7 +19,7 @@ #include #include #include - +#include namespace fs = std::filesystem; class Settings { @@ -44,69 +44,14 @@ class Settings { int mouse_sensitivity; }; -class AdditionalSettings -{ -public: - int screenshot_width; - int screenshot_height; - std::string lang; - - AdditionalSettings() : - screenshot_width(1920), - screenshot_height(1080), - lang("English") - {} - - void Load(const std::string& fname) { - int increment = 0; - std::ifstream config; - config.open(fname); - if (config.fail()) - { - return; - } - std::string line; - while (getline(config, line)) - { - if (line.substr(0, 1) != "#") - { - increment++; - std::istringstream iss(line); - float num; - while ((iss >> num)) - { - switch (increment) - { - case 1: - screenshot_width = num; - break; - case 2: - screenshot_height = num; - break; - case 4: - - break; - default: - break; - } - } - if (increment == 3) - { - lang = line; - } - } - } - } -}; - struct MainSettings { - sf::Vector2i rendering_resolution; - sf::Vector2i screenshot_resolution; + int rendering_resolution; + int screenshot_resolution; int MRRM_scale; int shadow_resolution; int bloom_resolution; - std::string language; + int language; bool shadows; bool refl_refr; @@ -127,10 +72,16 @@ struct MainSettings float motion_blur; float exposure; + int shader_config; + + bool fullscreen; + bool VSYNC; }; -static const MainSettings default_settings = { sf::Vector2i(1280, 800), - sf::Vector2i(2560, 1440), 4, 2, 2, "English", true, true, true, 0.05, 2.7, 3, 2.2, 90, 1, 1, 0.005, false, 0.005, 0.7 }; +extern TwEnumVal resolutions[]; + +static const MainSettings default_settings = { 6, + 10, 4, 2, 2, 0, true, true, true, 0.05, 2.7, 3, 2.2, 90, 20, 20, 0.005, 0.2, false, 0.005, 0.7, 0, false, true }; class AllSettings @@ -146,17 +97,26 @@ class AllSettings Load(settings_file); } - void Load(std::string settings_file) + bool Load(std::string settings_file) { if (!LoadFromFile(settings_file)) { - stg = default_settings; + stg = default_settings; + first_start = true; + return true; } + first_start = false; + return false; } bool LoadFromFile(std::string settings_file) { filename = settings_file; + if (!fs::exists(settings_file)) + { + return false; + } + int cfg_size = fs::file_size(settings_file); int MainSettings_size = sizeof(MainSettings); @@ -182,11 +142,11 @@ class AllSettings cfg_file.close(); } - bool new_settings; - MainSettings stg; std::string filename; + bool first_start; + ~AllSettings() { SaveToFile(filename); diff --git a/src/Shaders.cpp b/src/Shaders.cpp index 53aed322..7d591ed1 100644 --- a/src/Shaders.cpp +++ b/src/Shaders.cpp @@ -1,4 +1,5 @@ #include "Shaders.h" +bool initialized = false; ComputeShader::ComputeShader() { @@ -150,7 +151,6 @@ void ComputeShader::setCamera(gl_camera cam) setUniform("Camera.bloomtreshold", cam.bloomtreshold); setUniform("Camera.bloomintensity", cam.bloomintensity); setUniform("Camera.speckle", cam.speckle); - setUniform("Camera.stepN", cam.stepN); } GLuint ComputeShader::getNativeHandle() @@ -160,10 +160,15 @@ GLuint ComputeShader::getNativeHandle() bool INIT() { - if (glewInit() != GLEW_OK) { + if (initialized) + { + return true; + } + if ( glewInit() != GLEW_OK) { ERROR_MSG("Failed to initialize GLEW\n"); return false; } + initialized = true; return true; }