OpenGL Tessellation control Shader(细分曲面控制着色器)

                                  OpenGL Tessellation control Shader(细分曲面控制着色器)

OpenGL Tessellation

阶段:

 

 

1,TCS: Tessellation Control Shader,细分控制材质

2,PG:Primitive Generator,图元生成器

3,TES:Tessellation Evalution Shader,细分执行材质

4,CP:Control Points,The TCS works on a group of vertices called Control Points (CP),TCS工作在一组控制点上,CP点得移动会影响 被控制的表面。

 

 

TCS阶段是输入一个patch 输出一个 patch,TCS还要计算一个重要的功能: Tessllation levels:TL,Tessellation level of detai - how many triangles to generate for the patch(在一个patch上生成多少个三角形)

如果rasterized triangle覆盖了100个像素,可以决定TL的值是3,如果覆盖了101-500 可以为7。

另外也可以根据摄像机距离来决定TL值。

 

TCS完成之后,PG就是执行细分。PG阶段并不是真正的细分,你可能连访问他的权限都没有。但是TL & subdives 来定义了一个新的概念:Domain,domain是一个2D 0-1区间square,或者3d的barycentric coordinates

如右边的三角形,Barycentric coordinates坐标为:<1/3,1/3,1/3>,所以满足这个坐标,他的x+y+z = 1.0

For simplicity let's focus on the triangle domain from now on.

 

In general, the TLs tell the PG the number of segments on the outer edge of the triangle and the number rings towards the center

At any rate, remember that the PG ignores both the input and output patch of the TCS. All it cares about are the per patch TLs.

 

在TES中,和vertex shader相似。我们要执行矩阵变换。变换到摄像机空间。

TES不能生成点或者删除点在一个调用。

The main purpose of the TES that the architects of Tessellation in OpenGL envisioned is to evaluate the surface equation at the given domain location

 

1,测试1:细分一个三角形

 vs:

复制代码

#version 450 core
layout(location =0 ) in vec3 vs_p;
layout(location =1 ) in vec3 vs_cd;
out vec3 vs_color;
void main(){
    gl_Position = vec4(vs_p,1.0);
    vs_color = vs_cd;
}

复制代码

tcs:

注意下面

gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;实际上把vert shader的材质传入

复制代码

#version 450 core
layout (vertices = 3) out;
void main(){
    //inner
    gl_TessLevelInner[0] = 5;
    // outer
    gl_TessLevelOuter[0] = 5;
    gl_TessLevelOuter[1] = 5;
    gl_TessLevelOuter[2] = 5;
    
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;

}

复制代码

tes:

复制代码

#version 450 core
layout(triangles , equal_spacing,ccw) in;
void main(){

    vec4 upos= gl_TessCoord.x * gl_in[0].gl_Position;
    vec4 vpos= gl_TessCoord.y * gl_in[1].gl_Position;
    vec4 wpos= gl_TessCoord.z * gl_in[2].gl_Position;
    gl_Position = upos + vpos + wpos;

}

复制代码

frag:

#version 450 core
out vec4 color;
void main(){
    color = vec4(1,1,1,1);
}

 main.cpp

CPP中要设置:

glPatchParameteri(GL_PATCH_VERTICES,3);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

render时候:

void display(){
    // render
    // ------
    glUseProgram(shaderProgram);
    glDrawArrays(GL_PATCHES,0,3);
}

 

2,修改材质,支持我们的vert shading里面的变量。比如我们输入了vs_cd;

vert保持不变:

复制代码

#version 450 core
layout(location =0 ) in vec3 vs_p;
layout(location =1 ) in vec3 vs_cd;
out vec3 vs_color;
out vec4 vs_pos;
void main(){
    gl_Position = vec4(vs_p,1.0);
    vs_pos = vec4(vs_p,1.0);  // same as up
    vs_color = vs_cd;
}

复制代码

tcs修改:可以不用gl_out[gl_InvocationID].gl_Position。

复制代码

#version 450 core
layout (vertices = 3) out;
// ----------- from vert shader ---------------
in vec4 vs_pos[];
in vec3 vs_color[];
// ---------- out put -------------------------
out vec4 tcs_pos[];
out vec3 tcs_color[];

void main(){
    //inner
    gl_TessLevelInner[0] = 5;
    // outer
    gl_TessLevelOuter[0] = 5;
    gl_TessLevelOuter[1] = 5;
    gl_TessLevelOuter[2] = 5;

    tcs_pos[gl_InvocationID]   = vs_pos[gl_InvocationID];
    tcs_color[gl_InvocationID] = vs_color[gl_InvocationID];
}

复制代码

TES 重心坐标插值。

复制代码

#version 450 core
layout(triangles , equal_spacing,ccw) in;

vec2 interpolate2D(vec2 v0, vec2 v1, vec2 v2)
{
    return vec2(gl_TessCoord.x) * v0 + vec2(gl_TessCoord.y) * v1 + vec2(gl_TessCoord.z) * v2;
}
vec3 interpolate3D(vec3 v0, vec3 v1, vec3 v2)
{
    return vec3(gl_TessCoord.x) * v0 + vec3(gl_TessCoord.y) * v1 + vec3(gl_TessCoord.z) * v2;
}

// ----------------------- in variables from TCS -------------------
in vec4 tcs_pos[];
in vec3 tcs_color[];
// ----------------------- Out variables from TES ------------------
out vec4 P;   // it can transfer to fragment or geometry shader
out vec3 Cd;  // transfer to fragment shader

void main(){
    vec3 iterP = interpolate3D(tcs_pos[0].xyz,tcs_pos[1].xyz,tcs_pos[2].xyz);
    vec3 iterCd = interpolate3D(tcs_color[0],tcs_color[1],tcs_color[2]);
    P = vec4(iterP , 1);
    Cd = iterCd;
    gl_Position = P;  // may be need to MVP matrix here
}

复制代码

frag材质可以看到拿到细分后的颜色完全正确。

#version 450 core
out vec4 color;
in vec3 Cd;
void main(){
    color = vec4(Cd , 1.0);
}

 

 

 

版权

AlgebraMaster

https://www.cnblogs.com/gearslogy/p/13141035.html

 

REF:

http://ogldev.atspace.co.uk/www/tutorial30/tutorial30.html

https://www.youtube.com/watch?v=A96elMGacqI

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
细分shader和几何shader是计算机图形学中的两种重要的着色器类型。 细分shaderTessellation Shader)是一种用于进行细分操作的着色器。它可以将输入的三角形网格进行细分,并生成更高分辨率的三角形网格。细分shader通常用于提高曲面细节的展示效果。通过在输入的三角形上插入新的顶点,并对这些顶点进行位置调整,细分着色器可以产生更加平滑的曲面细节,并增加模型的细节级别。细分shader常用于模型细分细节的增强,如地形细分、角色细分曲面细分等。 几何shader(Geometry Shader)是在细分shader之后执行的着色器细分shader生成的细分网格会进一步传递给几何shader。几何shader可以对输入的三角形网格进行操作,包括增加、删除和改变顶点的属性。通过几何shader,我们可以对模型进行各种形状的变换和处理,如通过给三角形添加顶点产生更多的几何图元,或者通过删除顶点合并多个三角形。几何shader在进一步处理模型形状、拆分或合并模型几何体、调整三角形顶点属性等方面具有极大的灵活性。它可以在多个输入图元之间进行交互,并能够生成不同类型的图元作为输出。 综上所述,细分shader和几何shader是在计算机图形学中常用的两种着色器类型。细分shader用于增加模型的细节级别,而几何shader用于对模型的形状进行操作和变换。它们在计算机图形学中扮演着重要的角色,为实时渲染和图形处理提供了更大的灵活性和细节控制

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值