两种好用的全屏Quad绘制方法

后期处理时经常要用到全屏Quad渲染,最简单的方法是绘制两个三角形拼成一个全屏的quad,这个不用思考太多。

另外一种则是绘制一个足够覆盖整个屏幕的三角形,这种做法在unity和ue4中都被采用了。

具体做法如下:

//cpu input
pos0 = float2(-1, -1);
pos1 = float2(3, -1);
pos2 = float2(-1, 3);
uv0 = float2(0, 0);
uv1 = float2(2, 0);
uv2 = float2(0, 2);

////////// 光栅插值模拟 /////////////

// 屏幕左下角
pos_bl = pos0 = float2(-1,-1);    
uv_bl  = uv0 = float2(0,0);     

// 屏幕右下角
pos_br = (pos0 + pos1)*0.5 = float2(1,-1);    
uv_br  = (uv0 + uv1)*0.5   = float2(1,0);  

// 屏幕左上角 
pos_tl = (pos0 + pos2)*0.5 = float2(-1,1);    
uv_tl  = (uv0 + uv2)*0.5   = float2(0,1);    

// 屏幕右上角
pos_tr = (pos1 + pos2)*0.5 = float2(1,1);    
uv_tr  = (uv1 + uv2)*0.5   = float2(1,1);

另外一种做法是在顶点着色器直接利用gl_VertexIndex算出一个全屏三角形,这连vao和vbo绑定都省了:

/////////////// cpu ////////////////
vkCmdDraw(cmd_buf, 3, 1, 0, 0);

////////////// vertex shader ////////////

#version 450
layout (location = 0) out vec2 outUV;
void main() 
{
	outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
	gl_Position = vec4(outUV * 2.0f - 1.0f, 0.0f, 1.0f);
}

这里要注意绘制方向为顺时针方向,因此要设置管线状态如下:

rasterizationState.cullMode = VK_CULL_MODE_FRONT_BIT;
rasterizationState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
© - 2024 · 月光下的旅行。 禁止转载