三个可与 controlnet 一起使用的普通着色器

问题描述 投票:0回答:2

我怎样才能写这个普通的着色器,这样它就可以绕过 controlnet 的预处理器 https://jsfiddle.net/lunchie/mpuanxL3/4/


    skinnedMesh.material = new THREE.ShaderMaterial( {
        vertexShader: [
              '#include <skinning_pars_vertex>',
              'varying vec3 vNormal;',
    
              'void main() {',
    
                '#include <skinbase_vertex>',
                '#include <begin_vertex>',
                '#include <skinning_vertex>',
                '#include <project_vertex>',
    
                'mat4 skinMatrix = boneMatX * skinWeight.x + boneMatY * skinWeight.y + boneMatZ * skinWeight.z + boneMatW * skinWeight.w;',
                'vNormal = (skinMatrix * vec4(normal, 0.0)).xyz;',
              '}'
               ].join( '\n' ),
               fragmentShader: [
                 'varying vec3 vNormal;',
                 'void main() {',
                 '       gl_FragColor = vec4(abs(vNormal), 1.0);',
                 '}'
               ].join( '\n' ),
             skinning: true
        } );

它似乎与 controlnet 用于法线的格式不同,它给出这样的图像

javascript animation three.js shader vertex-shader
2个回答
2
投票

Three.js 和大多数 3D 渲染器显示其法线的方式是将范围从

[-1, 1]
移动到
[0, 1]
的可见颜色范围。这是一个简单的等式:

gl_FragColor = vec4(vNormal * 0.5 + 0.5, 1.0);

或者有时你的 skinnnedMesh 可能会拉伸法线,所以你想将它们缩小到 1 的长度:

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

这应该是你的结果,就像

MeshNormalMaterial


0
投票

要绕过 THREE.js 材质的顶点着色器中的预处理器,您可以将 #include 指令替换为相应的代码片段。以下是您可以在小提琴中修改着色器的方法:

skinnedMesh.material = new THREE.ShaderMaterial({
    vertexShader: `
        attribute vec4 skinIndex;
        attribute vec4 skinWeight;

        uniform mat4 bindMatrix;
        uniform mat4 bindMatrixInverse;
        uniform mat4 boneMatX;
        uniform mat4 boneMatY;
        uniform mat4 boneMatZ;
        uniform mat4 boneMatW;

        varying vec3 vNormal;

        void main() {
            vec4 skinVertex = bindMatrix * vec4(position, 1.0);

            mat4 skinMatrix = boneMatX * skinWeight.x + boneMatY * skinWeight.y + boneMatZ * skinWeight.z + boneMatW * skinWeight.w;

            skinVertex = skinMatrix * skinVertex;
            skinVertex = bindMatrixInverse * skinVertex;

            vNormal = (skinMatrix * vec4(normal, 0.0)).xyz;

            gl_Position = projectionMatrix * modelViewMatrix * skinVertex;
        }
    `,
    fragmentShader: `
        varying vec3 vNormal;

        void main() {
            gl_FragColor = vec4(abs(vNormal), 1.0);
        }
    `,
    skinning: true
});

在这个修改过的着色器中,我用它们引用的代码片段替换了#include 指令。我还将顶点着色器转换为模板字符串,以便它可以跨越多行。

© www.soinside.com 2019 - 2024. All rights reserved.