cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=1b142d09d951a53e44ce2f1a98b5cc85616756f9
commit 1b142d09d951a53e44ce2f1a98b5cc85616756f9 Author: Dmytro Dadyka <d.dad...@samsung.com> Date: Mon Feb 23 14:25:49 2015 +0100 evas: Evas_3D - add parallax occlusion shading. Reviewers: Hermet, cedric Reviewed By: cedric Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D2018 --- src/Makefile_Evas.am | 2 + src/examples/evas/evas-3d-parallax-occlusion.c | 276 ++++++++++++++++ src/examples/evas/four_NM_height.tga | Bin 0 -> 262188 bytes src/examples/evas/rocks.jpg | Bin 0 -> 128423 bytes src/examples/evas/rocks_NM_height.tga | Bin 0 -> 262188 bytes src/examples/evas/wood.jpg | Bin 0 -> 94417 bytes src/lib/evas/Evas_Eo.h | 2 + src/modules/evas/engines/gl_common/evas_gl_3d.c | 8 +- .../gl_common/shader_3d/evas_gl_3d_shaders.x | 368 ++++++++++++++++++++- .../gl_common/shader_3d/normal_map_frag.shd | 8 +- ...al_map_frag.shd => parallax_occlusion_frag.shd} | 122 ++++--- .../shader_3d/parallax_occlusion_vert.shd | 151 +++++++++ 12 files changed, 882 insertions(+), 55 deletions(-) diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index d7b62a7..f88560b 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -747,6 +747,8 @@ modules/evas/engines/gl_common/shader_3d/shadow_map_vert.shd \ modules/evas/engines/gl_common/shader_3d/shadow_map_frag.shd \ 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 \ $(NULL) EXTRA_DIST += \ diff --git a/src/examples/evas/evas-3d-parallax-occlusion.c b/src/examples/evas/evas-3d-parallax-occlusion.c new file mode 100644 index 0000000..ca25b1f --- /dev/null +++ b/src/examples/evas/evas-3d-parallax-occlusion.c @@ -0,0 +1,276 @@ +/** + * Example illustrating usage of parallax occlusion shading and texture animation. + * + * Press "n" for use normal mapping shading. Pres "p" for use parallax occlusion mapping shading. + * + * @verbatim + * gcc -o evas-3d-parallax-occlusion evas-3d-parallax-occlusion.c evas-3d-primitives.c `pkg-config --libs --cflags evas ecore ecore-evas eo`-lm + * @endverbatim + */ + +#define EFL_EO_API_SUPPORT +#define EFL_BETA_API_SUPPORT + +#include <Eo.h> +#include <Evas.h> +#include <Ecore.h> +#include <Ecore_Evas.h> +#include "evas-3d-primitives.h" + +#define WIDTH 400 +#define HEIGHT 400 + +typedef struct _Scene_Data +{ + Eo *scene; + Eo *root_node; + Eo *camera_node; + Eo *light_node; + Eo *mesh_node; + + Eo *camera; + Eo *light; + Eo *mesh; + Eo *material_rocks; + Eo *material_wood; + Eo *texture_rocks; + Eo *texture_rocks_n; + Eo *texture_wood; + Eo *texture_four_n; +} Scene_Data; + +static Ecore_Evas *ecore_evas = NULL; +static Evas *evas = NULL; +static Eo *background = NULL; +static Eo *image = NULL; + +static void +_on_key_down(void *data, Evas *e EINA_UNUSED, Evas_Object *eo EINA_UNUSED, void *event_info) +{ + Scene_Data *scene = (Scene_Data *)data; + Evas_Event_Key_Down *ev = event_info; + + if (!strcmp("n", ev->key)) + eo_do(scene->mesh, evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_NORMAL_MAP)); + + if (!strcmp("p", ev->key)) + eo_do(scene->mesh, evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_PARALLAX_OCCLUSION)); +} + +static void +_on_delete(Ecore_Evas *ee EINA_UNUSED) +{ + ecore_main_loop_quit(); +} + +static void +_on_canvas_resize(Ecore_Evas *ee) +{ + int w, h; + + ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); + eo_do(background, evas_obj_size_set(w, h)); + eo_do(image, evas_obj_size_set(w, h)); +} + +static Eina_Bool +_animate_scene(void *data) +{ + static float angle = 0.0f; + Scene_Data *scene = (Scene_Data *)data; + + angle += 0.5; + + eo_do(scene->mesh_node, + evas_3d_node_orientation_angle_axis_set(angle, 0.0, 1.0, 0.0)); + + eo_do(scene->mesh_node, evas_3d_node_mesh_frame_set(scene->mesh, 50 * (1 + sin(angle / 180.0 * M_PI)))); + /* Rotate */ + if (angle > 360.0) angle = 0.0f; + + return EINA_TRUE; +} + +static void +_camera_setup(Scene_Data *data) +{ + data->camera = eo_add(EVAS_3D_CAMERA_CLASS, evas); + + eo_do(data->camera, + evas_3d_camera_projection_perspective_set(60.0, 1.0, 2.0, 50.0)); + + data->camera_node = eo_add(EVAS_3D_NODE_CLASS, evas, + evas_3d_node_constructor(EVAS_3D_NODE_TYPE_CAMERA)); + eo_do(data->camera_node, + evas_3d_node_camera_set(data->camera), + evas_3d_node_position_set(0.0, 0.0, 10.0), + evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 0.0, 0.0, 0.0, + EVAS_3D_SPACE_PARENT, 0.0, 1.0, 0.0)); + eo_do(data->root_node, evas_3d_node_member_add(data->camera_node)); +} + +static void +_light_setup(Scene_Data *data) +{ + data->light = eo_add(EVAS_3D_LIGHT_CLASS, evas); + eo_do(data->light, + evas_3d_light_ambient_set(0.2, 0.2, 0.2, 1.0), + evas_3d_light_diffuse_set(1.0, 1.0, 1.0, 1.0), + evas_3d_light_specular_set(1.0, 1.0, 1.0, 1.0)); + + data->light_node = eo_add(EVAS_3D_NODE_CLASS, evas, + evas_3d_node_constructor(EVAS_3D_NODE_TYPE_LIGHT)); + eo_do(data->light_node, + evas_3d_node_light_set(data->light), + evas_3d_node_position_set(-20.0, 20.0, 50.0), + evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 0.0, 0.0, 0.0, + EVAS_3D_SPACE_PARENT, 0.0, 1.0, 0.0)); + eo_do(data->root_node, evas_3d_node_member_add(data->light_node)); +} + +static void +_mesh_setup(Scene_Data *data) +{ + /* Setup material. */ + data->material_rocks = eo_add(EVAS_3D_MATERIAL_CLASS, evas); + + data->texture_rocks = eo_add(EVAS_3D_TEXTURE_CLASS, evas); + data->texture_rocks_n = eo_add(EVAS_3D_TEXTURE_CLASS, evas); + eo_do(data->texture_rocks, evas_3d_texture_file_set("rocks.jpg", NULL), + evas_3d_texture_wrap_set(EVAS_3D_WRAP_MODE_REPEAT, + EVAS_3D_WRAP_MODE_REPEAT)); + eo_do(data->texture_rocks_n, evas_3d_texture_file_set("rocks_NM_height.tga", NULL), + evas_3d_texture_wrap_set(EVAS_3D_WRAP_MODE_REPEAT, + EVAS_3D_WRAP_MODE_REPEAT)); + + eo_do(data->material_rocks, + evas_3d_material_texture_set(EVAS_3D_MATERIAL_NORMAL, data->texture_rocks_n), + evas_3d_material_texture_set(EVAS_3D_MATERIAL_DIFFUSE, data->texture_rocks), + evas_3d_material_texture_set(EVAS_3D_MATERIAL_AMBIENT, data->texture_rocks), + evas_3d_material_texture_set(EVAS_3D_MATERIAL_SPECULAR, data->texture_rocks), + evas_3d_material_enable_set(EVAS_3D_MATERIAL_AMBIENT, EINA_TRUE), + evas_3d_material_enable_set(EVAS_3D_MATERIAL_NORMAL, EINA_TRUE), + evas_3d_material_enable_set(EVAS_3D_MATERIAL_DIFFUSE, EINA_TRUE), + evas_3d_material_enable_set(EVAS_3D_MATERIAL_SPECULAR, EINA_TRUE), + + evas_3d_material_color_set(EVAS_3D_MATERIAL_AMBIENT, 0.1, 0.1, 0.1, 1.0), + evas_3d_material_color_set(EVAS_3D_MATERIAL_DIFFUSE, 1.0, 1.0, 1.0, 1.0), + evas_3d_material_color_set(EVAS_3D_MATERIAL_SPECULAR, 1.0, 1.0, 1.0, 1.0), + evas_3d_material_shininess_set(100.0)); + + data->material_wood = eo_add(EVAS_3D_MATERIAL_CLASS, evas); + + data->texture_wood = eo_add(EVAS_3D_TEXTURE_CLASS, evas); + data->texture_four_n = eo_add(EVAS_3D_TEXTURE_CLASS, evas); + eo_do(data->texture_wood, evas_3d_texture_file_set("wood.jpg", NULL), + evas_3d_texture_wrap_set(EVAS_3D_WRAP_MODE_REPEAT, + EVAS_3D_WRAP_MODE_REPEAT)); + eo_do(data->texture_four_n, evas_3d_texture_file_set("four_NM_height.tga", NULL), + evas_3d_texture_wrap_set(EVAS_3D_WRAP_MODE_REPEAT, + EVAS_3D_WRAP_MODE_REPEAT)); + + eo_do(data->material_wood, + evas_3d_material_texture_set(EVAS_3D_MATERIAL_NORMAL, data->texture_four_n), + evas_3d_material_texture_set(EVAS_3D_MATERIAL_DIFFUSE, data->texture_wood), + evas_3d_material_texture_set(EVAS_3D_MATERIAL_AMBIENT, data->texture_wood), + evas_3d_material_texture_set(EVAS_3D_MATERIAL_SPECULAR, data->texture_wood), + evas_3d_material_enable_set(EVAS_3D_MATERIAL_AMBIENT, EINA_TRUE), + evas_3d_material_enable_set(EVAS_3D_MATERIAL_NORMAL, EINA_TRUE), + evas_3d_material_enable_set(EVAS_3D_MATERIAL_DIFFUSE, EINA_TRUE), + evas_3d_material_enable_set(EVAS_3D_MATERIAL_SPECULAR, EINA_TRUE), + + evas_3d_material_color_set(EVAS_3D_MATERIAL_AMBIENT, 0.1, 0.1, 0.1, 1.0), + evas_3d_material_color_set(EVAS_3D_MATERIAL_DIFFUSE, 1.0, 1.0, 1.0, 1.0), + evas_3d_material_color_set(EVAS_3D_MATERIAL_SPECULAR, 1.0, 1.0, 1.0, 1.0), + evas_3d_material_shininess_set(100.0)); + + /* Setup mesh. */ + data->mesh = eo_add(EVAS_3D_MESH_CLASS, evas); + evas_3d_add_cube_frame(data->mesh, 0); + + evas_3d_add_cube_frame(data->mesh, 100); + eo_do(data->mesh, + evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_PARALLAX_OCCLUSION), + evas_3d_mesh_frame_material_set(0, data->material_rocks)); + + eo_do(data->mesh, + evas_3d_mesh_frame_material_set(100, data->material_wood)); + + data->mesh_node = eo_add(EVAS_3D_NODE_CLASS, evas, + evas_3d_node_constructor(EVAS_3D_NODE_TYPE_MESH)); + eo_do(data->root_node, evas_3d_node_member_add(data->mesh_node)); + eo_do(data->mesh_node, evas_3d_node_mesh_add(data->mesh), + evas_3d_node_scale_set(3, 3, 3)); +} + +static void +_scene_setup(Scene_Data *data) +{ + data->scene = eo_add(EVAS_3D_SCENE_CLASS, evas); + eo_do(data->scene, + evas_3d_scene_size_set(WIDTH, HEIGHT); + evas_3d_scene_background_color_set(0.0, 0.0, 0.0, 0.0)); + + data->root_node = eo_add(EVAS_3D_NODE_CLASS, evas, + evas_3d_node_constructor(EVAS_3D_NODE_TYPE_NODE)); + + _camera_setup(data); + _light_setup(data); + _mesh_setup(data); + + eo_do(data->scene, + evas_3d_scene_root_node_set(data->root_node), + evas_3d_scene_camera_node_set(data->camera_node)); +} + +int +main(void) +{ + //Unless Evas 3D supports Software renderer, we set gl backened forcely. + setenv("ECORE_EVAS_ENGINE", "opengl_x11", 1); + + Scene_Data data; + + if (!ecore_evas_init()) return 0; + + ecore_evas = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL); + + if (!ecore_evas) return 0; + + ecore_evas_callback_delete_request_set(ecore_evas, _on_delete); + ecore_evas_callback_resize_set(ecore_evas, _on_canvas_resize); + ecore_evas_show(ecore_evas); + + evas = ecore_evas_get(ecore_evas); + + _scene_setup(&data); + + /* Add a background rectangle objects. */ + background = eo_add(EVAS_RECTANGLE_CLASS, evas); + eo_do(background, + evas_obj_color_set(0, 0, 0, 255), + evas_obj_size_set(WIDTH, HEIGHT), + evas_obj_visibility_set(EINA_TRUE)); + + /* Add an image object for 3D scene rendering. */ + image = evas_object_image_filled_add(evas); + eo_do(image, + evas_obj_size_set(WIDTH, HEIGHT), + evas_obj_visibility_set(EINA_TRUE), + evas_object_focus_set(image, EINA_TRUE)); + + /* Set the image object as render target for 3D scene. */ + eo_do(image, evas_obj_image_scene_set(data.scene)); + + /* Add animation timer callback. */ + ecore_timer_add(0.01, _animate_scene, &data); + evas_object_event_callback_add(image, EVAS_CALLBACK_KEY_DOWN, _on_key_down, &data); + + /* Enter main loop. */ + ecore_main_loop_begin(); + + ecore_evas_free(ecore_evas); + ecore_evas_shutdown(); + + return 0; +} diff --git a/src/examples/evas/four_NM_height.tga b/src/examples/evas/four_NM_height.tga new file mode 100644 index 0000000..08bb3a2 Binary files /dev/null and b/src/examples/evas/four_NM_height.tga differ diff --git a/src/examples/evas/rocks.jpg b/src/examples/evas/rocks.jpg new file mode 100644 index 0000000..7383271 Binary files /dev/null and b/src/examples/evas/rocks.jpg differ diff --git a/src/examples/evas/rocks_NM_height.tga b/src/examples/evas/rocks_NM_height.tga new file mode 100644 index 0000000..7c8ee3b Binary files /dev/null and b/src/examples/evas/rocks_NM_height.tga differ diff --git a/src/examples/evas/wood.jpg b/src/examples/evas/wood.jpg new file mode 100644 index 0000000..cff2cb2 Binary files /dev/null and b/src/examples/evas/wood.jpg differ diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h index 4ee08aa..f82dbed 100644 --- a/src/lib/evas/Evas_Eo.h +++ b/src/lib/evas/Evas_Eo.h @@ -781,6 +781,8 @@ typedef enum _Evas_3D_Shade_Mode EVAS_3D_SHADE_MODE_SHADOW_MAP_RENDER, /**< rendering to additional frame bufer*/ EVAS_3D_SHADE_MODE_COLOR_PICK, + /**< Per-pixel parallax occlusion map shading */ + EVAS_3D_SHADE_MODE_PARALLAX_OCCLUSION, } Evas_3D_Shade_Mode; /** diff --git a/src/modules/evas/engines/gl_common/evas_gl_3d.c b/src/modules/evas/engines/gl_common/evas_gl_3d.c index eab4351..9e7dfd0 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_3d.c +++ b/src/modules/evas/engines/gl_common/evas_gl_3d.c @@ -1240,7 +1240,8 @@ _mesh_draw_data_build(E3D_Draw_Data *data, if (_flags_need_tex_coord(data->flags)) BUILD(vertex_attrib, VERTEX_TEXCOORD, EINA_FALSE); } - else if (pdmesh->shade_mode == EVAS_3D_SHADE_MODE_NORMAL_MAP) + else if ((pdmesh->shade_mode == EVAS_3D_SHADE_MODE_NORMAL_MAP) || + (pdmesh->shade_mode == EVAS_3D_SHADE_MODE_PARALLAX_OCCLUSION)) { BUILD(vertex_attrib, VERTEX_POSITION, EINA_TRUE); BUILD(vertex_attrib, VERTEX_NORMAL, EINA_TRUE); @@ -1248,6 +1249,11 @@ _mesh_draw_data_build(E3D_Draw_Data *data, BUILD(material_texture, MATERIAL_NORMAL, EINA_TRUE); BUILD(vertex_attrib, VERTEX_TANGENT, EINA_FALSE); + + if (pdmesh->shade_mode == EVAS_3D_SHADE_MODE_NORMAL_MAP) + BUILD(vertex_attrib, VERTEX_TANGENT, EINA_FALSE); + else BUILD(vertex_attrib, VERTEX_TANGENT, EINA_TRUE); + BUILD(material_color, MATERIAL_AMBIENT, EINA_FALSE); BUILD(material_color, MATERIAL_DIFFUSE, EINA_FALSE); BUILD(material_color, MATERIAL_SPECULAR, EINA_FALSE); diff --git a/src/modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x b/src/modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x index f1d347e..cae8825 100644 --- a/src/modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x +++ b/src/modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x @@ -930,11 +930,11 @@ static const char const normal_map_frag_glsl[] = " vec3 normal;\n" " vec4 color;\n" "#ifdef NORMAL_TEXTURE_BLEND\n" - " normal = texture2D(uTextureNormal0, vTexCoord).rgb * uTextureNormalWeight;\n" - " normal += texture2D(uTextureNormal1, vTexCoord).rgb *\n" + " normal = texture2D(uTextureNormal0, vTexCoord).rgb * uTextureNormalWeight / texture2D(uTextureNormal0, vTexCoord).a;\n" + " normal += texture2D(uTextureNormal1, vTexCoord).rgb / texture2D(uTextureNormal1, vTexCoord).a *\n" " (1.0 - uTextureNormalWeight);\n" "#else\n" - " normal = texture2D(uTextureNormal0, vTexCoord).rgb;\n" + " normal = texture2D(uTextureNormal0, vTexCoord).rgb / texture2D(uTextureNormal0, vTexCoord).a;\n" "#endif //NORMAL_TEXTURE_BLEND\n" " normal = 2.0 * normal - 1.0;\n" "#ifndef VERTEX_TANGENT\n" @@ -1029,7 +1029,7 @@ static const char const normal_map_frag_glsl[] = " 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" + " shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0)*size).x);\n" " return shadow / 64.0;\n" "}\n" "#endif //SHADOWED\n" @@ -1105,6 +1105,364 @@ static const char const color_pick_frag_glsl[] = " gl_FragColor = vec4(uColorPick);\n" "}\n"; +static const char const parallax_occlusion_vert_glsl[] = + "uniform mat4 uMatrixMvp;\n" + "uniform mat3 uMatrixNormal;\n" + "uniform mat4 uMatrixModelview;\n" + "uniform vec4 uLightPosition;\n" + "varying vec3 vLightVector;\n" + "varying vec3 vLightHalfVector;\n" + "varying vec3 vEyeVector;\n" + "#ifdef SHADOWED\n" + "uniform mat4 uMatrixLight;\n" + "varying vec4 vLightPosition;\n" + "#endif //SHADOWED\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" + "#ifdef VERTEX_NORMAL\n" + "attribute vec4 aNormal0;\n" + "#endif //VERTEX_NORMAL\n" + "#ifdef VERTEX_NORMAL_BLEND\n" + "attribute vec4 aNormal1;\n" + "uniform float uNormalWeight;\n" + "#endif //VERTEX_NORMAL_BLEND\n" + "#ifdef VERTEX_TANGENT\n" + "attribute vec4 aTangent0;\n" + "#endif //VERTEX_TANGENT\n" + "#ifdef VERTEX_TANGENT_BLEND\n" + "attribute vec4 aTangent1;\n" + "uniform float uTangentWeight;\n" + "#endif //VERTEX_TANGENT_BLEND\n" + "#ifdef VERTEX_TEXCOORD\n" + "attribute vec4 aTexCoord0;\n" + "#endif //VERTEX_TEXCOORD\n" + "#ifdef VERTEX_TEXCOORD_BLEND\n" + "attribute vec4 aTexCoord1;\n" + "uniform float uTexCoordWeight;\n" + "#endif //VERTEX_TEXCOORD_BLEND\n" + "#ifdef NEED_TEX_COORD\n" + "varying vec2 vTexCoord;\n" + "#endif //NEED_TEX_COORD\n" + "#ifdef LIGHT_ATTENUATION\n" + "varying float vLightDist;\n" + "#endif //LIGHT_ATTENUATION\n" + "void vertexParallaxOcclusion(vec4 position, vec3 normal, vec3 tangent)\n" + "{\n" + " vec3 n = normalize(uMatrixNormal * normal);\n" + " vec3 t = normalize(uMatrixNormal * tangent);\n" + " vec3 b = cross(n, t);\n" + " vec3 tmp;\n" + " position = uMatrixModelview * position;\n" + "#ifdef LIGHT_DIRECTIONAL\n" + " vec3 lightDir = uLightPosition.xyz;\n" + "#else\n" + " vec3 lightDir = uLightPosition.xyz - position.xyz;\n" + "#ifdef LIGHT_ATTENUATION\n" + " vLightDist = length(lightDir);\n" + "#endif //LIGHT_ATTENUATION\n" + " lightDir = normalize(lightDir);\n" + "#endif //LIGHT_DIRECTIONAL\n" + " tmp.x = dot(lightDir, t);\n" + " tmp.y = dot(lightDir, b);\n" + " tmp.z = dot(lightDir, n);\n" + " vLightVector = tmp;\n" + " tmp.x = dot(position.xyz, t);\n" + " tmp.y = dot(position.xyz, b);\n" + " tmp.z = dot(position.xyz, n);\n" + " vEyeVector = normalize(tmp);\n" + " vec3 hv = normalize(normalize(-position.xyz) + lightDir);\n" + " tmp.x = dot(hv, t);\n" + " tmp.y = dot(hv, b);\n" + " tmp.z = dot(hv, n);\n" + " vLightHalfVector = tmp;\n" + "}\n" + "void main()\n" + "{\n" + "#ifdef VERTEX_POSITION_BLEND\n" + " vec4 position = aPosition0 * uPositionWeight +\n" + " aPosition1 * (1.0 - 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" + "#ifdef VERTEX_NORMAL_BLEND\n" + " vec3 normal = aNormal0.xyz * uNormalWeight +\n" + " aNormal1.xyz * (1.0 - uNormalWeight);\n" + "#else\n" + "#ifdef VERTEX_NORMAL\n" + " vec3 normal = aNormal0.xyz;\n" + "#endif //VERTEX_NORMAL\n" + "#endif //VERTEX_NORMAL_BLEND\n" + "#ifdef VERTEX_TANGENT_BLEND\n" + " vec3 tangent = aTangent0.xyz * uTangentWeight +\n" + " aTangent1.xyz * (1.0 - uTangentWeight);\n" + "#else\n" + "#ifdef VERTEX_TANGENT\n" + " vec3 tangent = aTangent0.xyz;\n" + "#endif //VERTEX_TANGENT\n" + "#endif //VERTEX_TANGENT_BLEND\n" + "#ifdef VERTEX_TEXCOORD_BLEND\n" + " vTexCoord = aTexCoord0.st * uTexCoordWeight +\n" + " aTexCoord1.st * (1.0 - uTexCoordWeight);\n" + "#else\n" + "#ifdef VERTEX_TEXCOORD\n" + " vTexCoord = aTexCoord0.st;\n" + "#endif //VERTEX_TEXCOORD\n" + "#endif //VERTEX_TEXCOORD_BLEND\n" + " gl_Position = uMatrixMvp * position;\n" + " vertexParallaxOcclusion(position, normal, tangent);\n" + "#ifdef SHADOWED\n" + " vLightPosition = uMatrixLight * position;\n" + "#endif //SHADOWED\n" + "}\n"; + +static const char const parallax_occlusion_frag_glsl[] = + "varying vec3 vLightVector;\n" + "varying vec3 vLightHalfVector;\n" + "uniform sampler2D uTextureNormal0;\n" + "varying vec3 vEyeVector;\n" + "#ifdef NEED_TEX_COORD\n" + "varying vec2 vTexCoord;\n" + "#endif //TEX_COORD\n" + "#ifdef FOG_ENABLED\n" + "uniform float uFogFactor;\n" + "uniform vec4 uFogColor;\n" + "#endif //FOG_ENABLED\n" + "#ifdef SHADOWED\n" + "varying vec4 vLightPosition;\n" + "uniform sampler2D uShadowMap;\n" + "float shadow;\n" + "#endif //SHADOWED\n" + "#ifdef NORMAL_TEXTURE_BLEND\n" + "uniform sampler2D uTextureNormal1;\n" + "uniform float uTextureNormalWeight;\n" + "#endif //NORMAL_TEXTURE_BLEND\n" + "#ifdef DIFFUSE\n" + "uniform vec4 uMaterialDiffuse;\n" + "uniform vec4 uLightDiffuse;\n" + "#ifdef DIFFUSE_TEXTURE\n" + "uniform sampler2D uTextureDiffuse0;\n" + "#endif //DIFFUSE_TEXTURE\n" + "#ifdef DIFFUSE_TEXTURE_BLEND\n" + "uniform sampler2D uTextureDiffuse1;\n" + "uniform float uTextureDiffuseWeight;\n" + "#endif //DIFFUSE_TEXTURE_BLEND\n" + "#endif //DIFFUSE\n" + "#ifdef SPECULAR\n" + "uniform vec4 uLightSpecular;\n" + "uniform float uMaterialShininess;\n" + "uniform vec4 uMaterialSpecular;\n" + "#ifdef SPECULAR_TEXTURE\n" + "uniform sampler2D uTextureSpecular0;\n" + "#endif //SPECULAR_TEXTURE\n" + "#ifdef SPECULAR_TEXTURE_BLEND\n" + "uniform sampler2D uTextureSpecular1;\n" + "uniform float uTextureSpecularWeight;\n" + "#endif //SPECULAR_TEXTURE_BLEND\n" + "#endif //SPECULAR\n" + "#ifdef AMBIENT\n" + "uniform vec4 uMaterialAmbient;\n" + "uniform vec4 uLightAmbient;\n" + "#ifdef AMBIENT_TEXTURE\n" + "uniform sampler2D uTextureAmbient0;\n" + "#endif //AMBIENT_TEXTURE\n" + "#ifdef AMBIENT_TEXTURE_BLEND\n" + "uniform sampler2D uTextureAmbient1;\n" + "uniform float uTextureAmbientWeight;\n" + "#endif //AMBIENT_TEXTURE_BLEND\n" + "#endif //AMBIENT\n" + "#ifdef EMISSION\n" + "uniform vec4 uMaterialEmission;\n" + "#ifdef EMISSION_TEXTURE\n" + "uniform sampler2D uTextureEmission0;\n" + "#endif //EMISSION_TEXTURE\n" + "#ifdef EMISSION_TEXTURE_BLEND\n" + "uniform sampler2D uTextureEmission1;\n" + "uniform float uTextureEmissionWeight;\n" + "#endif //EMISSION_TEXTURE_BLEND\n" + "#endif //EMISSION\n" + "#ifdef LIGHT_SPOT\n" + "uniform vec3 uLightSpotDir;\n" + "uniform float uLightSpotExp;\n" + "uniform float uLightSpotCutoffCos;\n" + "#endif //LIGHT_SPOT\n" + "#ifdef LIGHT_ATTENUATION\n" + "varying float vLightDist;\n" + "#endif //LIGHT_ATTENUATION\n" + "const float parallaxScale = 0.2;\n" + "vec2 parallaxMapping(in vec3 view, in vec2 tex, out float parallaxHeight)\n" + "{\n" + " const float minLayers = 10.0;\n" + " const float maxLayers = 30.0;\n" + " float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0, 0, 1), view)));\n" + " vec2 texStep = parallaxScale * view.xy / view.z / numLayers;\n" + " float layerHeight = 1.0 / numLayers;\n" + " float curLayerHeight = 0.0;\n" + " vec2 dtex = parallaxScale * view.xy / view.z / numLayers;\n" + " vec2 currentTextureCoords = tex;\n" + "#ifdef NORMAL_TEXTURE_BLEND\n" + " float heightFromTexture = (1.0 - texture2D(uTextureNormal0, currentTextureCoords).a) * uTextureNormalWeight;\n" + " heightFromTexture += (1.0 - texture2D(uTextureNormal1, currentTextureCoords).a) *\n" + " (1.0 - uTextureNormalWeight);\n" + "#else\n" + " float heightFromTexture = 1.0 - texture2D(uTextureNormal0, currentTextureCoords).a;\n" + "#endif //NORMAL_TEXTURE_BLEND\n" + " while(heightFromTexture > curLayerHeight)\n" + " {\n" + " curLayerHeight += layerHeight;\n" + " currentTextureCoords -= dtex;\n" + "#ifdef NORMAL_TEXTURE_BLEND\n" + " heightFromTexture = (1.0 - texture2D(uTextureNormal0, currentTextureCoords).a) * uTextureNormalWeight;\n" + " heightFromTexture += (1.0 - texture2D(uTextureNormal1, currentTextureCoords).a) *\n" + " (1.0 - uTextureNormalWeight);\n" + "#else\n" + " heightFromTexture = 1.0 - texture2D(uTextureNormal0, currentTextureCoords).a;\n" + "#endif //NORMAL_TEXTURE_BLEND\n" + " }\n" + " vec2 prevTCoords = currentTextureCoords + texStep;\n" + " float nextH = heightFromTexture - curLayerHeight;\n" + "#ifdef NORMAL_TEXTURE_BLEND\n" + " float prevH = (1.0 - texture2D(uTextureNormal0, prevTCoords).a\n" + " - curLayerHeight + layerHeight) * uTextureNormalWeight;\n" + " prevH += (1.0 - texture2D(uTextureNormal1, prevTCoords).a\n" + " - curLayerHeight + layerHeight) * (1.0 - uTextureNormalWeight);\n" + "#else\n" + " float prevH = 1.0 - texture2D(uTextureNormal0, prevTCoords).a\n" + " - curLayerHeight + layerHeight;\n" + "#endif //NORMAL_TEXTURE_BLEND\n" + " float weight = nextH / (nextH - prevH);\n" + " vec2 finalTexCoords = prevTCoords * weight + currentTextureCoords * (1.0-weight);\n" + " parallaxHeight = curLayerHeight + prevH * weight + nextH * (1.0 - weight);\n" + " return finalTexCoords;\n" + "}\n" + "void fragmentParallaxMap()\n" + "{\n" + " float factor;\n" + " vec3 normal;\n" + " vec4 color;\n" + " float parallaxHeight;\n" + " vec2 tex = parallaxMapping(vEyeVector, vTexCoord, parallaxHeight);\n" + " vec3 lv = normalize(vLightVector);\n" + "#ifdef NORMAL_TEXTURE_BLEND\n" + " normal = texture2D(uTextureNormal0, tex).rgb * uTextureNormalWeight / texture2D(uTextureNormal0, tex).a;\n" + " normal += texture2D(uTextureNormal1, tex).rgb *\n" + " (1.0 - uTextureNormalWeight) / texture2D(uTextureNormal1, tex).a;\n" + "#else\n" + " normal = texture2D(uTextureNormal0, tex).rgb / texture2D(uTextureNormal0, tex).a;\n" + "#endif //NORMAL_TEXTURE_BLEND\n" + " normal = 2.0 * normal - 1.0;\n" + " normal = normalize(normal);\n" + " factor = dot(lv, normal);\n" + "#ifdef LIGHT_SPOT\n" + " float f = dot(-lv, normalize(uLightSpotDir));\n" + " if (f > uLightSpotCutoffCos)\n" + " factor *= pow(f, uLightSpotExp);\n" + " else\n" + " factor = 0.0;\n" + "#endif //LIGHT_SPOT\n" + " if (factor > 0.0)\n" + " {\n" + "#ifdef DIFFUSE\n" + "#ifdef DIFFUSE_TEXTURE_BLEND\n" + " color = texture2D(uTextureDiffuse0, tex) * uTextureDiffuseWeight +\n" + " texture2D(uTextureDiffuse1, tex) * (1.0 - uTextureDiffuseWeight);\n" + "#else\n" + "#ifdef DIFFUSE_TEXTURE\n" + " color = texture2D(uTextureDiffuse0, tex);\n" + "#else\n" + " color = uMaterialDiffuse;\n" + "#endif //DIFFUSE_TEXTURE\n" + "#endif //DIFFUSE_TEXTURE_BLEND\n" + " gl_FragColor = uLightDiffuse * color * factor;\n" + "#else\n" + " gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" + "#endif //DIFFUSE\n" + "#ifdef SPECULAR\n" + " factor = dot(normalize(vLightHalfVector), normal);\n" + " if (factor > 0.0)\n" + " {\n" + " factor = pow(factor, uMaterialShininess);\n" + "#ifdef SPECULAR_TEXTURE_BLEND\n" + " color = texture2D(uTextureSpecular0, tex) * uTextureSpecularWeight +\n" + " texture2D(uTextureSpecular1, tex) * (1.0 - uTextureSpecularWeight);\n" + "#else\n" + "#ifdef SPECULAR_TEXTURE\n" + " color = texture2D(uTextureSpecular0, tex);\n" + "#else\n" + " color = uMaterialSpecular;\n" + "#endif //SPECULAR_TEXTURE\n" + "#endif //SPECULAR_TEXTURE_BLEND\n" + " gl_FragColor += uLightSpecular * color * factor;\n" + " }\n" + "#endif //SPECULAR\n" + "#ifdef SHADOWED\n" + " gl_FragColor *= shadow;\n" + "#endif //SHADOWED\n" + " }\n" + " else\n" + " gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" + "#ifdef AMBIENT\n" + "#ifdef AMBIENT_TEXTURE_BLEND\n" + " color = texture2D(uTextureAmbient0, tex) * uTextureAmbientWeight +\n" + " texture2D(uTextureAmbient1, tex) * (1.0 - uTextureAmbientWeight);\n" + "#else\n" + "#ifdef AMBIENT_TEXTURE\n" + " color = texture2D(uTextureAmbient0, tex);\n" + "#else\n" + " color = uMaterialAmbient;\n" + "#endif //AMBIENT_TEXTURE\n" + "#endif //AMBIENT_TEXTURE_BLEND\n" + " gl_FragColor += uLightAmbient * color;\n" + "#endif //AMBIENT\n" + "#ifdef LIGHT_ATTENUATION\n" + " gl_FragColor /= dot(uLightAtten, vec3(1.0, vLightDist, vLightDist * vLightDist));\n" + "#endif //LIGHT_ATTENUATION\n" + "#ifdef EMISSION\n" + "#ifdef EMISSION_TEXTURE_BLEND\n" + " color = texture2D(uTextureEmission0, tex) * uTextureEmissionWeight +\n" + " texture2D(uTextureEmission1, tex) * (1.0 - uTextureEmissionWeight);\n" + "#else\n" + "#ifdef EMISSION_TEXTURE\n" + " color = texture2D(uTextureEmission0, tex);\n" + "#else\n" + " color = uMaterialEmission;\n" + "#endif //EMISSION_TEXTURE\n" + "#endif //EMISSION_TEXTURE_BLEND\n" + " gl_FragColor += color;\n" + "#endif //EMISSION\n" + "}\n" + "#ifdef SHADOWED\n" + "float pcf(vec4 lpos, float size)\n" + "{\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" + "}\n" + "#endif //SHADOWED\n" + "void main() {\n" + "#ifdef SHADOWED\n" + " shadow = pcf(vLightPosition, 1.0 / 200.0);\n" + "#endif //SHADOWED\n" + " fragmentParallaxMap();\n" + "#ifdef FOG_ENABLED\n" + " float z = gl_FragCoord.z / gl_FragCoord.w;\n" + " float fogFactor = exp2( -uFogFactor * uFogFactor * z * z * 1.44);\n" + " fogFactor = clamp(fogFactor, 0.0, 1.0);\n" + " gl_FragColor = mix(uFogColor, gl_FragColor, fogFactor);\n" + "#endif //FOG_ENABLED\n" + "}\n"; + static const char *vertex_shaders[] = { vertex_color_vert_glsl, @@ -1114,6 +1472,7 @@ static const char *vertex_shaders[] = normal_map_vert_glsl, shadow_map_vert_glsl, color_pick_vert_glsl, + parallax_occlusion_vert_glsl, }; static const char *fragment_shaders[] = @@ -1125,4 +1484,5 @@ static const char *fragment_shaders[] = normal_map_frag_glsl, shadow_map_frag_glsl, color_pick_frag_glsl, + parallax_occlusion_frag_glsl, }; diff --git a/src/modules/evas/engines/gl_common/shader_3d/normal_map_frag.shd b/src/modules/evas/engines/gl_common/shader_3d/normal_map_frag.shd index 766e07f..4e2d826 100644 --- a/src/modules/evas/engines/gl_common/shader_3d/normal_map_frag.shd +++ b/src/modules/evas/engines/gl_common/shader_3d/normal_map_frag.shd @@ -127,11 +127,11 @@ void fragmentNormalMap() vec4 color; #ifdef NORMAL_TEXTURE_BLEND - normal = texture2D(uTextureNormal0, vTexCoord).rgb * uTextureNormalWeight; - normal += texture2D(uTextureNormal1, vTexCoord).rgb * + normal = texture2D(uTextureNormal0, vTexCoord).rgb * uTextureNormalWeight / texture2D(uTextureNormal0, vTexCoord).a; + normal += texture2D(uTextureNormal1, vTexCoord).rgb / texture2D(uTextureNormal1, vTexCoord).a * (1.0 - uTextureNormalWeight); #else - normal = texture2D(uTextureNormal0, vTexCoord).rgb; + normal = texture2D(uTextureNormal0, vTexCoord).rgb / texture2D(uTextureNormal0, vTexCoord).a; #endif //NORMAL_TEXTURE_BLEND normal = 2.0 * normal - 1.0; @@ -259,7 +259,7 @@ float pcf(vec4 lpos, float size) 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); + shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0)*size).x); return shadow / 64.0; } #endif //SHADOWED diff --git a/src/modules/evas/engines/gl_common/shader_3d/normal_map_frag.shd b/src/modules/evas/engines/gl_common/shader_3d/parallax_occlusion_frag.shd similarity index 57% copy from src/modules/evas/engines/gl_common/shader_3d/normal_map_frag.shd copy to src/modules/evas/engines/gl_common/shader_3d/parallax_occlusion_frag.shd index 766e07f..3356829 100644 --- a/src/modules/evas/engines/gl_common/shader_3d/normal_map_frag.shd +++ b/src/modules/evas/engines/gl_common/shader_3d/parallax_occlusion_frag.shd @@ -23,10 +23,6 @@ uniform sampler2D uTextureNormal1; uniform float uTextureNormalWeight; #endif //NORMAL_TEXTURE_BLEND -#ifndef VERTEX_TANGENT -varying vec3 vNormal; -#endif //VERTEX_TANGENT - #ifdef DIFFUSE uniform vec4 uMaterialDiffuse; uniform vec4 uLightDiffuse; @@ -97,50 +93,84 @@ uniform float uLightSpotCutoffCos; varying float vLightDist; #endif //LIGHT_ATTENUATION -#ifndef VERTEX_TANGENT +const float parallaxScale = 0.2; -mat3 cotangent_frame(vec3 n, vec3 p, vec2 uv) +vec2 parallaxMapping(in vec3 view, in vec2 tex, out float parallaxHeight) { - vec3 dp1 = dFdx(p); - vec3 dp2 = dFdy(p); - vec2 duv1 = dFdx(uv); - vec2 duv2 = dFdy(uv); - vec3 dp2perp = cross(dp2, n); - vec3 dp1perp = cross(n, dp1); - vec3 t = dp2perp * duv1.x + dp1perp * duv2.x; - vec3 b = dp2perp * duv1.y + dp1perp * duv2.y; - float invmax = inversesqrt(max(dot(t, t), dot(b, b))); - return mat3(t * invmax, b * invmax, n); -} + const float minLayers = 10.0; + const float maxLayers = 30.0; + float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0, 0, 1), view))); + vec2 texStep = parallaxScale * view.xy / view.z / numLayers; -vec3 perturb_normal(vec3 normal) -{ - mat3 tbn = cotangent_frame(vNormal, -vEyeVector, vTexCoord); - return normalize(tbn * normal); + float layerHeight = 1.0 / numLayers; + float curLayerHeight = 0.0; + vec2 dtex = parallaxScale * view.xy / view.z / numLayers; + + vec2 currentTextureCoords = tex; + +#ifdef NORMAL_TEXTURE_BLEND + float heightFromTexture = (1.0 - texture2D(uTextureNormal0, currentTextureCoords).a) * uTextureNormalWeight; + heightFromTexture += (1.0 - texture2D(uTextureNormal1, currentTextureCoords).a) * + (1.0 - uTextureNormalWeight); +#else + float heightFromTexture = 1.0 - texture2D(uTextureNormal0, currentTextureCoords).a; +#endif //NORMAL_TEXTURE_BLEND + + while(heightFromTexture > curLayerHeight) + { + curLayerHeight += layerHeight; + currentTextureCoords -= dtex; + +#ifdef NORMAL_TEXTURE_BLEND + heightFromTexture = (1.0 - texture2D(uTextureNormal0, currentTextureCoords).a) * uTextureNormalWeight; + heightFromTexture += (1.0 - texture2D(uTextureNormal1, currentTextureCoords).a) * + (1.0 - uTextureNormalWeight); +#else + heightFromTexture = 1.0 - texture2D(uTextureNormal0, currentTextureCoords).a; +#endif //NORMAL_TEXTURE_BLEND + } + + vec2 prevTCoords = currentTextureCoords + texStep; + float nextH = heightFromTexture - curLayerHeight; + +#ifdef NORMAL_TEXTURE_BLEND + float prevH = (1.0 - texture2D(uTextureNormal0, prevTCoords).a + - curLayerHeight + layerHeight) * uTextureNormalWeight; + prevH += (1.0 - texture2D(uTextureNormal1, prevTCoords).a + - curLayerHeight + layerHeight) * (1.0 - uTextureNormalWeight); +#else + float prevH = 1.0 - texture2D(uTextureNormal0, prevTCoords).a + - curLayerHeight + layerHeight; +#endif //NORMAL_TEXTURE_BLEND + + float weight = nextH / (nextH - prevH); + vec2 finalTexCoords = prevTCoords * weight + currentTextureCoords * (1.0-weight); + parallaxHeight = curLayerHeight + prevH * weight + nextH * (1.0 - weight); + + return finalTexCoords; } -#endif //VERTEX_TANGENT -void fragmentNormalMap() +void fragmentParallaxMap() { float factor; vec3 normal; vec4 color; + float parallaxHeight; + vec2 tex = parallaxMapping(vEyeVector, vTexCoord, parallaxHeight); + + vec3 lv = normalize(vLightVector); + #ifdef NORMAL_TEXTURE_BLEND - normal = texture2D(uTextureNormal0, vTexCoord).rgb * uTextureNormalWeight; - normal += texture2D(uTextureNormal1, vTexCoord).rgb * - (1.0 - uTextureNormalWeight); + normal = texture2D(uTextureNormal0, tex).rgb * uTextureNormalWeight / texture2D(uTextureNormal0, tex).a; + normal += texture2D(uTextureNormal1, tex).rgb * + (1.0 - uTextureNormalWeight) / texture2D(uTextureNormal1, tex).a; #else - normal = texture2D(uTextureNormal0, vTexCoord).rgb; + normal = texture2D(uTextureNormal0, tex).rgb / texture2D(uTextureNormal0, tex).a; #endif //NORMAL_TEXTURE_BLEND normal = 2.0 * normal - 1.0; -#ifndef VERTEX_TANGENT - normal = perturb_normal(normal); -#endif //VERTEX_TANGENT - - vec3 lv = normalize(vLightVector); normal = normalize(normal); factor = dot(lv, normal); @@ -160,12 +190,12 @@ void fragmentNormalMap() #ifdef DIFFUSE #ifdef DIFFUSE_TEXTURE_BLEND - color = texture2D(uTextureDiffuse0, vTexCoord) * uTextureDiffuseWeight + - texture2D(uTextureDiffuse1, vTexCoord) * (1.0 - uTextureDiffuseWeight); + color = texture2D(uTextureDiffuse0, tex) * uTextureDiffuseWeight + + texture2D(uTextureDiffuse1, tex) * (1.0 - uTextureDiffuseWeight); #else #ifdef DIFFUSE_TEXTURE - color = texture2D(uTextureDiffuse0, vTexCoord); + color = texture2D(uTextureDiffuse0, tex); #else color = uMaterialDiffuse; #endif //DIFFUSE_TEXTURE @@ -186,11 +216,11 @@ void fragmentNormalMap() factor = pow(factor, uMaterialShininess); #ifdef SPECULAR_TEXTURE_BLEND - color = texture2D(uTextureSpecular0, vTexCoord) * uTextureSpecularWeight + - texture2D(uTextureSpecular1, vTexCoord) * (1.0 - uTextureSpecularWeight); + color = texture2D(uTextureSpecular0, tex) * uTextureSpecularWeight + + texture2D(uTextureSpecular1, tex) * (1.0 - uTextureSpecularWeight); #else #ifdef SPECULAR_TEXTURE - color = texture2D(uTextureSpecular0, vTexCoord); + color = texture2D(uTextureSpecular0, tex); #else color = uMaterialSpecular; #endif //SPECULAR_TEXTURE @@ -212,19 +242,19 @@ void fragmentNormalMap() #ifdef AMBIENT #ifdef AMBIENT_TEXTURE_BLEND - color = texture2D(uTextureAmbient0, vTexCoord) * uTextureAmbientWeight + - texture2D(uTextureAmbient1, vTexCoord) * (1.0 - uTextureAmbientWeight); + color = texture2D(uTextureAmbient0, tex) * uTextureAmbientWeight + + texture2D(uTextureAmbient1, tex) * (1.0 - uTextureAmbientWeight); #else #ifdef AMBIENT_TEXTURE - color = texture2D(uTextureAmbient0, vTexCoord); + color = texture2D(uTextureAmbient0, tex); #else color = uMaterialAmbient; #endif //AMBIENT_TEXTURE #endif //AMBIENT_TEXTURE_BLEND - gl_FragColor += uLightAmbient * color; + gl_FragColor += uLightAmbient * color; #endif //AMBIENT #ifdef LIGHT_ATTENUATION @@ -234,12 +264,12 @@ void fragmentNormalMap() #ifdef EMISSION #ifdef EMISSION_TEXTURE_BLEND - color = texture2D(uTextureEmission0, vTexCoord) * uTextureEmissionWeight + - texture2D(uTextureEmission1, vTexCoord) * (1.0 - uTextureEmissionWeight); + color = texture2D(uTextureEmission0, tex) * uTextureEmissionWeight + + texture2D(uTextureEmission1, tex) * (1.0 - uTextureEmissionWeight); #else #ifdef EMISSION_TEXTURE - color = texture2D(uTextureEmission0, vTexCoord); + color = texture2D(uTextureEmission0, tex); #else color = uMaterialEmission; #endif //EMISSION_TEXTURE @@ -270,7 +300,7 @@ void main() { shadow = pcf(vLightPosition, 1.0 / 200.0); #endif //SHADOWED - fragmentNormalMap(); + fragmentParallaxMap(); #ifdef FOG_ENABLED float z = gl_FragCoord.z / gl_FragCoord.w; diff --git a/src/modules/evas/engines/gl_common/shader_3d/parallax_occlusion_vert.shd b/src/modules/evas/engines/gl_common/shader_3d/parallax_occlusion_vert.shd new file mode 100644 index 0000000..aec49a2 --- /dev/null +++ b/src/modules/evas/engines/gl_common/shader_3d/parallax_occlusion_vert.shd @@ -0,0 +1,151 @@ +uniform mat4 uMatrixMvp; +uniform mat3 uMatrixNormal; +uniform mat4 uMatrixModelview; +uniform vec4 uLightPosition; +varying vec3 vLightVector; +varying vec3 vLightHalfVector; +varying vec3 vEyeVector; + +#ifdef SHADOWED +uniform mat4 uMatrixLight; +varying vec4 vLightPosition; +#endif //SHADOWED + +#ifdef VERTEX_POSITION +attribute vec4 aPosition0; +#endif //VERTEX_POSITION + +#ifdef VERTEX_POSITION_BLEND +attribute vec4 aPosition1; +uniform float uPositionWeight; +#endif //VERTEX_POSITION_BLEND + +#ifdef VERTEX_NORMAL +attribute vec4 aNormal0; +#endif //VERTEX_NORMAL + +#ifdef VERTEX_NORMAL_BLEND +attribute vec4 aNormal1; +uniform float uNormalWeight; +#endif //VERTEX_NORMAL_BLEND + +#ifdef VERTEX_TANGENT +attribute vec4 aTangent0; +#endif //VERTEX_TANGENT + +#ifdef VERTEX_TANGENT_BLEND +attribute vec4 aTangent1; +uniform float uTangentWeight; +#endif //VERTEX_TANGENT_BLEND + +#ifdef VERTEX_TEXCOORD +attribute vec4 aTexCoord0; +#endif //VERTEX_TEXCOORD + +#ifdef VERTEX_TEXCOORD_BLEND +attribute vec4 aTexCoord1; +uniform float uTexCoordWeight; +#endif //VERTEX_TEXCOORD_BLEND + +#ifdef NEED_TEX_COORD +varying vec2 vTexCoord; +#endif //NEED_TEX_COORD + +#ifdef LIGHT_ATTENUATION +varying float vLightDist; +#endif //LIGHT_ATTENUATION + +void vertexParallaxOcclusion(vec4 position, vec3 normal, vec3 tangent) +{ + vec3 n = normalize(uMatrixNormal * normal); + vec3 t = normalize(uMatrixNormal * tangent); + vec3 b = cross(n, t); + vec3 tmp; + + position = uMatrixModelview * position; + +#ifdef LIGHT_DIRECTIONAL + vec3 lightDir = uLightPosition.xyz; +#else + vec3 lightDir = uLightPosition.xyz - position.xyz; + +#ifdef LIGHT_ATTENUATION + vLightDist = length(lightDir); +#endif //LIGHT_ATTENUATION + + lightDir = normalize(lightDir); +#endif //LIGHT_DIRECTIONAL + + tmp.x = dot(lightDir, t); + tmp.y = dot(lightDir, b); + tmp.z = dot(lightDir, n); + vLightVector = tmp; + + tmp.x = dot(position.xyz, t); + tmp.y = dot(position.xyz, b); + tmp.z = dot(position.xyz, n); + vEyeVector = normalize(tmp); + + vec3 hv = normalize(normalize(-position.xyz) + lightDir); + tmp.x = dot(hv, t); + tmp.y = dot(hv, b); + tmp.z = dot(hv, n); + vLightHalfVector = tmp; +} + +void main() +{ + +#ifdef VERTEX_POSITION_BLEND + vec4 position = aPosition0 * uPositionWeight + + aPosition1 * (1.0 - uPositionWeight); + position = vec4(position.xyz, 1.0); +#else + +#ifdef VERTEX_POSITION + vec4 position = vec4(aPosition0.xyz, 1.0); +#endif // VERTEX_POSITION + +#endif //VERTEX_POSITION_BLEND + +#ifdef VERTEX_NORMAL_BLEND + vec3 normal = aNormal0.xyz * uNormalWeight + + aNormal1.xyz * (1.0 - uNormalWeight); +#else + +#ifdef VERTEX_NORMAL + vec3 normal = aNormal0.xyz; +#endif //VERTEX_NORMAL + +#endif //VERTEX_NORMAL_BLEND + +#ifdef VERTEX_TANGENT_BLEND + vec3 tangent = aTangent0.xyz * uTangentWeight + + aTangent1.xyz * (1.0 - uTangentWeight); +#else + +#ifdef VERTEX_TANGENT + vec3 tangent = aTangent0.xyz; +#endif //VERTEX_TANGENT + +#endif //VERTEX_TANGENT_BLEND + +#ifdef VERTEX_TEXCOORD_BLEND + vTexCoord = aTexCoord0.st * uTexCoordWeight + + aTexCoord1.st * (1.0 - uTexCoordWeight); +#else + +#ifdef VERTEX_TEXCOORD + vTexCoord = aTexCoord0.st; +#endif //VERTEX_TEXCOORD + +#endif //VERTEX_TEXCOORD_BLEND + + gl_Position = uMatrixMvp * position; + + vertexParallaxOcclusion(position, normal, tangent); + +#ifdef SHADOWED + vLightPosition = uMatrixLight * position; +#endif //SHADOWED +} --