[英]Shaders : Best practice to store them
為了存儲着色器,作者在<script>
標記中聲明了它們:
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
}
</script>
然后使用一些javascript代碼檢索它們:
function getShader(gl, id) {
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
var str = "";
var k = shaderScript.firstChild;
while (k) {
if (k.nodeType == 3)
str += k.textContent;
k = k.nextSibling;
}
var shader;
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
我發現檢索着色器非常復雜,因此問題很簡單:
檢索和編譯着色器的最佳實踐是什么? 這是標准方式嗎? 我希望能夠將着色器存儲在其他文件中。
我在webGL中不太好,但是我做了一些事情。 我也在問自己這個問題。 我知道有3種常見方法。 第一個是您在此處介紹的基本內容。 是的,它很雜亂,很復雜,但是有一些優點。 着色器代碼易於維護。
我發現的第二種方法是將着色器代碼放入數組中,然后立即加入數組,使其成為字符串。 之后,您可以將字符串傳遞給gl.createShader
函數。
這種技術在three.js javascript庫中非常普遍,該庫中有很多着色器代碼。 它使着色器易於閱讀,而不像第一個那樣混亂,但是如您所見,維護着色器代碼會有點困難。 要點是,它將使您可以將所有內容保存在一個javascript文件中,這是每個好的庫都需要的行為。
一個小例子,這是我們的頂點着色器:
var vertexShader = [
"attribute vec3 aVertexPosition;",
"uniform mat4 uMVMatrix;",
"uniform mat4 uPMatrix;",
"void main(void) {",
"gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);",
"}"
].join( "\n" );
編輯
有人找到了一種更好的方法!
var vertexShader = `attribute vec3 aVertexPosition;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
}`;
編輯結束
可以處理着色器的功能
function getShader(gl, source, type) {
var shader;
if (type == "fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (type == "vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
簡單函數調用
// var fragmentShader = getShader(gl, fragmentShader, "fragment");
var vertexShader = getShader(gl, vertexShader, "vertex");
但是您可能正在尋找與眾不同的東西。 因此,對您來說最好的選擇是制作“ myvertexshader”之類的文件,然后調用ajax將文件加載到變量中。 jQuery是一個不錯的選擇。
jQuery.get('myvertexshader', callback);
function callback(source) {
var shader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(shader, source);
gl.compileShader(shader);
...
}
然后將您的着色器代碼與javascript分開。 您還可以設置自己的文件擴展名,並在IDE中為着色器開發制定不同的規則,這對於豐富的着色器來說是個好主意。
PS:我聽說有一些謠言稱Blob文件將能夠編譯着色器(也許我已經知道了)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.