【问题标题】:THREE.JS, dynamically shader couldn't compile三.JS,动态着色器无法编译
【发布时间】:2014-10-25 19:48:50
【问题描述】:

我正在尝试使用粒子在 3D 场景中显示飘落的雪花。 我不想在 HTML 页面中创建着色器,因为我的项目不允许添加特定脚本,并且许多其他脚本正在动态加载,不包括在 HTML 页面中作为<script src=''>

我收到下一个错误(短:http://pastebin.com/KqiZze49,完整:http://pastebin.com/LZHhCnuh):

THREE.WebGLShader: Shader couldn't compile. three.min.js:592(anonymous function) 
three.min.js:592(anonymous function) three.min.js:588initMaterial three.min.js:566z
three.min.js:488renderBuffer three.min.js:544v three.min.js:483render 
three.min.js:556Rekod3DBuildings.Engine.renderScene rekod3d-new.js:668
(anonymous function) new-index.html:71
THREE.WebGLShader: gl.getShaderInfoLog() ERROR: 0:68: 'gl_FragColor' : undeclared identifier
ERROR: 0:68: 'assign' :  cannot convert from '4-component vector of float' to 'float'
ERROR: 0:68: 'gl_PointCoord' : undeclared identifier
ERROR: 0:68: 'texture2D' : no matching overloaded function found

您可以告诉我“伙计,看看控制台,您在控制台中发现了所有错误,只需 google。” 但是,奇怪的是,如果使用相同的着色器,它们在 JavaScript 中动态生成,但在 HTML 页面中作为准备部分使用,没有错误,结果是:

正如您在上面的屏幕截图中所看到的,如果 HTML 页面中包含着色器,则不会出现错误。 当然,从逻辑上讲,很明显我在 JavaScript 中创建着色器不正确,但也有一些奇怪的地方,让我们看看:

1)。如何在 JavaScript 中生成着色器?

http://pastebin.com/HncUKMUL

Rekod3DBuildings.Engine.prototype.createVertexShaderForSnowParticles = function( scriptId ) {
    if ( typeof scriptId === 'string' ) {
        var script = document.createElement( 'script' );
        script.id = scriptId;
        script.type = 'x-shader/x-vertex';
        script.textContent = '\
                attribute float size;\
                attribute float time;\
                attribute vec3 customColor;\
                uniform float globalTime;\
                varying vec3 vColor;\
                varying float fAlpha;\
                \
                void main() {\
                    vColor = customColor;\
                    vec3 pos = position;\
                    float localTime = time + globalTime;\
                    float modTime = mod( localTime, 1.0 );\
                    float accTime = modTime * modTime;\
                    pos.x += cos( modTime * 8.0 + ( position.z ) ) * 70.0;\
                    pos.z += sin( modTime * 6.0 + ( position.x ) ) * 100.0;\
                    fAlpha = ( pos.z ) / 1800.0;\
                    vec3 animated = vec3( pos.x, pos.y * accTime, pos.z );\
                    vec4 mvPosition = modelViewMatrix * vec4( animated, 1.0 );\
                    gl_PointSize = min( 150.0, size * ( 150.0 / length( mvPosition.xyz ) ) );\
                    gl_Position = projectionMatrix * mvPosition;\
                }';
        document.head.appendChild( script );        
        return script;
    }
    else
        console.error( 'Script id for the vertex shader isn\'t a type of `string`.' );
};
Rekod3DBuildings.Engine.prototype.createFragmentShaderForSnowParticles = function( scriptId ) {
    if ( typeof scriptId === 'string' ) {
        var script = document.createElement( 'script' );
        script.id = scriptId;
        script.type = 'x-shader/x-fragment';
        script.textContent = '\
                uniform vec3 color;\
                uniform sampler2D texture;\
                varying vec3 vColor;\
                varying float fAlpha;\
                \
                void main() {\
                    gl_FragColor = vec4( color * vColor, fAlpha );\
                    gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );\
                }';
        document.head.appendChild( script );        
        return script;
    }
    else
        console.error( 'Script id for the fragment shader isn\'t a type of `string`.' );
};

2)。创建好后,我们看看有没有添加?

看截图,着色器添加成功:

源码,准备粒子(http://pastebin.com/HgLHJWFu):

Rekod3DBuildings.Engine.prototype.setSnowParticles = function() {
    var map = THREE.ImageUtils.loadTexture( 'images/textures/snowflake.png' );

    var attributes = {
        size:        { type: 'f', value: [] },
        customColor: { type: 'c', value: [] },
        time:        { type: 'f', value: [] },
    };

    this.snowUniforms = {
        color:      { type: "c", value: new THREE.Color( 0x777777 ) },
        texture:    { type: "t", value: 0, texture: map },
        globalTime: { type: "f", value: 0.0 },
    };

    var shaderMaterial = new THREE.ShaderMaterial( {
        uniforms:       this.snowUniforms,
        attributes:     attributes,
        vertexShader:   document.getElementById( 'fragmentshader-airplane' ).textContent,
        fragmentShader: document.getElementById( 'vertexshader-airplane' ).textContent,
        blending:       THREE.AdditiveBlending,
        depthTest:      false,
        transparent:    true,
    });

    var geometry = new THREE.Geometry();

    for ( var i = 0; i < 10000; i++ )
        geometry.vertices.push( new THREE.Vector3( Math.random() * 18000 - 1500, -5000, Math.random() * 18000 ) );

    var particles = new THREE.PointCloud( geometry, shaderMaterial );
    particles.position.x = -5000; 
    particles.position.y = 5000;
    particles.position.z = -5000;

    var vertices = particles.geometry.vertices;
    var values_size = attributes.size.value;
    var values_color = attributes.customColor.value;
    var values_time = attributes.time.value;

    for( var v = 0; v < vertices.length; v++ ) {
        values_size[ v ] = 50 + Math.random() * 80;
        values_color[ v ] = new THREE.Color( 0xffffff );
        values_time[ v ] = Math.random();
    }

    this.scene.add( particles );
};

那么,怎么了?

请帮我提个建议。

【问题讨论】:

    标签: javascript three.js glsl webgl shader


    【解决方案1】:

    读取屏幕截图中的代码片段,您正在将 片段着色器文本 加载到 顶点着色器 中,反之亦然,因此着色器编译器会出现有关 gl_FragColor 的错误。我很确定扭转这些将有很大帮助。 :-)

    【讨论】:

      【解决方案2】:

      你真的需要通过 DOM 吗?

      我可以通过这种方式动态创建着色器

      THREE.SlicedBoxGeometry.prototype.GetVertexShader = function()  {
          var r = "";
      
          r+= "uniform vec4 uClipPlane1;              \n";
          r+= "uniform vec4 uClipPlane2;              \n";
          r+= "uniform vec4 uClipPlane3;              \n";
          r+= "varying vec3 vPos;                     \n";
      
      
          r+= "void main()                                                \n";
          r+= "{                                                  \n";
          r+= "   vec3 newPosition = position;                            \n";
      
          r+= "   if (position.x == " + this.width_half.toFixed(2) + " ) {            \n";
          r+= "       newPosition.x = - uClipPlane1.w / uClipPlane1.x;        \n";
          r+= "   }                                                   \n";
          r+= "   if (position.y == " + this.height_half.toFixed(2) + ") {            \n";
          r+= "       newPosition.y = - uClipPlane2.w / uClipPlane2.y;        \n";
          r+= "   }                                                   \n";
          r+= "   if (position.z == " + this.depth_half.toFixed(2) + ") {         \n";
          r+= "       newPosition.z = - uClipPlane3.w / uClipPlane3.z;        \n";
          r+= "   }                                                   \n";
          r+= "   gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );\n";
          r+= "   vPos = newPosition; \n";
          r+= "}\n";
      
          return r;
      }
      

      可能不是更好的方法,但它确实有效......

      在 DOM 中放置着色器的唯一原因是直接在

      <script type="something-not-javascript" id="someId">
      shader code goes here
      </script>
      

      然后您可以使用

      检索它
      var shaderSource = document.getElementById("someId").text
      

      您将它放在 DOM 中,因为这样您就可以对其进行编辑,而不必用引号等将每一行括起来......

      否则,如果你打算把它放在 JavaScript 中,那么上面的格式或类似的格式也可以工作

      THREE.SlicedBoxGeometry.prototype.GetVertexShader = function()  {
        return [  
          "uniform vec4 uClipPlane1;              ",
          "uniform vec4 uClipPlane2;              ",
          "uniform vec4 uClipPlane3;              ",
          "varying vec3 vPos;                     ",
          "",
          "",
          "void main()                                                ",
          "{                                                  ",
          "   vec3 newPosition = position;                            ",
      
          "   if (position.x == " + this.width_half.toFixed(2) + " ) {            ",
          "       newPosition.x = - uClipPlane1.w / uClipPlane1.x;        ",
          "   }                                                   ",
          "   if (position.y == " + this.height_half.toFixed(2) + ") {            ",
          "       newPosition.y = - uClipPlane2.w / uClipPlane2.y;        ",
          "   }                                                   ",
          "   if (position.z == " + this.depth_half.toFixed(2) + ") {         ",
          "       newPosition.z = - uClipPlane3.w / uClipPlane3.z;        ",
          "   }                                                   ",
          "   gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );",
          "   vPos = newPosition; ",
          "}",
        ].join("¥n");
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多