如何以角度 (9) 在 WebGL 画布中显示 GLSL 片段着色器?

emb*_*mbm 5 canvas glsl webgl fragment-shader angular

这是我第一次处理使用 Angular 构建的项目,因此我仍在习惯针对 Angular 和 WebPack 的大量实践。

我希望在全屏画布中加载自定义片段着色器(.frag/.glsl)以用作组件的背景。对于过去的模型或其他不使用角度的项目,我设法在GlslCanvas等库的帮助下轻松做到这一点,这些库管理全屏四边形和基本制服的设置,但现在我无法弄清楚向我抛出的一些错误当尝试构建我的角度应用程序时。

经过几个小时的浏览,我找到了如何成功导入着色器代码,使用GLSL-shader-loader并通过 @Angular-devkit/build-Angular 和 @Angular-builder/custom-webpacks 添加自定义 Webpack 配置:

# my-custom-webpack.config.js

module.exports = {
    module: {
        rules: [{
            test: /\.(frag|vert|glsl)$/,
            use: [
                { 
                loader: 'glsl-shader-loader',
                options: {}  
                }
            ]
        }]
    }
}
Run Code Online (Sandbox Code Playgroud)

我还了解到我必须通过定义所需的声明来阻止打字稿抱怨导入时的非 ts 模块,即:

# my-declarations.d.ts

declare module '*.glsl';
declare module '*.frag';
declare module '*.vert';
Run Code Online (Sandbox Code Playgroud)

此时,片段着色器的代码已正确导入(或者我认为是这样?),我可以将其记录或打印出来(例如{{ myShaderCode }}):

# glsl-bg.component.ts

import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
import frag from './myShader.frag';
import * as GlslCanvas from 'glslCanvas'

@Component({
  selector: 'app-glsl-bg',
  templateUrl: './glsl-bg.component.html',
  styleUrls: ['./glsl-bg.component.css']
})
export class GlslBgComponent implements OnInit {

  @ViewChild('bgCanvas', {static: true})
  public bgCanvas: ElementRef<HTMLCanvasElement>;

  myShaderCode = frag;

  constructor() { }

  ngOnInit() {
    console.log(this.myShaderCode);
  }

}
Run Code Online (Sandbox Code Playgroud)

但是,这就是我陷入困境的地方:我尝试使用各种灯光库(没有像 Three.js 这样的大东西),但没有成功在画布中运行着色器代码。

使用 glslCanvas 构建时,它编译成功,但画布中没有显示任何内容,我在控制台中看到:

ERROR TypeError: glslCanvas__WEBPACK_IMPORTED_MODULE_2__ is not a constructor
Run Code Online (Sandbox Code Playgroud)

然而,如果我使用glsl-canvas-js(前者的 ts 端口),它无法编译,给我这个日志:

ERROR in ./node_modules/glsl-canvas-js/dist/glsl-canvas.js
Module not found: Error: Can't resolve './buffers' in '[...]\node_modules\glsl-canvas-js\dist'
ERROR in ./node_modules/glsl-canvas-js/dist/glsl-canvas.js
Module not found: Error: Can't resolve './common' in '[...]\node_modules\glsl-canvas-js\dist'
ERROR in ./node_modules/glsl-canvas-js/dist/glsl-canvas.js
Module not found: Error: Can't resolve './context' in '[...]\node_modules\glsl-canvas-js\dist'
ERROR in ./node_modules/glsl-canvas-js/dist/glsl-canvas.js
Module not found: Error: Can't resolve './iterable' in '[...]\node_modules\glsl-canvas-js\dist'
ERROR in ./node_modules/glsl-canvas-js/dist/glsl-canvas.js
Module not found: Error: Can't resolve './logger' in '[...]\node_modules\glsl-canvas-js\dist'
ERROR in ./node_modules/glsl-canvas-js/dist/glsl-canvas.js
Module not found: Error: Can't resolve './subscriber' in '[...]\node_modules\glsl-canvas-js\dist'
ERROR in ./node_modules/glsl-canvas-js/dist/glsl-canvas.js
Module not found: Error: Can't resolve './textures' in '[...]\node_modules\glsl-canvas-js\dist'
ERROR in ./node_modules/glsl-canvas-js/dist/glsl-canvas.js
Module not found: Error: Can't resolve './uniforms' in '[...]\node_modules\glsl-canvas-js\dist'

* [...] = full paths removed for simplification
Run Code Online (Sandbox Code Playgroud)

任何帮助或提示将不胜感激!

tfr*_*rei 0

我不是 Angular 开发人员,但这里有来自https://darvin.dev Webpack Boilerplate 的 Typescript/Webpack 设置:

Webpack 的 GLSL 加载器:

// https://github.com/unic/darvin-webpack-boilerplate/blob/master/webpack/settings/addon-glsl/index.js
// setting with raw-loader and glslify
rules: [
  {
    test: /\.(glsl|frag|vert)$/,
    exclude: /node_modules/,
    use: [
      'raw-loader',
      {
        loader: 'glslify-loader',
        options: {
          transform: [
            ['glslify-hex', { 'option-1': true, 'option-2': 42 }]
          ]
        }
      }
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

我建议在反应式框架之外创建一个 webgl 实例并通过 pubsub 调用它,这样您就不会进行额外的轮询。这是一个具有高性能时间处理功能的示例助手,您可以在 Darvin 2.0 中找到它作为演示示例。

// https://github.com/unic/darvin-webpack-boilerplate/blob/master/webpack/settings/addon-glsl/index.js
// setting with raw-loader and glslify
rules: [
  {
    test: /\.(glsl|frag|vert)$/,
    exclude: /node_modules/,
    use: [
      'raw-loader',
      {
        loader: 'glslify-loader',
        options: {
          transform: [
            ['glslify-hex', { 'option-1': true, 'option-2': 42 }]
          ]
        }
      }
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

玩得开心