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
}
`;