evas: fix compatibility with GLES2.0. Shadow effect

Summary:
Use RGBA texture unit for generation shadow. Use separate framebuffer and
renderbuffer for shadow map.
Refactor shadow map shader to use position of shadow and pack depth value in
RGBA texture.
Refactor shader function for generation shadow factor to unpack depth value from
RGBA shadow map.

Reviewers: cedric, Hermet

Subscribers: cedric

Differential Revision: https://phab.enlightenment.org/D2578

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
Oleksandr Shcherbina 2015-05-26 18:40:03 +02:00 committed by Cedric BAIL
parent 6986e3126d
commit abc1eabecb
6 changed files with 157 additions and 60 deletions

View File

@ -276,6 +276,9 @@ e3d_drawable_new(int w, int h, int alpha, GLenum depth_format, GLenum stencil_fo
GLuint depth_stencil_buf = 0;
GLuint depth_buf = 0;
GLuint stencil_buf = 0;
#ifdef GL_GLES
GLuint shadow_fbo, depth_render_buf;
#endif
Eina_Bool depth_stencil = EINA_FALSE;
glGenTextures(1, &tex);
@ -298,8 +301,13 @@ e3d_drawable_new(int w, int h, int alpha, GLenum depth_format, GLenum stencil_fo
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
#ifndef GL_GLES
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, w, h, 0, GL_RED, GL_UNSIGNED_SHORT, 0);
#else
glGenFramebuffers(1, &shadow_fbo);
glGenFramebuffers(1, &depth_render_buf);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#endif
glGenFramebuffers(1, &color_pick_fb_id);
glGenTextures(1, &texcolorpick);
glBindTexture(GL_TEXTURE_2D, texcolorpick);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
@ -310,8 +318,6 @@ e3d_drawable_new(int w, int h, int alpha, GLenum depth_format, GLenum stencil_fo
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, w, h, 0, GL_RED, GL_UNSIGNED_SHORT, 0);
#endif
glGenFramebuffers(1, &color_pick_fb_id);
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
@ -393,7 +399,10 @@ e3d_drawable_new(int w, int h, int alpha, GLenum depth_format, GLenum stencil_fo
drawable->depth_buf = depth_buf;
drawable->stencil_buf = stencil_buf;
drawable->texDepth = texDepth;
#ifdef GL_GLES
drawable->shadow_fbo = shadow_fbo;
drawable->depth_render_buf = depth_render_buf;
#endif
return drawable;
error:
@ -403,6 +412,8 @@ error:
glDeleteTextures(1, &tex);
if (texcolorpick)
glDeleteTextures(1, &texcolorpick);
if (texDepth)
glDeleteTextures(1, &texDepth);
if (fbo)
glDeleteFramebuffers(1, &fbo);
@ -424,6 +435,13 @@ error:
if (stencil_buf)
glDeleteRenderbuffers(1, &stencil_buf);
#ifdef GL_GLES
if (shadow_fbo)
glDeleteFramebuffers(1, &shadow_fbo);
if (depth_render_buf)
glDeleteFramebuffers(1, &depth_render_buf);
#endif
return NULL;
}
@ -1146,7 +1164,9 @@ _mesh_draw(E3D_Renderer *renderer, Evas_3D_Mesh *mesh, int frame, Evas_3D_Node *
e3d_renderer_draw(renderer, &data);
}
void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_3D_Scene_Public_Data *data, Evas_Mat4 *matrix_light_eye, Evas_3D_Node *light)
void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer,
Evas_3D_Scene_Public_Data *data, Evas_Mat4 *matrix_light_eye,
Evas_3D_Node *light)
{
Eina_List *l;
Evas_3D_Node *n;
@ -1157,12 +1177,24 @@ void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_3D_S
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(4.0, 100.0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawable->texDepth, 0);
#ifdef GL_GLES
glBindFramebuffer(GL_FRAMEBUFFER, drawable->shadow_fbo);
glBindRenderbuffer(GL_RENDERBUFFER, drawable->depth_render_buf);
#endif
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
drawable->texDepth, 0);
#ifdef GL_GLES
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, drawable->w,
drawable->h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
drawable->depth_render_buf);
#endif
e3d_renderer_target_set(renderer, drawable);
e3d_renderer_clear(renderer, &c);
Evas_3D_Node_Data *pd_light_node = eo_data_scope_get(light, EVAS_3D_NODE_CLASS);
Evas_3D_Light_Data *pd = eo_data_scope_get(pd_light_node->data.light.light, EVAS_3D_LIGHT_CLASS);
Evas_3D_Light_Data *pd = eo_data_scope_get(pd_light_node->data.light.light,
EVAS_3D_LIGHT_CLASS);
Evas_Vec4 planes[6];
evas_mat4_multiply(&matrix_vp, &pd->projection, matrix_light_eye);
@ -1180,7 +1212,8 @@ void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_3D_S
blend_enabled = pdmesh->blending;
pdmesh->blending = EINA_FALSE;
pdmesh->shade_mode = EVAS_3D_SHADE_MODE_SHADOW_MAP_RENDER;
_mesh_draw(renderer, nm->mesh, nm->frame, light, matrix_light_eye, &matrix_mv, &matrix_mvp, &matrix_mvp);
_mesh_draw(renderer, nm->mesh, nm->frame, light, matrix_light_eye,
&matrix_mv, &matrix_mvp, &matrix_mvp);
pdmesh->shade_mode = shade_mode;
pdmesh->blending = blend_enabled;
}
@ -1189,6 +1222,9 @@ void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_3D_S
}
glDisable(GL_POLYGON_OFFSET_FILL);
#ifdef GL_GLES
glBindFramebuffer(GL_FRAMEBUFFER, drawable->fbo);
#endif
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawable->tex, 0);
}

View File

@ -147,6 +147,10 @@ struct _E3D_Drawable
GLuint texDepth;
GLuint texcolorpick;
GLuint color_pick_fb_id;
#ifdef GL_GLES
GLuint shadow_fbo;
GLuint depth_render_buf;
#endif
};
/* Texture internal functions. */

View File

@ -403,19 +403,25 @@ static const char flat_frag_glsl[] =
"uniform sampler2D uShadowMap;\n"
"float shadow;\n"
"float pcf(vec4 lpos, float size)\n"
" {\n"
"{\n"
" vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n"
" float i, j, shadow;\n"
" shadow = 0.0;\n"
"#ifndef GL_ES\n"
" vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n"
" float i, j, randx, randy, shadow;\n"
" shadow = 0.0;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n"
" return shadow / 64.0;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n"
"#else\n"
" /*TODO Add algorithm generate shadow*/\n"
" return 1.0;\n"
" const vec4 unpack = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);\n"
" const float bias = 0.00015 /*TODO Optimizate set of offset*/;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" {\n"
" vec4 zvalue = texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size);\n"
" shadow += float(smcoord.z < dot(zvalue, unpack) + bias);\n"
" }\n"
"#endif //GL_ES\n"
" return shadow / 64.0;\n"
"}\n"
"#endif //SHADOWED\n"
"#ifdef DIFFUSE\n"
@ -734,19 +740,25 @@ static const char phong_frag_glsl[] =
"uniform sampler2D uShadowMap;\n"
"float shadow;\n"
"float pcf(vec4 lpos, float size)\n"
" {\n"
"{\n"
" vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n"
" float i, j, shadow;\n"
" shadow = 0.0;\n"
"#ifndef GL_ES\n"
" vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n"
" float i, j, randx, randy, shadow;\n"
" shadow = 0.0;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n"
" return shadow / 64.0;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n"
"#else\n"
" /*TODO Add algorithm generate shadow*/\n"
" return 1.0;\n"
" const vec4 unpack = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);\n"
" const float bias = 0.00015 /*TODO Optimizate set of offset*/;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" {\n"
" vec4 zvalue = texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size);\n"
" shadow += float(smcoord.z < dot(zvalue, unpack) + bias);\n"
" }\n"
"#endif //GL_ES\n"
" return shadow / 64.0;\n"
"}\n"
"#endif //SHADOWED\n"
"#ifdef DIFFUSE\n"
@ -1158,19 +1170,25 @@ static const char normal_map_frag_glsl[] =
"uniform sampler2D uShadowMap;\n"
"float shadow;\n"
"float pcf(vec4 lpos, float size)\n"
" {\n"
"{\n"
" vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n"
" float i, j, shadow;\n"
" shadow = 0.0;\n"
"#ifndef GL_ES\n"
" vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n"
" float i, j, randx, randy, shadow;\n"
" shadow = 0.0;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n"
" return shadow / 64.0;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n"
"#else\n"
" /*TODO Add algorithm generate shadow*/\n"
" return 1.0;\n"
" const vec4 unpack = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);\n"
" const float bias = 0.00015 /*TODO Optimizate set of offset*/;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" {\n"
" vec4 zvalue = texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size);\n"
" shadow += float(smcoord.z < dot(zvalue, unpack) + bias);\n"
" }\n"
"#endif //GL_ES\n"
" return shadow / 64.0;\n"
"}\n"
"#endif //SHADOWED\n"
"#ifdef NORMAL_TEXTURE\n"
@ -1461,6 +1479,7 @@ static const char shadow_map_vert_glsl[] =
"precision lowp sampler2D;\n"
"#endif\n"
"uniform mat4 uMatrixMvp;\n"
"varying vec4 shadowmapposition;\n"
"#ifdef VERTEX_POSITION\n"
"attribute vec4 aPosition0;\n"
"#endif //VERTEX_POSITION\n"
@ -1500,6 +1519,7 @@ static const char shadow_map_vert_glsl[] =
"#endif //VERTEX_TEXCOORD_BLEND\n"
"#endif //ALPHA_TEST_ENABLED\n"
" gl_Position = uMatrixMvp * position;\n"
" shadowmapposition = gl_Position;\n"
"}\n";
static const char shadow_map_frag_glsl[] =
@ -1508,6 +1528,7 @@ static const char shadow_map_frag_glsl[] =
"precision mediump int;\n"
"precision lowp sampler2D;\n"
"#endif\n"
"varying vec4 shadowmapposition;\n"
"#ifdef ALPHA_TEST_ENABLED\n"
"#ifdef NEED_TEX_COORD\n"
"varying vec2 vTexCoord;\n"
@ -1544,7 +1565,7 @@ static const char shadow_map_frag_glsl[] =
" (1.0 - uTextureDiffuseWeight));\n"
"#else\n"
"#ifdef DIFFUSE_TEXTURE\n"
" color = texture2D(uTextureDiffuse0, vec2(Tex0CoordDiffuse)) ;\n"
" color = texture2D(uTextureDiffuse0, vec2(Tex0CoordDiffuse));\n"
"#else\n"
" color = vec4(1);\n"
"#endif //DIFFUSE_TEXTURE\n"
@ -1590,7 +1611,18 @@ static const char shadow_map_frag_glsl[] =
" gl_FragColor = color;\n"
"#endif //GL_ES\n"
"#endif //ALPHA_TEST_ENABLED\n"
"#ifndef GL_ES\n"
" gl_FragColor.r = gl_FragCoord.z;\n"
"#else\n"
" const vec4 pack = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);\n"
" const vec4 mask = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);\n"
" vec4 depthcolor;\n"
" float normdist = shadowmapposition.z / shadowmapposition.w;\n"
" normdist = ((normdist + 1.0) / 2.0);\n"
" depthcolor = vec4(fract(pack * normdist));\n"
" depthcolor -= depthcolor.xxyz * mask;\n"
" gl_FragColor = depthcolor;\n"
"#endif\n"
"}\n";
static const char color_pick_vert_glsl[] =
@ -1832,19 +1864,25 @@ static const char parallax_occlusion_frag_glsl[] =
"uniform sampler2D uShadowMap;\n"
"float shadow;\n"
"float pcf(vec4 lpos, float size)\n"
" {\n"
"{\n"
" vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n"
" float i, j, shadow;\n"
" shadow = 0.0;\n"
"#ifndef GL_ES\n"
" vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n"
" float i, j, randx, randy, shadow;\n"
" shadow = 0.0;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n"
" return shadow / 64.0;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n"
"#else\n"
" /*TODO Add algorithm generate shadow*/\n"
" return 1.0;\n"
" const vec4 unpack = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);\n"
" const float bias = 0.00015 /*TODO Optimizate set of offset*/;\n"
" for (i = -4.0; i < 4.0; i++)\n"
" for (j = -4.0; j < 4.0; j++)\n"
" {\n"
" vec4 zvalue = texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size);\n"
" shadow += float(smcoord.z < dot(zvalue, unpack) + bias);\n"
" }\n"
"#endif //GL_ES\n"
" return shadow / 64.0;\n"
"}\n"
"#endif //SHADOWED\n"
"#ifdef DIFFUSE\n"

View File

@ -42,19 +42,25 @@ varying vec4 vLightPosition;
uniform sampler2D uShadowMap;
float shadow;
float pcf(vec4 lpos, float size)
{
{
vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;
float i, j, shadow;
shadow = 0.0;
`#ifndef GL_ES'
vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;
float i, j, randx, randy, shadow;
shadow = 0.0;
for (i = -4.0; i < 4.0; i++)
for (j = -4.0; j < 4.0; j++)
shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);
return shadow / 64.0;
for (i = -4.0; i < 4.0; i++)
for (j = -4.0; j < 4.0; j++)
shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);
`#else'
/*TODO Add algorithm generate shadow*/
return 1.0;
const vec4 unpack = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);
const float bias = 0.00015 /*TODO Optimizate set of offset*/;
for (i = -4.0; i < 4.0; i++)
for (j = -4.0; j < 4.0; j++)
{
vec4 zvalue = texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size);
shadow += float(smcoord.z < dot(zvalue, unpack) + bias);
}
`#endif //GL_ES'
return shadow / 64.0;
}
#endif //SHADOWED')

View File

@ -1,3 +1,4 @@
varying vec4 shadowmapposition;
#ifdef ALPHA_TEST_ENABLED
FRAGMENT_SHADER_USE_TEX_COORD
FRAGMENT_SHADER_USE_ALPHA_TEST_GLES
@ -39,7 +40,7 @@ void main() {
#else
#ifdef DIFFUSE_TEXTURE
color = texture2D(uTextureDiffuse0, vec2(Tex0CoordDiffuse)) ;
color = texture2D(uTextureDiffuse0, vec2(Tex0CoordDiffuse));
#else
color = vec4(1);
#endif //DIFFUSE_TEXTURE
@ -49,5 +50,16 @@ void main() {
FRAGMENT_SHADER_ALPHA_TEST_GLES_APPLY(color)
#endif //ALPHA_TEST_ENABLED
#ifndef GL_ES
gl_FragColor.r = gl_FragCoord.z;
#else
const vec4 pack = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);
const vec4 mask = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
vec4 depthcolor;
float normdist = shadowmapposition.z / shadowmapposition.w;
normdist = ((normdist + 1.0) / 2.0);
depthcolor = vec4(fract(pack * normdist));
depthcolor -= depthcolor.xxyz * mask;
gl_FragColor = depthcolor;
#endif
}

View File

@ -1,5 +1,5 @@
uniform mat4 uMatrixMvp;
varying vec4 shadowmapposition;
VERTEX_SHADER_USE_POSITION
#ifdef ALPHA_TEST_ENABLED
@ -17,4 +17,5 @@ VERTEX_SHADER_POSITION
#endif //ALPHA_TEST_ENABLED
gl_Position = uMatrixMvp * position;
shadowmapposition = gl_Position;
}