在WebGL中使用GLSL着色器的流行方式似乎是将它们嵌入到主html文件中.顶点和片段着色器嵌入在以下标记中:
<script id="shader-fs" type="x-shader/x-fragment">
Run Code Online (Sandbox Code Playgroud)
这与我在Mozilla Developer Network页面中的WebGL示例中看到的相同.
这适用于简单的应用程序,但是当你有一个带有许多着色器的复杂应用程序时,html文件会变得混乱.(我一直在编辑错误的着色器!)另外,如果你想重复使用着色器,这个方案很不方便.
所以我考虑将这些着色器放在一个单独的XML文件中,并使用XMLHttpRequest()加载它们.然后我看到其他人有同样的想法:
http://webreflection.blogspot.com/2010/09/fragment-and-vertex-shaders-my-way-to.html
我喜欢使用.c文件的建议,因为这为GLSL提供了语法高亮和其他编辑器便利.
但是上述方法的问题是(据我所知)XMLHttpRequest()在开发和测试WebGL应用程序时无法加载本地.c文件 - 即在客户端.但是在此过程中继续将其上传到服务器是很麻烦的.
因此,如果我想将着色器保留在html文件之外,那么将它们作为字符串嵌入代码中是唯一的选择吗?但这会使编写和调试变得困难......
我很感激有关在WebGL应用程序中管理多个GLSL着色器的任何建议.
问候
编辑(2011年5月5日)
由于我使用Mac进行开发,我决定启用Apache服务器,并将我的webgl代码放在http:// localhost/~username /下.这避免了在开发期间禁用文件:协议的问题.现在javascript文件加载代码在本地工作,因为使用了http:而不是file:.我以为我会把它放在这里以防万一有人发现它有用.
Gil*_*mas 18
是的,如果你想使用XHR,本地服务器真的是唯一的出路.我写过一堆WebGL课程,经常考虑不再在HTML中嵌入着色器,但是我已经被大量关于网络安全的解释吓到了......
幸运的是,运行服务器非常容易.然后打开一个shell
cd path-to-files
python -m SimpleHTTPServer
Run Code Online (Sandbox Code Playgroud)
然后将浏览器指向
http://localhost:8000
Run Code Online (Sandbox Code Playgroud)
这适用于纹理和GLSL等简单情况.对于视频和音频流看看
什么是Python的http.server(或SimpleHTTPServer)的更快的替代品?
在另一方面,支持WebGL的每一个浏览器支持ES6辑阵行模板文字,所以如果你不关心旧的浏览器你可以把你的着色器在JavaScript中使用这样的反引号
var vertexShaderSource = `
attribute vec4 position;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * position;
}
`;
Run Code Online (Sandbox Code Playgroud)
Val*_*ler 15
我一直在使用require.js的文本插件.
这是一个片段:
define(
/* Dependencies (I also loaded the gl-matrix library) */
["glmatrix", "text!shaders/fragment.shader", "text!shaders/vertex.shader"],
/* Callback when all has been loaded */
function(glmatrix, fragmentShaderCode, vertexShaderCode) {
....
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderCode);
gl.compileShader(vertexShader);
....
}
);
Run Code Online (Sandbox Code Playgroud)
目录结构如下:
~require-gl-shaders/
|~js/
| |+lib/
| |~shaders/
| | |-fragment.shader
| | `-vertex.shader
| |-glmatrix.js - gl-matrix library
| |-shader.js
| |-text.js - require.js's text plugin
|-index.html
|-main.js
`-require.js - the require.js library
Run Code Online (Sandbox Code Playgroud)
就个人而言,我有一点学习曲线与require,但它确实帮助我保持清洁代码.
我的好友创建了一个很好的utils对象,为这种场景提供了一些方便的功能.您可以将着色器存储在纯文本文件中名为"着色器"的文件夹中:
filename:vertex.shader
attribute vec3 blah;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;
void main(void) {
magic goes here
}
Run Code Online (Sandbox Code Playgroud)
filename:fragment.shader
#ifdef GL_ES
precision highp float;
#endif
varying vec4 vYadaYada;
uniform sampler2D uSampler;
void main(void) {
fragic magic goes here
}
Run Code Online (Sandbox Code Playgroud)
你只需调用它来创建一个包含这些着色器文件的新程序:
var shaderProgram = utils.addShaderProg(gl, 'vertex.shader', 'fragment.shader');
Run Code Online (Sandbox Code Playgroud)
这里是处理biz的sweet util对象:
utils = {};
utils.allShaders = {};
utils.SHADER_TYPE_FRAGMENT = "x-shader/x-fragment";
utils.SHADER_TYPE_VERTEX = "x-shader/x-vertex";
utils.addShaderProg = function (gl, vertex, fragment) {
utils.loadShader(vertex, utils.SHADER_TYPE_VERTEX);
utils.loadShader(fragment, utils.SHADER_TYPE_FRAGMENT);
var vertexShader = utils.getShader(gl, vertex);
var fragmentShader = utils.getShader(gl, fragment);
var prog = gl.createProgram();
gl.attachShader(prog, vertexShader);
gl.attachShader(prog, fragmentShader);
gl.linkProgram(prog);
if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {alert("Could not initialise main shaders");}
return prog;
};
utils.loadShader = function(file, type) {
var cache, shader;
$.ajax({
async: false, // need to wait... todo: deferred?
url: "shaders/" + file, //todo: use global config for shaders folder?
success: function(result) {
cache = {script: result, type: type};
}
});
// store in global cache
uilts.allShaders[file] = cache;
};
utils.getShader = function (gl, id) {
//get the shader object from our main.shaders repository
var shaderObj = utils.allShaders[id];
var shaderScript = shaderObj.script;
var shaderType = shaderObj.type;
//create the right shader
var shader;
if (shaderType == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderType == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
//wire up the shader and compile
gl.shaderSource(shader, shaderScript);
gl.compileShader(shader);
//if things didn't go so well alert
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
//return the shader reference
return shader;
};//end:getShader
Run Code Online (Sandbox Code Playgroud)
感谢好友为甜蜜的codeezy ...享受他对webgl社区的贡献..使简化程序/着色器管理更容易.
小智 7
在@ droidballoon的提示后,我最终使用了stack.gl,"这是一个开源的WebGL生态系统,建立在browserify和npm之上".
它的glslify提供了一个browserify变换,可以与gl-shader一起使用以加载着色器.Javascript看起来像这样:
var glslify = require('glslify');
var loadShader = require('gl-shader');
var createContext = require('gl-context');
var canvas = document.createElement('canvas');
var gl = createContext(canvas);
var shader = loadShader(
gl,
glslify('./shader.vert'),
glslify('./shader.frag')
);
Run Code Online (Sandbox Code Playgroud)
我正在使用:https : //www.npmjs.com/package/webpack-glsl-loader它具有优先权,可以防止语法高亮显示具有适当的glsl文件而不是文本片段。稍后再报告。
[2015年8月17日编辑]这种方法对我来说效果很好。它假定webpack在您的构建流程中,但这并不是一件坏事。
[2016年6月11日编辑] https://github.com/kulicuu/Spacewar_WebGL_React有一个有效的示例,用于通过Webpack构建导入glsl文件。游戏本身应在未来一周内开发。
| 归档时间: |
|
| 查看次数: |
24809 次 |
| 最近记录: |