之前(2年前)以及ThreeJS github和SO的几个地方都曾提到过这个问题。但仍然有很多人(包括我)在这方面遇到了问题。这就是我现在所拥有的(它是更大系统的一部分):
function dataLoader()
{
this.data_count = 0;
this.data_array = new Array();
}
function loadFile( file, loader ){
var FileObject = new Object();
FileObject.data = "";
FileObject.ready = false;
FileObject.id = loader.data_count;
loader.data_array[loader.data_count] = false;
$.ajax({
type: "GET",
url: file,
dataType: "text"
}).done( function( msg ) {
FileObject.data = msg;
FileObject.ready = true;
loader.data_array[FileObject.id] = true;
});
loader.data_count += 1;
return FileObject;
}
然后我这样做:
var loader = new dataLoader();
var SkyVertexShader = loadFile( "Shaders/sky.frag", loader );
var SkyFragmentShader = loadFile( "Shaders/sky.vertex", loader );
然后我创建这样的材料:
var skyMat = new THREE.ShaderMaterial( { vertexShader: SkyVertexShader.data, fragmentShader: SkyFragmentShader.data, uniforms: uniforms, side: THREE.BackSide } );
sky.frag和sky.vertex中的着色器是纯文本,没有任何标签或任何东西。当我调试时,我可以看到SkyFragmentShader.data和SkyVertexShader.data都已正确设置。着色器是webgl_lights_hemisphere示例中的着色器。 但是当我加载时我得到了这个错误:
ERROR: 0:37: 'modelMatrix' : undeclared identifier
ERROR: 0:37: 'position' : undeclared identifier
ERROR: 0:37: 'constructor' : not enough data provided for construction
ERROR: 0:38: 'assign' : l-value required "vWorldPosition" (can't modify a varying) ERROR: 0:40: 'gl_Position' : undeclared identifier
ERROR: 0:40: 'projectionMatrix' : undeclared identifier
ERROR: 0:40: 'modelViewMatrix' : undeclared identifier
ERROR: 0:40: 'constructor' : not enough data provided for construction
ERROR: 0:40: 'assign' : cannot convert from '4-component vector of float' to 'float' �
但是当我这样做时它会起作用(就像在例子中一样):
var fragmentShader = document.getElementById( 'fragmentShader' ).textContent;
var vertexShader = document.getElementById( 'vertexShader' ).textContent;
var skyMat = new THREE.ShaderMaterial( { vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, side: THREE.BackSide } );
最后一部分当然只有在HTML中使用着色器时才有效。因此,即使.textContent方法和Ajax GET方法(只是一些选项卡和换行符)之间的内容几乎相同,它也会显示有关未定义变量的语法错误。那会是什么导致这种情况呢?
答案 0 :(得分:2)
好的我明白了。我正在以相反的顺序加载它们,这使得顶点着色器成为第一个并将第二个着色。这使得ThreeJS在错误的位置添加了代码并且发生了错误。很遗憾让我调试了很长时间,因为错误似乎是通用的,但它可以通过Firebug获得完整生成的着色器文本,这对很多人有帮助。 但是感谢gaitat,它确实让我看起来更接近装载。
答案 1 :(得分:2)
这是一个很好的轻量级外部着色器加载器:https://github.com/codecruzer/webgl-shader-loader-js
答案 2 :(得分:0)
如果您指的是这篇文章https://github.com/mrdoob/three.js/issues/283(已有两年),那么您并没有完全遵循他们的解决方案。您是否尝试将“async:false”设置为ajax请求以获得同步请求,因为您可能尝试在实际加载之前执行着色器。