ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

OpenGL 细分控制着色器执行次数

2020-12-10 15:34:26  阅读:315  来源: 互联网

标签:GL OpenGL color vec4 细分 gl 着色器 out


Tessellation Control Shader

细分控制着色器执行模式与大多数其他着色器阶段不同;它与计算着色器最相似。与几何着色器每个调用都可以输出多个图元不同,每个细分控制着色器调用只负责生成输出面片中的单个顶点。

对于渲染期间提供的每个面片,将执行n次细分控制着色器调用,其中n是输出面片中的顶点数。因此,如果一个绘制命令绘制了20个面片,并且每个输出有4个顶点,那么总共将有80个单独的细分控制着色器调用。

为同一面片提供数据的不同调用是相互连接的。这些调用都共享它们的输出值。它们可以读取同一面片的其他调用写入的输出值。但是为了做到这一点,他们必须使用同步机制(barrier)来确保细分控制着色器的所有其他调用至少已经执行了写入。

因此,细分控制着色器不同调用可以共享数据并彼此通信。

输出面片的顶点数量可以通过布局限定符(layout)来设置,也即设置了控制着色器执行的次数:

layout(vertices = patch_size) out;

patch_size 的大小不是必须与输入面片顶点的大小(glPatchParameteri(GL_PATCH_VERTICES, n))匹配。

细分控制着色器的输出变量直接传递到细分计算着色器,而不需要任何形式的插值(这是细分计算着色器的主要工作)。这些可以是逐顶点输出或逐面片输出。

下面来测试下执行的次数:

// 创建原子计数器缓存
glGenBuffers(1, &atomic_counter_buffer);
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomic_counter_buffer);
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_READ);
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomic_counter_buffer);
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomic_counter_buffer);
GLuint*  data = (GLuint *)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY);
data[0] = 0;
glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);

//设置输入面片的顶点数
glPatchParameteri(GL_PATCH_VERTICES, 3);
//绘制六个顶点
glDrawArrays(GL_PATCHES, 0, 6);
//输出执行次数
data = (GLuint *)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY);
cout << "invocations:" << *data << endl;		
glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);

逐顶点输出:


//顶点着色器
#version 440 core

layout(location = 0) in vec4 VsInPos;
layout(location = 1) in vec4 VsInColor;

out vec4 color;
out vec4 pos;
void main()
{
	gl_Position = VsInPos;
	color = VsInColor;
}

//细分控制着色器
#version 440 core
//输出顶点数为3
layout(vertices = 3) out;
layout (binding = 0, offset = 0) uniform atomic_uint TessCoord;

in vec4 color[];

out	vec4 TCcolor[];

void main()
{
	atomicCounterIncrement(TessCoord);

	gl_TessLevelInner[0] = 2.0;

	gl_TessLevelOuter[0] = 2.0;
	gl_TessLevelOuter[1] = 2.0;
	gl_TessLevelOuter[2] = 2.0;

	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
	TCcolor[gl_InvocationID] = color[gl_InvocationID];		
}

//细分计算着色器
#version 440 core

layout(triangles, equal_spacing, cw) in;

in vec4 TCcolor[]; 
    
flat out vec4 color;
 
void main()
{
	float u = gl_TessCoord.x;
	float v = gl_TessCoord.y;
	float w = gl_TessCoord.z;
	
	gl_Position = u * gl_in[0].gl_Position + v * gl_in[1].gl_Position + w * gl_in[2].gl_Position;	
	color = TCcolor[0]*u + TCcolor[1]*v +TCcolor[2]*w;
}

在这里插入图片描述

逐面片输出:

//顶点着色器
#version 440 core

layout(location = 0) in vec4 VsInPos;
layout(location = 1) in vec4 VsInColor;

out vec4 color;
out vec4 pos;
void main()
{
	pos = VsInPos;
	color = VsInColor;
}


//细分控制着色器
#version 440 core
//输出顶点数为1
layout(vertices = 1) out;
layout (binding = 0, offset = 0) uniform atomic_uint TessCoord;

in vec4 color[];
in vec4 pos[];

struct OutputPatch
{
	//必须指定数组大小
	vec4 TCpos[3];
	vec4 TCcolor[3];
};
out patch OutputPatch oPatch;       

void main()
{
	atomicCounterIncrement(TessCoord);
	
	gl_TessLevelInner[0] = 2.0;

	gl_TessLevelOuter[0] = 2.0;
	gl_TessLevelOuter[1] = 2.0;
	gl_TessLevelOuter[2] = 2.0;

	for(int i=0;i<3;i++)
	{
		oPatch.TCpos[i] = pos[i];
		oPatch.TCcolor[i] = color[i];	
	}	
}


//细分计算着色器
#version 440 core

layout(triangles, equal_spacing, cw) in;

struct OutputPatch
{
	vec4 TCpos[3];
	vec4 TCcolor[3];
};

in patch OutputPatch oPatch;           
flat out vec4 color;
 
void main()
{
	float u = gl_TessCoord.x;
	float v = gl_TessCoord.y;
	float w = gl_TessCoord.z;
	
	gl_Position = u * oPatch.TCpos[0] + v * oPatch.TCpos[1] + w * oPatch.TCpos[2];	
	color = oPatch.TCcolor[0]*u + oPatch.TCcolor[1]*v +oPatch.TCcolor[2]*w;
}

在这里插入图片描述

标签:GL,OpenGL,color,vec4,细分,gl,着色器,out
来源: https://blog.csdn.net/qq_26328385/article/details/110951547

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有