当前位置:网站首页>[opengl] geometry shader
[opengl] geometry shader
2022-07-03 14:42:00 【ZJU_ fish1996】
reference:https://www.khronos.org/opengl/wiki/Geometry_Shader
Geometry shaders (GS) It's a use GLSL Prepared by processing elements shader Program , It is located in the vertex shader ( Or optional subdivision stage ) And fixed vertex post-processing stage .
Geometry shaders are optional , It's not necessary .
The geometry shader call takes a single entity as input , Zero or more elements may be output . You can limit a single GS The number of elements generated by the call . We write GS To accept specific element input and specific element output .
Even though GS It can be used to enlarge geometry , So as to realize rough surface subdivision , But this is usually not GS A good use of . Use GS The main reason is :
- Layered rendering : Take advantage of an entity and render it to multiple images , Without changing the bound render target .
- Transform feedback: Usually used in GPU On ( Before calculating shaders ) Perform calculation tasks .
stay OpenGL 4.0 in ,GS Two new features have been added . One is the ability to write multiple output streams , This feature is dedicated to transform feedback, This is different feedback Buffer can get different feedback data .
Another feature is GS Instantiation , It allows multiple calls to be made on the same entity . This makes layered rendering easier to implement and possibly more efficient , Because each layered element can be composed of a single GS Example calculation .
Be careful : Although before GL_EXT_geometry_shader4 and GL_ARB_geometry_shader4 The extension includes geometry shaders , But these extensions are implemented in a different way from the standard , This article only introduces the standard features .
Element input / Output specifications
Each geometry shader is designed to accept specific types of input and output entity types . The acceptable input entity types are shader The definitions in are as follows :
layout(input_primitive) in;
input_primitive Must be provided to GS To match the vertex flow of . If surface subdivision is supported , Then the entity type depends on the output of the subdivision evaluation shader ; If surface tessellation is disabled , Then the entity type is provided by the painting instruction rendered by the shader program .Input_primitive Effective value , And effective OpenGL The form of original type or subdivision is as follows :
The number of vertices is GS The number of vertices each input entity accepts .
The output entity type is defined as follows :
layout(output_primitive, max_vertices=vert_count) out;
out_primitive It must be one of the following :
- points
- line_strip
- triangle_strip
The way they work corresponds to OpenGL The rendering mode is exactly the same , To output a single triangle or line , Just set each group 2 or 3 Call after vertices EndPrimitive( See below )
The output must have max_vertices The definition of . This number should be a constant at compile time , It defines once GS The maximum number of vertices that can be written after the call . This number must not be greater than the limit defined by the implementation MAX_GEOMETRY_OUTPUT_VERTICES. The minimum value of this limit is 256, See the following limitations .
Instantiation
GS Can also be instantiated ( This is separate from instanced rendering , Because it is GS Localized ). This makes GS Make multiple calls to the same input entity . For each of the specific elements GS Calls have different gl_InvocationID value , This is useful for layered rendering or output to multiple streams ( See below ).
To use instantiation , There must be the following layout qualifiers :
layout(invocations=num_instances) in;
Num_instances The value of should not be greater than MAX_GEOMETRY_SHADER_INVOCATIONS(( At least for 32). Built in variables gl_InvocationID Specifies a specific instance of this shader , Its value lies in the half open interval [0, num_instances]
Instantiate the output entity according to gl_InvocationID Sort . So if you render two primitives , And set up num_insances by 3, that GS The valid call order of is as follows :(prim0,inst0),(prim0,inst1),(prim0,inst2),(prim1,inst0)…,GS The output entities of are sorted according to the input sequence . So if (prim0,inst0) Output two triangles , They all render (prim0,inst1) Any triangle of is rendered before .
Input
Geometry shaders take entities as input , Each entity consists of multiple vertices of the picture type defined in the shader .
Output of vertex shaders ( Or subdivision stage ) Passed as a variable array to GS. These can be designed as a single variable or as part of an interface building block . Each independent variable will be an array of the number and length of primitive vertices , For interface blocks , The blocks themselves will be arranged by this length . The vertex data in the input array corresponds to the vertex order specified in the previous shading stage .
The input of a geometric shader may have an interpolation qualifier . If any , The output of the previous stage must have the same qualifier .
The geometry shader has the following built-in input variables :
in gl_PerVertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_in[];
The meaning of these variables is obtained from the assignment passed in the previous shader stage .
Somewhat GS The input value of is based on entities rather than vertices . They are not included in the array , as follows :
int gl_PrimitiveIDIn;
int gl_InvocationID; // need GLSL4.0 or ARB_gpu_shader5
gl_PrimitiveIDIn
Current input element ID, be based on GS The number of elements processed under the current drawing instruction
gl_InvocationID
The current instance , Define when instantiating geometry shaders .
Output
Geometry shaders can output any number of vertices as needed ( The maximum is max_vertices layout Vertex specified by qualifier ). So , The output value in the geometry shader is not an array , It's a function based interface .
GS The code writes all the output values for a vertex , And then call EmitVertex(). This tells the system where to write these output values to the output vertex . After calling the definition function , All output variables contain undefined values . So you need to set the next vertex ( If it exists ) You need to write them all again before .
Be careful : You must always EmitVertex() Write each output variable before calling ( For each of the multiple stream outputs EmitStreamVertex() call )
GS Defines the entity type of each vertex output .GS You can also call EndPrimitive() Function to end the current element and start a new element . This function does not produce a vertex .
In order to be in GS Write two independent triangles in , You need to take advantage of EmitVertex() Call three independent vertices , And then call EndPrimitive() End the current phase and start a new . And then reuse it EmitVertex() Write three additional vertices .
GLSL Output variables are also defined . They are either grouped into interface blocks , Or as an independent variable . Output variables can contain interpolation qualifiers . The interface variable corresponding to the slice shader should have the same qualifier .
The geometry shader contains the following built-in outputs :
out gl_PerVertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
gl_PerVertex Defines the interface block of the output . This block has no instance name , So you don't need a prefix name .
GS It is the final stage of vertex processing . therefore , Unless rasterization is turned off , You have to write some values . These outputs and streams 0 Related . So if you want to send vertices to other streams , You don't have to write them .
gl_Position
The output position of the current vertex clipping space . If you need to flow 0 Send vertex , Then the value must be written , Unless rasterization is turned off .
gl_pointSize
The width of the pixel being rasterized / Height . This content needs to be written only when exporting point entities .
gl_clipdistance
Allows shaders to set the distance from vertices to each user-defined clipping plane . A positive distance means that the vertex is behind the clipping plane , A negative distance means that the vertex is in front of the clipping plane . In order to use this variable , The user must redeclare it with the display size ( So redeclare the interface block )
Some predefined outputs have special meanings and semantics :
out gl_PrimitiveID;
Primitives id Will be sent to the slice shader . Specific line / Triangular primitives id From this line / Triangular provoking vertex In order to get .
This value is any value you want . however , If you want and standard OpenGL Match the meaning (ie: If not used gs, Slice shader can get ), You must do this before sending each vertex :
gl_PrimitiveID = gl_PrimitiveIDIn;
This will naturally assume GS The number of exported elements is equal to GS Number of elements received .
Layered rendering
Layered rendering uses GS Pass specific entities to hierarchical frame buffers in different layers . This is making cube shadow mapping , Or it is very helpful to render cube environment mapping without rendering the whole scene multiple times .
GS Layered rendering in works with two special output variables :
out int gl_Layer;
out int gl_viewportindex; // need GL4.1 perhaps ARB_viewport_array
gl_Layer Output defines which layer of the layered image the element will be output to . Each vertex of an entity must have the same hierarchical subscript . Notice when rendering cube arrays ,g_layer The value represents the level of the face ( All faces in a layer ), Not the level of the cube .
gl_ViewportIndex, need gl 4.1 or ARB_viewport_array, It indicates which viewport subscript uses this element .
Be careful :ARB_viewport_array, Although it is 4.1 Characteristics of , But in NVIDIA and AMD Of 3.3 Widely used in hardware .
Use GS Instantiation can make layered rendering more efficient , Because it's different GS Calls can be executed in parallel during instantiation . Besides , Although most of 3.3 Hardware manufacturers support ARB_viewport_array, But they do not support ARB_gpu_shader5.
Warning :gl_Layer and gl_ViewportIndex yes GS The output variable of . therefore , Every time you call EmitVertex when , Their values will become undefined . therefore , These variables must be set every time the loop outputs .
If not written in the geometry shader gl_ViewportIndex, Then it is equivalent to the assignment of 0.
Determine vertex
gl_Layer and gl_ViewportIndex Is per vertex attribute , But they actually specify the properties of the entire element . therefore , There's a problem , Which vertex in a specific entity defines the layer and viewportIndex?
The answer is related to its implementation .OpenGL There are two queries in to determine which vertex is used by the current implementation :GL_LAYER_PROVOKING_VERTEX and GL_VIEWPORT_INDEX_PROVOKING_VERTEX.
glGetIntegerv The return value of will be one of the following enumerated values :
GL_PROVOKING_VERTEX: The vertices used will track the currently set excitation vertices (provoking index).
GL_LAST_VERTEX_CONVENTION: The vertex used will be the last excitation vertex .
GL_FIRST_VERTEX_CONVENTION: The vertex used will be the first excitation vertex .
GL_UNDEFINED_VERTEX: Implementation unknown .
For maximum portability , The same... Must be provided for each element layer and viewportIndex. therefore , If you want to output triangle belt , Different triangles have different indexes , That would be too bad . You have to cut it into different primitives .
Output stream
When using transform feedback To calculate the value , It is usually necessary to send different vertex sets to different buffers at different rates . for example ,GS You can build each instance data in a stream at the same time , Send vertex data to another stream . Vertex data and per instance data can have different lengths , Write at different rates .
The type of entities that need to be output from multiple output streams is point (points). You can still choose any input you like .
To achieve this , You can add layout qualifiers :
layout(stream={param|stream_index}}) out vec4 some_output;
Set the default value of a stream as follows :
layout(stream=2) out;
All subsequent output variables will use streams 2 Unless they have a specified stream . The default value can be modified later . The initial default value is 0.
To write vertices to the specified stream , You need to use functions EmitStreamVertex. This function requires a given stream index , Only output variables are written . Allied ,EndStreamPrimitive Will end a specific entity flow . however , Since multiple stream outputs require the use of point entities , The latter function is of little practical use .
Only pass to the stream 0 The primitive will be actually transferred to the vertex post-processing stage rendering . The remaining streams are only in use transform feedback You will use . call EmitVertex or EndPrimitive Equivalent to their relative flow 0 Copy of .
边栏推荐
- Doris学习笔记之数据表的创建
- PHP GD image upload bypass
- C language fcntl function
- NOI OPENJUDGE 1.4(15)
- [qingniaochangping campus of Peking University] in the Internet industry, which positions are more popular as they get older?
- Creation of data table of Doris' learning notes
- The picture quality has been improved! LR enhancement details_ Lightroom turns on AI photo detail enhancement: picture clarity increases by 30%
- Thread. Sleep and timeunit SECONDS. The difference between sleep
- 洛谷P5536 【XR-3】核心城市 题解
- Zzuli:1048 factorial table
猜你喜欢
Accelerating strategy learning using parallel differentiable simulation
Tonybot humanoid robot checks the port and corresponds to port 0701
pyQt界面制作(登录+跳转页面)
My QT learning path -- how qdatetimeedit is empty
adc128s022 ADC verilog设计实现
分布式事务(Seata) 四大模式详解
Dllexport and dllimport
The picture quality has been improved! LR enhancement details_ Lightroom turns on AI photo detail enhancement: picture clarity increases by 30%
如何查询淘宝天猫的宝贝类目
Adobe Premiere Pro 15.4 has been released. It natively supports Apple M1 and adds the function of speech to text
随机推荐
ConstraintLayout 的使用
天谋科技 Timecho 完成近亿元人民币天使轮融资,打造工业物联网原生时序数据库
556. 下一个更大元素 III : 简单构造模拟题
NPM install is stuck with various strange errors of node NPY
Qt development - scrolling digital selector commonly used in embedded system
表单文本框的使用(一) 选择文本
Creation of data table of Doris' learning notes
Luogu p5536 [xr-3] core city solution
DDK for XP
Detailed explanation of four modes of distributed transaction (Seata)
Preliminary summary of structure
String reverse order
C language dup2 function
Puzzle (016.4) domino effect
Use of constraintlayout
Find books ()
Plane vector addition
US stock listing of polar: how can the delivery of 55000 units support the valuation of more than 20billion US dollars
洛谷P3065 [USACO12DEC]First! G 题解
adc128s022 ADC verilog设计实现