WebGL入门(四十一)-使用帧缓冲区对象(FBO)实现将渲染结果作为纹理绘制到另一个物体上

Posted 点燃火柴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebGL入门(四十一)-使用帧缓冲区对象(FBO)实现将渲染结果作为纹理绘制到另一个物体上相关的知识,希望对你有一定的参考价值。

1. demo效果

在这里插入图片描述

2. 相关知识点

我们已经知道,在默认情况下,WebGL是在 颜色缓冲区 中进行绘制,当开启隐藏面消除功能时,会用到 深度缓冲区,如果你想将渲染结果作为纹理贴到另一个三维物体上时,就需要用到 帧缓冲区对象

2.1 帧缓冲区对象(FBO)

帧缓冲区对象(framebuffer object)可以用来替代颜色缓冲区或深度缓冲区,在帧缓冲区中进行绘制的过程又称为 离屏绘制 (offscreen drawing)
使用帧缓冲区绘制图形并不是直接发生在帧缓冲区中,而是发生在帧缓冲区所关联的对象上,帧缓冲区一共有三个关联对象:

  1. 颜色关联对象(color attachment) 可以用来替代颜色缓冲区
  2. 深度关联对象(depth attachment) 可以用来替代深度缓冲区
  3. 模板关联对象(stencil attachment) 可以用来替代模板缓冲区

每个关联对象都可以关联两种类型的对象,分别是 纹理对象渲染缓冲区对象

如果将纹理对象作为颜色关联对象关联到帧缓冲区对象,然后在帧缓冲区中进行绘制,此时的颜色关联对象(即纹理对象)就替代了颜色缓冲区;

如果要进行隐藏面消除,就需要创建一个渲染缓冲区对象,将这个渲染缓冲区对象作为深度关联对象关联到帧缓冲区对象,完成关联后这个渲染缓冲区对象 就可以替代 深度缓冲区

2.2 渲染到纹理配置步骤

  1. 创建帧缓冲区对象(gl.createFramebuffer())
  2. 创建纹理对象并设置参数(gl.createTexture()、gl.bindTexture()、gl.texImage2D()、gl.Parameteri())
  3. 创建渲染缓冲区对象(gl.createRenderbuffer())
  4. 绑定渲染缓冲区对象并设置尺寸(gl.bindRenderbuffer()、gl.renderbufferStorage())
  5. 将帧缓冲区的颜色关联对象指定为一个纹理对象(gl.framebufferTexture2D())
  6. 将帧缓冲区的深度关联对象指定为一个渲染缓冲区(gl.framebufferRenderbuffer())
  7. 检查帧缓冲区是否配置正确(gl.checkFramebufferStatus())
  8. 在帧缓冲区中进行绘制(gl.bindFramebuffer())

3. 相关API

3.1 创建帧缓冲区对象 gl.createFramebuffer()


调用示例:gl.createFramebuffer()
--------------------------------------------------------------------------
函数功能:创建帧缓冲区对象
--------------------------------------------------------------------------		
参数		无
--------------------------------------------------------------------------		
返回值		non-null	新创建的帧缓冲区对象
			null		创建帧缓冲区对象失败
--------------------------------------------------------------------------
错误		无	

3.2 删除帧缓冲区对象 gl.deleteFramebuffer()


调用示例:gl.deleteFramebuffer(framebuffer)
--------------------------------------------------------------------------
函数功能:删除帧缓冲区对象
--------------------------------------------------------------------------		
参数		framebuffer		指定要删除的帧缓冲区对象
--------------------------------------------------------------------------		
返回值		无
--------------------------------------------------------------------------
错误		无	

3.3 创建渲染缓冲区对象 gl.createRenderbuffer()


调用示例:gl.createRenderbuffer()
--------------------------------------------------------------------------
函数功能:创建渲染缓冲区对象
--------------------------------------------------------------------------		
参数		无
--------------------------------------------------------------------------		
返回值		non-null	新创建的渲染缓冲区对象
			null		创建渲染缓冲区对象失败
--------------------------------------------------------------------------
错误		无	

3.4 删除渲染缓冲区对象 gl.deleteRenderbuffer()


调用示例:gl.deleteRenderbuffer(renderbuffer)
--------------------------------------------------------------------------
函数功能:删除渲染缓冲区对象
--------------------------------------------------------------------------		
参数		renderbuffer		指定要删除的渲染缓冲区对象
--------------------------------------------------------------------------		
返回值		无
--------------------------------------------------------------------------
错误		无	

3.5 绑定渲染缓冲区 gl.bindRenderbuffer()

在使用创建出的渲染缓冲区之前,还需要先将它绑定到目标上


调用示例:gl.bindRenderbuffer(target, renderbuffer)
--------------------------------------------------------------------------
函数功能:将renderbuffer指定的渲染缓冲区对象绑定在target目标上,
如果renderbuffer为null,则将已经绑定在target目标上的渲染缓冲区对象解除绑定
--------------------------------------------------------------------------		
参数		
			target			必须为 gl.RENDERBUFFER
			renderbuffer	指定要绑定的渲染缓冲区对象
--------------------------------------------------------------------------		
返回值		无
--------------------------------------------------------------------------
错误		INVALID_ENUM	target 不是 gl.RENDERBUFFER	

3.6 设置渲染缓冲区尺寸 gl.renderbufferStorage()

渲染缓冲区完成绑定后,就可设置它的格式、宽度、高度等,这里需要注意
作为深度关联对象的渲染缓冲区,宽度和高度必须与作为颜色关联对象的纹理缓冲区一致


调用示例:gl.renderbufferStorage(target, internalforamt, width, height)
-----------------------------------------------------------------------------------
函数功能:创建并初始化渲染缓冲区的数据区
-----------------------------------------------------------------------------------		
参数		
		target					必须为 gl.RENDERBUFFER
		internalforamt			指定渲染缓冲区中的数据格式,可以是以下几项参数
		  gl.EDPTH_COMPONENT16	表示渲染缓冲区将替代深度缓冲区
		  gl.STENCIL_INDEX8		表示渲染缓冲区将替代模板缓冲区
		  gl.RGBA4				表示渲染缓冲区将替代颜色缓冲区,RGBA四个分量各占4比特
		  gl.RGB5_A1			表示渲染缓冲区将替代颜色缓冲区,RGB各占5比特,A1比特
		  gl.RGB565				表示渲染缓冲区将替代颜色缓冲区,RGB分别占565比特
		width 和 height			表示渲染缓冲区的宽度和高度,以像素为单位
								
-----------------------------------------------------------------------------------	
返回值	无
-----------------------------------------------------------------------------------
错误	INVALID_ENUM			target 不是 gl.RENDERBUFFER	
		INVALID_OPERATION		target上没有绑定渲染缓冲区

3.7 绑定帧缓冲区 gl.bindFramebuffer()


调用示例:gl.bindFramebuffer(target, framebuffer)
--------------------------------------------------------------------------
函数功能:将framebuffer指定的帧缓冲区对象绑定在target目标上,
如果framebuffer为null,则将已经绑定在target目标上的帧缓冲区对象解除绑定
--------------------------------------------------------------------------		
参数		
			target			必须为 gl.FRAMEBUFFER
			framebuffer		指定要绑定的帧缓冲区对象
--------------------------------------------------------------------------		
返回值		无
--------------------------------------------------------------------------
错误		INVALID_ENUM	target 不是 gl.FRAMEBUFFER	

3.8 纹理对象关联到帧缓冲区对象 gl.framebufferTexture2D()


调用示例:gl.framebufferTexture2D(target, attachment, textarget, texture, level)
-----------------------------------------------------------------------------------------
函数功能:将texture指定的纹理对象关联到绑定在target目标上的帧缓冲区对象
-----------------------------------------------------------------------------------------		
参数		
			target			必须为 gl.FRAMEBUFFER
			attachment		指定关联的类型
			  gl.COLOR_ATTACHMENT0	表示texture是颜色关联对象
			  gl.DEPTH_ATTACHMENT	表示texture是深度关联对象
			textarget		gl.TEXTURE_2D或gl.TEXTURE_BUVE_MAP分别代表二维纹理和立方体纹理
			texture			指定关联的纹理对象
			level			指定为0(在使用MIPMAP纹理时指定纹理的层级)
-----------------------------------------------------------------------------------------		
返回值		无
-----------------------------------------------------------------------------------------
错误		INVALID_ENUM	target 不是 gl.FRAMEBUFFER 或者attachment或textarget的值无效	
			INVALID_VALUE	level的值无效
			INVALID_OPERATION	target上没有绑定帧缓冲区

3.9 将渲染缓冲区对象关联到帧缓冲区对象 gl.framebufferRenderbuffer()


调用示例:gl.framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer)
-----------------------------------------------------------------------------------------
函数功能:将renderbuffer指定的渲染缓冲区对象关联到绑定在target目标上的帧缓冲区对象
-----------------------------------------------------------------------------------------		
参数		
			target			必须为 gl.FRAMEBUFFER
			attachment		指定关联的类型
			  gl.COLOR_ATTACHMENT0	表示renderbuffer是颜色关联对象
			  glWebGL入门(四十二)-使用(FBO)实现阴影效果

WebGL入门(四十三)-WebGL加载OBJ-MTL三维模型

WebGL入门(四十)-通过切换着色器实现一个页面同时展示多个立方体

使用帧缓冲区对象 (FBO) 或?

将opengl主帧缓冲区复制到fbo

将我的场景渲染到帧缓冲区对象(FBO)然后将该 FBO 渲染到屏幕所需的步骤是啥?