Javascript 使用Three.js着色器材质并编写片段着色器

Javascript 使用Three.js着色器材质并编写片段着色器,javascript,opengl-es,three.js,glsl,shader,Javascript,Opengl Es,Three.js,Glsl,Shader,关于使用Three.js ShaderMaterial,我有几个问题 如何设置颜色?Three.js似乎通过制服和ShaderChunk提供了很多变量。我一直无法确定如何获得颜色。我认为它与设置任何其他材质的颜色没有太大区别。我试图复制虚线材质中的内容,但它总是显示为灰色 如何设置可以在for循环中访问的统一数组?这可能不是特定于Three.js的。请参见下面的问题。我在片段着色器上面描述它 我试图创建一种可以处理数组中特殊虚线图案存储的材质。负片是空白,正片是破折号。例如[0.5,-0.250

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

  • 如何设置颜色?Three.js似乎通过制服和ShaderChunk提供了很多变量。我一直无法确定如何获得颜色。我认为它与设置任何其他材质的颜色没有太大区别。我试图复制虚线材质中的内容,但它总是显示为灰色
  • 如何设置可以在for循环中访问的统一数组?这可能不是特定于Three.js的。请参见下面的问题。我在片段着色器上面描述它
  • 我试图创建一种可以处理数组中特殊虚线图案存储的材质。负片是空白,正片是破折号。例如
    [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中包含的“虚线”着色器复制的代码,但它总是变成浅灰色。下面是带有一些测试代码的着色器。输出总是一条蓝色实线,所以模式[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');
    

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

    制服变量
    漫反射
    是颜色。如何使用着色器材质设置特定实体的颜色<代码>颜色:0x1c30da?如果我使用
    gl\u FragColor=vec4(漫反射,不透明度)它总是显示为浅灰色。我想在这里。这把小提琴应该会让你走上正确的道路:。谢谢。我就快到了。让我偏离正轨的是,画布渲染器不需要调用
    computelinedistance()
    。另外,linedistance的属性是自动处理的,您不必将其传递到
    ShaderMaterial({…})
    。正因为如此,我认为它是在某处自动调用的。最近才发现vLineDistance的结果是0。这足够让我走完剩下的路了。谢谢说得好。我很想知道你是如何选择将数据传递到着色器的。
    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
    });