Simple Introduction to Geometry Shaders in GLSL (Part 2)

本文介绍如何使用GLSL几何着色器复制并平移输入几何体,通过顶点着色器传递法线信息到几何着色器中,并展示了如何利用接口块来简化变量传递过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


Simple Introduction to Geometry Shaders in GLSL (Part 2)



Firenze...

Content:

You missed the first part of this introduction to GS? No problem, you can find it HERE.

1 – Doubling the geometry with the geometry shader

Let’s see a more interesting use of the GS: a geometry doubler. This geometry doubler duplicates the input primitives and translates them along the vertex normal.

GeeXLab, geometry shader in GLSL
The GS doubler demo in GeeXLab – green: input geometry – yellow: duplicated geometry

Like in the first example, the GLSL program includes a VS, A GS and a PS.

The geometry doubler allows us to see how to pass data from vertex shader to geometry shader.

Vertex shader:

#version 330 compatibility
out vec4 normal;
void main()
{	
  gl_Position = gl_Vertex;
  normal =  vec4(gl_Normal.xyz, 0.0);
}

As you can see, this vertex shader is rather mininal (a pass-trought VS). Why? because the vertex transformation will be done in the geometry shader.

In this vertex shader, normal is a vertex attribute and is sent to the geometry shader like the built-in gl_Position. Now let’s see how to read the vertex normal in the GS.

Geomerty shader:

#version 330 compatibility

layout(triangles) in;
layout(triangle_strip, max_vertices=6) out;

uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;

in vec4 normal[];

out vec4 vertex_color;

void main()
{	
  mat4 modelViewMatrix = viewMatrix * modelMatrix;
  mat4 viewProjectionMatrix = projectionMatrix * viewMatrix;
  int i;
  
  //====== First triangle - identical to the input one.
  //
  for(i=0; i<3; i++)
  {
    vec4 view_pos = modelViewMatrix * gl_in[i].gl_Position;
    gl_Position = projectionMatrix * view_pos;
    vertex_color = vec4(0.0, 1.0, 0.0, 1.0);
    EmitVertex();
  }
  EndPrimitive();
  
  //====== Second triangle - translated version of the 
  // input triangle.
  //
  for(i=0; i<3; i++)
  {
    vec4 N =  normal[i];
    vec4 world_pos = modelMatrix * (gl_in[i].gl_Position + normalize(N) * 10.0);
    gl_Position = viewProjectionMatrix * world_pos;
    vertex_color = vec4(1.0, 1.0, 0.0, 1.0);
    EmitVertex();
  }
  EndPrimitive();
}

Remember, we are in a geometry shader: that’s why we retrieve per-vertex normals in an array. There is one normal per vertex and the size of the array is… 3 elements because the GS takes a triangle as input data. The number of elements of the array is automatically set by the GLSL compiler according to the input layout (here a triangle).

The geometry doubler shader outputs two triangles: one the is input triangle and the second one is a new triangle: the double. This second triangle is translated along the vertex normal. The translation is done in object space (object space? refresh your memory with this article about transformation spaces) that’s why we do all the computations in the geometry shader. If you try to translate along the normal in another space (world, view, projection), you will end up with strange results…

In order to tell OpenGL we output two triangles, we must modify a bit the output layout compared to our first GS in the part 1:

layout(triangle_strip, max_vertices=6) out;

The GS outputs now 6 vertices.

We used an array to retrieve the normals in the GS. But if you need to pass more vertex attributes between the VS and the GS, there is a more handy way to do it: by using an interface block. An interface block allows to pack in a structure all vertex attributes and to pass a single array from the VS to the GS:

Vertex shader with interface block:

#version 330 compatibility

out VertexAttrib
{
  vec3 normal;
  vec4 color;
} vertex;

void main()
{	
  gl_Position = gl_Vertex;
  vertex.normal =  vec4(gl_Normal.xyz, 0.0);
  vertex.color =  vec4(1.0, 1.0, 0.0, 1.0);
}

Geomerty shader with interface block:

#version 330 compatibility

layout(triangles) in;
layout(triangle_strip, max_vertices=6) out;

uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;

in VertexAttrib
{
  vec3 normal;
  vec4 color;
} vertex[];

out vec4 vertex_color;

void main()
{	
  mat4 modelViewMatrix = viewMatrix * modelMatrix;
  mat4 viewProjectionMatrix = projectionMatrix * viewMatrix;
  int i;
  
  //====== First triangle - identical to the input one.
  //
  for(i=0; i<3; i++)
  {
    vec4 view_pos = modelViewMatrix * gl_in[i].gl_Position;
    gl_Position = projectionMatrix * view_pos;
    vertex_color = vec4(0.0, 1.0, 0.0, 1.0);
    EmitVertex();
  }
  EndPrimitive();
  
  //====== Second triangle - translated version of the 
  // input triangle.
  //
  for(i=0; i<3; i++)
  {
    vec4 N =  vertex[i].normal;
    vec4 world_pos = modelMatrix * (gl_in[i].gl_Position + normalize(N) * 10.0);
    gl_Position = viewProjectionMatrix * world_pos;
    vertex_color = vertex[i].color;
    EmitVertex();
  }
  EndPrimitive();
}

And the last shader of our GLSL program:
Pixel shader:

#version 330 compatibility
in vec4 vertex_color;
void main(void)
{
  gl_FragColor = vertex_color;	
}

Nothing special about the PS.

2 – The Demo

 The GeeXLab demo is available in the GLSL_Geometry_Shader/ folder of GeeXLab code sample pack:
[download#40#image]

This demo requires GeeXLab 0.3.2+ (GS support has been added in the 0.3.x branch of GeeXLab).

GeeXLab, geometry shader in GLSL
The GS doubler demo in GeeXLab with live coding



http://www.geeks3d.com/20111117/simple-introduction-to-geometry-shader-in-glsl-part-2/

内容概要:本文详细探讨了双馈风力发电机(DFIG)在Simulink环境下的建模方法及其在不同风速条件下的电流与电压波形特征。首先介绍了DFIG的基本原理,即定子直接接入电网,转子通过双向变流器连接电网的特点。接着阐述了Simulink模型的具体搭建步骤,包括风力机模型、传动系统模型、DFIG本体模型和变流器模型的建立。文中强调了变流器控制算法的重要性,特别是在应对风速变化时,通过实时调整转子侧的电压和电流,确保电流和电压波形的良好特性。此外,文章还讨论了模型中的关键技术和挑战,如转子电流环控制策略、低电压穿越性能、直流母线电压脉动等问题,并提供了具体的解决方案和技术细节。最终,通过对故障工况的仿真测试,验证了所建模型的有效性和优越性。 适用人群:从事风力发电研究的技术人员、高校相关专业师生、对电力电子控制系统感兴趣的工程技术人员。 使用场景及目标:适用于希望深入了解DFIG工作原理、掌握Simulink建模技能的研究人员;旨在帮助读者理解DFIG在不同风速条件下的动态响应机制,为优化风力发电系统的控制策略提供理论依据和技术支持。 其他说明:文章不仅提供了详细的理论解释,还附有大量Matlab/Simulink代码片段,便于读者进行实践操作。同时,针对一些常见问题给出了实用的调试技巧,有助于提高仿真的准确性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值