2017-03-31 81 views
0

我想有准备着色器组件(用于多采样特)WebGL的着色检查纹理状态sampler2D

在我使用(激活和绑定)仅2纹理图像我的当前状态。

,但此行:

gl_FragColor = textureColor + textureColor1 + textureColor2; 

制造麻烦与我的纹理视图的纹理我从没有结合的样品textureColor2。

在着色器中无法使用console.log或任何其他标准调试方法。我有兴趣了解有关着色器的更多信息,但我被卡住了。

代码:

...

precision mediump float; 

varying vec2 vTextureCoord; 
varying vec3 vLightWeighting; 

uniform sampler2D uSampler; 
uniform sampler2D uSampler1; 
uniform sampler2D uSampler2; 
uniform sampler2D uSampler3; 
uniform sampler2D uSampler4; 
uniform sampler2D uSampler5; 
uniform sampler2D uSampler6; 
uniform sampler2D uSampler7; 
uniform sampler2D uSampler8; 
uniform sampler2D uSampler9; 
uniform sampler2D uSampler10; 
uniform sampler2D uSampler11; 
uniform sampler2D uSampler12; 
uniform sampler2D uSampler13; 


void main(void) { 


vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); 
vec4 textureColor1 = texture2D(uSampler1, vec2(vTextureCoord.s, vTextureCoord.t)); 
vec4 textureColor2 = texture2D(uSampler2, vec2(vTextureCoord.s, vTextureCoord.t)); 

// Need help here 
gl_FragColor = textureColor + textureColor1 ; 

//gl_FragColor = textureColor + textureColor1 + textureColor2; 

//修订问题

if ( ${numTextures} == 1) 
     { 
      gl_FragColor = textureColor; 
     } 
    else if (${numTextures} == 2) 
     { 
      gl_FragColor = textureColor + textureColor1; 
     } 
    else if (${numTextures} == 3) 
     { 
      gl_FragColor = textureColor + textureColor1 + textureColor2; 
     } 

//我用简单实用的if else现在。

//我通过值到着色器上负载

// i的运行时仍然无法更新着色

////////////////// /////////////////////

//这是绘制函数段:

for (var t=0;t<object.textures.length;t++) { 

eval(" world.GL.gl.activeTexture(world.GL.gl.TEXTURE"+t+"); ") 
    world.GL.gl.bindTexture(world.GL.gl.TEXTURE_2D, object.textures[t]); 
    world.GL.gl.pixelStorei(world.GL.gl.UNPACK_FLIP_Y_WEBGL, false); 
    world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_MAG_FILTER, world.GL.gl.NEAREST); 
    world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_MIN_FILTER, world.GL.gl.NEAREST); 
    world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_WRAP_S, world.GL.gl.CLAMP_TO_EDGE); 
    world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_WRAP_T, world.GL.gl.CLAMP_TO_EDGE); 
    // -- Allocate storage for the texture 
    //world.GL.gl.texStorage2D(world.GL.gl.TEXTURE_2D, 1, world.GL.gl.RGB8, 512, 512); 
    //world.GL.gl.texSubImage2D(world.GL.gl.TEXTURE_2D, 0, 0, 0, world.GL.gl.RGB, world.GL.gl.UNSIGNED_BYTE, image); 
    //world.GL.gl.generateMipmap(world.GL.gl.TEXTURE_2D); 
    world.GL.gl.uniform1i(object.shaderProgram.samplerUniform, t); 

} 

...

也许在运行最好的方法是用object.textures数组操作?!

  • 最后:

    • 用新标志覆盖着色器
    • 编译着色器 新材料更新
+1

你可能想要混合你的颜色,而不是总结它们。我有许多着色器示例[这里](http://blog.2pha.com/experimenting-threejs-shaders-and-shadermaterial),还有一些在我的jsfiddle [HERE](https://jsfiddle.net/user/2pha /拨弄/)。请注意,这些示例适用于旧版本的three.js,并且照明信息发送到着色器的方式已更改。 – 2pha

+0

谢谢你,很好的例子,我会探讨这个肯定... –

回答

1

什么是你想实现什么?

使用大量纹理的正常的方法是使用其上覆盖朝向的this article

否则底部的texture atlas,没有就没有办法,如果一个纹理着色器加载到检测。你需要传递你自己的标志。例如

uniform bool textureLoaded[NUM_TEXTURES]; 

uniform float textureMixAmount[NUM_TEXTURES]; 

我会使用一个纹理图集但如果我是你,除非你真的知道你在做一些独特的,实际上需要14个纹理。

在飞行中生成着色器也很常见。几乎所有的游戏引擎都这样做。 Three.js也是如此。因此,不要打开和关闭纹理,而要编写一些代码来生成N个纹理的着色器。然后当你只有一个纹理生成1纹理着色器,当你有2生成2纹理着色器等等。这对于GPU而言比拥有14纹理着色器并试图关闭13纹理更加高效。

例子:

// note, I'm not recommending this shader, only showing some code 
 
// that generates a shader 
 

 
function generateShaderSrc(numTextures) { 
 

 
    return ` 
 
    // shader for ${numTextures} textures 
 
    precision mediump float; 
 
    
 
    varying vec2 vTextureCoord; 
 
    varying vec3 vLightWeighting; 
 

 
    uniform sampler2D uSampler[${numTextures}]; 
 
    uniform float uMixAmount[${numTextures}]; 
 
    
 
    void main() { 
 
     vec4 color = vec4(0); 
 

 
     for (int i = 0; i < ${numTextures}; ++i) { 
 
     vec4 texColor = texture2D(uSampler[i], vTextureCoord); 
 
     color = mix(color, texColor, uMixAmount[i]); 
 
     } 
 
     
 
     gl_FragColor = color; 
 
    } 
 
    `; 
 
} 
 

 
log(generateShaderSrc(1)); 
 
log(generateShaderSrc(4)); 
 

 
function log(...args) { 
 
    const elem = document.createElement("pre"); 
 
    elem.textContent = [...args].join(' '); 
 
    document.body.appendChild(elem); 
 
}

这是一个非常简单的例子。真正的着色器生成器通常会进行更多的字符串操作。

您应该了解WebGL 1.0只需要支持8个纹理单元。 According to webglstats about 15% of devices only support 8 texture units所以你可能想检查用户有多少纹理单元,并警告他们你的应用程序如果他们的应用程序需求低于你的应用程序就不会工作。