const int max_samples = 128; layout(set=0) uniform CameraTransform { mat4 eye_world_matrix; mat4 world_eye_matrix; mat4 clip_eye_matrix; mat4 eye_clip_matrix; }; layout(set=2) uniform sampler2D source; layout(set=2) uniform sampler2D depth; layout(set=2) uniform sampler2D occlusion; layout(set=2) uniform sampler2D rotate; layout(set=2) uniform AmbientOcclusionParams { float darkness; vec3 sample_points[max_samples]; int n_samples; float occlusion_radius; float edge_depth_threshold; }; #pragma MSP stage(fragment) vec3 project(vec3 position) { if(position.z>=0.0) return vec3(0.0, 0.0, -1.0); vec4 pp = clip_eye_matrix*vec4(position, 1.0); return pp.xyz/pp.w; } vec3 unproject(vec3 position) { vec4 upp = eye_clip_matrix*vec4(position, 1.0); return upp.xyz/upp.w; } vec3 get_fragment_position(vec2 tc) { return unproject(vec3(tc*2.0-1.0, texture(depth, tc).r)); } vec3 get_slope(vec3 a, vec3 x, vec3 b) { float dz1 = abs(x.z-a.z); float dz2 = abs(b.z-x.z); return (dz1>2.0*dz2 ? b-x : dz2>2.0*dz1 ? x-a : b-a); }