【问题标题】:GLSL layering textures with alpha and no multiplication具有 alpha 且无乘法的 GLSL 分层纹理
【发布时间】:2017-03-17 16:23:01
【问题描述】:

我希望那里可能有一位 GLSL 专家可以帮助解决这个问题, 我正在尝试使用三个单独的纹理作为 alpha 通道(黑白图像)将三个纹理混合在一起,我希望它们堆叠在一起而不增加下面的亮度,但我使用threejs 和着色器材质类。我可以成功地在每一层上映射不透明度,但是当我尝试将它们组合起来时,它们似乎会奇怪地相乘和混合(这意味着在顶部应用每一层时,图像会变得更亮)

我在下面使用的纹理示例...

扩散:

Alpha 贴图(黑白):

我的片段着色器就是这样.....

            #ifdef GL_ES
            precision highp float;
            #endif

            uniform sampler2D tOne;
            uniform sampler2D tSec;
            uniform sampler2D tThi;

            uniform sampler2D aOne;
            uniform sampler2D aSec;
            uniform sampler2D aThi;

            varying vec2 vUv;


            void main(void)
            {
                vec3 c;
                vec3 d;
                vec3 e;
                vec3 f;

                vec3 m1;
                vec3 m2;

                vec4 Ca = texture2D(tOne, vUv);
                vec4 Cb = texture2D(tSec, vUv);
                vec4 Cc = texture2D(tThi, vUv);
                vec4 Aa = texture2D(aOne, vUv);
                vec4 Ab = texture2D(aSec, vUv);
                vec4 Ac = texture2D(aThi, vUv);

                c = (Ca.rgb * Aa.rgb)*1.0;
                d = (Cb.rgb * Ab.rgb)*1.0;
                e = (Cc.rgb * Ac.rgb)*1.0;

                f = (c.rgb + d.rgb + e.rgb * (1.0))*1.0;

                gl_FragColor= vec4(f, 1.0);

            }

如果我用......运行它

gl_FragColor= vec4(c, 1.0);

结果:

gl_FragColor= vec4(d, 1.0);

结果:

gl_FragColor= vec4(e, 1.0);

结果:

我可以看到具有正确不透明度和 rgb 值的每一层 但正如我所说,我无法将它们组合在一起以使它们保持在正确的 rgb 值,它们似乎正在成倍增加并变得更亮。

我在某处读过关于将混合模式指定为默认打开的信息。但我不知道你会如何在threejs之类的东西上关闭它。

当前结果:

期望的结果:

或者也许我的计算只需要修正图层的组合

对此有任何帮助将不胜感激?

感谢大家的宝贵时间!

-里斯·托马斯


工作!!

MarGenDo - 你是一个明星!!! ,你说得对,我必须开始添加 alpha 的倒置部分才能让它进入下一层。

按照您的建议,一切正常,修改后的 Alpha 版!

正确的字母:

虽然我确信我可以尝试将 alpha 与着色器合并,但你的逻辑绝对合理!

再次感谢MarGenDo


所以再次工作

首先感谢 MarGenDo 和传说中的 gman,最适合我的解决方案是 gmans,因为我无法处理减去 alpha 等问题,mix 命令工作得很好!!!此外,如果您想查看它的实际效果,请查看http://www.polygonprophecy.com/html5/Island - 最好在手机上查看,因为它允许您放大和缩小(捏合和打孔)以及绕岛旋转(两根手指旋转),它的现在非常快速地使用良好的着色器编程(再次感谢你们!!!),希望在坏手机上也能快速工作! gman 你是一个该死的明星!

请注意,这是我的最终结果着色器:-

        #ifdef GL_ES
        precision highp float;
        #endif

        uniform sampler2D tOne;
        uniform sampler2D tSec;
        uniform sampler2D tThi;

        uniform sampler2D aOne;
        uniform sampler2D aSec;
        uniform sampler2D aThi;

        varying vec2 vUv;


        void main(void)
        {
            vec4 Ca = texture2D(tOne, vUv);
            vec4 Cb = texture2D(tSec, vUv);
            vec4 Cc = texture2D(tThi, vUv);
            vec4 Aa = texture2D(aOne, vUv);
            vec4 Ab = texture2D(aSec, vUv);
            vec4 Ac = texture2D(aThi, vUv);
            vec4 g;

            g = vec4(0);

            g = mix(g, Ca, Aa);
            g = mix(g, Cb, Ab);
            g = mix(g, Cc, Ac);

            gl_FragColor= vec4(g.rgb, Aa.rgb+Ab.rgb+Ac.rgb);

        }

【问题讨论】:

    标签: three.js glsl webgl


    【解决方案1】:

    我认为这可能适用于您的原始 Alpha 纹理

                vec4 Ca = texture2D(tOne, vUv);
                vec4 Cb = texture2D(tSec, vUv);
                vec4 Cc = texture2D(tThi, vUv);
                vec4 Aa = texture2D(aOne, vUv);
                vec4 Ab = texture2D(aSec, vUv);
                vec4 Ac = texture2D(aThi, vUv);
    
                // This is the default color. 
                // The color when all the alphas are zero
                f = vec4(0);
    
                f = mix(f, Ca, Aa);
                f = mix(f, Cb, Ab);
                f = mix(f, Cc, Ac);
    
                gl_FragColor= vec4(f, 1.0);
    

    试一试

    "use strict";
    var gl = twgl.getWebGLContext(document.getElementById("c"));
    var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
    
    var arrays = {
      position: [-1, -1, 0, 1, -1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1, 1, 0],
    };
    var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
    
    var textures = twgl.createTextures(gl, {
      tOne: { src: "https://i.imgur.com/P5bZckC.jpg", crossOrigin: "", },
      tSec: { src: "https://i.imgur.com/2FI5CHY.jpg", crossOrigin: "", },
      tThi: { src: "https://i.imgur.com/YV0Wrxn.jpg", crossOrigin: "", },
      aOne: { src: "https://i.imgur.com/Kzk0cEx.jpg", crossOrigin: "", },
      aSec: { src: "https://i.imgur.com/weFi9dr.jpg", crossOrigin: "", },
      aThi: { src: "https://i.imgur.com/Ebkh1j1.jpg", crossOrigin: "", },
    }, function() {
      
      var uniforms = {
        tOne: textures.tOne,
        tSec: textures.tSec,
        tThi: textures.tThi,
        aOne: textures.aOne,
        aSec: textures.aSec,
        aThi: textures.aThi,
      };
    
      gl.useProgram(programInfo.program);
      twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
      twgl.setUniforms(programInfo, uniforms);
      twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo);
    
    });
    <script id="vs" type="notjs">
    attribute vec4 position;
    
    varying vec2 vUv;
    
    void main() {
      gl_Position = position;
      vUv = position.xy * 0.5 + 0.5;
    }
      </script>
      <script id="fs" type="notjs">
    precision mediump float;
    
    
    uniform sampler2D tOne;
    uniform sampler2D tSec;
    uniform sampler2D tThi;
    
    uniform sampler2D aOne;
    uniform sampler2D aSec;
    uniform sampler2D aThi;
    
    varying vec2 vUv;
    
    
    void main(void)
    {
      vec4 f;
    
      vec4 Ca = texture2D(tOne, vUv);
      vec4 Cb = texture2D(tSec, vUv);
      vec4 Cc = texture2D(tThi, vUv);
      vec4 Aa = texture2D(aOne, vUv);
      vec4 Ab = texture2D(aSec, vUv);
      vec4 Ac = texture2D(aThi, vUv);
    
      // This is the default color. 
      // The color when all the alphas are zero
      f = vec4(0);
    
      f = mix(f, Ca, Aa);
      f = mix(f, Cb, Ab);
      f = mix(f, Cc, Ac);
    
      gl_FragColor= vec4(f.rgb, 1.0);
    }
      </script>
      <script src="https://twgljs.org/dist/twgl.min.js"></script>
    <canvas id="c" width="128" height="128"></canvas>

    【讨论】:

    • 嗨,gman,我确实尝试过,不幸的是,threejs 着色器似乎抛出错误或使用混合运算符进行排序。然而,我已经开始使用着色器以另一种方式合并 alpha,仍然有一点困难,但今晚会尝试发布一些东西,这取决于我能走多远。即使代码对我来说似乎合乎逻辑,它似乎也遇到了类似的问题。因此,我将再次尝试发布一些希望自己或 margendo 可以帮助我的东西。谢谢-Rhys Thomas @MarGenDo
    • 啊,我的坏人,它确实有效,完美,事实上我只需要改变这条线.... gl_FragColor= vec4(f, 1.0);到 gl_FragColor= vec4(f.rgb, 1.0);
    • 再次感谢将在家里再次尝试并发布结果
    【解决方案2】:

    嗯,你的问题在于你的 alpha 纹理。你必须稍微改变它们。例如,在中间,您将所有三个纹理的颜色值相加,但您只想查看其中一个(岩石纹理)。除了岩石之外的每个 alpha 纹理中间都应该是黑色的。

    这是一个沙子 alpha 纹理应该是什么样子的示例。

    (对不起,我的画很丑,但我希望你明白我的意思)

    【讨论】:

    • 啊,我明白了,我当然应该在每一层上组合这些 alpha 纹理,很好!今晚我会试一试,然后回复你!
    • 谢谢!如果您有任何其他问题,请随时提问:)
    猜你喜欢
    • 2014-04-03
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多