【问题标题】:A-Frame A-Text MaskA-Frame A-Text 蒙版
【发布时间】:2018-09-22 03:28:07
【问题描述】:

我找不到任何关于使用 a-text 原语或其他可能性与 a-frame 或threejs 隐藏图片的答案。位图文本应该是底层图像的掩码。有人告诉我,这可以通过着色器https://aframe.io/docs/0.8.0/primitives/a-text.html#attributes_shader 解决,并建议我阅读着色器之书https://thebookofshaders.com 有155 页的预知!我不确定这是否是正确的提示!?

在这里你可以看到图示的任务位置作为图形视图:

https://photos.app.goo.gl/MLZjcucfpuqmtinH7

Codepen:http://codepen.w3x.de

【问题讨论】:

  • 你想要它像那个例子(3D 文本)还是它在平面文本上的样子?我认为您必须从 A-Frame 存储库中复制/粘贴/修改文本着色器才能进行纹理查找。应该是很有可能的,因为文本在一个平面上,使得 UV 映射非常容易。
  • @ngokevin 感谢您的验证。你有一个建议的例子,我可以在我的 codepen 例子中注入吗?我没有找到任何代码示例/建议通过着色器解决这个 webGL 挑战。 photos.app.goo.gl/MLZjcucfpuqmtinH7
  • 我想知道您是否可以使用THREE.TextGeometrygithub.com/chandlerprall/ThreeCSG 从平面或框中减去文本?我没有例子,但这听起来比使用着色器更容易......

标签: shader aframe


【解决方案1】:

复制并粘贴 A-Frame 文本着色器代码(删除 module.exports)并注册文本着色器。这是当前的 MSDF 着色器:

AFRAME.registerShader('yourtextshader', {
      schema: {
        alphaTest: {type: 'number', is: 'uniform', default: 0.5},
        color: {type: 'color', is: 'uniform', default: 'white'},
        map: {type: 'map', is: 'uniform'},
        negate: {type: 'boolean', is: 'uniform', default: true},
        opacity: {type: 'number', is: 'uniform', default: 1.0}
      },

      raw: true,

      vertexShader: [
        'attribute vec2 uv;',
        'attribute vec3 position;',
        'uniform mat4 projectionMatrix;',
        'uniform mat4 modelViewMatrix;',
        'varying vec2 vUV;',
        'void main(void) {',
        '  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);',
        '  vUV = uv;',
        '}'
      ].join('\n'),

      fragmentShader: [
        '#ifdef GL_OES_standard_derivatives',
        '#extension GL_OES_standard_derivatives: enable',
        '#endif',

        'precision highp float;',
        'uniform bool negate;',
        'uniform float alphaTest;',
        'uniform float opacity;',
        'uniform sampler2D map;',
        'uniform vec3 color;',
        'varying vec2 vUV;',

        'float median(float r, float g, float b) {',
        '  return max(min(r, g), min(max(r, g), b));',
        '}',

        // FIXME: Experimentally determined constants.
        '#define BIG_ENOUGH 0.001',
        '#define MODIFIED_ALPHATEST (0.02 * isBigEnough / BIG_ENOUGH)',

        'void main() {',
        '  vec3 sample = texture2D(map, vUV).rgb;',
        '  if (negate) { sample = 1.0 - sample; }',

        '  float sigDist = median(sample.r, sample.g, sample.b) - 0.5;',
        '  float alpha = clamp(sigDist / fwidth(sigDist) + 0.5, 0.0, 1.0);',
        '  float dscale = 0.353505;',
        '  vec2 duv = dscale * (dFdx(vUV) + dFdy(vUV));',
        '  float isBigEnough = max(abs(duv.x), abs(duv.y));',

        '  // Do modified alpha test.',
        '  if (alpha < alphaTest * MODIFIED_ALPHATEST) { discard; return; }',
        '  gl_FragColor = vec4(color.xyz, alpha * opacity);',
        '}'
      ].join('\n')
    });

片段着色器用于计算文本的颜色。你会得到vUV,它是那个片段的UV贴图,告诉你在纹理的哪里采样。

你需要做什么来修改这个着色器。还没有时间做一个完整的例子,但是......:

  1. 接受纹理的另一个参数,添加到架构中。
  2. 将该纹理传递到着色器 (&lt;a-entity text="shader: yourTextShader; yourTexture: #texture)。
  3. 在片段着色器uniform sampler2D yourTexture中为该纹理添加一个制服。
  4. 修改片段着色器以使用纹理颜色而不是颜色gl_FragColor = vec4(texture2D(yourTexture, vUv), alpha * opacity)

【讨论】:

  • 您好 Kevin,我已经尝试完成您的示例,但似乎文本原语需要额外的纹理属性而不是着色器(所以我们还需要注册一个新的原语)?相反,您的“文本几何”扩展工作正常(Don McCurdy 提示),但这作为 2D 会很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 1970-01-01
  • 2020-07-23
  • 2020-12-02
  • 2015-03-07
相关资源
最近更新 更多