3

I am trying to convert a 330 shader to 110 but can't find a work around for:

v_norm = normalize(mat3(modelview) * vNormal);

The error returned is:

GLSL 110 does not allow sub- or super-matrix constructors

The complete shader:

#version 110

attribute  vec3 vPosition;
attribute  vec3 vNormal;
varying vec3 v_norm;

uniform mat4 modelview;

void main()
{
    gl_Position = modelview * vec4(vPosition, 1.0);
    v_norm = normalize(mat3(modelview) * vNormal);
    v_norm = vNormal;
}
livin_amuk
  • 1,285
  • 12
  • 26
  • If you assign again v_norm to vNormal at the end if your shader, the assignment above where you have your problem is useless and can be safely removed. – elenfoiro78 Dec 23 '15 at 14:21

1 Answers1

6

I'll assume that you don't understand what "sub- or super-matrix construction" is, since if you did, the workaround would be obvious.

The statement mat3(modelview) tells GLSL to construct a mat3. But the matrix passed to it is a mat4, a 4x4 matrix. Obviously there are 16 numbers instead of the 9 used by mat3.

Under the rules of decent GLSL versions, this would extract the upper-left 3x3 sub-matrix of the given mat4. GLSL 1.10 is not decent.

So the workaround for this is to do it manually. Construct a mat3 made from 9 values, taken from the upper-left portion of the modelview matrix. Or from three vectors:

mat3(modelview[0].xyz, modelview[1].xyz, modelview[2].xyz)
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • No I didn't, but I do now, thanks, you explained it clearly. So is there are cleaner way than this: `mat3 NicolBolas = mat3(modelview[0][0], modelview[0][1], modelview[0][2], modelview[1][0], modelview[1][1], modelview[1][2], modelview[2][0], modelview[2][1], modelview[2][2]);` ? – livin_amuk Dec 23 '15 at 14:07
  • @livin_amuk: See edits. I assume that your old version of GLSL can construct matrices from (column) vectors. – Nicol Bolas Dec 23 '15 at 14:10