From b5238de3623d93c2484fa7ac532b4bd988190ac8 Mon Sep 17 00:00:00 2001 From: Porteries Tristan Date: Wed, 24 Aug 2016 00:17:45 +0000 Subject: [PATCH] UPBGE: Fix GLSL inverse support. The inverse GLSL function is needed for geometry instancing, but this function is quite recent as it is unsupported before GLSL 1.40. To avoid forbid geometry instancing for a GLSL function support, an equivalent of the inverse function is written. This equivalent is put in gpu_shader_lib.glsl in the marco test : __VERSION__ < 140. This file is added in both vertex and fragment shader when compiling it. --- source/blender/gpu/CMakeLists.txt | 1 + source/blender/gpu/intern/gpu_shader.c | 10 +++-- .../blender/gpu/shaders/gpu_shader_lib.glsl | 45 +++++++++++++++++++ .../gpu/shaders/gpu_shader_vertex.glsl | 3 +- 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 source/blender/gpu/shaders/gpu_shader_lib.glsl diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index f8979a5e105c..2c4d8b69a249 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -128,6 +128,7 @@ data_to_c_simple(shaders/gpu_shader_fx_dof_hq_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_fx_dof_hq_geo.glsl SRC) data_to_c_simple(shaders/gpu_shader_fx_depth_resolve.glsl SRC) data_to_c_simple(shaders/gpu_shader_fx_lib.glsl SRC) +data_to_c_simple(shaders/gpu_shader_lib.glsl SRC) if(WITH_GAMEENGINE) add_definitions(-DWITH_GAMEENGINE) diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 812cc51e0b79..7a47c10cb43a 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -66,6 +66,7 @@ extern char datatoc_gpu_shader_fx_dof_hq_vert_glsl[]; extern char datatoc_gpu_shader_fx_dof_hq_geo_glsl[]; extern char datatoc_gpu_shader_fx_depth_resolve_glsl[]; extern char datatoc_gpu_shader_fx_lib_glsl[]; +extern char datatoc_gpu_shader_lib_glsl[]; static struct GPUShadersGlobal { struct { @@ -333,13 +334,14 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, gpu_shader_standard_extensions(standard_extensions, geocode != NULL); if (vertexcode) { - const char *source[6]; + const char *source[7]; /* custom limit, may be too small, beware */ int num_source = 0; source[num_source++] = gpu_shader_version(); source[num_source++] = standard_extensions; source[num_source++] = standard_defines; + source[num_source++] = datatoc_gpu_shader_lib_glsl; if (defines) source[num_source++] = defines; if (resetline) { @@ -364,12 +366,13 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, } if (fragcode) { - const char *source[8]; + const char *source[9]; int num_source = 0; source[num_source++] = gpu_shader_version(); source[num_source++] = standard_extensions; source[num_source++] = standard_defines; + source[num_source++] = datatoc_gpu_shader_lib_glsl; #ifdef WITH_OPENSUBDIV /* TODO(sergey): Move to fragment shader source code generation. */ @@ -407,12 +410,13 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, } if (geocode) { - const char *source[7]; + const char *source[8]; int num_source = 0; source[num_source++] = gpu_shader_version(); source[num_source++] = standard_extensions; source[num_source++] = standard_defines; + source[num_source++] = datatoc_gpu_shader_lib_glsl; if (defines) source[num_source++] = defines; if (resetline) { diff --git a/source/blender/gpu/shaders/gpu_shader_lib.glsl b/source/blender/gpu/shaders/gpu_shader_lib.glsl new file mode 100644 index 000000000000..0d14d24bb44c --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_lib.glsl @@ -0,0 +1,45 @@ +#if __VERSION__ < 140 +/* Manual implementation of inverse(mat4) for GLSL version before 1.40, + * copied from https://github.com/stackgl/glsl-inverse/blob/master/index.glsl + */ + +mat4 inverse(mat4 m) { + float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3], + a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3], + a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3], + a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3], + + b00 = a00 * a11 - a01 * a10, + b01 = a00 * a12 - a02 * a10, + b02 = a00 * a13 - a03 * a10, + b03 = a01 * a12 - a02 * a11, + b04 = a01 * a13 - a03 * a11, + b05 = a02 * a13 - a03 * a12, + b06 = a20 * a31 - a21 * a30, + b07 = a20 * a32 - a22 * a30, + b08 = a20 * a33 - a23 * a30, + b09 = a21 * a32 - a22 * a31, + b10 = a21 * a33 - a23 * a31, + b11 = a22 * a33 - a23 * a32, + + det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + return mat4( + a11 * b11 - a12 * b10 + a13 * b09, + a02 * b10 - a01 * b11 - a03 * b09, + a31 * b05 - a32 * b04 + a33 * b03, + a22 * b04 - a21 * b05 - a23 * b03, + a12 * b08 - a10 * b11 - a13 * b07, + a00 * b11 - a02 * b08 + a03 * b07, + a32 * b02 - a30 * b05 - a33 * b01, + a20 * b05 - a22 * b02 + a23 * b01, + a10 * b10 - a11 * b08 + a13 * b06, + a01 * b08 - a00 * b10 - a03 * b06, + a30 * b04 - a31 * b02 + a33 * b00, + a21 * b02 - a20 * b04 - a23 * b00, + a11 * b07 - a10 * b09 - a12 * b06, + a00 * b09 - a01 * b07 + a02 * b06, + a31 * b01 - a30 * b03 - a32 * b00, + a20 * b03 - a21 * b01 + a22 * b00) / det; +} +#endif diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl index 6d2e4af2aabb..7b6759766175 100644 --- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl +++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl @@ -108,9 +108,10 @@ void main() vec4(ininstmatrix[1], ininstposition.y), vec4(ininstmatrix[2], ininstposition.z), vec4(0.0, 0.0, 0.0, 1.0)); + varinstmat = transpose(instmat); - varinstinvmat = inverse(varinstmat); varinstlocaltoviewmat = unfviewmat * varinstmat; + varinstinvmat = inverse(varinstmat); varinstinvlocaltoviewmat = inverse(varinstlocaltoviewmat); varinstcolor = ininstcolor;