WebGL:淡入淡出图形缓冲区

WebGL:淡入淡出图形缓冲区,webgl,Webgl,我已将preserveDrawingBuffer设置为true。 但是,这样做会导致在缓冲区上绘制的所有内容都可以一次看到, 我想知道是否有一种方法可以随着时间的推移以某种方式使缓冲区褪色,从而使绘制的旧元素随着时间的推移消失,而最新绘制的元素以相对较高的不透明度出现,直到它们也褪色为止 有没有更好的方法来达到这样的效果 我试图通过降低不透明度来再次渲染以前的元素,直到它达到0,但这似乎不是一种有效的淡入淡出方式,因为一旦画出某样东西,我不打算更改它 谢谢 在内存有限的设备(移动电话)上,pre

我已将
preserveDrawingBuffer
设置为
true
。 但是,这样做会导致在缓冲区上绘制的所有内容都可以一次看到, 我想知道是否有一种方法可以随着时间的推移以某种方式使缓冲区褪色,从而使绘制的旧元素随着时间的推移消失,而最新绘制的元素以相对较高的不透明度出现,直到它们也褪色为止

有没有更好的方法来达到这样的效果

我试图通过降低不透明度来再次渲染以前的元素,直到它达到0,但这似乎不是一种有效的淡入淡出方式,因为一旦画出某样东西,我不打算更改它


谢谢

在内存有限的设备(移动电话)上,
preserveDrawingBuffer
标志非常有用,因为它允许这些设备重用该内存块


淡入/重影效果是以不同的方式完成的:您分配一个与视口大小相同的纹理,并对该纹理进行变暗处理。在将“颜色”值乘以褪色因子(例如0.9)的同时,重新渲染该纹理内容的每一帧。然后,在同一纹理上渲染新元素,最后将纹理渲染到视口(简单的“复制渲染”)。

对于内存有限的设备(移动电话),
preserveDrawingBuffer
标志非常有用,因为它允许这些设备重用该内存块


淡入/重影效果是以不同的方式完成的:您分配一个与视口大小相同的纹理,并对该纹理进行变暗处理。在将“颜色”值乘以褪色因子(例如0.9)的同时,重新渲染该纹理内容的每一帧。然后,在同一个纹理上渲染新元素,最后将纹理渲染到视口(一个简单的“复制渲染”)。

这实际上很常见,只是我在这里重画了一些东西

重画意味着你可以让一些东西不褪色。例如,如果你正在制作一个太空射击游戏,你只想让爆炸和导弹轨迹淡出,但你不想让宇宙飞船和小行星淡出,那么你需要重新绘制所有东西,并手动淡出它们,同时降低它们的阿尔法

如果你只是想让一切都淡出,那么你可以使用后处理类型效果

制作2个纹理并将其附加到2个帧缓冲区。使用fadeColor将第一个帧缓冲区
fadeFb1
混合/淡入第二个帧缓冲区
fadeFb2

gl_FragColor = mix(textureColor, fadeColor, mixAmount);
然后将任何新内容绘制到
fadeFb2

然后最后在画布上绘制
fadeFb2
,以便查看结果

在下一帧中,除了交换要绘制的缓冲区和要淡入的缓冲区之外,您执行相同的操作

frame 0: mix(fadeFb1,fadeColor)->fadeFb2, draw->fadeFb2, fadeFB2->canvas
frame 1: mix(fadeFb2,fadeColor)->fadeFb1, draw->fadeFb1, fadeFB1->canvas
frame 2: mix(fadeFb1,fadeColor)->fadeFb2, draw->fadeFb2, fadeFB2->canvas
...
注意你不清楚什么时候画画,因为你需要留下结果

关于设置帧缓冲区,这里有一个教程可能很有用

下面是一个使用的示例,因为我太懒了,无法直接使用WebGL

var-vs=`
属性向量4位置;
均匀mat4u_矩阵;
void main(){
gl_位置=u_矩阵*位置;
}
`;
var fs=`
精密中泵浮子;
均匀的vec4 u_颜色;
void main(){
gl_FragColor=u_颜色;
}
`;
var vsQuad=`
属性向量4位置;
属性向量2 texcoord;
可变矢量2 v_texcoord;
void main(){
gl_位置=位置;
v_texcoord=texcoord;
}
`;
var fsFade=`
精密中泵浮子;
可变矢量2 v_texcoord;
均匀的二维u_纹理;
均匀浮动u_混合量;
统一的vec4 u_fadeColor;
void main(){
vec4颜色=纹理2D(u_纹理,v_纹理坐标);
gl_FragColor=混合(颜色、u_fadeColor、u_混合量);
}
`;
变量fsCopy=`
精密中泵浮子;
可变矢量2 v_texcoord;
均匀的二维u_纹理;
void main(){
gl_FragColor=纹理2D(u_纹理,v_texcoord);
}
`;
var$=document.querySelector.bind(文档);
var mixAmount=0.05;
var mixElem=$(“#mix”);
var mixvaluelem=$(“#mixValue”);
mixElem.addEventListener('input',函数(e){
setMixAmount(即目标值/100);
});
函数setMixAmount(值){
混合量=值;
mixValueElem.innerHTML=mixAmount;
}
设置mixAmount(mixAmount);
var gl=$(“canvas”).getContext(“webgl”);
var m4=twgl.m4;
var programInfo=twgl.createProgramInfo(gl[vs,fs]);
var fadeProgramInfo=twgl.createProgramInfo(gl[vsQuad,fsFade]);
var copyProgramInfo=twgl.createProgramInfo(gl[vsQuad,fsCopy]);
//创建一个-1到+1的四边形
var quadBufferInfo=twgl.primitives.createXYQuadBufferInfo(gl);
//创建RGBA/无符号字节纹理和深度缓冲区帧缓冲区
var imgFbi=twgl.createFramebufferInfo(gl);
//创建2个RGBA纹理+深度帧缓冲区
var fadeAttachments=[
{格式:gl.RGBA,min:gl.NEAREST,max:gl.NEAREST,wrap:gl.CLAMP_TO_EDGE,},
{格式:gl.DEPTH_STENCIL},
];
var fadeFbi1=twgl.createFramebufferInfo(gl,fadeAttachments);
var fadeFbi2=twgl.createFramebufferInfo(gl,fadeAttachments);
函数绘图(gl、x、y、旋转、比例、颜色){
var矩阵=m4.正交(0,gl.canvas.width,gl.canvas.height,0,-1,1);
矩阵=m4.平移(矩阵[x,y,0]);
矩阵=m4.旋转(矩阵,旋转);
矩阵=m4.标度(矩阵,[标度,标度,1]);
总账使用程序(programInfo.program);
twgl.setBuffersAndAttributes(总帐、程序信息、四缓冲区信息);
twgl.设置制服(程序信息{
u_矩阵:矩阵,
颜色:颜色,
});
twgl.drawBufferInfo(gl,gl.TRIANGLES,quadBufferInfo);
}
函数随机数(最小值、最大值){
如果(最大值===未定义){
最大值=最小值;
最小值=0;
}
返回min+Math.random()*(max-min);
}
函数渲染(时间){
if(总图尺寸CanvasToDisplaySize(总图画布)){
twgl.resizeFramebufferInfo(总图、fadeFbi1、fadeAttachments);
twgl.resizeFramebufferInfo(gl、fadeFbi2、fadeAttachments);
}
//通过使用mixAmount将fadeFbi1复制到fabeFbi2中进行淡入淡出。
//fadeFbi2将继续