WebGL自学教程——关于WebGL着色器中的自定义函数
2011-11-10 14:32
274 查看
首先看看下面的两个自定义函数:
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或未知
}
很愁人的写法,不过总算能解决问题了。
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或未知
}
很愁人的写法,不过总算能解决问题了。
相关文章推荐
- PHP 自学教程之自定义函数及数组
- EXCEL 中自定义函数的应用(关于 XOR 在 EXCEL 中的用法 及 文本型数字求和)
- WebGL自学教程——WebGL示例:14.0 代码整理
- WebGL自学课程(11):ELSL着色器编程中内置的运算符与函数
- 百宝云自定义功能函数教程
- WebGL自学教程——WebGL示例:测试了一下模板缓冲,目前FF还不支持。。。
- 求助(关于自定义函数位置的问题)
- 关于set的自定义比较函数的使用及结构体的上下二分用法
- Yii自学-框架自定义全局工具函数
- PHP入门教程之自定义函数用法详解(创建,调用,变量,参数,返回值等)
- cocos进阶教程(1)Lua调用自定义C++类和函数的最佳实践
- WebGL自学课程(2):使用自定义glTranslate与glRotate
- WebGL自学教程——WebGL示例:13. 混合
- 关于自定义比较函数 usort 如何使用 类中的方法
- 关于jQuery中自定义函数的操作
- 关于MySql中使用自定义函数的学习心得
- WebGL自学教程——WebGL示例:5. 用键盘控制三角形的旋转
- WebGL自学教程——WebGL示例:6. 第一个三维的物体:立方体
- WebGL自学教程——WebGL示例:悲摧了,浏览器升级后,有些功能我的本本的显卡不支持了
- WebGL自学教程——WebGL示例:12. 要有光