mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-11 00:28:21 +03:00
post_process: merge aa into main struct
This commit is contained in:
+268
-26
@@ -18,6 +18,11 @@ extern bool task_stage_is_modern;
|
||||
|
||||
extern render_context* rctx_ptr;
|
||||
|
||||
static void post_process_generate_area_texture(post_process* pp);
|
||||
static void post_process_calculate_area_texture_data(uint8_t* data, int32_t cross1, int32_t cross2);
|
||||
static void post_process_calculate_area_texture_data_area(float_t* val_left,
|
||||
float_t* val_right, int32_t cross1, int32_t cross2, int32_t dleft, int32_t dright);
|
||||
|
||||
post_process_frame_texture_render_texture::post_process_frame_texture_render_texture() : texture() {
|
||||
type = POST_PROCESS_FRAME_TEXTURE_MAX;
|
||||
}
|
||||
@@ -34,15 +39,14 @@ post_process_frame_texture::~post_process_frame_texture() {
|
||||
|
||||
}
|
||||
|
||||
post_process::post_process() : ssaa(), mlaa(), ss_alpha_mask(), aet_back_tex(),
|
||||
render_textures_data(), movie_textures_data(), aet_back(), texture_counter(), lens_shaft_query(),
|
||||
lens_flare_query(), lens_shaft_query_data(), lens_flare_query_data(), lens_flare_query_index(),
|
||||
lens_flare_texture(), lens_shaft_texture(), lens_ghost_texture(), lens_ghost_count(),
|
||||
lens_flare_pos(), lens_shaft_scale(), lens_shaft_inv_scale(), lens_flare_power(),
|
||||
post_process::post_process() : ssaa(), mlaa(), ss_alpha_mask(), aet_back_tex(), render_textures_data(),
|
||||
movie_textures_data(), aet_back(), mlaa_area_texture(), sss_contour_texture(), texture_counter(),
|
||||
lens_shaft_query(), lens_flare_query(), lens_shaft_query_data(), lens_flare_query_data(),
|
||||
lens_flare_query_index(), lens_flare_texture(), lens_shaft_texture(), lens_ghost_texture(),
|
||||
lens_ghost_count(), lens_flare_pos(), lens_shaft_scale(), lens_shaft_inv_scale(), lens_flare_power(),
|
||||
field_A10(), lens_flare_appear_power(), render_width(), render_height(), view_point(),
|
||||
interest(), view_point_prev(), interest_prev(), reset_exposure(), sprite_width(), sprite_height(),
|
||||
screen_x_offset(), screen_y_offset(), screen_width(), screen_height(), mag_filter() {
|
||||
aa = new post_process_aa();
|
||||
blur = new post_process_blur();
|
||||
dof = new post_process_dof();
|
||||
exposure = new post_process_exposure();
|
||||
@@ -80,6 +84,8 @@ screen_x_offset(), screen_y_offset(), screen_width(), screen_height(), mag_filte
|
||||
gl_state_bind_array_buffer(0);
|
||||
gl_state_bind_vertex_array(0);
|
||||
|
||||
post_process_generate_area_texture(this);
|
||||
|
||||
if (!lens_shaft_query[0])
|
||||
glGenQueries(3, lens_shaft_query);
|
||||
|
||||
@@ -101,11 +107,6 @@ post_process::~post_process() {
|
||||
if (aet_back_tex)
|
||||
texture_free(aet_back_tex);
|
||||
|
||||
if (aa) {
|
||||
delete aa;
|
||||
aa = 0;
|
||||
}
|
||||
|
||||
if (blur) {
|
||||
delete blur;
|
||||
blur = 0;
|
||||
@@ -126,6 +127,11 @@ post_process::~post_process() {
|
||||
tone_map = 0;
|
||||
}
|
||||
|
||||
if (mlaa_area_texture) {
|
||||
glDeleteTextures(1, &mlaa_area_texture);
|
||||
mlaa_area_texture = 0;
|
||||
}
|
||||
|
||||
if (samplers[0]) {
|
||||
glDeleteSamplers(2, samplers);
|
||||
samplers[0] = 0;
|
||||
@@ -160,10 +166,6 @@ post_process::~post_process() {
|
||||
}
|
||||
|
||||
void post_process::apply(camera* cam, texture* light_proj_tex, int32_t npr_param) {
|
||||
fbo::blit(rend_texture.fbos[0], pre_texture.fbos[0],
|
||||
0, 0, render_width, render_height,
|
||||
0, 0, render_width, render_height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
for (int32_t i = 0; i < 8; i++)
|
||||
gl_state_bind_sampler(i, 0);
|
||||
|
||||
@@ -177,11 +179,11 @@ void post_process::apply(camera* cam, texture* light_proj_tex, int32_t npr_param
|
||||
exposure->get_exposure(cam, render_width, render_height, reset_exposure,
|
||||
blur->tex[4].color_texture->tex, blur->tex[2].color_texture->tex);
|
||||
tone_map->apply(&rend_texture, light_proj_tex, (texture*)(aet_back ? aet_back_tex : 0),
|
||||
&rend_texture, &buf_texture,/* &sss_contour_texture,*/
|
||||
&rend_texture, &buf_texture,/* sss_contour_texture,*/
|
||||
blur->tex[0].color_texture->tex,
|
||||
exposure->exposure.color_texture->tex, npr_param, this);
|
||||
if (mlaa)
|
||||
aa->apply_mlaa(&rend_texture, &buf_texture, samplers, ss_alpha_mask);
|
||||
apply_mlaa(samplers, ss_alpha_mask);
|
||||
|
||||
for (int32_t i = 0; i < 16; i++) {
|
||||
if (!render_textures_data[i])
|
||||
@@ -206,10 +208,6 @@ void post_process::apply(camera* cam, texture* light_proj_tex, int32_t npr_param
|
||||
|
||||
frame_texture_reset_capture();
|
||||
|
||||
fbo::blit(rend_texture.fbos[0], post_texture.fbos[0],
|
||||
0, 0, render_width, render_height,
|
||||
0, 0, render_width, render_height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
screen_texture.Bind();
|
||||
glViewport(0, 0, sprite_width, sprite_height);
|
||||
if (ssaa) {
|
||||
@@ -257,6 +255,43 @@ void post_process::apply(camera* cam, texture* light_proj_tex, int32_t npr_param
|
||||
gl_state_bind_sampler(i, 0);
|
||||
}
|
||||
|
||||
void post_process::apply_mlaa(GLuint* samplers, int32_t ss_alpha_mask) {
|
||||
gl_state_begin_event("PostProcess::mlaa");
|
||||
mlaa_buffer.Bind();
|
||||
gl_state_active_bind_texture_2d(0, rend_texture.color_texture->tex);
|
||||
gl_state_bind_sampler(0, samplers[1]);
|
||||
uniform_value[U_MLAA] = 0;
|
||||
shaders_ft.set(SHADER_FT_MLAA);
|
||||
RenderTexture::DrawQuad(&shaders_ft, render_width, render_height);
|
||||
|
||||
temp_buffer.Bind();
|
||||
gl_state_active_bind_texture_2d(0, mlaa_buffer.color_texture->tex);
|
||||
gl_state_active_bind_texture_2d(1, mlaa_area_texture);
|
||||
gl_state_bind_sampler(0, samplers[0]);
|
||||
gl_state_bind_sampler(1, samplers[1]);
|
||||
uniform_value[U_MLAA] = 1;
|
||||
uniform_value[U_MLAA_SEARCH] = 2;
|
||||
shaders_ft.set(SHADER_FT_MLAA);
|
||||
RenderTexture::DrawQuad(&shaders_ft, render_width, render_height);
|
||||
|
||||
buf_texture.Bind();
|
||||
gl_state_active_bind_texture_2d(0, rend_texture.color_texture->tex);
|
||||
gl_state_active_bind_texture_2d(1, temp_buffer.color_texture->tex);
|
||||
gl_state_bind_sampler(0, samplers[1]);
|
||||
uniform_value[U_MLAA] = 2;
|
||||
uniform_value[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0;
|
||||
shaders_ft.set(SHADER_FT_MLAA);
|
||||
RenderTexture::DrawQuad(&shaders_ft, render_width, render_height);
|
||||
uniform_value[U_ALPHA_MASK] = 0;
|
||||
gl_state_active_bind_texture_2d(0, 0);
|
||||
gl_state_active_bind_texture_2d(1, 0);
|
||||
|
||||
fbo::blit(buf_texture.fbos[0], rend_texture.fbos[0],
|
||||
0, 0, buf_texture.color_texture->width, buf_texture.color_texture->height,
|
||||
0, 0, rend_texture.color_texture->width, rend_texture.color_texture->height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
gl_state_end_event();
|
||||
}
|
||||
|
||||
void post_process::ctrl(camera* cam) {
|
||||
view_point_prev = view_point;
|
||||
interest_prev = interest;
|
||||
@@ -621,25 +656,24 @@ void post_process::init_fbo(int32_t render_width, int32_t render_height,
|
||||
return;
|
||||
|
||||
if (this->render_width != render_width || this->render_height != render_height) {
|
||||
aa->init_fbo(render_width, render_height);
|
||||
blur->init_fbo(render_width, render_height);
|
||||
dof->init_fbo(render_width, render_height);
|
||||
exposure->init_fbo();
|
||||
tone_map->init_fbo();
|
||||
rend_texture.Init(render_width, render_height, 0, GL_RGBA16F, GL_DEPTH_COMPONENT32F);
|
||||
buf_texture.Init(render_width, render_height, 0, GL_RGBA16F, 0);
|
||||
sss_contour_texture.Init(render_width, render_height, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F);
|
||||
if (aet_back_tex)
|
||||
texture_free(aet_back_tex);
|
||||
aet_back_tex = texture_load_tex_2d(texture_id(0x25, texture_counter++), GL_RGBA8, render_width, render_height, 0, 0, false);
|
||||
aet_back_texture.SetColorDepthTextures(aet_back_tex->tex, 0, rend_texture.depth_texture->tex);
|
||||
pre_texture.Init(render_width, render_height, 0, GL_RGBA16F, 0);
|
||||
post_texture.Init(render_width, render_height, 0, GL_RGBA16F, 0);
|
||||
transparency_texture.Init(render_width, render_height, 0, GL_RGBA16F, GL_DEPTH_COMPONENT32F);
|
||||
mlaa_buffer.Init(render_width, render_height, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F);
|
||||
temp_buffer.Init(render_width, render_height, 0, GL_RGBA8, 0);
|
||||
sss_contour_texture = &mlaa_buffer;
|
||||
gl_state_bind_texture_2d(rend_texture.depth_texture->tex);
|
||||
GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_ONE };
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
|
||||
gl_state_bind_texture_2d(sss_contour_texture.depth_texture->tex);
|
||||
gl_state_bind_texture_2d(mlaa_buffer.depth_texture->tex);
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
|
||||
gl_state_bind_texture_2d(0);
|
||||
this->render_width = render_width;
|
||||
@@ -837,3 +871,211 @@ void post_process::set_render_texture(bool aet_back) {
|
||||
rend_texture.Bind();
|
||||
glViewport(0, 0, render_width, render_height);
|
||||
}
|
||||
|
||||
#define MAX_EDGE_DETECTION_LEN (3)
|
||||
#define GRID_SIDE_LEN (2 * MAX_EDGE_DETECTION_LEN + 1)
|
||||
#define SIDE_LEN (5 * GRID_SIDE_LEN)
|
||||
|
||||
static void post_process_generate_area_texture(post_process* pp) {
|
||||
uint8_t* data = (uint8_t*)malloc(SIDE_LEN * SIDE_LEN * 2);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
for (int32_t cross2 = 0; cross2 < 5; cross2++)
|
||||
for (int32_t cross1 = 0; cross1 < 5; cross1++)
|
||||
post_process_calculate_area_texture_data(data, cross1, cross2);
|
||||
|
||||
glGenTextures(1, &pp->mlaa_area_texture);
|
||||
gl_state_bind_texture_2d(pp->mlaa_area_texture);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, SIDE_LEN, SIDE_LEN, 0, GL_RG, GL_UNSIGNED_BYTE, data);
|
||||
gl_state_bind_texture_2d(0);
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void post_process_calculate_area_texture_data(uint8_t* data, int32_t cross1, int32_t cross2) {
|
||||
uint8_t* _data = &data[(SIDE_LEN * GRID_SIDE_LEN * cross2 + GRID_SIDE_LEN * cross1) * 2];
|
||||
for (int32_t dright = 0; dright < GRID_SIDE_LEN; dright++) {
|
||||
for (int32_t dleft = 0; dleft < GRID_SIDE_LEN; dleft++) {
|
||||
float_t val_left = 0.0f;
|
||||
float_t val_right = 0.0f;
|
||||
post_process_calculate_area_texture_data_area(&val_left, &val_right, cross1, cross2, dleft, dright);
|
||||
_data[0] = (uint8_t)(val_left * 255.9f);
|
||||
_data[1] = (uint8_t)(val_right * 255.9f);
|
||||
_data += 2;
|
||||
}
|
||||
_data += GRID_SIDE_LEN * 4 * 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void post_process_calculate_area_texture_data_area(float_t* val_left,
|
||||
float_t* val_right, int32_t cross1, int32_t cross2, int32_t dleft, int32_t dright) {
|
||||
auto calc_area_tex_val = [&](int32_t a1, int32_t a2) {
|
||||
float_t v2 = (float_t)(-0.5 / ((float_t)a2 - 0.5));
|
||||
float_t v3 = (float_t)a1 * v2 + 0.5f;
|
||||
if (a1 >= a2 - 1)
|
||||
return (v3 * 0.5f) * 0.5f;
|
||||
else
|
||||
return ((float_t)(a1 + 1) * v2 + 0.5f + v3) * 0.5f;
|
||||
};
|
||||
|
||||
int32_t dist = dleft + dright + 1;
|
||||
float_t _val_left = 0.0f;
|
||||
float_t _val_right = 0.0f;
|
||||
switch (cross2) {
|
||||
case 0:
|
||||
switch (cross1) {
|
||||
case 1:
|
||||
_val_right = calc_area_tex_val(dleft, min_def(dist, GRID_SIDE_LEN));
|
||||
break;
|
||||
case 3:
|
||||
_val_left = calc_area_tex_val(dleft, min_def(dist, GRID_SIDE_LEN));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
switch (cross1) {
|
||||
case 0:
|
||||
_val_right = calc_area_tex_val(dright, min_def(dist, GRID_SIDE_LEN));
|
||||
break;
|
||||
case 1:
|
||||
if (dist % 2) {
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_right = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_right = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_right = calc_area_tex_val(v15, v12) * 2.0f;
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft >= v12)
|
||||
_val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
if (dist % 2) {
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_left = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_right = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_left = _val_right = calc_area_tex_val(v15, v12);
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft < v12)
|
||||
_val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
switch (cross1) {
|
||||
case 0:
|
||||
_val_left = calc_area_tex_val(dright, min_def(dist, GRID_SIDE_LEN));
|
||||
break;
|
||||
case 1:
|
||||
case 4:
|
||||
if (dist % 2) {
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_right = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_left = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_left = _val_right = calc_area_tex_val(v15, v12);
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft < v12)
|
||||
_val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (dist % 2) {
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_left = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_left = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_left = calc_area_tex_val(v15, v12) * 2.0f;
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft < v12)
|
||||
_val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
switch (cross1) {
|
||||
case 1:
|
||||
if (dist % 2) {
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_right = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_left = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_left = _val_right = calc_area_tex_val(v15, v12);
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft < v12)
|
||||
_val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (dist % 2) {
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_left = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_right = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_left = _val_right = calc_area_tex_val(v15, v12);
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft < v12)
|
||||
_val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*val_left = _val_left;
|
||||
*val_right = _val_right;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "../KKdLib/default.hpp"
|
||||
#include "../KKdLib/vec.hpp"
|
||||
#include "GL/uniform_buffer.hpp"
|
||||
#include "post_process/aa.hpp"
|
||||
#include "post_process/blur.hpp"
|
||||
#include "post_process/dof.hpp"
|
||||
#include "post_process/exposure.hpp"
|
||||
@@ -61,11 +60,8 @@ struct post_process {
|
||||
int32_t ss_alpha_mask;
|
||||
RenderTexture rend_texture;
|
||||
RenderTexture buf_texture;
|
||||
RenderTexture sss_contour_texture;
|
||||
texture* aet_back_tex;
|
||||
RenderTexture aet_back_texture;
|
||||
RenderTexture pre_texture;
|
||||
RenderTexture post_texture;
|
||||
texture* aet_back_tex;
|
||||
RenderTexture transparency_texture;
|
||||
RenderTexture screen_texture;
|
||||
texture* render_textures_data[16];
|
||||
@@ -73,7 +69,6 @@ struct post_process {
|
||||
texture* movie_textures_data[1];
|
||||
RenderTexture movie_textures[1];
|
||||
int32_t aet_back;
|
||||
post_process_aa* aa;
|
||||
post_process_blur* blur;
|
||||
post_process_dof* dof;
|
||||
post_process_exposure* exposure;
|
||||
@@ -82,6 +77,10 @@ struct post_process {
|
||||
GLuint query_vao;
|
||||
GLuint lens_ghost_vao;
|
||||
GLuint lens_ghost_vbo;
|
||||
RenderTexture mlaa_buffer;
|
||||
RenderTexture temp_buffer;
|
||||
GLuint mlaa_area_texture;
|
||||
RenderTexture* sss_contour_texture;
|
||||
GL::UniformBuffer sun_quad_ubo;
|
||||
int32_t texture_counter;
|
||||
GLuint lens_shaft_query[3];
|
||||
@@ -121,6 +120,7 @@ struct post_process {
|
||||
~post_process();
|
||||
|
||||
void apply(camera* cam, texture* light_proj_tex, int32_t npr_param);
|
||||
void apply_mlaa(GLuint* samplers, int32_t ss_alpha_mask);
|
||||
void ctrl(camera* cam);
|
||||
void draw_lens_flare(camera* cam);
|
||||
void draw_lens_ghost(RenderTexture* rt);
|
||||
|
||||
@@ -1,292 +0,0 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#include "aa.hpp"
|
||||
#include "../fbo.hpp"
|
||||
#include "../gl_state.hpp"
|
||||
#include "../post_process.hpp"
|
||||
#include "../shader_ft.hpp"
|
||||
|
||||
static void post_process_aa_generate_area_texture(post_process_aa* aa);
|
||||
static void post_process_aa_calculate_area_texture_data(uint8_t* data, int32_t cross1, int32_t cross2);
|
||||
static void post_process_aa_calculate_area_texture_data_area(float_t* val_left,
|
||||
float_t* val_right, int32_t cross1, int32_t cross2, int32_t dleft, int32_t dright);
|
||||
static float_t calc_area_tex_val(int32_t a1, int32_t a2);
|
||||
|
||||
#define MAX_EDGE_DETECTION_LEN (3)
|
||||
#define GRID_SIDE_LEN (2 * MAX_EDGE_DETECTION_LEN + 1)
|
||||
#define SIDE_LEN (5 * GRID_SIDE_LEN)
|
||||
|
||||
post_process_aa::post_process_aa() : width(), height(), mlaa_area_texture() {
|
||||
post_process_aa_generate_area_texture(this);
|
||||
}
|
||||
|
||||
post_process_aa::~post_process_aa() {
|
||||
if (!this)
|
||||
return;
|
||||
|
||||
if (mlaa_area_texture) {
|
||||
glDeleteTextures(1, &mlaa_area_texture);
|
||||
mlaa_area_texture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void post_process_aa::apply_mlaa(RenderTexture* rt,
|
||||
RenderTexture* buf_rt, GLuint* samplers, int32_t ss_alpha_mask) {
|
||||
gl_state_begin_event("PostProcess::mlaa");
|
||||
mlaa_buffer.Bind();
|
||||
gl_state_active_bind_texture_2d(0, rt->color_texture->tex);
|
||||
gl_state_bind_sampler(0, samplers[1]);
|
||||
uniform_value[U_MLAA] = 0;
|
||||
shaders_ft.set(SHADER_FT_MLAA);
|
||||
RenderTexture::DrawQuad(&shaders_ft, width, height);
|
||||
|
||||
temp_buffer.Bind();
|
||||
gl_state_active_bind_texture_2d(0, mlaa_buffer.color_texture->tex);
|
||||
gl_state_active_bind_texture_2d(1, mlaa_area_texture);
|
||||
gl_state_bind_sampler(0, samplers[0]);
|
||||
gl_state_bind_sampler(1, samplers[1]);
|
||||
uniform_value[U_MLAA] = 1;
|
||||
uniform_value[U_MLAA_SEARCH] = 2;
|
||||
shaders_ft.set(SHADER_FT_MLAA);
|
||||
RenderTexture::DrawQuad(&shaders_ft, width, height);
|
||||
|
||||
buf_rt->Bind();
|
||||
gl_state_active_bind_texture_2d(0, rt->color_texture->tex);
|
||||
gl_state_active_bind_texture_2d(1, temp_buffer.color_texture->tex);
|
||||
gl_state_bind_sampler(0, samplers[1]);
|
||||
uniform_value[U_MLAA] = 2;
|
||||
uniform_value[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0;
|
||||
shaders_ft.set(SHADER_FT_MLAA);
|
||||
RenderTexture::DrawQuad(&shaders_ft, width, height);
|
||||
uniform_value[U_ALPHA_MASK] = 0;
|
||||
gl_state_active_bind_texture_2d(0, 0);
|
||||
gl_state_active_bind_texture_2d(1, 0);
|
||||
|
||||
fbo::blit(buf_rt->fbos[0], rt->fbos[0],
|
||||
0, 0, buf_rt->color_texture->width, buf_rt->color_texture->height,
|
||||
0, 0, rt->color_texture->width, rt->color_texture->height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
gl_state_end_event();
|
||||
}
|
||||
|
||||
void post_process_aa::init_fbo(int32_t width, int32_t height) {
|
||||
if (!this || (this->width == width && this->height == height))
|
||||
return;
|
||||
|
||||
this->width = max_def(width, 1);
|
||||
this->height = max_def(height, 1);
|
||||
|
||||
mlaa_buffer.Init(this->width, this->height, 0, GL_RGBA8, 0);
|
||||
temp_buffer.Init(this->width, this->height, 0, GL_RGBA8, 0);
|
||||
}
|
||||
|
||||
static void post_process_aa_generate_area_texture(post_process_aa* aa) {
|
||||
if (aa->mlaa_area_texture) {
|
||||
glDeleteTextures(1, &aa->mlaa_area_texture);
|
||||
aa->mlaa_area_texture = 0;
|
||||
}
|
||||
|
||||
uint8_t* data = (uint8_t*)malloc(SIDE_LEN * SIDE_LEN * 2);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
for (int32_t cross2 = 0; cross2 < 5; cross2++)
|
||||
for (int32_t cross1 = 0; cross1 < 5; cross1++)
|
||||
post_process_aa_calculate_area_texture_data(data, cross1, cross2);
|
||||
|
||||
glGenTextures(1, &aa->mlaa_area_texture);
|
||||
gl_state_bind_texture_2d(aa->mlaa_area_texture);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, SIDE_LEN, SIDE_LEN, 0, GL_RG, GL_UNSIGNED_BYTE, data);
|
||||
gl_state_bind_texture_2d(0);
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void post_process_aa_calculate_area_texture_data(uint8_t* data, int32_t cross1, int32_t cross2) {
|
||||
uint8_t* _data = &data[(SIDE_LEN * GRID_SIDE_LEN * cross2 + GRID_SIDE_LEN * cross1) * 2];
|
||||
for (int32_t dright = 0; dright < GRID_SIDE_LEN; dright++) {
|
||||
for (int32_t dleft = 0; dleft < GRID_SIDE_LEN; dleft++) {
|
||||
float_t val_left = 0.0f;
|
||||
float_t val_right = 0.0f;
|
||||
post_process_aa_calculate_area_texture_data_area(&val_left, &val_right, cross1, cross2, dleft, dright);
|
||||
_data[0] = (uint8_t)(val_left * 255.9f);
|
||||
_data[1] = (uint8_t)(val_right * 255.9f);
|
||||
_data += 2;
|
||||
}
|
||||
_data += GRID_SIDE_LEN * 4 * 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void post_process_aa_calculate_area_texture_data_area(float_t* val_left,
|
||||
float_t* val_right, int32_t cross1, int32_t cross2, int32_t dleft, int32_t dright) {
|
||||
int32_t dist = dleft + dright + 1;
|
||||
float_t _val_left = 0.0f;
|
||||
float_t _val_right = 0.0f;
|
||||
switch (cross2) {
|
||||
case 0:
|
||||
switch (cross1) {
|
||||
case 1:
|
||||
_val_right = calc_area_tex_val(dleft, min_def(dist, GRID_SIDE_LEN));
|
||||
break;
|
||||
case 3:
|
||||
_val_left = calc_area_tex_val(dleft, min_def(dist, GRID_SIDE_LEN));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
switch (cross1) {
|
||||
case 0:
|
||||
_val_right = calc_area_tex_val(dright, min_def(dist, GRID_SIDE_LEN));
|
||||
break;
|
||||
case 1:
|
||||
if (dist % 2) {
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_right = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_right = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_right = calc_area_tex_val(v15, v12) * 2.0f;
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft >= v12)
|
||||
_val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
if (dist % 2) {
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_left = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_right = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_left = _val_right = calc_area_tex_val(v15, v12);
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft < v12)
|
||||
_val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
switch (cross1) {
|
||||
case 0:
|
||||
_val_left = calc_area_tex_val(dright, min_def(dist, GRID_SIDE_LEN));
|
||||
break;
|
||||
case 1:
|
||||
case 4:
|
||||
if (dist % 2) {
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_right = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_left = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_left = _val_right = calc_area_tex_val(v15, v12);
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft < v12)
|
||||
_val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (dist % 2){
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_left = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_left = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_left = calc_area_tex_val(v15, v12) * 2.0f;
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft < v12)
|
||||
_val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
switch (cross1) {
|
||||
case 1:
|
||||
if (dist % 2) {
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_right = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_left = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_left = _val_right = calc_area_tex_val(v15, v12);
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft < v12)
|
||||
_val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (dist % 2) {
|
||||
int32_t v12 = dist / 2 + 1;
|
||||
int32_t v15 = dist / 2;
|
||||
if (dleft < v15)
|
||||
_val_left = calc_area_tex_val(dleft, v12);
|
||||
else if (dright < v15)
|
||||
_val_right = calc_area_tex_val(dright, v12);
|
||||
else
|
||||
_val_left = _val_right = calc_area_tex_val(v15, v12);
|
||||
}
|
||||
else {
|
||||
int32_t v12 = dist / 2;
|
||||
float_t v14 = -0.5f / (float_t)v12;
|
||||
if (dleft < v12)
|
||||
_val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
else
|
||||
_val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*val_left = _val_left;
|
||||
*val_right = _val_right;
|
||||
return;
|
||||
}
|
||||
|
||||
static float_t calc_area_tex_val(int32_t a1, int32_t a2) {
|
||||
float_t v2 = (float_t)(-0.5 / ((float_t)a2 - 0.5));
|
||||
float_t v3 = (float_t)a1 * v2 + 0.5f;
|
||||
if (a1 >= a2 - 1)
|
||||
return (v3 * 0.5f) * 0.5f;
|
||||
else
|
||||
return ((float_t)(a1 + 1) * v2 + 0.5f + v3) * 0.5f;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
by korenkonder
|
||||
GitHub/GitLab: korenkonder
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../KKdLib/default.hpp"
|
||||
#include "../../KKdLib/vec.hpp"
|
||||
#include "../shared.hpp"
|
||||
#include "../render_texture.hpp"
|
||||
|
||||
struct post_process_aa {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
RenderTexture mlaa_buffer;
|
||||
RenderTexture temp_buffer;
|
||||
GLuint mlaa_area_texture;
|
||||
|
||||
post_process_aa();
|
||||
~post_process_aa();
|
||||
|
||||
void apply_mlaa(RenderTexture* rt,
|
||||
RenderTexture* buf_rt, GLuint* samplers, int32_t ss_alpha_mask);
|
||||
void init_fbo(int32_t width, int32_t height);
|
||||
};
|
||||
@@ -541,7 +541,7 @@ namespace rndr {
|
||||
gl_state_enable_blend();
|
||||
gl_state_disable_cull_face();
|
||||
sprite_manager_draw(rctx, 2, true,
|
||||
pp->aa->temp_buffer.color_texture,
|
||||
pp->temp_buffer.color_texture,
|
||||
rctx->camera->view_projection_aet_3d);
|
||||
gl_state_enable_cull_face();
|
||||
gl_state_disable_blend();
|
||||
@@ -819,7 +819,7 @@ namespace rndr {
|
||||
gl_state_enable_blend();
|
||||
gl_state_disable_cull_face();
|
||||
sprite_manager_draw(rctx, 0, true,
|
||||
pp->aa->temp_buffer.color_texture,
|
||||
pp->temp_buffer.color_texture,
|
||||
rctx->camera->view_projection_aet_2d);
|
||||
gl_state_enable_cull_face();
|
||||
gl_state_disable_blend();
|
||||
@@ -839,7 +839,7 @@ namespace rndr {
|
||||
|
||||
void RenderManager::pass_3d_contour(render_context* rctx) {
|
||||
RenderTexture* rt = &rctx->post_process.rend_texture;
|
||||
RenderTexture* contour_rt = &rctx->post_process.sss_contour_texture;
|
||||
RenderTexture* contour_rt = rctx->post_process.sss_contour_texture;
|
||||
|
||||
gl_state_enable_blend();
|
||||
gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@@ -888,7 +888,7 @@ namespace rndr {
|
||||
gl_state_enable_blend();
|
||||
gl_state_disable_cull_face();
|
||||
sprite_manager_draw(rctx, 1, true,
|
||||
pp->aa->temp_buffer.color_texture,
|
||||
pp->temp_buffer.color_texture,
|
||||
rctx->camera->view_projection_aet_2d);
|
||||
}
|
||||
}
|
||||
@@ -1175,7 +1175,7 @@ static bool draw_pass_shadow_litproj(render_context* rctx, light_proj* litproj)
|
||||
}
|
||||
|
||||
static void draw_pass_sss_contour(render_context* rctx, post_process* pp) {
|
||||
pp->sss_contour_texture.Bind();
|
||||
pp->sss_contour_texture->Bind();
|
||||
gl_state_enable_depth_test();
|
||||
gl_state_set_depth_func(GL_ALWAYS);
|
||||
gl_state_set_depth_mask(GL_TRUE);
|
||||
|
||||
Reference in New Issue
Block a user