【问题标题】:Normalize function in webGL not working (THREE.js)webGL 中的规范化功能不起作用(THREE.js)
【发布时间】:2013-01-28 08:49:39
【问题描述】:

我目前正致力于在 THREE.JS 中创建一个着色器,它的作用类似于普通着色器,但使用颜色作为输入来定义它的着色方式。

以下是导致问题的代码,然后是对我这样做的原因以及我认为导致问题的原因的详细解释:

fragmentShader: [

        "uniform float opacity;",
        "varying vec3 vNormal;",
        "uniform vec3 color;",
        "void main() {",
            //THIS IS WHAT I THINK IS SCREWING UP EVERYTHING

            //Can I not call normalize with that complex
            //of equations within a normalize function?

            "gl_FragColor = vec4( normalize(color.r + (vNormal.x*color.r)*.5, color.g + (vNormal.y*color.g)*.5, color.b + (vNormal.z*color.b)*.5), opacity );",

        "}"

    ].join("\n")

更长的描述:

我在THREE.shaderLib中基本使用和普通shader一样的代码,如下:

'normal': {

    uniforms: {

        "opacity" : { type: "f", value: 1.0 }

    },

    vertexShader: [

        "varying vec3 vNormal;",

        "void main() {",

            "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
            "vNormal = normalize( normalMatrix * normal );",

            "gl_Position = projectionMatrix * mvPosition;",

        "}"

    ].join("\n"),

    fragmentShader: [

        "uniform float opacity;",
        "varying vec3 vNormal;",

        "void main() {",

            "gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",

        "}"

    ].join("\n")

},

我使用的基本上是这个,但添加了颜色方面,它在定义新着色器的函数中调用,如下所示:

function assignNewShader(color){
var colorAssign = new THREE.Color(color)

THREE.ShaderLib[color] = {

    uniforms: {

        "opacity" : { type: "f", value: 1.0 },
        "color" : { type: "c", value: colorAssign },


    },

    vertexShader: [

        "varying vec3 vNormal;",

        "void main() {",

            "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
            "vNormal = normalMatrix * normal;",

            "gl_Position = projectionMatrix * mvPosition;",

        "}"

    ].join("\n"),

    fragmentShader: [

        "uniform float opacity;",
        "varying vec3 vNormal;",
        "uniform vec3 color;",
        "void main() {",

            "gl_FragColor = vec4(color.r + (vNormal.x*color.r)*.5, color.g + (vNormal.y*color.g)*.5, color.b + (vNormal.z*color.b)*.5, opacity );",

        "}"

    ].join("\n")

}


}

您可以看到最大的区别在于“fragmentShader”部分,其中 vNormal 用于使 gl_FragColor 与函数中给出的颜色相似(但不完全相同)。

我的问题是:随着对象被“缩放”,这种颜色差异会变得越来越大,以至于所有颜色都尽可能亮。因此,我尝试对代码的“fragmentShader”部分执行以下操作:

fragmentShader: [

        "uniform float opacity;",
        "varying vec3 vNormal;",
        "uniform vec3 color;",
        "void main() {",

            "gl_FragColor = vec4( normalize(color.r + (vNormal.x*color.r)*.5, color.g + (vNormal.y*color.g)*.5, color.b + (vNormal.z*color.b)*.5), opacity );",

        "}"

    ].join("\n")

当我这样做时,我会遇到大量错误,包括:

错误:0:37:'normalize':找不到匹配的重载函数 错误:0:37:'constructor':没有为构造提供足够的数据

WebGL:INVALID_VALUE:attachShader:没有对象或对象被删除

无法初始化着色器 VALIDATE_STATUS: false,gl 错误 [1281]

WebGL:INVALID_OPERATION:getUniformLocation:程序未链接

我在进入 THREE 的 webGL 部分时肯定是一头雾水,但在我看来,这种改变片段着色器的模式应该可以工作。有没有人知道为什么它可能不会?

【问题讨论】:

    标签: three.js webgl fragment-shader normalize


    【解决方案1】:

    Normalize 采用 vec3 而不是 vec4。

    【讨论】:

    • normalize(color.r + (vNormal.xcolor.r).5, color.g + (vNormal.ycolor.g).5, color.b + (vNormal.zcolor.b).5) 这不是 vec3 吗?
    • 我可能记错了括号
    • 我假设您已尝试将该行换成 vec4(1,1,1,1) 以查看是否通过。
    • 是的,我不使用 normalize 的那个也可以。似乎只是规范化功能搞砸了......
    • 你能把不透明度设为 1 看看会发生什么。否则,您的颜色和 vNormals 向量的验证范围是多少。
    猜你喜欢
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多