【问题标题】:Problems loading shaders from external file in ThreeJS从 ThreeJS 中的外部文件加载着色器的问题
【发布时间】:2013-02-12 12:55:35
【问题描述】:

之前(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 方法之间的内容几乎相同(只是一些制表符和换行符),它也会显示有关未定义变量的语法错误。那么是什么原因造成的呢?

【问题讨论】:

    标签: three.js webgl shader


    【解决方案1】:

    好的,我想通了。我以相反的顺序加载它们,这使顶点着色器成为第一个,片段化成为第二个。这使得 ThreeJS 在错误的位置添加代码并导致错误。遗憾的是,它让我调试了很长时间,因为这些错误似乎很笼统,但可以通过 Firebug 获得完整的生成着色器文本,这很有帮助。 但感谢 gaitat,它确实让我在加载时看得更仔细。

    【讨论】:

      【解决方案2】:

      这是一个不错的轻量级外部着色器加载器:https://github.com/codecruzer/webgl-shader-loader-js

      【讨论】:

      • 这仍然依赖于将它添加到 html 脚本标签中——有没有办法在不将文件添加到脚本标签中的情况下使用它?
      【解决方案3】:

      如果您指的是这篇帖子https://github.com/mrdoob/three.js/issues/283(已有两年历史),您并没有完全遵循他们的解决方案。您是否尝试过将“async: false”设置为您的 ajax 请求以获得同步请求,因为您可能试图在着色器实际加载之前执行它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-05-14
        • 2012-01-18
        • 2014-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多