javascript - 如何将 GLSL 着色器代码包含在主 html 的单独文件中?

标签 javascript html three.js glsl

我开始着手编写着色器,并且使用 THREE.js 构建 OpenGL 场景以便使用用 GLSL 编写的着色器非常方便。到目前为止,我一直将 GLSL 代码包含在主 HTML 文件内的脚本字段中:

<html>
<head>
    <meta charset=uft-8>
    <title>Babby's first three.js app</title>
    <style>
        body { margin: 0; }
        canvas { width: 100%; height: 100% }
    </style>
</head>
<body>
    <script src="js/three.js"></script>

    <script id="fragShader" type="shader-code">
        // GLSL shader goes here!
        void main(){
            /* shader body */
        }
    </script>

    <script>
        // Three.js scene setup goes here

        // Get shader code from fragShader script element
        var shaderCode = document.getElementById("fragShader").innerHTML; 

        // Apply it to a material
        bufferMaterial = new THREE.ShaderMaterial({
            uniforms : {
                bufferTexture : {type : "t", value : textureA},
            },
            fragmentShader : shaderCode 
        });

        // Render everything
    </script>
</body> 

我正在开发一个更复杂的着色器项目,并且希望将主 html 文件分开,以便着色器代码可以保持独立,但我发现这非常难以做到。

我尝试使用 jquery 读取存储在单独文本文件中的着色器代码(我正在运行本地服务器):

<script src ="node_modules/jquery/dist/jquery.js"></script>
<script> 
    $(function(){
        $("#fragShader").load("mainShader.html"); // contains GLSL code
    });
</script> 

<script id="fragShader"></script>

但是着色器无法编译 - fragment ERROR: Missing main() .

非常感谢对这个 js 新手的任何帮助!

最佳答案

我经常创建一个单独的 js 文件,其中包含以下形式的对象:

var customShaderObject = {
  fragmentShader: /* code (see below) */
  vertexShader: /* code (see below) */
  ... etc.
}

每个着色器都是一个字符串数组,每个索引代表一行,使用新行作为分隔符在末尾连接,例如

fragmentShader: [
  'line 1',
  'line 2',
  'line 3',
  ' etc. '
].join('\r\n');

在编辑代码方面,一种更简单的方法是使用模板文字语法(反引号 `)而不是数组,因为这样您基本上可以像多行普通代码一样编辑单个字符串。

这种方法(使用数组和模板文字)还有一个额外的优点,即允许您将值创建为函数,以便您可以在运行时将变量插入着色器的各个部分,例如

fragmentShader: function (bar) {
    return [
      'float foo = ' + bar.toString() + ';',
      'line 2',
      'line 3',
      ' etc. '
    ].join('\r\n');
  }

或使用模板文字:

fragmentShader: function (bar) {
    return `
      float foo = ${bar.toString()};
      line 2
      line 3
      //etc.
    `;
  }

然后,您可以通过引用着色器的父对象来调用着色器,就像调用任何其他 JS 对象一样。

关于javascript - 如何将 GLSL 着色器代码包含在主 html 的单独文件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49340900/

相关文章:

php - PHP 中的文本到图像/PDF 转换器

html - css代码如何删除div类之间的空间

javascript - 无法渲染在 jQuery $.get 请求函数中添加到场景的三个 js 对象

javascript - 需要使用 Node js 从 websocket 流更新 CSV 文件

jQuery FormData POST - 用于文件上传

javascript - THREE.js 对象不会旋转

javascript - Three.js 中平面上的点

javascript - 编译失败 : Parsing error: Unexpected token, 预期 ";"

javascript - 如何折叠多维数组

javascript - 在线文本编辑器如何工作?