如果几何着色器处于活动状态,如何将信息从顶点着色器传递到片段着色器?

Posted

技术标签:

【中文标题】如果几何着色器处于活动状态,如何将信息从顶点着色器传递到片段着色器?【英文标题】:How to pass information from vertex shader to fragment shader if there is a geometry shader active? 【发布时间】:2018-03-31 08:24:17 【问题描述】:

在添加几何着色器之前,我在顶点着色器中声明了一个变量:

out vec3 normal; 

被片段着色器接收为:

in vec3 normal; 

但是,如果我在程序中添加几何着色器,链接器会告诉我法线没有被声明为上一阶段的输出。但我不确定如何在几何着色器中接收或发送输出。

【问题讨论】:

【参考方案1】:

顶点着色器的输出是几何着色器的输入,几何着色器的输出是片段着色器的输入。 几何着色器的输入将是图元顶点数长度的数组。 (见Geometry Shader - Inputs)。

这意味着你必须在几何着色器中声明一个输入数组和一个输出:

in  vec3 normal[];
out vec3 geo_normal;

将输入传递给输出:

geo_normal = normal[i];
EmitVertex();

在片段着色器中声明一个输入:

in vec3 geo_normal;


一个选项是使用Layout Qualifiers

几何着色器:

in vec3 normal[]; // <---- array

out layout(location=1) vec3 geo_normal;  

geo_normal = normal[i];
EmitVertex();

片段着色器:

in layout(location=1) vec3 normal; // link by layout location 1 and not by name 


另一种选择是使用Interface Blocks:

顶点着色器:

out TData

    vec3 normal;
 outData;

outData.normal = .....;

几何着色器:

in TData

    vec3 normal;
 inData[]; // <---- array

out TData

    vec3 normal;
 outData;

outData.normal = inData.normal[i];
EmitVertex();

片段着色器:

in TData

    vec3 normal;
 inData;

..... = inData.normal;

【讨论】:

所以如果我添加几何着色器,我需要自己根据三角形的重心坐标手动合并法线? @Makogan 不,在几何着色器中,您可以访问一个图元的所有顶点坐标(例如三角形的 3 个角)。您可以将属性从顶点着色器传递到 geoemtry 着色器,并且可以进行原本在顶点着色器中进行的转换,然后在几何着色器中进行(当然还有更多基于图元的几何操作)。

以上是关于如果几何着色器处于活动状态,如何将信息从顶点着色器传递到片段着色器?的主要内容,如果未能解决你的问题,请参考以下文章

几何着色器被错误地解释为顶点着色器

Linux OpenGL 实践篇-13-geometryshader

如何在片段着色器中找到 4 个顶点之间的插值位置?

Unity Shader:几何着色器

opengl ---几何着色器

渲染管道几何阶段二“顶点着色器”