Int value for texture array

Is webgl2 already support int value for texture array?
I use this code fragmant shader:

const int count=6;
uniform sampler2D map[count];
varying float tex_num;

void main(){
if(tex_num==0.0){ gl_FragColor=texture2D(map[0],vUv); }
else if(tex_num==1.0){ gl_FragColor=texture2D(map[1],vUv); }
else if(tex_num==2.0){ gl_FragColor=texture2D(map[2],vUv); }
else if(tex_num==3.0){ gl_FragColor=texture2D(map[3],vUv); }
else if(tex_num==4.0){ gl_FragColor=texture2D(map[4],vUv); }
else if(tex_num==5.0){ gl_FragColor=texture2D(map[5],vUv); }
}

Need something like:

const int count=6;
uniform sampler2D map[count];
varying float tex_num;

void main(){
gl_FragColor=texture2D(map[tex_num],vUv); }
}

You want DataArrayTexture, and in your shader:

uniform sampler2DArray map;
varying float tex_num;

void main() {
  gl_FragColor=texture(map, vec3(vUv.xy, tex_num));
}

NB: all textures have to have the same dimensions

2 Likes

Thank you, i know it. But maybe it can be without fixed dimension. 3d texture good solution also with atlas. If nobody know then i try 3d texture.

A 3D texture has the same requirement.

I’m quite sure accessing an array of samplers with a non-constant index is not supported in WebGL. Doing it with branches as in your example is terrible for performance. You have to squeeze your textures into an ArrayTexture, somehow, if you want it to perform well.

I’ve heard branching penalities aren’t as bad as they used to be…

Now i use DataArrayTexture and canvas for pack and atlas:

function set_DataArrayTexture(items){
	

let width=0;
let height=0;
let depth=items.length;


for(let n=0;n<depth;n++){
if(width<items[n].image.width){ width=items[n].image.width; }
if(height<items[n].image.height){ height=items[n].image.height; }
}


let size=width*height;
let size_4=size*4;
let data=new Uint8Array(4*size*depth);


let canvas=document.createElement("canvas");
let ctx=canvas.getContext("2d");
canvas.width=width;
canvas.height=height;


for(let n=0;n<depth;n++){
let texture_height=items[n].image.height;
ctx.save();
ctx.scale(1,-1);
ctx.translate(0,-texture_height);
ctx.drawImage(items[n].source.data,0,0);
let image_data=ctx.getImageData(0,0,width,height).data;
let offset=n*size_4;
for(let i=0;i<size_4;i++){
data[offset+i]=image_data[i];
}
ctx.restore();
ctx.clearRect(0,0,width,height);
}


let texture=new THREE.DataArrayTexture(data,width,height,depth);
texture.wrapS=texture.wrapT=THREE.RepeatWrapping;
texture.colorSpace=THREE.SRGBColorSpace;
texture.generateMipmaps=true;
texture.minFilter=THREE.LinearMipmapLinearFilter;
texture.magFilter=THREE.LinearFilter;
texture.needsUpdate=true;
return texture; 


}

Into material i use glslVersion:THREE.GLSL3:

mat["sprite_far"]=new THREE.ShaderMaterial({
uniforms:{
map:{value:set_DataArrayTexture([tex["a-0"],tex["a-1"],tex["a-2"]])},
cameraDirection:{value:[0,0,0]},
cameraAngle:{value:[0,0]},
time:{value:0}
},
vertexShader:vs["sprite"],
fragmentShader:fs["sprite"],
glslVersion:THREE.GLSL3,
transparent:true,
depthWrite:false,
blending:THREE.CustomBlending,
blendEquation:THREE.AddEquation,
blendSrc:THREE.OneFactor,
blendDst:THREE.OneMinusSrcAlphaFactor
});

Into fragment shader float texture number work good:

fs["sprite"]=`


uniform sampler2DArray map;
uniform sampler2D tDepth;
uniform mat4 projectionMatrix;
uniform vec2 screen_resolution;
varying vec2 vUv;
varying vec4 vColor;
varying float vBlend;
varying vec4 vFrame;
varying float tex_num;
varying float vViewPosition;
out vec4 outColor;
	
	
void main(){


outColor=texture(map,vec3(vUv/vFrame.xy+vFrame.zw,tex_num))*vColor;


#ifdef depth


float scene_depth=texture2D(tDepth,gl_FragCoord.xy/screen_resolution).r;
scene_depth=projectionMatrix[3][2]/((scene_depth*2.0-1.0)+projectionMatrix[2][2]);


float soft=clamp(scene_depth+vViewPosition,0.0,1.0);
soft=smoothstep(0.0,0.5,soft);


outColor.rgb*=outColor.a*soft; // ДЛЯ ПРАВИЛЬНОГО ОТОБРАЖЕНИЯ
outColor.a*=vBlend*soft; // ЧЕМ МЕНЬШЕ, ТЕМ БОЛЬШЕ ADDITIVE. ЧЕМ ВЫШЕ, ТЕМ ГУЩЕ


#else


outColor.rgb*=outColor.a; // ДЛЯ ПРАВИЛЬНОГО ОТОБРАЖЕНИЯ
outColor.a*=vBlend; // ЧЕМ МЕНЬШЕ, ТЕМ БОЛЬШЕ ADDITIVE. ЧЕМ ВЫШЕ, ТЕМ ГУЩЕ


#endif


}


`;




2 Likes