Three.js 具有alpha和无乘法的GLSL分层纹理
我希望有一位GLSL大师能帮上忙, 我正在尝试使用三个单独的纹理作为alpha通道(黑白图像)将三个纹理混合在一起,我希望它们相互叠加,而不增加下面一个纹理的亮度,但是我使用了threejs和ShaderMaterial类。我可以成功地在每一层上映射不透明度,但当我尝试将它们组合在一起时,它们似乎会以奇怪的方式成倍增加和混合(这意味着图像在每一层应用于顶部时会变得更亮) 下面是我正在使用的纹理示例 扩散的: Alpha贴图(黑白): 我的片段着色器就是这样Three.js 具有alpha和无乘法的GLSL分层纹理,three.js,glsl,webgl,Three.js,Glsl,Webgl,我希望有一位GLSL大师能帮上忙, 我正在尝试使用三个单独的纹理作为alpha通道(黑白图像)将三个纹理混合在一起,我希望它们相互叠加,而不增加下面一个纹理的亮度,但是我使用了threejs和ShaderMaterial类。我可以成功地在每一层上映射不透明度,但当我尝试将它们组合在一起时,它们似乎会以奇怪的方式成倍增加和混合(这意味着图像在每一层应用于顶部时会变得更亮) 下面是我正在使用的纹理示例 扩散的: Alpha贴图(黑白): 我的片段着色器就是这样 #ifde
#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);
结果:
或
结果:
或
结果:
我可以看到每一层正确的不透明度和rgb值
但正如我所说,我很难将它们组合在一起,使它们保持在正确的rgb值,它们似乎在此刻倍增并变得更亮
我在某个地方读到过关于将blendmode指定为默认打开状态的内容。但我不知道你会如何关闭像3J这样的东西
当前结果:
预期结果:
或者我的计算只是需要修正层的组合
如果您能帮上忙,我们将不胜感激
谢谢大家抽出时间
-里斯·托马斯
工作!! 玛根多-你是一位明星,你是对的,我必须开始添加alpha的反转部分,以便它能够进入下一层 这里是所有的工作和修改阿尔法正如你所建议的 正确的字母: 虽然我确信我可以尝试将Alpha与着色器进行一些合并,但您的逻辑绝对正确 再次感谢MarGenDo
这又起作用了 首先感谢MarGenDo和传奇的gman,对我来说最有效的解决方案是gman,因为我不能处理负号字母等等,mix命令工作得很好!!!此外,如果你想看到它的行动,请看一看-最好是在手机上观看,因为它允许你放大和缩小(捏和冲压),也可以围绕岛屿旋转(两个手指旋转),它现在非常快速的使用良好的着色器编程(再次感谢你们!!!),希望在一个坏的手机上也能快速工作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);
}
你的问题在于你的阿尔法纹理。你必须稍微改变一下。例如,在中间,你添加了所有三个纹理的颜色值,但是你只想看到其中一个(岩石纹理)。除了岩石以外,每一个阿尔法纹理都应该是黑色的。 这是一个示例,说明了sand alpha纹理的外观
(对不起,我的画很难看,但我希望你明白我的意思)我想这可能适用于你原来的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);
试一试
“严格使用”;
var gl=twgl.getWebGLContext(document.getElementById(“c”));
var programInfo=twgl.createProgramInfo(gl,[“vs”,“fs]”);
变量数组={
位置:[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{
音调:{src:'https://i.imgur.com/P5bZckC.jpg,交叉原点:,},
tSec:{src:“https://i.imgur.com/2FI5CHY.jpg,交叉原点:,},
tThi:{src:“https://i.imgur.com/YV0Wrxn.jpg,交叉原点:,},
aOne:{src:“https://i.imgur.com/Kzk0cEx.jpg,交叉原点:,},
aSec:{src:“https://i.imgur.com/weFi9dr.jpg,交叉原点:,},
aThi:{src:“https://i.imgur.com/Ebkh1j1.jpg,交叉原点:,},
},函数(){
变量={
色调:纹理,色调,
tSec:textures.tSec,
tThi:textures.tThi,
aOne:textures.aOne,
aSec:textures.aSec,
阿西:纹理,阿西,
};
总账使用程序(programInfo.program);
twgl.setBuffersAndAttributes(总帐、程序信息、缓冲信息);
twgl.设置制服(程序信息、制服);
twgl.drawBufferInfo(总图,总图三角形,bufferInfo);
});代码>
属性向量4位置;
可变vec2 vUv;
void main(){
gl_位置=位置;
vUv=位置.xy*0.5+0.5;
}
精密中泵浮子;
均匀的二维音调;
均匀采样器;
均匀采样2d-tThi;
均匀采样;
均匀采样;
均匀取样器;
可变vec2 vUv;
真空总管(真空)
{
vec4f;
vec4 Ca=纹理2D(色调,vUv);
vec4 Cb=纹理2d(tSec,vUv);
vec4 Cc=纹理2d(tThi,vUv);
vec4 Aa=纹理2d(aOne,vUv);
vec4 Ab=纹理2d(aSec,vUv);
vec4 Ac=纹理2d(aThi,vUv);
//这是默认颜色。
//所有字母为零时的颜色
f=vec4(0);
f=混合物(f,Ca,Aa);
f=混合物(f、Cb、Ab);
f=混合物(f、Cc、Ac);
gl_FragColor=vec4(f.rgb,1.0);
}
啊,我明白了,我当然应该在每一层上结合这些alpha纹理,捕捉得很好!!!今晚我会试一试,然后再打给你!!谢谢如果您有任何其他问题,请随时提问:)嗨,gman,我确实尝试过这一点。不幸的是,threejs着色器似乎抛出错误或使用混合运算符排序。不过,我已经开始用另一种方式合并Alpha,仍然有点困难,但今晚将尝试发布一些东西,具体取决于我能走多远。它似乎遇到了类似的问题,尽管代码对我来说似乎是合乎逻辑的。所以我会再次尝试发布一些东西,希望你自己或margendo能帮助我。谢谢-Rhys Thomas@MarGenDoAh我的坏gman它确实有效,完美事实上我只是不得不改变这一行。。。。gl_FragColor=vec4(f,1.0);到gl_FragColor=vec4(f.rgb,1.0);再次感谢您,我们将在家中再次尝试并发布结果
#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);
}
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);