我正在使用OpenGLES 2.0为webgl移植为Android和IOS设备编写的引擎,我偶然发现了使用着色器的问题。为移动应用程序编写的大多数着色器不适用于webGL。示例:
(在编译之前,$由预处理器替换为值)
顶点着色器:
uniform mat4 u_mvpMatrix;
attribute vec4 a_position;
attribute vec2 TexCoordIn;
varying vec2 TexCoordOut;
varying highp vec2 MCPosition;
varying float radius1;
varying float radius2;
uniform int time;
const int delay = ($2*60)/1000;
const int animDuration = ($3*60)/1000;
void main()
{
gl_Position = u_mvpMatrix * a_position;
MCPosition = a_position.xy;
TexCoordOut = TexCoordIn;
int timer = time - delay;
radius1 = float(240 * (timer-26) / animDuration);
radius2 = float(240 * (timer-1) / animDuration);
}
Fragment Shader:
precision mediump float;
uniform vec2 spriteSize;
uniform vec2 spritePosition;
uniform lowp float alpha;
uniform lowp float brightness;
uniform sampler2D Texture;
uniform int time;
varying vec2 MCPosition;
varying vec2 TexCoordOut;
varying float radius1;
varying float radius2;
const float hexRadius = 7.0;
const float hexWidth = hexRadius*sqrt(3.0);
const float cos30 = hexRadius/hexWidth;
const float midHexRadius = hexRadius/2.0;
const float midHexWidth = hexWidth/2.0;
const vec2 centerEffect = vec2($1,$0);
const float SIDE = hexRadius * 3. / 2.;
const float HEIGHT = hexWidth;
const float SEMI_HEIGHT = HEIGHT / 2.;
const float RADIUS = hexRadius;
vec2 cellIndex(float i, float j)
{
float mX = i * SIDE;
float mY = SEMI_HEIGHT * (2. * j + mod(i, 2.));
return vec2(mX, mY);
}
void main()
{
vec2 center;
bool isOnEdge = false;
float x = MCPosition.y;
float y = MCPosition.x;
float ci = floor(x/SIDE);
float cx = mod(x, SIDE);
float isCiImpair = mod(ci, 2.);
float ty = y - isCiImpair * SEMI_HEIGHT;
float cj = floor( ty / HEIGHT);
float cy = ty - HEIGHT * cj;
float border = abs(RADIUS / 2. - RADIUS * cy / HEIGHT);
if (cx > border)
{
center = cellIndex(ci , cj);
if( cy < 1. || cy > (HEIGHT-1.) || (cx- border) < 1.0)
{
isOnEdge = true;
}
}
else
{
center = cellIndex(ci - 1., cj + isCiImpair - ((cy < SEMI_HEIGHT) ? 1. : 0.));
if( (border - cx ) < 1.0)
{
isOnEdge = true;
}
}
float distFromCenter = distance(centerEffect, center);
if(distFromCenter > radius2)
{
gl_FragColor = vec4(0.);
}
else
{
vec4 texColor = texture2D(Texture, TexCoordOut);
//filling is over
if(distFromCenter < radius1)
{
gl_FragColor = texColor;
}
else
{
float ratio = (radius2 - distFromCenter)/(radius2 - radius1);
gl_FragColor = vec4(texColor.a * ratio);
if(!isOnEdge)
{
gl_FragColor.rgb *= texColor.rgb;
}
}
gl_FragColor.rgb *= brightness;
}
}
它就像OpenGLES上的魅力一样,但在webGL上,我有关于使用非常量值初始化const float的报告。在声明const时,我所做的操作总是返回相同的结果。
An error occurred compiling the shaders: ERROR: 0:17: '=' : assigning non-constant to 'const mediump float'
ERROR: 0:18: '=' : assigning non-constant to 'const mediump float'
ERROR: 0:20: '=' : assigning non-constant to 'const mediump float'
ERROR: 0:24: '=' : assigning non-constant to 'const mediump float'
ERROR: 0:25: '=' : assigning non-constant to 'const mediump float'
我可以做些什么,或者我是否必须重写所有着色器以匹配WebGL GLSL细节?
答案 0 :(得分:4)
当我在使用webGL着色器时,唯一允许使用的是纯数字,我仍然没有找到方法。似乎重写是唯一的选择。 :P
答案 1 :(得分:0)
为什么不使用int / floats的定义(着色器代码中的#define)?
对我来说,“const vec2”工作正常。如果它不适合你 - 将它们移动到统一处(顺便说一下,似乎nVidia驱动程序将consts视为制服)。