首先看看下面的两个自定义函数:
vec2 GetV2TexCoord(void)
{
if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_TEXCOORD) return a_v2TexCoord;
if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_XY) return v_v4SrcPosition.xy;
if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_XZ) return v_v4SrcPosition.xz;
if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_YZ) return v_v4SrcPosition.yz;
if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_XY) return v_v4Position.xy;
if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_XZ) return v_v4Position.xz;
if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_YZ) return v_v4Position.yz;
if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_TEXCOORD) return a_v2TexCoord;
if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_SRC_POSITION) return v_v4SrcPosition.xy;
if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_POSITION) return v_v4Position.xy;
return vec2(0.0, 0.0);//EJSWEBGLTEXTURECOORDTYPE.NONE或未知
}
vec3 GetV3TexCoord(void)
{
if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_TEXCOORD) return vec3(a_v3TexCoord.xy, 1.0);
if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_XY) return vec3(v_v4SrcPosition.xy, 1.0);
if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_XZ) return vec3(v_v4SrcPosition.xz, 1.0);
if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_YZ) return vec3(v_v4SrcPosition.yz, 1.0);
if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_XY) return vec3(v_v4Position.xy, 1.0);
if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_XZ) return vec3(v_v4Position.xz, 1.0);
if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_YZ) return vec3(v_v4Position.yz, 1.0);
if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE.CUBE_TEXCOORD) return a_v3TexCoord;
if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE.CUBE_SRC_POSITION) return vec3(v_v4SrcPosition.xyz);
if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE.CUBE_POSITION) return vec3(v_v4Position.xyz);
return vec3(0.0, 0.0, 0.0);//EJSWEBGLTEXTURECOORDTYPE.NONE或未知
}
看起来好像没有问题,理论上也不应当有问题(EJSWEBGLTEXTURECOORDTYPE._2D_TEXCOORD之类的会被自动替换成*.0之类的数字,此处就不扯浮点数不能直接用==号比较的话)。实际上,编译也没有问题,但是,在链接到程序对象时,出现了下面的问题:
(144,4): error X4505: maximum temp register index exceeded
(149,4): error X4505: maximum temp register index exceeded
(154,4): error X4505: maximum temp register index exceeded
(154,4): error X4505: maximum temp register index exceeded
(149,4): error X4505: maximum temp register index exceeded
对WebGL的着色器代码,我不知道有什么离线编译和汇编工具,没能看到编译后的代码。不过,在我所使用FF上,估计最后是借助了DirectX的HLSL(首先在线编译着色器代码,然后将编译好的汇编代码交给HLSL链接到程序)。链接过程中,对代码进行了重排和优化。可惜,做得不到位,有bug(在DirectX的HLSL,确实是有这么一个bug的,后来应当已经修正,但我没有更新过)。当然,这不是重点,重点是如果让上面的两个函数跑起来。
参考DirectX的HLSL的bug,发现问题发生在返回值使用的临时变量上:第一个返回的临时变量使用寄存器123,第二个返回的临时变量使用寄存器456,而不是使用寄存器123(只是为了说明问题,事实并不绝对如此)。最终,导致整个函数中需要使用的寄存器数量太多。既然如此,那就不使用返回临时变量。修改为:
void GetV2TexCoord(out vec2 v2Value)
{
if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_TEXCOORD) v2Value = a_v2TexCoord;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_XY) v2Value = v_v4SrcPosition.xy;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_XZ) v2Value = v_v4SrcPosition.xz;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_YZ) v2Value = v_v4SrcPosition.yz;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_XY) v2Value = v_v4Position.xy;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_XZ) v2Value = v_v4Position.xz;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_YZ) v2Value = v_v4Position.yz;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_TEXCOORD) v2Value = a_v2TexCoord;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_SRC_POSITION) v2Value = v_v4SrcPosition.xy;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_POSITION) v2Value = v_v4Position.xy;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_POSITION) v2Value = v_v4Position.xy;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_POSITION) v2Value = v_v4Position.xy;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_POSITION) v2Value = v_v4Position.xy;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_POSITION) v2Value = v_v4Position.xy;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_POSITION) v2Value = v_v4Position.xy;
else if(u_im4Modes[1][0] == EJSWEBGLTEXTURECOORDTYPE.CUBE_POSITION) v2Value = v_v4Position.xy;
else v2Value = vec2(0.0, 0.0);//EJSWEBGLTEXTURECOORDTYPE.NONE或未知
}
void GetV3TexCoord(out vec3 v3Value)
{
if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_TEXCOORD) v3Value = vec3(a_v3TexCoord.xy, 1.0);
else if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_XY) v3Value = vec3(v_v4SrcPosition.xy, 1.0);
else if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_XZ) v3Value = vec3(v_v4SrcPosition.xz, 1.0);
else if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_SRC_POSITION_YZ) v3Value = vec3(v_v4SrcPosition.yz, 1.0);
else if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_XY) v3Value = vec3(v_v4Position.xy, 1.0);
else if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_XZ) v3Value = vec3(v_v4Position.xz, 1.0);
else if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE._2D_POSITION_YZ) v3Value = vec3(v_v4Position.yz, 1.0);
else if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE.CUBE_TEXCOORD) v3Value = a_v3TexCoord;
else if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE.CUBE_SRC_POSITION) v3Value = vec3(v_v4SrcPosition.xyz);
else if(u_im4Modes[1][1] == EJSWEBGLTEXTURECOORDTYPE.CUBE_POSITION) v3Value = vec3(v_v4Position.xyz);
else v3Value = vec3(0.0, 0.0, 0.0);//EJSWEBGLTEXTURECOORDTYPE.NONE或未知
}
很愁人的写法,不过总算能解决问题了。