将数据通过细分着色器传递到片段着色器 [英] Passing data through tessellation shaders to the fragment shader

查看:284
本文介绍了将数据通过细分着色器传递到片段着色器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对于着色器管线如何在通过每个阶段传递数据方面有所困惑。



我想要做的是传递颜色数据通过细分控制着色器,然后使用细分评估着色器,使用 glVertexAttrib4fv()加载到顶点阶段,以便它可以在片段着色器中使用。我不知道如果我有一些概念上的错误(很可能,因为我仍然试图让我的头围绕这个固定的功能),但无论如何,一旦我尝试和通过任何东西通过曲面细分着色器,我的原语拒绝渲染。在此之前,我的原始呈现,但它只呈现为黑色。我的着色如下:



顶点着色器:

  vec4偏移中的GLchar * vss [] = 
{
#version 430 core \\\

\\\

n
layout(location = 1)in vec4 color; \\\

\\\

out vec4 vs_color; \\\

\ n
void main(void)\\\

{\\\

const vec4 vertices [] = vec4 [](vec4(0.25,-0.25,-0.5 ,1.0),\ n
vec4(-0.25,-0.25,-0.5,1.0),\\\

vec4(0.25,0.25, \\\

\\\

gl_Position = vertices [gl_VertexID] + offset; \\\

vs_color = color; \\\

} \\\

};



控制着色器:

  static const GLchar * tc_ss [] = 
{
#version 430 core \\ \\ n
layout(vertices = 3)out; \\\

in vec4 vs_color; \\\

out vec4 tcs_color; \\\

void main(void)\\\

{\\\

if(gl_InvocationID == 0)\\\

{ \\\

gl_TessLevelInner [0] = 10.0; \\\

gl_TessLevelOuter [0] = 10.0; \\\

gl_TessLevelOuter [1] = 10.0; \\\

gl_TessLevelOuter [2] = 10.0; \\\

} \\\

gl_out [gl_InvocationID] .gl_Position = gl_in [gl_InvocationID] .gl_Position; \\\

tcs_color = vs_color; \\\

}
};

Tessellation评估着色器:

  static const GLchar * te_ss [] = 
{
#version 430 core \\\

in vec4 tcs_color; \\\

out vec4 tes_color; \\\

layout(triangles,equal_spacing,cw)in; \\\

void main(void)\\\

{\\\

gl_Position =(gl_TessCoord.x * gl_in [0] .gl_Position + \\\

gl_TessCoord.y * gl_in [1] .gl_Position + \\\

gl_TessCoord.z * gl_in [2] .gl_Position); \\\

tes_color = tcs_color; \\\

}
};

片段着色器: / p>

  static const GLchar * fss [] = 
{
#version 430 core \\\

in vec4 tes_color; \\\

out vec4 color; \\\

\\\

void main(void)\\\

{\\\

color = tes_color; \\\

} \\\

};


解决方案

这并不奇怪,TCS输入/输出必须是以下形式:

 在vec4 vs_color []; 
out vec4 tcs_color [];

也采用无界数组的形式:

 在CustomVertex {
vec4 color;
} custom_vs [ ;

out CustomVertex {
vec4 color;
} custom_tcs [];

对于一点点上下文,这是一个TCS /几何着色器作为顶点着色器的输出:

  in gl_PerVertex 
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance [];
} gl_in [];






为了尽可能简单,我将避免使用接口块。相反,我将介绍每补丁输入和输出的概念,因为他们将进一步简化您的着色器,因为考虑到颜色在整个镶嵌表面是恒定的...

p>

修改镶嵌控制着色器:



  in vec4 vs_color []; 
patch out vec4 patch_color;

...

patch_color = VS_color [gl_InvocationID];



修改镶嵌评估着色器:



  patch in vec4 patch_color; 
出vec4 tes_color;

...

tes_color = patch_color;

有了这些变化,你应该有一个工作的传递,和TES阶段工作。


I'm a bit confused about how the shader pipeline works with regards to passing data through each stage.

What I'm trying to do is pass color data that is loaded in the vertex stage using glVertexAttrib4fv() through the tessellation control shader, and then the tessellation evaluation shader, so that it can be used in the fragment shader. I'm not sure if I've made some sort of conceptual mistake (quite possible, since I'm still trying to get my head around this over fixed functions), but either way, as soon as I try and pass anything through the tessellation shaders, my primitives refuse to render at all. Before that, my primitive renders, but it only renders in black. My shaders are as follows:

Vertex Shader:

static const GLchar* vss[] =
    {
        "#version 430 core                                                  \n"
        "                                                                   \n"
        "layout (location = 0) in vec4 offset;                              \n"
        "layout (location = 1) in vec4 color;                               \n"
        "                                                                   \n"
        "out vec4 vs_color;                                                 \n"
        "                                                                   \n"
        "void main(void)                                                    \n"
        "{                                                                  \n"
        "   const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, -0.5, 1.0),   \n"
        "                                  vec4(-0.25, -0.25, -0.5, 1.0),   \n"
        "                                  vec4( 0.25,  0.25, -0.5, 1.0));  \n"
        "                                                                   \n"
        "   gl_Position = vertices[gl_VertexID] + offset;                   \n"
        "   vs_color = color;                                               \n"
        "}                                                                  \n"
    };

Tessellation control shader:

static const GLchar* tc_ss[] =
    {
        "#version 430 core                                                              \n"
        "layout (vertices = 3) out;                                                     \n"
        "in vec4 vs_color;                                                              \n"
        "out vec4 tcs_color;                                                            \n"
        "void main(void)                                                                \n"
        "{                                                                              \n"
        "   if (gl_InvocationID == 0)                                                   \n"
        "   {                                                                           \n"
        "       gl_TessLevelInner[0]    = 10.0;                                         \n"
        "       gl_TessLevelOuter[0]    = 10.0;                                         \n"
        "       gl_TessLevelOuter[1]    = 10.0;                                         \n"
        "       gl_TessLevelOuter[2]    = 10.0;                                         \n"
        "   }                                                                           \n"
        "   gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;   \n"
        "   tcs_color = vs_color;                                                       \n"
        "}"
    };

Tessellation Evaluation shader:

static const GLchar* te_ss[] =
    {
        "#version 430 core                                                                  \n"
        "in vec4 tcs_color;                                                                 \n"
        "out vec4 tes_color;                                                                \n"
        "layout (triangles, equal_spacing, cw) in;                                          \n"
        "void main(void)                                                                    \n"
        "{                                                                                  \n"
        "   gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position +                          \n"
        "                  gl_TessCoord.y * gl_in[1].gl_Position +                          \n"
        "                  gl_TessCoord.z * gl_in[2].gl_Position);                          \n"
        "   tes_color = tcs_color;                                                          \n"
        "}"
    };

Fragment shader:

static const GLchar* fss[] =
    {
        "#version 430 core      \n"
        "in vec4 tes_color;     \n"
        "out vec4 color;        \n"
        "                       \n"
        "void main(void)        \n"
        "{                      \n"
        "    color = tes_color; \n"
        "}                      \n"
    };

解决方案

This is not surprising, TCS inputs/outputs must be in the form:

in  vec4 vs_color  [];
out vec4 tcs_color [];

or in input/output blocks that also take the form of unbounded arrays:

in CustomVertex {
  vec4 color;
} custom_vs [];

out CustomVertex {
  vec4 color;
} custom_tcs [];

For a little bit of context, this is what a TCS / geometry shader sees as the output from vertex shaders:

in gl_PerVertex
{
  vec4  gl_Position;
  float gl_PointSize;
  float gl_ClipDistance [];
} gl_in [];


To keep things as simple as possible, I will avoid using interface blocks.

Instead, I will introduce the concept of per-patch inputs and outputs, because they will further simplify your shaders considering the color is constant across the entire tessellated surface...

Modified Tessellation Control Shader:

      in  vec4 vs_color [];
patch out vec4 patch_color;

...

  patch_color = vs_color [gl_InvocationID];

Modified Tessellation Evaluation Shader:

patch in  vec4 patch_color;
      out vec4 tes_color;

...

  tes_color = patch_color;

With these changes, you should have a working pass-through and a slightly better understanding of how the TCS and TES stages work.

这篇关于将数据通过细分着色器传递到片段着色器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆