Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
graph/shaders/dof.vert

68 lines
2.3 KiB
GLSL
Raw Normal View History

2018-11-03 07:24:32 -04:00
#version 460 core
layout(location = 0) out vec2 outUV;
layout(location = 1) out vec2 outLoc;
layout(location = 2) out float cocRadius;
layout(binding = 2) uniform sampler2D depthSampler;
layout(push_constant) uniform PushConstants {
vec4 dpack;
vec4 dpack2;
int reverse;
2018-11-03 07:24:32 -04:00
} pushConstants;
// we calculate a circle of confusion based off of a bias and scale
// we basically do aperture * difference based off of surrounding depth
// the bias and scale calculations are based off of Bart Wronski's work:
// https://bartwronski.com/2014/04/07/bokeh-depth-of-field-going-insane-part-1/
float calculate_coc(vec2 inUV) {
const float bias = pushConstants.dpack[0] * (1.0 - pushConstants.dpack2[0] / pushConstants.dpack2[1]);
const float scale = pushConstants.dpack[0] * pushConstants.dpack2[0] * (pushConstants.dpack2[2] - pushConstants.dpack2[1]) / (pushConstants.dpack2[2] * pushConstants.dpack2[1]);
const vec4 depth = textureGather(depthSampler, inUV);
const float maxDepth = max(max(depth.x, depth.y), max(depth.z, depth.w));
return scale * maxDepth + bias;
}
2018-11-03 07:24:32 -04:00
void main() {
const vec2 res = vec2(pushConstants.dpack[2], pushConstants.dpack[3]);
const vec2 loc = vec2((gl_InstanceIndex % int(res.x)), ((gl_InstanceIndex / int(res.x)) % int(res.y)));
outLoc = loc;
const float coc = calculate_coc(vec2(loc.x / res.x, loc.y / res.y));
// this dof implementation relies on two separate fields, so we want to cull near objects when rendering the far field, and vice versa
const bool near = coc < 0.0f;
float cocScale = abs(coc);
if(pushConstants.reverse == 1) {
if(!near) {
cocScale = 0.0;
}
} else {
if(near) {
cocScale = 0.0;
}
}
// we limit the radius of every bokeh sample to 32, any higher risks heavy overdraw
const float size = min(cocScale, 32.0);
2018-11-03 07:24:32 -04:00
cocRadius = size;
2018-11-03 07:24:32 -04:00
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
vec2 pos = outUV * 2.0 + -1.0;
pos *= size;
2018-11-03 07:24:32 -04:00
pos *= vec2(1.0 / res.x, 1.0 / res.y);
pos.x -= 1;
pos.y -= 1;
pos.x += loc.x / (res.x / 2.0);
pos.y += loc.y / (res.y / 2.0);
// invalid bokeh is culled out of viewport
gl_Position = vec4(pos, 0.0, (cocScale < 1.0) ? -1.0 : 1.0);
2018-11-03 07:24:32 -04:00
}