Skip to content

Commit

Permalink
UPBGE: Fix GLSL inverse support.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
panzergame committed Nov 22, 2016
1 parent b7b3dee commit b5238de
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 4 deletions.
1 change: 1 addition & 0 deletions source/blender/gpu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 7 additions & 3 deletions source/blender/gpu/intern/gpu_shader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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) {
Expand All @@ -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. */
Expand Down Expand Up @@ -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) {
Expand Down
45 changes: 45 additions & 0 deletions source/blender/gpu/shaders/gpu_shader_lib.glsl
Original file line number Diff line number Diff line change
@@ -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
3 changes: 2 additions & 1 deletion source/blender/gpu/shaders/gpu_shader_vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit b5238de

Please sign in to comment.