forked from enlightenment/efl
evas.canvas3d: Add FXAA post processing render.
Summary: Add post processing render function as rendering full screen quard after rendering to texture. Add possibility use size of current frame in shader. Add FXAA shader source files Reviewers: raster, cedric, Hermet Subscribers: jpeg Differential Revision: https://phab.enlightenment.org/D3847
This commit is contained in:
parent
5f9e73b966
commit
1f66a9e731
|
@ -785,6 +785,8 @@ modules/evas/engines/gl_common/shader_3d/color_pick_vert.shd \
|
|||
modules/evas/engines/gl_common/shader_3d/color_pick_frag.shd \
|
||||
modules/evas/engines/gl_common/shader_3d/parallax_occlusion_vert.shd \
|
||||
modules/evas/engines/gl_common/shader_3d/parallax_occlusion_frag.shd \
|
||||
modules/evas/engines/gl_common/shader_3d/post_processing_fxaa_vert.shd \
|
||||
modules/evas/engines/gl_common/shader_3d/post_processing_fxaa_frag.shd \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST += \
|
||||
|
|
|
@ -29,7 +29,7 @@ _efl_canvas_scene3d_scene3d_get(Eo *eo_obj, void *pd EINA_UNUSED)
|
|||
}
|
||||
|
||||
void
|
||||
_evas_image_3d_render(Evas *eo_e, Evas_Object *eo_obj EINA_UNUSED,
|
||||
_evas_image_3d_render(Evas *eo_e, Evas_Object *eo_obj,
|
||||
Evas_Object_Protected_Data *obj, Evas_Image_Data *o EINA_UNUSED,
|
||||
Evas_Canvas3D_Scene *scene)
|
||||
{
|
||||
|
@ -107,7 +107,14 @@ _evas_image_3d_render(Evas *eo_e, Evas_Object *eo_obj EINA_UNUSED,
|
|||
scene_data.camera_node = pd_scene->camera_node;
|
||||
scene_data.depth_offset = pd_scene->depth_offset;
|
||||
scene_data.depth_constant = pd_scene->depth_constant;
|
||||
|
||||
if (evas_object_anti_alias_get(eo_obj))
|
||||
{
|
||||
/*Use post processing render*/
|
||||
scene_data.post_processing = EINA_TRUE;
|
||||
scene_data.color_pick_enabled = EINA_FALSE;
|
||||
scene_data.render_to_texture = EINA_TRUE;
|
||||
scene_data.post_processing_type = EVAS_CANVAS3D_SHADE_MODE_POST_PROCESSING_FXAA;
|
||||
}
|
||||
/* Phase 1 - Update scene graph tree. */
|
||||
evas_canvas3d_object_update(scene);
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ evas_canvas3d_scene_data_init(Evas_Canvas3D_Scene_Public_Data *data)
|
|||
data->colors_node_mesh = NULL;
|
||||
data->render_to_texture = EINA_FALSE;
|
||||
data->lod_distance = 0;
|
||||
data->post_processing = EINA_FALSE;
|
||||
data->post_processing_type = EVAS_CANVAS3D_SHADE_MODE_POST_PROCESSING_FXAA;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -78,7 +80,6 @@ _evas_canvas3d_scene_eo_base_constructor(Eo *obj, Evas_Canvas3D_Scene_Data *pd)
|
|||
pd->colors_node_mesh = NULL;
|
||||
pd->depth_offset = 4.0;
|
||||
pd->depth_constant = 100.0;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -635,6 +636,7 @@ _evas_canvas3d_scene_pick(const Eo *obj, Evas_Canvas3D_Scene_Data *pd, Evas_Real
|
|||
scene_data.camera_node = pd->camera_node;
|
||||
scene_data.color_pick_enabled = pd->color_pick_enabled;
|
||||
update_scene = evas_canvas3d_object_dirty_get(obj, EVAS_CANVAS3D_STATE_SCENE_UPDATED);
|
||||
scene_data.post_processing = EINA_FALSE;
|
||||
if (update_scene)
|
||||
{
|
||||
if (pd->node_mesh_colors)
|
||||
|
|
|
@ -160,7 +160,7 @@ class Evas.Canvas3D.Scene (Evas.Canvas3D.Object, Evas.Common_Interface)
|
|||
depth offset]]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Eo.Base.constructor;
|
||||
Evas.Canvas3D.Object.update_notify;
|
||||
|
|
|
@ -297,6 +297,7 @@ enum Evas.Canvas3D.State
|
|||
scene_shadows_enabled,
|
||||
scene_updated, [[@since 1.14]]
|
||||
scene_shadows_depth,
|
||||
scene_render_to_texture,
|
||||
|
||||
texture_data = 1,
|
||||
texture_wrap,
|
||||
|
@ -487,14 +488,15 @@ enum Evas.Canvas3D.Shade_Mode
|
|||
[[Shader shade modes
|
||||
|
||||
@since 1.10]]
|
||||
vertex_color = 0, [[Shaded using vertex color attribute]]
|
||||
diffuse, [[Shaded using material diffuse term]]
|
||||
flat, [[Per-vertex flat lighting]]
|
||||
phong, [[Per-pixel phong shading]]
|
||||
normal_map, [[Per-pixel normal map shading]]
|
||||
shadow_map_render, [[Fragment color is defined by its z-coord]]
|
||||
color_pick, [[Rendering to additional frame bufer]]
|
||||
parallax_occlusion [[Per-pixel parallax occlusion map shading]]
|
||||
vertex_color = 0, [[Shaded using vertex color attribute]]
|
||||
diffuse, [[Shaded using material diffuse term]]
|
||||
flat, [[Per-vertex flat lighting]]
|
||||
phong, [[Per-pixel phong shading]]
|
||||
normal_map, [[Per-pixel normal map shading]]
|
||||
shadow_map_render, [[Fragment color is defined by its z-coord]]
|
||||
color_pick, [[Rendering to additional frame bufer]]
|
||||
parallax_occlusion, [[Per-pixel parallax occlusion map shading]]
|
||||
post_processing_FXAA [[Render full screen quard]]
|
||||
}
|
||||
|
||||
enum Evas.Canvas3D.Vertex_Attrib
|
||||
|
|
|
@ -458,6 +458,9 @@ struct _Evas_Canvas3D_Scene_Public_Data
|
|||
Eina_Bool render_to_texture;
|
||||
|
||||
unsigned int lod_distance;
|
||||
|
||||
Eina_Bool post_processing :1;
|
||||
Evas_Canvas3D_Shade_Mode post_processing_type;
|
||||
};
|
||||
|
||||
struct _Evas_Canvas3D_Pick_Data
|
||||
|
|
|
@ -1167,7 +1167,6 @@ void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer,
|
|||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
drawable->texDepth, 0);
|
||||
|
||||
e3d_renderer_target_set(renderer, drawable);
|
||||
e3d_renderer_clear(renderer, &c);
|
||||
|
||||
Evas_Canvas3D_Node_Data *pd_light_node = eo_data_scope_get(light, EVAS_CANVAS3D_NODE_CLASS);
|
||||
|
@ -1199,19 +1198,20 @@ void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer,
|
|||
}
|
||||
}
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
if (data->render_to_texture)
|
||||
{
|
||||
data->render_to_texture = EINA_FALSE;
|
||||
e3d_renderer_color_pick_target_set(renderer, drawable);
|
||||
}
|
||||
else
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
drawable->tex, 0);
|
||||
e3d_renderer_clear(renderer, &data->bg_color);
|
||||
}
|
||||
if (data->render_to_texture)
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
drawable->texcolorpick, 0);
|
||||
e3d_renderer_clear(renderer, &data->bg_color);
|
||||
}
|
||||
else
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
drawable->tex, 0);
|
||||
e3d_renderer_clear(renderer, &data->bg_color);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1301,8 +1301,49 @@ e3d_drawable_scene_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_C
|
|||
e3d_renderer_target_set(renderer, drawable);
|
||||
e3d_renderer_clear(renderer, &data->bg_color);
|
||||
|
||||
/*Render scene data*/
|
||||
_scene_render(drawable, renderer, data);
|
||||
if (data->post_processing)
|
||||
e3d_drawable_scene_render_to_texture(drawable, renderer, data);//Render to additional texture
|
||||
else
|
||||
_scene_render(drawable, renderer, data);//Common main render
|
||||
}
|
||||
|
||||
void
|
||||
_scene_post_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_Canvas3D_Scene_Public_Data *data)
|
||||
{
|
||||
E3D_Draw_Data drawable_data;
|
||||
float vertices_of_square[] = {-1.0, 1.0, 0.0, 1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0, 1.0, -1.0, 0.0};
|
||||
unsigned short indices_of_square[] = {0, 1, 2, 2, 1, 3};
|
||||
|
||||
memset(&drawable_data, 0x00, sizeof(E3D_Draw_Data));
|
||||
|
||||
drawable_data.flags |= E3D_SHADER_FLAG_VERTEX_POSITION;
|
||||
drawable_data.mode = data->post_processing_type;
|
||||
drawable_data.assembly = EVAS_CANVAS3D_VERTEX_ASSEMBLY_TRIANGLES;
|
||||
drawable_data.indices = indices_of_square;
|
||||
drawable_data.vertex_count = 4;
|
||||
drawable_data.index_count = 6;
|
||||
drawable_data.index_format = EVAS_CANVAS3D_INDEX_FORMAT_UNSIGNED_SHORT;
|
||||
eina_matrix4_identity(&drawable_data.matrix_mv);
|
||||
eina_matrix4_identity(&drawable_data.matrix_mvp);
|
||||
drawable_data.frame_size_h = (Evas_Real)drawable->h;
|
||||
drawable_data.frame_size_w = (Evas_Real)drawable->w;
|
||||
/*Initialize Evas_Canvas3D_Vertex_Buffer for full screen quard*/
|
||||
drawable_data.vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION].vertex0.data = (void *)vertices_of_square;
|
||||
drawable_data.vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION].vertex0.element_count = 3;
|
||||
drawable_data.vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION].vertex0.stride = 3 * sizeof(float);
|
||||
drawable_data.vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION].vertex0.owns_data = EINA_FALSE;
|
||||
drawable_data.vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION].vertex0.size = 0;
|
||||
|
||||
e3d_renderer_clear(renderer, &data->bg_color);
|
||||
|
||||
/*Initialize texture units*/
|
||||
drawable_data.smap_sampler = e3d_renderer_sampler_shadowmap_get(renderer);
|
||||
drawable_data.colortex_sampler = e3d_renderer_sampler_colortexture_get(renderer);
|
||||
|
||||
/*Render full screen quard with color pick texture unit*/
|
||||
e3d_renderer_draw(renderer, &drawable_data);
|
||||
e3d_renderer_flush(renderer);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
|
@ -1315,10 +1356,10 @@ e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable, E3D_Renderer *rende
|
|||
Eina_Iterator *itmn;
|
||||
void *ptrmn;
|
||||
Eina_List *repeat_node = NULL;
|
||||
Evas_Color c = {0.0, 0.0, 0.0, 0.0}, *unic_color = NULL;
|
||||
Evas_Color *unic_color = NULL;
|
||||
|
||||
e3d_renderer_color_pick_target_set(renderer, drawable);
|
||||
e3d_renderer_clear(renderer, &c);
|
||||
e3d_renderer_clear(renderer, &data->bg_color);
|
||||
|
||||
if (data->color_pick_enabled) //Use rendering to texture in color pick mechanism
|
||||
{
|
||||
|
@ -1374,10 +1415,12 @@ e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable, E3D_Renderer *rende
|
|||
else
|
||||
{
|
||||
_scene_render(drawable, renderer, data); //Just render scene in texture
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, drawable->fbo);
|
||||
/*Render full screen quard*/
|
||||
if (data->post_processing)
|
||||
_scene_post_render(drawable, renderer, data);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, drawable->fbo);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,9 @@ struct _E3D_Draw_Data
|
|||
Evas_Real constant_bias;
|
||||
|
||||
Eina_Bool render_to_texture;
|
||||
|
||||
Evas_Real frame_size_h;
|
||||
Evas_Real frame_size_w;
|
||||
};
|
||||
|
||||
struct _E3D_Texture
|
||||
|
@ -175,4 +178,6 @@ void e3d_renderer_draw(E3D_Renderer *renderer, E3D_Draw_Data *da
|
|||
void e3d_renderer_flush(E3D_Renderer *renderer);
|
||||
void e3d_renderer_color_pick_target_set(E3D_Renderer *renderer, E3D_Drawable *drawable);
|
||||
Eina_Bool e3d_renderer_rendering_to_texture_get(E3D_Renderer *renderer);
|
||||
GLint e3d_renderer_sampler_colortexture_get(E3D_Renderer *renderer);
|
||||
GLint e3d_renderer_sampler_shadowmap_get(E3D_Renderer *renderer);
|
||||
#endif /* EVAS_GL_3D_PRIVATE_H */
|
||||
|
|
|
@ -414,3 +414,15 @@ e3d_renderer_flush(E3D_Renderer *renderer EINA_UNUSED)
|
|||
{
|
||||
glFlush();
|
||||
}
|
||||
|
||||
GLint
|
||||
e3d_renderer_sampler_colortexture_get(E3D_Renderer *renderer)
|
||||
{
|
||||
return renderer->colortex_sampler;
|
||||
}
|
||||
|
||||
GLint
|
||||
e3d_renderer_sampler_shadowmap_get(E3D_Renderer *renderer)
|
||||
{
|
||||
return renderer->smap_sampler;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,8 @@ typedef enum _E3D_Uniform
|
|||
E3D_UNIFORM_ALPHATEST_COMPARISON,
|
||||
E3D_UNIFORM_ALPHATEST_REFVALUE,
|
||||
E3D_UNIFORM_RENDER_TO_TEXTURE,
|
||||
|
||||
E3D_UNIFORM_FRAME_SIZE_H,
|
||||
E3D_UNIFORM_FRAME_SIZE_W,
|
||||
E3D_UNIFORM_COUNT,
|
||||
} E3D_Uniform;
|
||||
|
||||
|
@ -363,6 +364,8 @@ static const char *uniform_names[] =
|
|||
"uAlphaTestComparison",
|
||||
"uAlphaTestRefValue",
|
||||
"uColorTexture",
|
||||
"uFrameSizeH",
|
||||
"uFrameSizeW"
|
||||
};
|
||||
|
||||
static inline void
|
||||
|
@ -635,6 +638,12 @@ _uniform_upload(E3D_Uniform u, GLint loc, const E3D_Draw_Data *data)
|
|||
case E3D_UNIFORM_RENDER_TO_TEXTURE:
|
||||
glUniform1i(loc, data->colortex_sampler);
|
||||
break;
|
||||
case E3D_UNIFORM_FRAME_SIZE_H:
|
||||
glUniform1f(loc, data->frame_size_h);
|
||||
break;
|
||||
case E3D_UNIFORM_FRAME_SIZE_W:
|
||||
glUniform1f(loc, data->frame_size_w);
|
||||
break;
|
||||
default:
|
||||
ERR("Invalid uniform ID.");
|
||||
break;
|
||||
|
|
|
@ -2112,6 +2112,94 @@ static const char parallax_occlusion_frag_glsl[] =
|
|||
"#endif //FOG_ENABLED\n"
|
||||
"}\n";
|
||||
|
||||
static const char post_processing_fxaa_vert_glsl[] =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision mediump float;\n"
|
||||
"precision mediump int;\n"
|
||||
"precision lowp sampler2D;\n"
|
||||
"#endif\n"
|
||||
"uniform mat4 uMatrixMvp;\n"
|
||||
"#ifdef VERTEX_POSITION\n"
|
||||
"attribute vec4 aPosition0;\n"
|
||||
"#endif //VERTEX_POSITION\n"
|
||||
"#ifdef VERTEX_POSITION_BLEND\n"
|
||||
"attribute vec4 aPosition1;\n"
|
||||
"uniform float uPositionWeight;\n"
|
||||
"#endif //VERTEX_POSITION_BLEND\n"
|
||||
"varying vec2 tc0;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" #ifdef VERTEX_POSITION_BLEND\n"
|
||||
" vec4 position = mix(aPosition1, aPosition0, uPositionWeight);\n"
|
||||
" position = vec4(position.xyz, 1.0);\n"
|
||||
"#else\n"
|
||||
"#ifdef VERTEX_POSITION\n"
|
||||
" vec4 position = vec4(aPosition0.xyz, 1.0);\n"
|
||||
"#endif // VERTEX_POSITION\n"
|
||||
"#endif //VERTEX_POSITION_BLEND\n"
|
||||
" gl_Position = uMatrixMvp * position;\n"
|
||||
" tc0 = position.xy * 0.5 + 0.5;\n"
|
||||
"}\n";
|
||||
|
||||
static const char post_processing_fxaa_frag_glsl[] =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision mediump float;\n"
|
||||
"precision mediump int;\n"
|
||||
"precision lowp sampler2D;\n"
|
||||
"#endif\n"
|
||||
"//FXAA fragment shader by Timothy Lottes\n"
|
||||
"//http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf\n"
|
||||
"//modified and adapted to www.enlightenment.org by Oleksander Shcherbina\n"
|
||||
"uniform sampler2D uColorTexture;\n"
|
||||
"uniform float uFrameSizeH;\n"
|
||||
"uniform float uFrameSizeW;\n"
|
||||
"varying vec2 tc0;\n"
|
||||
"vec4 fxaa()\n"
|
||||
"{\n"
|
||||
" float _SPAN_MAX_ = 8.0;\n"
|
||||
" float _REDUCE_MUL_ = (1.0/8.0);\n"
|
||||
" float _REDUCE_MIN_ = (1.0/128.0);\n"
|
||||
" vec4 l = vec4(0.299, 0.587, 0.114, 0.0);\n"
|
||||
" vec2 frameBufSize = vec2(uFrameSizeW, uFrameSizeH);\n"
|
||||
" vec2 direction;\n"
|
||||
" vec4 colorNW = texture2D(uColorTexture, tc0 + (vec2(-1.0, -1.0)/frameBufSize));\n"
|
||||
" vec4 colorNE = texture2D(uColorTexture, tc0 + (vec2(1.0, -1.0)/frameBufSize));\n"
|
||||
" vec4 colorSW = texture2D(uColorTexture, tc0 + (vec2(-1.0, 1.0)/frameBufSize));\n"
|
||||
" vec4 colorSE = texture2D(uColorTexture, tc0 + (vec2(1.0, 1.0)/frameBufSize));\n"
|
||||
" vec4 colorM = texture2D(uColorTexture,tc0);\n"
|
||||
" float lNW = dot(colorNW, l);\n"
|
||||
" float lNE = dot(colorNE, l);\n"
|
||||
" float lSW = dot(colorSW, l);\n"
|
||||
" float lSE = dot(colorSE, l);\n"
|
||||
" float lM = dot(colorM, l);\n"
|
||||
" float lMin = min(lM, min(min(lNW, lNE), min(lSW, lSE)));\n"
|
||||
" float lMax = max(lM, max(max(lNW, lNE), max(lSW, lSE)));\n"
|
||||
" direction.x = -((lNW + lNE) - (lSW + lSE));\n"
|
||||
" direction.y = ((lNW + lSW) - (lNE + lSE));\n"
|
||||
" float directionReduce = max(\n"
|
||||
" (lNW + lNE + lSW + lSE) * (0.25 * _REDUCE_MUL_),\n"
|
||||
" _REDUCE_MIN_);\n"
|
||||
" float rcpDirMin = 1.0/(min(abs(direction.x), abs(direction.y)) + directionReduce);\n"
|
||||
" direction = min(vec2(_SPAN_MAX_, _SPAN_MAX_),\n"
|
||||
" max(vec2(-_SPAN_MAX_, -_SPAN_MAX_),\n"
|
||||
" direction * rcpDirMin)) / frameBufSize;\n"
|
||||
" vec4 colorA = 0.5 * (\n"
|
||||
" texture2D(uColorTexture, tc0.xy + direction * (1.0/3.0 - 0.5)) +\n"
|
||||
" texture2D(uColorTexture, tc0.xy + direction * (2.0/3.0 - 0.5)));\n"
|
||||
" vec4 colorB = colorA * 0.5 + 0.25 * (\n"
|
||||
" texture2D(uColorTexture, tc0.xy + direction * (- 0.5)) +\n"
|
||||
" texture2D(uColorTexture, tc0.xy + direction * 0.5));\n"
|
||||
" float lB = dot(colorB, l);\n"
|
||||
" if((lB < lMin) || (lB > lMax))\n"
|
||||
" return colorA;\n"
|
||||
" else\n"
|
||||
" return colorB;\n"
|
||||
"}\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = fxaa();\n"
|
||||
"}\n";
|
||||
|
||||
static const char *vertex_shaders[] =
|
||||
{
|
||||
vertex_color_vert_glsl,
|
||||
|
@ -2122,6 +2210,7 @@ static const char *vertex_shaders[] =
|
|||
shadow_map_vert_glsl,
|
||||
color_pick_vert_glsl,
|
||||
parallax_occlusion_vert_glsl,
|
||||
post_processing_fxaa_vert_glsl,
|
||||
};
|
||||
|
||||
static const char *fragment_shaders[] =
|
||||
|
@ -2134,4 +2223,5 @@ static const char *fragment_shaders[] =
|
|||
shadow_map_frag_glsl,
|
||||
color_pick_frag_glsl,
|
||||
parallax_occlusion_frag_glsl,
|
||||
post_processing_fxaa_frag_glsl,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
//FXAA fragment shader by Timothy Lottes
|
||||
//http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf
|
||||
//modified and adapted to www.enlightenment.org by Oleksander Shcherbina
|
||||
uniform sampler2D uColorTexture;
|
||||
uniform float uFrameSizeH;
|
||||
uniform float uFrameSizeW;
|
||||
varying vec2 tc0;
|
||||
|
||||
vec4 fxaa()
|
||||
{
|
||||
float _SPAN_MAX_ = 8.0;
|
||||
float _REDUCE_MUL_ = (1.0/8.0);
|
||||
float _REDUCE_MIN_ = (1.0/128.0);
|
||||
vec4 l = vec4(0.299, 0.587, 0.114, 0.0);
|
||||
vec2 frameBufSize = vec2(uFrameSizeW, uFrameSizeH);
|
||||
vec2 direction;
|
||||
|
||||
vec4 colorNW = texture2D(uColorTexture, tc0 + (vec2(-1.0, -1.0)/frameBufSize));
|
||||
vec4 colorNE = texture2D(uColorTexture, tc0 + (vec2(1.0, -1.0)/frameBufSize));
|
||||
vec4 colorSW = texture2D(uColorTexture, tc0 + (vec2(-1.0, 1.0)/frameBufSize));
|
||||
vec4 colorSE = texture2D(uColorTexture, tc0 + (vec2(1.0, 1.0)/frameBufSize));
|
||||
vec4 colorM = texture2D(uColorTexture,tc0);
|
||||
|
||||
float lNW = dot(colorNW, l);
|
||||
float lNE = dot(colorNE, l);
|
||||
float lSW = dot(colorSW, l);
|
||||
float lSE = dot(colorSE, l);
|
||||
float lM = dot(colorM, l);
|
||||
|
||||
float lMin = min(lM, min(min(lNW, lNE), min(lSW, lSE)));
|
||||
float lMax = max(lM, max(max(lNW, lNE), max(lSW, lSE)));
|
||||
|
||||
direction.x = -((lNW + lNE) - (lSW + lSE));
|
||||
direction.y = ((lNW + lSW) - (lNE + lSE));
|
||||
|
||||
float directionReduce = max(
|
||||
(lNW + lNE + lSW + lSE) * (0.25 * _REDUCE_MUL_),
|
||||
_REDUCE_MIN_);
|
||||
|
||||
float rcpDirMin = 1.0/(min(abs(direction.x), abs(direction.y)) + directionReduce);
|
||||
|
||||
direction = min(vec2(_SPAN_MAX_, _SPAN_MAX_),
|
||||
max(vec2(-_SPAN_MAX_, -_SPAN_MAX_),
|
||||
direction * rcpDirMin)) / frameBufSize;
|
||||
|
||||
vec4 colorA = 0.5 * (
|
||||
texture2D(uColorTexture, tc0.xy + direction * (1.0/3.0 - 0.5)) +
|
||||
texture2D(uColorTexture, tc0.xy + direction * (2.0/3.0 - 0.5)));
|
||||
vec4 colorB = colorA * 0.5 + 0.25 * (
|
||||
texture2D(uColorTexture, tc0.xy + direction * (- 0.5)) +
|
||||
texture2D(uColorTexture, tc0.xy + direction * 0.5));
|
||||
float lB = dot(colorB, l);
|
||||
|
||||
if((lB < lMin) || (lB > lMax))
|
||||
return colorA;
|
||||
else
|
||||
return colorB;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = fxaa();
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
uniform mat4 uMatrixMvp;
|
||||
|
||||
VERTEX_SHADER_USE_POSITION
|
||||
|
||||
varying vec2 tc0;
|
||||
void main()
|
||||
{
|
||||
VERTEX_SHADER_POSITION
|
||||
|
||||
gl_Position = uMatrixMvp * position;
|
||||
tc0 = position.xy * 0.5 + 0.5;
|
||||
}
|
Loading…
Reference in New Issue