使用Three.js ShaderMaterial并编写片段着色器

时间:2014-03-27 07:46:10

标签: javascript opengl-es three.js glsl shader

关于使用Three.js ShaderMaterial,我有几个问题。

  1. 如何设置颜色? Three.js似乎通过制服和ShaderChunk提供了很多变量。我一直无法确定如何获得颜色。我认为它与设置任何其他材料的颜色没有太大的不同。我试图复制DashedLineMaterial中的内容,但它总是灰色。
  2. 如何设置可在for循环中访问的统一数组?这可能不是Three.js特定的。请参阅下面的问题。我在片段着色器上面描述它。
  3. 我正在尝试创建一种可以处理数组中特殊虚线模式存储的材质。负面是差距,正面是破灭。例如[ 0.5, -0.250, 0.250, -0.250 ]

    dashedLineShader.uniforms = THREE.UniformsUtils.merge( [
    
        THREE.UniformsLib[ 'common' ],
        THREE.UniformsLib[ 'fog' ],
        {
            'pattern': { type: 'fv1', value: pattern },  // pattern eg [1.0, -0.5]
            'patternSize': { type: 'i', value: pattern.length },
            'patternLength': { type: 'f', value: totalLength }
        }
    ] );
    

    顶点着色器似乎很好

    dashedLineShader.vertexShader = [
        'attribute float lineDistance;',
    
        'varying float vLineDistance;',
    
        THREE.ShaderChunk[ 'color_pars_vertex' ],
    
    'void main() {',
    
        THREE.ShaderChunk[ 'color_vertex' ],
            'vLineDistance = lineDistance;',
            'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
        '}'
    ].join('\n');
    

    当模式[i]为负时,我想要一个间隙。当模式[i]为正时,我想要一个破折号。 (最终0将是一个点,但首先是第一件事。)

    此着色器尚未根据输入设置颜色。我尝试使用ShaderChunks和从'虚线'中复制的代码。着色器包含在Three.js中,但它总是变成浅灰色。下面是带有一些测试代码的着色器。输出始终为实线蓝线,因此pattern [i]始终为0,我不确定原因。

    dashedLineShader.fragmentShader = [
        'uniform vec3 diffuse;',
        'uniform float opacity;',
    
        'uniform float pattern[' + pattern.length + '];',
        'uniform float patternLength;',
        'varying float vLineDistance;',
    
        'void main() {',
        'float pos = mod( vLineDistance, patternLength );',
    
        'for ( int i = 0; i < ' + pattern.length + '; i++ ) {',
            'pos = pos - abs( pattern[i] );',
            'if ( pos <= 0.0 ) {',
                'if ( pattern[i] < 0.0 ) {',
                    'gl_FragColor = vec4(1.0, 0.0, 0.0, opacity );',
                '} else if (pattern[i] > 0.0 ) {',
                    'gl_FragColor = vec4(0.0, 0.0, 1.0, opacity );',
                '} else {',
                    'gl_FragColor = vec4(0.0, 1.0, 0.0, opacity );',
                '}',
                'break;',
            '}',
        '}',
    '}'
    ].join('\n');
    

    令人困惑的部分。如何输入颜色?

    material = new THREE.ShaderMaterial({
        //vertexColors: THREE.NoColors,
        //color: color,
        //attributes: { color: { type: 'c', value: new THREE.Color(color) } },
        uniforms: lineType.uniforms,
        vertexShader: lineType.vertexShader,
        fragmentShader: lineType.fragmentShader
    });
    

    最后说明:这是我对着色器的第一次尝试。 Three.js ShaderMaterial没有完整记录。通过调试代码学习,但着色器很难调试。

0 个答案:

没有答案