`
helloandroid
  • 浏览: 272353 次
  • 性别: Icon_minigender_1
  • 来自: 成都
博客专栏
107f8db3-b009-3b79-938a-dafddb49ea79
Android腾讯微博客户...
浏览量:94494
社区版块
存档分类
最新评论

shader一

 
阅读更多
递传顶点属性息信
    之前讲过,vertex shader会被个每顶点调用,常通一个顶点会包括很多息信,例如顶点标坐、顶点法向量、纹理标坐等等,我们称这些息信为顶点的属性。在之前的OpenGL版本里,个每属性都对应了一个特定的道通,我们应用glVertex,glTexCoord,,glNormal(或者通过拜访指针数函glVertexPointer, glTexCoordPointer, or glNormalPointer)等数函来拜访和置设它们。随后,shader会自己通过内置变量gl_Vertex 和 gl_Normal来拜访这些属性。但在OpenGL3.0版本里,这些都被弃用了。在后续版本里,甚至都被移除了。而在现,这些通过generic vertex attributes,形图顶点属性,来供提(常通和顶点缓冲对象互相协作来成完)。我们可以根据须要为个每顶点定义意任量数的(是实其在0到GL_MAX_VERTEX_ATTRIBS – 1之间)属性。OpenGL会为这些属性定义一个索引,我们只要根据这些索引来拜访以可就了。

    在一个vertex shader里,一个顶点属性是由GLSL 标识符 “in” 来定义的。例如,面下的代码里定义了两个vec3的属性,VertexPosition和VertexColor。

#version 400
in vec3 VertexPosition;
in vec3 VertexColor;
out vec3 Color;
void main()
{
    Color = VertexColor;
    gl_Position = vec4(VertexPosition,1.0);
}
    注意到这里还有一个型类为vec3的输出 Color,它将递传给下一层处置的shader中,这里也就是我们的fragment shader(fragment可以理解为拥有很多属性的像素)。这里,我们还是应用之前那个简略的fragment shader。

#version 400
in vec3 Color;
out vec4 FragColor;
void main() {
    FragColor = vec4(Color, 1.0);
}
    当然,vertex shader真正的据数还须要我们从OpenGL程序里传入。这就有了两种向Shader递传顶点属性的方法。

    在这之前,我们首先要创立一个VAO,vertex array object,顶点数组对象。要主想要细仔懂得这个是干吗的,还请自行查阅资料,还是很多滴。这里,我们只要道知,它包括了我们的缓冲区和入输的顶点属性之间的对应关系以可就了。在一个OpenGL程序里,我们可以应用多个VAO,并在它们之间切换。在现我们只应用一个。

GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
    最后一句话标明,接下来我们所做的有所绑定作操,例如建立顶点属性和入输之间的对应关系,都是针对这个VAO的。

    面下我们须要为要输传的据数成生对应的缓冲区。这些缓冲区随后会在绘制数函中,通过顶点属性索引递传给我们的shader。

    因为在本例中,我们有两个属性值,因此须要建立两个缓冲区。

    首先定义缓冲区的据数,也就是我们的顶点息信。我们在现须要画一个三角形,因此只须要三个点。

// An array of 3 vectors which represents 3 vertices
float positionData[] = {
    -0.8f, -0.8f, 0.0f,
    0.8f, -0.8f, 0.0f,
    0.0f, 0.8f, 0.0f };
    然后创立一个缓冲区,并用上面的据数为其充填。

// This will identify our vertex buffer
GLuint vertexbuffer;

// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);

// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(positionData), positionData, GL_STATIC_DRAW);
    这样就成完的第一个顶点属性,VertexPosition据数的后期备准任务。VertexColor的据数是似类的。

float colorData[] = {
    1.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 1.0f };
// This will identify our vertex buffer
GLuint colorbuffer;

// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &colorbuffer)
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);

// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(colorData), colorData, GL_STATIC_DRAW);
    在现备准好了据数(在现存储在两个buffer里),我们就得让OpenGL程序道知所要递传的据数该应给谁。面前说过,OpenGL会为顶点属性创立一个0到GL_MAX_VERTEX_ATTRIBS – 1的索引,既然如此,我们首先要定义一下索引和Shader里变量的对应关系,就好比我们在写一个目录,我们必须告知OpenGL,页码0对应的是什么内容,而页码1又对应着什么内容,这里的内容指的就是shader中以“in”为关键字的变量。定义了索引对应关系后,在绘制数函里,我们以可就根据索引来递传据数了。

    每日一道理
那蝴蝶花依然花开花落,而我心中的蝴蝶早已化作雄鹰飞向了广阔的蓝天。
    这里,根据定义种这索引对应关系的门路,可以分为面下两种。

   

应用glBindAttribLocation
    第一种方法是通过glBindAttribLocation数函来实现索引和变量之间的对应关系。

    首先,我们为shader中的个每顶点属性变量指定一个索引(一般从0开始)。

// Bind index 0 to the shader input variable "VertexPosition"
glBindAttribLocation(programHandle, 0, "VertexPosition");
// Bind index 1 to the shader input variable "VertexColor"
glBindAttribLocation(programHandle, 1, "VertexColor");
   

    上述代码定规,shader里名字为VertexPosition的变量对应顶点属性索引为0,VertexColor对应索引为1.

   

在Shader中直接指定
    另外一种方法则是在shader中直接指定,这是通过GLSL的关键词layout来是实现。为了实现这样的效果,我们须要改更之前的vertex shader的内容。如下:

#version 400
layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec3 VertexColor;
out vec3 Color;
void main()
{
    Color = VertexColor;
    gl_Position = vec4(VertexPosition,1.0);
}
    似类这样的代码layout(location = 0)指定了顶点属性VertexPosition对应了索引值0.

   

    在现有所的备准任务都做完了:我们既成完了缓冲区据数的充填,也成完了顶点属性索引和shader入输变量之间的对应关系,剩下的任务就是在绘制数函中告知OpenGL,请应用xxx buffer内的据数来为索引为x的顶点属性值赋。

// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
   0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
   3,                  // size
   GL_FLOAT,           // type
   GL_FALSE,           // normalized?
   0,                  // stride
   (void*)0            // array buffer offset
);
    第一行代码示表我们须要启用索引为0的顶点属性。然后第二行标明我们要应用vertexbuffer内的据数,面下的作操都是针对这个缓冲区的。第三行代码中数函的参数比较多,第一个参数指明要作操的属性索引值,第二个参数则说明个每顶点属性须要几个据数(可为以1,2,3或4),因为vertexbuffer里在现存储了3X3=9个据数,而实际上3个是一组,个每顶点须要应用3个据数。第三个参数指定了缓冲区内个每据数的型类,这里顶点标坐应用的是浮点型类。第四个参数标明据数是不是须要normalized,归一化(对于有号符整数,归一化将使据数保持在[-1, 1]范围内,对于无号符整数,则在范围[0, 1])。第五个参数是步幅,指定了两个连续的顶点属性之间的偏移量(以字节为位单)。这里我们的据数是连续的,因此数值为0。最后一个参数看似是一个指针,但实际上它并非起到指针的作用。实际上,它标明缓冲区的扫尾离距第一个顶点属性之间的偏移量。这里,缓冲区里第一个顶点属性之前并没有任何额定的息信,因为我们取值为0。

    colors的递传任务是一样的。

// 2cond attribute buffer : vertices
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(
   1,                  // attribute 1. No particular reason for 0, but must match the layout in the shader.
   3,                  // size
   GL_FLOAT,           // type
   GL_FALSE,           // normalized?
   0,                  // stride
   (void*)0            // array buffer offset
);
    哇哈哈,于终有所的任务都成完了,在现以可就告知OpenGL真正开始绘制了!这一步非常简略只须要一个数函。(在这之前请确保已绑定了我们最开始创立的VAO,如果没有,请调用glBindVertexArray(VertexArrayID))

glDrawArrays(GL_TRIANGLES, 0, 3 );
    这个数函标明,OpenGL将逐渐拜访个每顶点属性的缓冲区,然后把据数递传到OpenGL线管里交给vertex shader。第一个参数是染渲模式,这里标明我们将应用三角形停止绘制。第二个参数是指,在开启的属性中的第一个索引,这里我们开启了两个属性,分别为0和1,因此第一个索引为0。第三个参数是指染渲所需的索引量数,这里我们应用三角形模式,因此个每三角形须要3个顶点。个每顶点须要一个索引。

    除了glDrawArrays,我们还可以应用glDrawElements停止绘制,这在后之的文章会讲到。

   

    你可能注意到,对于fragment shader的输出,FragColor我们没有停止任何任务,它存储了个每像素最后输出的颜色值。这里我们先不必管它,我们只要道知,它默许将会递传给后台的颜色缓冲以可就了。
分享到:
评论

相关推荐

    Unity 全息投影效果 Sci Fi Hologram Shader

    Unity 全息投影效果 Sci Fi Hologram Shader

    ShaderX1 & ShaderX2

    Shader X1 和 Shader X2的pdf文件,压缩包 Direct3D ShaderX: Vertex and Pixel Shader Tips and Tricks ShaderX2: Introductions and Tutorials with DirectX 9.0

    最好用描边shader

    该文件里面总共有12个项目,2个为一组,共有6种表面着色器shader。 【功能】改着色器成功的解决了一般的描边shader存在有以下问题: 1,会丢失原来的材质 2,效果不好 【使用方法/注意事项】 1,文件夹需要保存在...

    (固定管线渲染器)fixedFunctionShader1.rar

    fixedFunctionShader1.rar是一个固定管线渲染器的功能的示例,该示例基于unity2017.4.27f1 ,使用shaderLab编写的一个示例演示!

    6种Shader编程

    Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的...

    All In 1 Sprite Shader 3.43

    Unity 插件资源 All In 1 Sprite Shader 是一种多合一的解决方案,以最简单和最快速的方式,为你的项目添加流行的酷炫精灵图和 UI 特效。 其包含 40 多种可组合的特效。拥有无尽可能 功能: - 只需点击一下即可堆...

    Unity反射折射Refractive Shader 1.2材质shader着色器插件

    淘宝花RMB买的·····Refractive Shader 1.2 最新版本,请勿用于商业用途,仅...- Smoothness < 1 Blurs refracted scene Includes: - 3 Shaders with different GPU footprints - Demo Scene with some textures

    XNA:管理Shader

    在学习了一点儿shader和图形卡发展的历史之后,你将经历创建一个简单shader的过程,只要渲染一个带有每像素镜面反射光的简单3D模型,然后把shader导入到你的游戏引擎。你将用来创建shader、甚至在你开始把更多代码...

    Unity3D内置Shader 详解

    Unity里面的Shaders是使用一种叫ShaderLab的语言编写的,它同微软的.FX文件或者NVIDIA的CgFX有些类似。传统意义上的vertex shader和pixel shader 还是使用标准的Cg/HLSL 编程语言编写的。(因此Unity文档里面的...

    All In 1 Sprite Shader unitypackage

    Unity 插件资源 All In 1 Sprite Shader 是一种多合一的解决方案,以最简单和最快速的方式,为你的项目添加流行的酷炫精灵图和 UI 特效。

    Unity-HDRP-ShaderGraph-透明Shader-旋转动画

    使用ShaderGragh制作透明指针。 Shader动画,有时候比Transform的动画更加高效。...有一句话叫做:黑透白不透。 利用黑底贴图做底,其他部件使用白色,Shader透明类型选择Additive,即可完美剔除黑色部分。

    外发光材质Shader1

    外发光材质Shader Posted on 2013年06月28日 by U3d / Unity3D脚本/插件/被围观 166 次 游戏中我们经常会遇到需要制作

    unity shader入门精要源码part1

    本书是一本难得的好书,图形学原理讲解清楚,代码注释描述到位,配套资源完整,配合shader源码可以更好的调试和理解shader算法原理。part2搜索:unity shader入门精要源码part2。

    shadergraph制作的双面shader

    一个简单的URP双面shader

    AllIn1Shader 1.95.unitypackage

    AllIn1Shader 1.95.unitypackage

    基于u3d内置管线的二次元shader

    参考了很多文章写出来的shader一开始用来内置的阴影宏三剑客来做投影,发现效果不是很好,后面改用了shadowmap 效果视频链接【u3d二次元材质】 ...

    unity shader 深度测试 案例1

    unity shader 深度测试 案例1

    ShaderLibrary.rar

    但是使用一个内置的shader编写工具有很多好处,比如FX Composer,尤其是期望在修改shaders后得到即时的视觉反馈。此外,使用FX Composer这种工具可以让你在深入学习图形API之前,集中学习基本的shader编写。但是你不...

    Shader Forge 完全详解教程 第1弹

    Shader Forge 完全详解教程 第1弹

    threejs 光效shader所用图片 1

    threejs 光效shader所用图片 1threejs 光效shader所用图片 1threejs 光效shader所用图片 1threejs 光效shader所用图片 1threejs 光效shader所用图片 1threejs 光效shader所用图片 1threejs 光效shader所用图片 1...

Global site tag (gtag.js) - Google Analytics