0

我正在尝试使用 GLSL 语言完成位置设置。

首先,当我看到这样的台词时:

attribute vec3 aVertexPosition;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;

void main( void ) {
    gl_Position = uPMatrix * uMVMatrix * vec4( aVertexPosition, 1.0 );
}

我想,我可以aVertexPosition从函数输入中设置。另外,我正在使用 GLSL 1.2(OpenGL ES 和 WebGL 也使用它),并且该项目是使用 JavaScript/WebGL 的 web one。

我可能已经为您未来的问题说了这些信息,但我认为,对于这种情况,主要的应用程序逻辑语言(C++ 或 JS)是什么并不重要,因为问题恰好发生在阴影部分不符合应用的逻辑之一。

所以......回到代码行......当我看到上面的行时,我想,我可以把它改成这样:

ClassName.prototype.createShaderVs = function( objectPosition ) {
    var script = document.createElement( 'script' );
    script.id = 'shader-vs';
    script.type = 'x-shader/x-vertex';
    script.text = 'varying vec3 aVertexPosition;\
                    uniform mat4 uMVMatrix;\
                    uniform mat4 uPMatrix;\
                    void main( void ) {\
                        aVertexPosition = vec3('
                           + objectPosition.x + ','
                           + objectPosition.y + ','
                           + objectPosition.z + ');\
                        gl_Position = uPMatrix * uMVMatrix * vec4( aVertexPosition, 1.0 );\
                    }';
    document.head.appendChild( script );
};

但是,当我尝试执行这样的逻辑时,控制台中出现错误:

在此处输入图像描述

为什么我认为它可以工作?因为当我尝试类似的事情时fragment-shader,当我为网格设置颜色时,它工作得很好:

ClassName.prototype.createShaderFs = function( colorSchema ) {
    var script = document.createElement( 'script' );
    script.id = 'shader-fs';
    script.type = 'x-shader/x-fragment';
    script.text = 'precision mediump float;\
                    void main( void ) {\
                        gl_FragColor = vec4('
                            + colorSchema.r + ','
                            + colorSchema.g + ','
                            + colorSchema.b + ','
                            + colorSchema.a + ');\
                    }';
    document.head.appendChild( script );
};

所以设置颜色fragment-shader确实有效,但设置位置vertex-shader- 不,为什么?

另外,我认为,通过 GLSL 进行位置设置的逻辑不能看起来像那样,但这只是我的建议。

还有一种方法不是从 GLSL 而是从 JS 部分设置位置:

mat4.identity( object3d.mvMatrix );
mat4.translate( object3d.mvMatrix, [ 0, 0.0, -7.0 ] );

但如果可能的话,我想知道通过 GLSL 语言设置它。因为我正在为我的程序准备 OO 解决方案,并且希望使用我的库的用户能够从构造函数中设置对象的位置,例如:

var triangle = new Triangle({
    position: { x: inputX, y: inputY; z: inputZ },
    ...etc...
});
this.scene.add( triangle );
4

1 回答 1

0

你显然没有完全理解着色器是如何工作的。

每个顶点调用一次
顶点着色器,顶点着色器阶段的输入是当前顶点的属性

每个片段调用一次片段
着色器,片段着色器阶段的输入是变化的变量,这些变量总是为当前处理的片段计算和插值(根据构成当前片段所属基元的多边形的属性) .

两个着色器阶段都可以使用统一变量,这些变量不会改变每个顶点/每个片段,但在所有这些变量中都是统一的(相同的)。


所以,让我试着解释一下为什么你写的代码是不可能工作的。

您创建顶点着色器并对其进行编译,然后创建片段着色器并对其进行编译,然后将顶点和片段着色器链接到一个着色器程序中。该程序是将要执行的代码,它会将模型的属性和制服作为其输入(如函数调用的参数)。但请注意,这些着色器和程序已经编译

您的片段着色器代码有效,因为您没有将统一变量传递给它,而是将变量硬编码到着色器的代码中并编译它。

问题是,顶点着色器仍然期望属性作为输入来使用,并且您不能对其中的变量进行硬编码。

请查看着色器编程教程以更好地理解它们。

希望这可以帮助。

于 2014-05-15T12:24:16.260 回答