OpenGL: Converted gpu_compositing.c to use batches.

This commit is contained in:
Clément Foucault 2017-03-15 13:17:08 +01:00
parent 79f94674fb
commit 407f8eed7d
10 changed files with 270 additions and 160 deletions

View File

@ -47,6 +47,7 @@
#include "GPU_glew.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
#include "GPU_batch.h"
#include "MEM_guardedalloc.h"
@ -193,7 +194,8 @@ struct GPUFX {
/* we have a stencil, restore the previous state */
bool restore_stencil;
unsigned int vbuffer;
Batch *quad_batch;
Batch *point_batch;
};
#if 0
@ -269,12 +271,32 @@ GPUFX *GPU_fx_compositor_create(void)
{
GPUFX *fx = MEM_callocN(sizeof(GPUFX), "GPUFX compositor");
glGenBuffers(1, &fx->vbuffer);
glBindBuffer(GL_ARRAY_BUFFER, fx->vbuffer);
glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(float), fullscreencos);
glBufferSubData(GL_ARRAY_BUFFER, 8 * sizeof(float), 8 * sizeof(float), fullscreenuvs);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* Quad buffer */
static VertexFormat format = {0};
static unsigned int pos, uvs;
if (format.attrib_ct == 0) {
pos = add_attrib(&format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
uvs = add_attrib(&format, "uvs", GL_FLOAT, 2, KEEP_FLOAT);
}
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, 4);
for (int i = 0; i < 4; ++i) {
setAttrib(vbo, pos, i, fullscreencos[i]);
setAttrib(vbo, uvs, i, fullscreenuvs[i]);
}
fx->quad_batch = Batch_create(GL_TRIANGLE_STRIP, vbo, NULL);
/* Point Buffer */
static VertexFormat format_point = {0};
static unsigned int dummy_attrib;
if (format_point.attrib_ct == 0) {
dummy_attrib = add_attrib(&format_point, "pos", GL_FLOAT, 2, KEEP_FLOAT);
}
float dummy[2] = {0.0f, 0.0f};
VertexBuffer *vbo_point = VertexBuffer_create_with_format(&format_point);
VertexBuffer_allocate_data(vbo_point, 1);
setAttrib(vbo_point, dummy_attrib, 0, &dummy);
fx->point_batch = Batch_create(GL_POINTS, vbo_point, NULL);
return fx;
}
@ -364,7 +386,8 @@ static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
void GPU_fx_compositor_destroy(GPUFX *fx)
{
cleanup_fx_gl_data(fx, true);
glDeleteBuffers(1, &fx->vbuffer);
Batch_discard_all(fx->quad_batch);
Batch_discard_all(fx->point_batch);
MEM_freeN(fx);
}
@ -702,19 +725,13 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
/* disable writing to color buffer, it's depth only pass */
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
/* set up quad buffer */
glBindBuffer(GL_ARRAY_BUFFER, fx->vbuffer);
glVertexPointer(2, GL_FLOAT, 0, NULL);
glTexCoordPointer(2, GL_FLOAT, 0, ((GLubyte *)NULL + 8 * sizeof(float)));
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
depth_resolve_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_RESOLVE, false);
if (depth_resolve_shader) {
GPUDepthResolveInterface *interface = GPU_fx_shader_get_interface(depth_resolve_shader);
GPU_shader_bind(depth_resolve_shader);
/* set up quad buffer */
Batch_set_program(fx->quad_batch, GPU_shader_get_program(depth_resolve_shader));
GPU_texture_bind(fx->depth_buffer_xray, 0);
GPU_texture_compare_mode(fx->depth_buffer_xray, false);
@ -722,7 +739,7 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
GPU_shader_uniform_texture(depth_resolve_shader, interface->depth_uniform, fx->depth_buffer_xray);
/* draw */
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_compare_mode(fx->depth_buffer_xray, true);
@ -734,10 +751,6 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopAttrib();
}
@ -774,13 +787,6 @@ bool GPU_fx_do_composite_pass(
src = fx->color_buffer;
target = fx->color_buffer_sec;
/* set up quad buffer */
glBindBuffer(GL_ARRAY_BUFFER, fx->vbuffer);
glVertexPointer(2, GL_FLOAT, 0, NULL);
glTexCoordPointer(2, GL_FLOAT, 0, ((GLubyte *)NULL + 8 * sizeof(float)));
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
/* full screen FX pass */
/* invert the view matrix */
@ -808,8 +814,6 @@ bool GPU_fx_do_composite_pass(
viewvecs[1][2] = vec_far[2] - viewvecs[0][2];
}
/* set invalid color in case shader fails */
glColor3f(1.0, 0.0, 1.0);
glDisable(GL_DEPTH_TEST);
/* ssao pass */
@ -830,7 +834,7 @@ bool GPU_fx_do_composite_pass(
GPUSSAOShaderInterface *interface = GPU_fx_shader_get_interface(ssao_shader);
GPU_shader_bind(ssao_shader);
Batch_set_program(fx->quad_batch, GPU_shader_get_program(ssao_shader));
GPU_shader_uniform_vector(ssao_shader, interface->ssao_uniform, 4, 1, ssao_params);
GPU_shader_uniform_vector(ssao_shader, interface->ssao_color_uniform, 4, 1, fx_ssao->color);
@ -854,7 +858,7 @@ bool GPU_fx_do_composite_pass(
/* draw */
gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(src);
@ -912,11 +916,8 @@ bool GPU_fx_do_composite_pass(
if (!(dof_shader_pass1 && dof_shader_pass2 && dof_shader_pass3)) {
GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
GPU_framebuffer_restore();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GPU_shader_unbind();
glBindBuffer(GL_ARRAY_BUFFER, 0);
return false;
}
@ -926,7 +927,7 @@ bool GPU_fx_do_composite_pass(
GPUDOFHQPassOneInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass1);
GPU_shader_bind(dof_shader_pass1);
Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass1));
GPU_shader_uniform_vector(dof_shader_pass1, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass1, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
@ -953,7 +954,8 @@ bool GPU_fx_do_composite_pass(
GPU_framebuffer_check_valid(fx->gbuffer, NULL);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_filter_mode(src, true);
GPU_texture_unbind(src);
@ -977,17 +979,16 @@ bool GPU_fx_do_composite_pass(
GPUDOFHQPassTwoInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass2);
GPU_shader_bind(dof_shader_pass2);
Batch_set_program(fx->point_batch, GPU_shader_get_program(dof_shader_pass2));
GPU_texture_bind(fx->dof_nearfar_coc, numslots++);
GPU_texture_bind(fx->dof_half_downsampled_far, numslots++);
GPU_texture_bind(fx->dof_half_downsampled_near, numslots++);
GPU_shader_uniform_vector(dof_shader_pass2, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector_int(dof_shader_pass2, interface->rendertargetdim_uniform, 2, 1, rendertargetdim);
GPU_shader_uniform_vector(dof_shader_pass2, interface->select_uniform, 2, 1, selection);
GPU_texture_bind(fx->dof_nearfar_coc, numslots++);
GPU_shader_uniform_texture(dof_shader_pass2, interface->coc_uniform, fx->dof_nearfar_coc);
GPU_texture_bind(fx->dof_half_downsampled_far, numslots++);
GPU_texture_bind(fx->dof_half_downsampled_near, numslots++);
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_half_downsampled_far);
GPU_texture_filter_mode(fx->dof_half_downsampled_far, false);
@ -1003,24 +1004,24 @@ bool GPU_fx_do_composite_pass(
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */
glDrawArraysInstancedARB(GL_POINTS, 0, 1, fx->dof_downsampled_w * fx->dof_downsampled_h);
Batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, NULL, NULL);
GPU_texture_unbind(fx->dof_half_downsampled_far);
GPU_framebuffer_texture_detach(fx->dof_far_blur);
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_half_downsampled_near);
GPU_texture_filter_mode(fx->dof_half_downsampled_near, false);
selection[0] = 1.0f;
selection[1] = 0.0f;
GPU_shader_uniform_vector(dof_shader_pass2, interface->select_uniform, 2, 1, selection);
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_half_downsampled_near);
GPU_texture_filter_mode(fx->dof_half_downsampled_near, false);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_blur, 0);
/* have to clear the buffer unfortunately */
glClear(GL_COLOR_BUFFER_BIT);
/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */
glDrawArraysInstancedARB(GL_POINTS, 0, 1, fx->dof_downsampled_w * fx->dof_downsampled_h);
Batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, NULL, NULL);
Batch_done_using_program(fx->point_batch);
/* disable bindings */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -1032,6 +1033,7 @@ bool GPU_fx_do_composite_pass(
GPU_texture_unbind(fx->dof_nearfar_coc);
GPU_framebuffer_texture_unbind(fx->gbuffer, fx->dof_far_blur);
numslots = 0;
}
/* third pass, accumulate the near/far blur fields */
@ -1040,7 +1042,7 @@ bool GPU_fx_do_composite_pass(
GPUDOFHQPassThreeInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass3);
GPU_shader_bind(dof_shader_pass3);
Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass3));
GPU_shader_uniform_vector(dof_shader_pass3, interface->dof_uniform, 4, 1, dof_params);
@ -1066,7 +1068,7 @@ bool GPU_fx_do_composite_pass(
/* if this is the last pass, prepare for rendering on the frambuffer */
gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_blur);
@ -1108,11 +1110,8 @@ bool GPU_fx_do_composite_pass(
if (!(dof_shader_pass1 && dof_shader_pass2 && dof_shader_pass3 && dof_shader_pass4 && dof_shader_pass5)) {
GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
GPU_framebuffer_restore();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GPU_shader_unbind();
glBindBuffer(GL_ARRAY_BUFFER, 0);
return false;
}
@ -1122,7 +1121,7 @@ bool GPU_fx_do_composite_pass(
GPUDOFPassOneInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass1);
GPU_shader_bind(dof_shader_pass1);
Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass1));
GPU_shader_uniform_vector(dof_shader_pass1, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass1, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
@ -1141,7 +1140,7 @@ bool GPU_fx_do_composite_pass(
/* binding takes care of setting the viewport to the downsampled size */
GPU_texture_bind_as_framebuffer(fx->dof_near_coc_buffer);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(src);
GPU_texture_compare_mode(fx->depth_buffer, true);
@ -1164,7 +1163,7 @@ bool GPU_fx_do_composite_pass(
dof_params[2] = GPU_texture_width(fx->dof_near_coc_blurred_buffer) / (scale_camera * fx_dof->sensor);
/* Blurring vertically */
GPU_shader_bind(dof_shader_pass2);
Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass2));
GPU_shader_uniform_vector(dof_shader_pass2, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass2, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
@ -1182,10 +1181,14 @@ bool GPU_fx_do_composite_pass(
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0);
/* Drawing quad */
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Batch_draw(fx->quad_batch);
/* Rebind Shader */
Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass2));
/* *unbind/detach */
GPU_texture_unbind(fx->dof_near_coc_buffer);
GPU_framebuffer_texture_detach(fx->dof_near_coc_final_buffer);
/* Blurring horizontally */
@ -1197,7 +1200,8 @@ bool GPU_fx_do_composite_pass(
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_near_coc_final_buffer);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_blurred_buffer, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Batch_draw(fx->quad_batch);
/* *unbind/detach */
GPU_texture_compare_mode(fx->depth_buffer, true);
@ -1216,7 +1220,7 @@ bool GPU_fx_do_composite_pass(
{
GPUDOFPassThreeInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass3);
GPU_shader_bind(dof_shader_pass3);
Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass3));
GPU_texture_bind(fx->dof_near_coc_buffer, numslots++);
GPU_shader_uniform_texture(dof_shader_pass3, interface->near_coc_downsampled, fx->dof_near_coc_buffer);
@ -1226,7 +1230,7 @@ bool GPU_fx_do_composite_pass(
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_coc_buffer);
GPU_texture_unbind(fx->dof_near_coc_blurred_buffer);
@ -1244,7 +1248,7 @@ bool GPU_fx_do_composite_pass(
GPUDOFPassFourInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass4);
GPU_shader_bind(dof_shader_pass4);
Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass4));
GPU_texture_bind(fx->dof_near_coc_final_buffer, numslots++);
GPU_shader_uniform_texture(dof_shader_pass4, interface->near_coc_downsampled, fx->dof_near_coc_final_buffer);
@ -1252,7 +1256,7 @@ bool GPU_fx_do_composite_pass(
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_coc_final_buffer);
@ -1269,7 +1273,7 @@ bool GPU_fx_do_composite_pass(
GPUDOFPassFiveInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass5);
GPU_shader_bind(dof_shader_pass5);
Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass5));
GPU_shader_uniform_vector(dof_shader_pass5, interface->dof_uniform, 4, 1, dof_params);
GPU_shader_uniform_vector(dof_shader_pass5, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
@ -1292,7 +1296,7 @@ bool GPU_fx_do_composite_pass(
/* if this is the last pass, prepare for rendering on the frambuffer */
gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Batch_draw(fx->quad_batch);
/* disable bindings */
GPU_texture_unbind(fx->dof_near_coc_buffer);
GPU_texture_unbind(fx->dof_near_coc_blurred_buffer);
@ -1318,10 +1322,6 @@ bool GPU_fx_do_composite_pass(
}
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GPU_shader_unbind();
return true;

View File

@ -1,5 +1,10 @@
uniform sampler2D depthbuffer;
varying vec4 uvcoordsvar;
#if __VERSION__ == 120
varying vec4 uvcoordsvar;
#else
in vec4 uvcoordsvar;
#endif
void main(void)
{

View File

@ -16,17 +16,35 @@ uniform vec4 dof_params;
// viewvectors for reconstruction of world space
uniform vec4 viewvecs[3];
// coordinates on framebuffer in normalized (0.0-1.0) uv space
varying vec4 uvcoordsvar;
#if __VERSION__ == 120
// coordinates on framebuffer in normalized (0.0-1.0) uv space
varying vec4 uvcoordsvar;
/* color texture coordinates, offset by a small amount */
varying vec2 color_uv1;
varying vec2 color_uv2;
/* color texture coordinates, offset by a small amount */
varying vec2 color_uv1;
varying vec2 color_uv2;
varying vec2 depth_uv1;
varying vec2 depth_uv2;
varying vec2 depth_uv3;
varying vec2 depth_uv4;
varying vec2 depth_uv1;
varying vec2 depth_uv2;
varying vec2 depth_uv3;
varying vec2 depth_uv4;
#define FragColor gl_FragColor
#else
// coordinates on framebuffer in normalized (0.0-1.0) uv space
in vec4 uvcoordsvar;
/* color texture coordinates, offset by a small amount */
in vec2 color_uv1;
in vec2 color_uv2;
in vec2 depth_uv1;
in vec2 depth_uv2;
in vec2 depth_uv3;
in vec2 depth_uv4;
out vec4 FragColor;
#endif
float calculate_far_coc(in float zdepth)
@ -102,7 +120,7 @@ void first_pass()
coc = max(calculate_near_coc(zdepth), coc);
final_coc = max(max(coc.x, coc.y), max(coc.z, coc.w));
gl_FragColor = vec4(color.rgb, final_coc);
FragColor = vec4(color.rgb, final_coc);
}
/* second pass, gaussian blur the downsampled image */
@ -119,7 +137,7 @@ void second_pass()
color += texture2D(colorbuffer, uvcoordsvar.xy - 2.5 * invrendertargetdim) * 0.09375;
color += texture2D(colorbuffer, uvcoordsvar.xy - 4.5 * invrendertargetdim) * 0.015625;
gl_FragColor = color;
FragColor = color;
}
@ -129,7 +147,7 @@ void third_pass()
vec4 color = texture2D(colorbuffer, uvcoordsvar.xy);
vec4 color_blurred = texture2D(blurredcolorbuffer, uvcoordsvar.xy);
float coc = 2.0 * max(color_blurred.a, color.a); -color.a;
gl_FragColor = vec4(color.rgb, coc);
FragColor = vec4(color.rgb, coc);
}
@ -141,7 +159,7 @@ void fourth_pass()
color += texture2D(colorbuffer, uvcoordsvar.xw);
color += texture2D(colorbuffer, uvcoordsvar.yw);
gl_FragColor = color / 4.0;
FragColor = color / 4.0;
}
vec4 small_sample_blur(in sampler2D colorbuffer, in vec2 uv, in vec4 color)
@ -188,7 +206,7 @@ void fifth_pass()
color /= dot(factors, vec4(1.0));
/* using original color is not correct, but use that for now because alpha of
* blurred buffers uses CoC instead */
gl_FragColor = vec4(color.rgb, color_orig.a);
FragColor = vec4(color.rgb, color_orig.a);
}

View File

@ -20,18 +20,42 @@ uniform vec4 dof_params;
/* viewvectors for reconstruction of world space */
uniform vec4 viewvecs[3];
/* initial uv coordinate */
varying vec2 uvcoord;
#if __VERSION__ == 120
/* initial uv coordinate */
varying vec2 uvcoord;
/* coordinate used for calculating radius et al set in geometry shader */
varying vec2 particlecoord;
varying vec4 color;
/* coordinate used for calculating radius et al set in geometry shader */
varying vec2 particlecoord;
varying vec4 color;
/* downsampling coordinates */
varying vec2 downsample1;
varying vec2 downsample2;
varying vec2 downsample3;
varying vec2 downsample4;
#define fragData0 gl_FragData[0]
#define fragData1 gl_FragData[1]
#define fragData2 gl_FragData[2]
#else
/* initial uv coordinate */
in vec2 uvcoord;
/* coordinate used for calculating radius et al set in geometry shader */
in vec2 particlecoord;
flat in vec4 color;
/* downsampling coordinates */
in vec2 downsample1;
in vec2 downsample2;
in vec2 downsample3;
in vec2 downsample4;
layout(location = 0) out vec4 fragData0;
layout(location = 1) out vec4 fragData1;
layout(location = 2) out vec4 fragData2;
#endif
/* downsampling coordinates */
varying vec2 downsample1;
varying vec2 downsample2;
varying vec2 downsample3;
varying vec2 downsample4;
#define M_PI 3.1415926535897932384626433832795
@ -82,16 +106,16 @@ void downsample_pass()
float norm_far = dot(far_weights, vec4(1.0));
/* now write output to weighted buffers. */
gl_FragData[0] = color1 * near_weights.x + color2 * near_weights.y + color3 * near_weights.z +
fragData0 = color1 * near_weights.x + color2 * near_weights.y + color3 * near_weights.z +
color4 * near_weights.w;
gl_FragData[1] = color1 * far_weights.x + color2 * far_weights.y + color3 * far_weights.z +
fragData1 = color1 * far_weights.x + color2 * far_weights.y + color3 * far_weights.z +
color4 * far_weights.w;
if (norm_near > 0.0)
gl_FragData[0] /= norm_near;
fragData0 /= norm_near;
if (norm_far > 0.0)
gl_FragData[1] /= norm_far;
gl_FragData[2] = vec4(near_coc, far_coc, 0.0, 1.0);
fragData1 /= norm_far;
fragData2 = vec4(near_coc, far_coc, 0.0, 1.0);
}
/* accumulate color in the near/far blur buffers */
@ -102,16 +126,16 @@ void accumulate_pass(void) {
if (dof_params.w == 0.0)
r = 1.0;
else
r = cos(M_PI / dof_params.w) /
(cos(theta - (2.0 * M_PI / dof_params.w) * floor((dof_params.w * theta + M_PI) / (2.0 * M_PI))));
r = cos(M_PI / dof_params.w) /
(cos(theta - (2.0 * M_PI / dof_params.w) * floor((dof_params.w * theta + M_PI) / (2.0 * M_PI))));
if (dot(particlecoord, particlecoord) > r * r)
discard;
gl_FragData[0] = color;
fragData0 = color;
}
#define MERGE_THRESHOLD 4.0
#define MERGE_THRESHOLD 4.0
/* combine the passes, */
void final_pass(void) {
vec4 finalcolor;
@ -152,7 +176,9 @@ void final_pass(void) {
finalcolor = mix(finalcolor, nearcolor, nearweight / totalweight);
}
gl_FragData[0] = finalcolor;
fragData0 = finalcolor;
// fragData0 = vec4(nearweight, farweight, 0.0, 1.0);
// fragData0 = vec4(nearcolor.rgb, 1.0);
}
void main()

View File

@ -24,7 +24,7 @@ uniform sampler2D cocbuffer;
#else
in vec2 uvcoord[];
out vec2 particlecoord;
out vec4 color;
flat out vec4 color;
#endif
#define M_PI 3.1415926535897932384626433832795
@ -46,21 +46,23 @@ void main()
vec2 offset_far = vec2(offset_val * 0.5) / vec2(rendertargetdim.x, rendertargetdim.y);
gl_Position = POS + vec4(-offset_far.x, -offset_far.y, 0.0, 0.0);
color = colortex;
gl_Position = POS + vec4(-offset_far.x, -offset_far.y, 0.0, 0.0);
particlecoord = vec2(-1.0, -1.0);
EmitVertex();
gl_Position = POS + vec4(-offset_far.x, offset_far.y, 0.0, 0.0);
particlecoord = vec2(-1.0, 1.0);
color = colortex;
EmitVertex();
gl_Position = POS + vec4(offset_far.x, -offset_far.y, 0.0, 0.0);
particlecoord = vec2(1.0, -1.0);
color = colortex;
EmitVertex();
gl_Position = POS + vec4(offset_far.x, offset_far.y, 0.0, 0.0);
particlecoord = vec2(1.0, 1.0);
color = colortex;
EmitVertex();
EndPrimitive();
}

View File

@ -1,27 +1,47 @@
#if __VERSION__ == 120
attribute vec2 pos;
attribute vec2 uvs;
/* initial uv coordinate */
varying vec2 uvcoord;
/* coordinate used for calculating radius et al set in geometry shader */
varying vec2 particlecoord;
/* downsampling coordinates */
varying vec2 downsample1;
varying vec2 downsample2;
varying vec2 downsample3;
varying vec2 downsample4;
#else
in vec2 pos;
in vec2 uvs;
/* initial uv coordinate */
out vec2 uvcoord;
/* coordinate used for calculating radius et al set in geometry shader */
out vec2 particlecoord;
/* downsampling coordinates */
out vec2 downsample1;
out vec2 downsample2;
out vec2 downsample3;
out vec2 downsample4;
#endif
uniform vec2 invrendertargetdim;
uniform ivec2 rendertargetdim;
/* initial uv coordinate */
varying vec2 uvcoord;
/* coordinate used for calculating radius et al set in geometry shader */
varying vec2 particlecoord;
/* downsampling coordinates */
varying vec2 downsample1;
varying vec2 downsample2;
varying vec2 downsample3;
varying vec2 downsample4;
void vert_dof_downsample()
{
/* gather pixels from neighbors. half dimensions means we offset half a pixel to
* get this right though it's possible we may lose a pixel at some point */
downsample1 = gl_MultiTexCoord0.xy + vec2(-0.5, -0.5) * invrendertargetdim;
downsample2 = gl_MultiTexCoord0.xy + vec2(-0.5, 0.5) * invrendertargetdim;
downsample3 = gl_MultiTexCoord0.xy + vec2(0.5, 0.5) * invrendertargetdim;
downsample4 = gl_MultiTexCoord0.xy + vec2(0.5, -0.5) * invrendertargetdim;
downsample1 = uvs.xy + vec2(-0.5, -0.5) * invrendertargetdim;
downsample2 = uvs.xy + vec2(-0.5, 0.5) * invrendertargetdim;
downsample3 = uvs.xy + vec2(0.5, 0.5) * invrendertargetdim;
downsample4 = uvs.xy + vec2(0.5, -0.5) * invrendertargetdim;
gl_Position = gl_Vertex;
gl_Position = vec4(pos, 0.0, 1.0);
}
/* geometry shading pass, calculate a texture coordinate based on the indexed id */
@ -42,8 +62,8 @@ void vert_dof_coc_scatter_pass()
void vert_dof_final()
{
uvcoord = gl_MultiTexCoord0.xy;
gl_Position = gl_Vertex;
uvcoord = uvs;
gl_Position = vec4(pos, 0.0, 1.0);
}
void main()

View File

@ -1,51 +1,72 @@
uniform vec2 invrendertargetdim;
//texture coordinates for framebuffer read
varying vec4 uvcoordsvar;
/* color texture coordinates, offset by a small amount */
varying vec2 color_uv1;
varying vec2 color_uv2;
#if __VERSION__ == 120
attribute vec2 pos;
attribute vec2 uvs;
varying vec2 depth_uv1;
varying vec2 depth_uv2;
varying vec2 depth_uv3;
varying vec2 depth_uv4;
//texture coordinates for framebuffer read
varying vec4 uvcoordsvar;
/* color texture coordinates, offset by a small amount */
varying vec2 color_uv1;
varying vec2 color_uv2;
varying vec2 depth_uv1;
varying vec2 depth_uv2;
varying vec2 depth_uv3;
varying vec2 depth_uv4;
#else
in vec2 pos;
in vec2 uvs;
//texture coordinates for framebuffer read
out vec4 uvcoordsvar;
/* color texture coordinates, offset by a small amount */
out vec2 color_uv1;
out vec2 color_uv2;
out vec2 depth_uv1;
out vec2 depth_uv2;
out vec2 depth_uv3;
out vec2 depth_uv4;
#endif
//very simple shader for gull screen FX, just pass values on
void vert_generic()
{
uvcoordsvar = gl_MultiTexCoord0;
gl_Position = gl_Vertex;
uvcoordsvar = vec4(uvs, 0.0, 0.0);
gl_Position = vec4(pos, 0.0, 1.0);
}
void vert_dof_first_pass()
{
/* we offset the texture coordinates by 1.5 pixel,
* then we reuse that to sample the surrounding pixels */
color_uv1 = gl_MultiTexCoord0.xy + vec2(-1.5, -1.5) * invrendertargetdim;
color_uv2 = gl_MultiTexCoord0.xy + vec2(0.5, -1.5) * invrendertargetdim;
color_uv1 = uvs.xy + vec2(-1.5, -1.5) * invrendertargetdim;
color_uv2 = uvs.xy + vec2(0.5, -1.5) * invrendertargetdim;
depth_uv1 = gl_MultiTexCoord0.xy + vec2(-1.5, -1.5) * invrendertargetdim;
depth_uv2 = gl_MultiTexCoord0.xy + vec2(-0.5, -1.5) * invrendertargetdim;
depth_uv3 = gl_MultiTexCoord0.xy + vec2(0.5, -1.5) * invrendertargetdim;
depth_uv4 = gl_MultiTexCoord0.xy + vec2(1.5, -1.5) * invrendertargetdim;
depth_uv1 = uvs.xy + vec2(-1.5, -1.5) * invrendertargetdim;
depth_uv2 = uvs.xy + vec2(-0.5, -1.5) * invrendertargetdim;
depth_uv3 = uvs.xy + vec2(0.5, -1.5) * invrendertargetdim;
depth_uv4 = uvs.xy + vec2(1.5, -1.5) * invrendertargetdim;
gl_Position = gl_Vertex;
gl_Position = vec4(pos, 0.0, 1.0);
}
void vert_dof_fourth_pass()
{
vec4 halfpixel = vec4(-0.5, 0.5, -0.5, 0.5);
uvcoordsvar = gl_MultiTexCoord0.xxyy +
uvcoordsvar = uvs.xxyy +
halfpixel *
vec4(invrendertargetdim.x,
invrendertargetdim.x,
invrendertargetdim.y,
invrendertargetdim.y);
gl_Position = gl_Vertex;
gl_Position = vec4(pos, 0.0, 1.0);
}
void vert_dof_fifth_pass()
@ -53,8 +74,8 @@ void vert_dof_fifth_pass()
vec4 halfpixel = vec4(-0.5, 0.5, -0.5, 0.5);
color_uv1 = vec2(0.5, 1.5) * invrendertargetdim;
uvcoordsvar = gl_MultiTexCoord0;
gl_Position = gl_Vertex;
uvcoordsvar = vec4(uvs, 0.0, 0.0);
gl_Position = vec4(pos, 0.0, 1.0);
}
void main()

View File

@ -1,14 +1,17 @@
uniform mat4 ProjectionMatrix;
/* simple depth reconstruction, see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer
* we change the factors from the article to fit the OpennGL model. */
#ifdef PERSP_MATRIX
/* perspective camera code */
vec3 get_view_space_from_depth(in vec2 uvcoords, in vec3 viewvec_origin, in vec3 viewvec_diff, in float depth)
{
float d = 2.0 * depth - 1.0;
float zview = -gl_ProjectionMatrix[3][2] / (d + gl_ProjectionMatrix[2][2]);
float zview = -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
return zview * (viewvec_origin + vec3(uvcoords, 0.0) * viewvec_diff);
}
@ -18,7 +21,7 @@ vec4 get_view_space_z_from_depth(in vec4 near, in vec4 range, in vec4 depth)
vec4 d = 2.0 * depth - vec4(1.0);
/* return positive value, so sign differs! */
return vec4(gl_ProjectionMatrix[3][2]) / (d + vec4(gl_ProjectionMatrix[2][2]));
return vec4(ProjectionMatrix[3][2]) / (d + vec4(ProjectionMatrix[2][2]));
}
#else

View File

@ -1,3 +1,4 @@
// color buffer
uniform sampler2D colorbuffer;
@ -9,8 +10,15 @@ uniform sampler1D ssao_concentric_tex;
// depth buffer
uniform sampler2D depthbuffer;
// coordinates on framebuffer in normalized (0.0-1.0) uv space
varying vec4 uvcoordsvar;
#if __VERSION__ == 120
// coordinates on framebuffer in normalized (0.0-1.0) uv space
varying vec4 uvcoordsvar;
#define FragColor gl_FragColor
#else
in vec4 uvcoordsvar;
out vec4 FragColor;
#endif
/* ssao_params.x : pixel scale for the ssao radious */
/* ssao_params.y : factor for the ssao darkening */
@ -46,9 +54,9 @@ float calculate_ssao_factor(float depth)
/* find the offset in screen space by multiplying a point
* in camera space at the depth of the point by the projection matrix. */
vec2 offset;
float homcoord = gl_ProjectionMatrix[2][3] * position.z + gl_ProjectionMatrix[3][3];
offset.x = gl_ProjectionMatrix[0][0] * ssao_params.x / homcoord;
offset.y = gl_ProjectionMatrix[1][1] * ssao_params.x / homcoord;
float homcoord = ProjectionMatrix[2][3] * position.z + ProjectionMatrix[3][3];
offset.x = ProjectionMatrix[0][0] * ssao_params.x / homcoord;
offset.y = ProjectionMatrix[1][1] * ssao_params.x / homcoord;
/* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
offset *= 0.5;
@ -90,5 +98,5 @@ void main()
float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
vec4 scene_col = texture2D(colorbuffer, uvcoordsvar.xy);
vec3 final_color = mix(scene_col.rgb, ssao_color.rgb, calculate_ssao_factor(depth));
gl_FragColor = vec4(final_color.rgb, scene_col.a);
FragColor = vec4(final_color.rgb, scene_col.a);
}

View File

@ -1,9 +1,16 @@
varying vec4 uvcoordsvar;
//very simple shader for full screen FX, just pass values on
#if __VERSION__ == 120
attribute vec2 pos;
attribute vec2 uvs;
varying vec4 uvcoordsvar;
#else
in vec2 pos;
in vec2 uvs;
out vec4 uvcoordsvar;
#endif
void main()
{
uvcoordsvar = gl_MultiTexCoord0;
gl_Position = gl_Vertex;
uvcoordsvar = vec4(uvs, 0.0, 0.0);
gl_Position = vec4(pos, 0.0, 1.0);
}