fffiloni's picture
Migrated from GitHub
2252f3d verified
#version 330
layout (location = 0) in vec3 a_Position;
layout (location = 1) in vec3 a_Normal;
layout (location = 2) in vec2 a_TextureCoord;
layout (location = 3) in vec3 a_Tangent;
layout (location = 4) in vec3 a_Bitangent;
layout (location = 5) in vec3 a_PRT1;
layout (location = 6) in vec3 a_PRT2;
layout (location = 7) in vec3 a_PRT3;
layout (location = 8) in vec3 a_Label;
out VertexData {
vec3 Position;
vec3 Depth;
vec3 ModelNormal;
vec2 Texcoord;
vec3 Tangent;
vec3 Bitangent;
vec3 PRT1;
vec3 PRT2;
vec3 PRT3;
vec3 Label;
} VertexOut;
uniform mat3 RotMat;
uniform mat4 NormMat;
uniform mat4 ModelMat;
uniform mat4 PerspMat;
float s_c3 = 0.94617469575; // (3*sqrt(5))/(4*sqrt(pi))
float s_c4 = -0.31539156525;// (-sqrt(5))/(4*sqrt(pi))
float s_c5 = 0.54627421529; // (sqrt(15))/(4*sqrt(pi))
float s_c_scale = 1.0/0.91529123286551084;
float s_c_scale_inv = 0.91529123286551084;
float s_rc2 = 1.5853309190550713*s_c_scale;
float s_c4_div_c3 = s_c4/s_c3;
float s_c4_div_c3_x2 = (s_c4/s_c3)*2.0;
float s_scale_dst2 = s_c3 * s_c_scale_inv;
float s_scale_dst4 = s_c5 * s_c_scale_inv;
void OptRotateBand0(float x[1], mat3 R, out float dst[1])
{
dst[0] = x[0];
}
// 9 multiplies
void OptRotateBand1(float x[3], mat3 R, out float dst[3])
{
// derived from SlowRotateBand1
dst[0] = ( R[1][1])*x[0] + (-R[1][2])*x[1] + ( R[1][0])*x[2];
dst[1] = (-R[2][1])*x[0] + ( R[2][2])*x[1] + (-R[2][0])*x[2];
dst[2] = ( R[0][1])*x[0] + (-R[0][2])*x[1] + ( R[0][0])*x[2];
}
// 48 multiplies
void OptRotateBand2(float x[5], mat3 R, out float dst[5])
{
// Sparse matrix multiply
float sh0 = x[3] + x[4] + x[4] - x[1];
float sh1 = x[0] + s_rc2*x[2] + x[3] + x[4];
float sh2 = x[0];
float sh3 = -x[3];
float sh4 = -x[1];
// Rotations. R0 and R1 just use the raw matrix columns
float r2x = R[0][0] + R[0][1];
float r2y = R[1][0] + R[1][1];
float r2z = R[2][0] + R[2][1];
float r3x = R[0][0] + R[0][2];
float r3y = R[1][0] + R[1][2];
float r3z = R[2][0] + R[2][2];
float r4x = R[0][1] + R[0][2];
float r4y = R[1][1] + R[1][2];
float r4z = R[2][1] + R[2][2];
// dense matrix multiplication one column at a time
// column 0
float sh0_x = sh0 * R[0][0];
float sh0_y = sh0 * R[1][0];
float d0 = sh0_x * R[1][0];
float d1 = sh0_y * R[2][0];
float d2 = sh0 * (R[2][0] * R[2][0] + s_c4_div_c3);
float d3 = sh0_x * R[2][0];
float d4 = sh0_x * R[0][0] - sh0_y * R[1][0];
// column 1
float sh1_x = sh1 * R[0][2];
float sh1_y = sh1 * R[1][2];
d0 += sh1_x * R[1][2];
d1 += sh1_y * R[2][2];
d2 += sh1 * (R[2][2] * R[2][2] + s_c4_div_c3);
d3 += sh1_x * R[2][2];
d4 += sh1_x * R[0][2] - sh1_y * R[1][2];
// column 2
float sh2_x = sh2 * r2x;
float sh2_y = sh2 * r2y;
d0 += sh2_x * r2y;
d1 += sh2_y * r2z;
d2 += sh2 * (r2z * r2z + s_c4_div_c3_x2);
d3 += sh2_x * r2z;
d4 += sh2_x * r2x - sh2_y * r2y;
// column 3
float sh3_x = sh3 * r3x;
float sh3_y = sh3 * r3y;
d0 += sh3_x * r3y;
d1 += sh3_y * r3z;
d2 += sh3 * (r3z * r3z + s_c4_div_c3_x2);
d3 += sh3_x * r3z;
d4 += sh3_x * r3x - sh3_y * r3y;
// column 4
float sh4_x = sh4 * r4x;
float sh4_y = sh4 * r4y;
d0 += sh4_x * r4y;
d1 += sh4_y * r4z;
d2 += sh4 * (r4z * r4z + s_c4_div_c3_x2);
d3 += sh4_x * r4z;
d4 += sh4_x * r4x - sh4_y * r4y;
// extra multipliers
dst[0] = d0;
dst[1] = -d1;
dst[2] = d2 * s_scale_dst2;
dst[3] = -d3;
dst[4] = d4 * s_scale_dst4;
}
void main()
{
// normalization
vec3 pos = (NormMat * vec4(a_Position,1.0)).xyz;
mat3 R = mat3(ModelMat) * RotMat;
VertexOut.ModelNormal = (R * a_Normal);
VertexOut.Position = R * pos;
VertexOut.Texcoord = a_TextureCoord;
VertexOut.Tangent = (R * a_Tangent);
VertexOut.Bitangent = (R * a_Bitangent);
VertexOut.Label = a_Label;
float PRT0, PRT1[3], PRT2[5];
PRT0 = a_PRT1[0];
PRT1[0] = a_PRT1[1];
PRT1[1] = a_PRT1[2];
PRT1[2] = a_PRT2[0];
PRT2[0] = a_PRT2[1];
PRT2[1] = a_PRT2[2];
PRT2[2] = a_PRT3[0];
PRT2[3] = a_PRT3[1];
PRT2[4] = a_PRT3[2];
OptRotateBand1(PRT1, R, PRT1);
OptRotateBand2(PRT2, R, PRT2);
VertexOut.PRT1 = vec3(PRT0,PRT1[0],PRT1[1]);
VertexOut.PRT2 = vec3(PRT1[2],PRT2[0],PRT2[1]);
VertexOut.PRT3 = vec3(PRT2[2],PRT2[3],PRT2[4]);
gl_Position = PerspMat * ModelMat * vec4(RotMat * pos, 1.0);
VertexOut.Depth = vec3(gl_Position.z / gl_Position.w);
}