WebGL 中距离场的文本渲染问题
Text Rendering Problem with Distance Field in WebGL
我用 Qt OpenGL 3.3 制作了这个距离场示例:
效果很好。我是使用此视频教程制作的:OpenGL 3D Game Tutorial 33: Distance Field Text Rendering
我用 WebGL 逐行重写了这个例子,它看起来很糟糕:
这似乎是与 Premultiplied Alpha (see Why does my WebGL alpha-transparency look wrong? 有关的问题。
您需要在片段着色器中将颜色通道乘以 alpha 通道:
void main() {
// [...]
vec4 color = ...;
gl_FragColor = vec4(color.rgb * color.a, color.a);
}
并将混合函数更改为 1 * source_color + (1 -alpha) * dest_color:
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
_Develop提出的另一个解决方案:
const options: WebGLContextAttributes = {
alpha: false, premultipliedAlpha: false
}
gl = (canvas as HTMLCanvasElement).getContext("webgl", options);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
precision mediump float;
varying vec2 vTexCoord;
uniform sampler2D uSampler;
const float width = 0.5;
const float edge = 0.1;
void main()
{
float distance = 1.0 - texture2D(uSampler, vTexCoord).a;
float alpha = 1.0 - smoothstep(width, width + edge, distance);
if (alpha < 0.001)
{
discard;
}
gl_FragColor = vec4(0.2, 0.5, 0.0, alpha);
}
我用 Qt OpenGL 3.3 制作了这个距离场示例:
效果很好。我是使用此视频教程制作的:OpenGL 3D Game Tutorial 33: Distance Field Text Rendering
我用 WebGL 逐行重写了这个例子,它看起来很糟糕:
这似乎是与 Premultiplied Alpha (see Why does my WebGL alpha-transparency look wrong? 有关的问题。
您需要在片段着色器中将颜色通道乘以 alpha 通道:
void main() {
// [...]
vec4 color = ...;
gl_FragColor = vec4(color.rgb * color.a, color.a);
}
并将混合函数更改为 1 * source_color + (1 -alpha) * dest_color:
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
_Develop提出的另一个解决方案:
const options: WebGLContextAttributes = {
alpha: false, premultipliedAlpha: false
}
gl = (canvas as HTMLCanvasElement).getContext("webgl", options);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
precision mediump float;
varying vec2 vTexCoord;
uniform sampler2D uSampler;
const float width = 0.5;
const float edge = 0.1;
void main()
{
float distance = 1.0 - texture2D(uSampler, vTexCoord).a;
float alpha = 1.0 - smoothstep(width, width + edge, distance);
if (alpha < 0.001)
{
discard;
}
gl_FragColor = vec4(0.2, 0.5, 0.0, alpha);
}