美文网首页OpenGL
iOS开发OpenGL ES学习 - 深入着色器

iOS开发OpenGL ES学习 - 深入着色器

作者: HoFie | 来源:发表于2018-01-18 16:40 被阅读93次

在上一篇已经讲过着色器了,但只是简单的介绍了着色器语言的数据类型,这里就继续介绍着色器语言,让你更全面的了解GLSL语言。

在前面我们已经知道OpenGL的渲染过程,其中的顶点着色器和片段着色器都是可编程的。顶点着色器是负责应用程序传入的顶点数据处理,而片段着色器主要是做最后显示的像素处理,这也说明为什么片段着色器无法直接接受顶点数据的原因。

关于着色器的基本编写与应用在前面的文章中已经说过。Xcode中可以在新建文件 -> Other -> Empty保存文件名后缀为.glsl即可。
然后就是着色器源码的运行时编译,这个在前面也有封装。

GLSL语法:
先可以看下上一篇的vetexShader源码

attribute vec4 Position;
void main(void) {
     gl_Position = Position;
}

比较简单,在接受到顶点数据之后不做任何处理直接赋值给gl_Position。

而片段着色器:

uniform vec4 color;
void main(void) {
    gl_FragColor = color;
}

我们定义了一个uniform属性,相当于全局属性,可以从应用程序中直接传值。

GLSL变量声明:
我们先看一下做过改进的着色器

attribute vec4 position;
attribute vec4 color;
uniform float variable;
varying vec4 fColor;
void main(void) {
    fColor = color;
    float xPos = position.x * sin(variable);
    float yPos = position.y * sin(variable);
    gl_Position = vec4(xPos, yPos, position.z, 1.0);
}

先看属性声明:
1.顶点位置属性:attribute是变量类型,vec4是数据类型,position是变量名
3.uniform:相当于定义的全局变量
4.varying:传递给片段着色器的变量,因为片段着色器无法直接接受顶点数据。

主函数体:
1.将传入的颜色数据color不作任何修改赋值给fColor
2.将位置变量的x值sin(change),其中change是应用程序传入
3.同样将位置变量的y值
sin(change)
4.赋值给gl_Position

下面再看片段着色器:

varying lowp vec4 fColor;
void main(void) {
    gl_FragColor = fColor;
}

比较简单,定义一个varying类型的4分享向量fColor以接受顶点着色器传入的颜色数据fColor未做处理直接赋值给gl_FragColor

看一下处理的最终效果:

对于顶点着色器中的处理不难理解,把顶点坐标的x和y乘以一个常量的正弦值,因为sin()值域在-1和1之间,所以三角形的顶点坐标会在正负之间转换,如果为0的话,那么就是在正中心,所以才有出现三角形颠倒转换和大小的收缩。

既然可以改变顶点坐标,那么我们也可以试试改变图形颜色,这里直接操作片段着色器即可:

precision highp float;
varying lowp vec4 fColor;
uniform float variable;
void main(void) {

// sin()的值域在[-1,1],而颜色分量值在0和1之间,所以将!sin()+1) / 2
    float scale = (sin(variable) + 1.0) / 2.0;
    gl_FragColor = fColor * scale;
}

第一行是指明变量的精度,在fragment shader的变量只能是uniform和varying,这里的varying是从Vertex Shader传过来的值。与Vertex Shader不同的是,这里的变量都要声明精度,比如 highp float processedElapsedTime = elapsedTime;中的highp代表高精度。精度包括lowp highp mediump,低精度,高精度,中等精度。如果你不想为每一个变量都指定精度可以在第一行写上precision highp float; ,当然这只是为float指定默认精度highp。要为其他类型指定精度的话继续加就好了。

在应用程序中,我们需要新增代码为change属性复制:

GLuint variableLoca = glGetUniformLocation(program, "variable");
glUniform1f(variableLoca, (GLfloat)self.changeValue);

先获取uniform highp float variable的位置,因为variable是float类型,所以使用glUniform1f进行赋值。

最后效果如下: 我们还可以设置每个顶点坐标进行旋转,从而达到整个三角形都在旋转的效果:

需要源码可以移步GitHub

参考《OpnGL ES编程指南》

相关文章

  • 资料

    多媒体 Android 音视频开发学习思路OpenGL ES 着色器语言GLSL

  • iOS开发OpenGL ES学习 - 深入着色器

    在上一篇已经讲过着色器了,但只是简单的介绍了着色器语言的数据类型,这里就继续介绍着色器语言,让你更全面的了解GLS...

  • 着色器

    着色器 OpenGL ES着色器语言之变量和数据类型(一) 我的OpenGL ES学习之路(一):GLSL着色器语言

  • OpenGL ES学习 - 着色器

    iOS开发之OpenGL ES学习01 -- Hello Triangle GLSL前一篇主要是学习OpenGL的...

  • Opengl es shading language

    着色器语言学习推荐:3.0文档,对应opengl es 3.0(默认1.0 对应opengl es 2.0) 概述...

  • OpenGL ES 3.0(二)着色器语言

    OpenGL ES 着色器语言:OpenGL ES Shading Language,下面简写为 ES SL 或 ...

  • 初识GLKit

    GLKit 框架是为了简化iOS上OpenGL ES的开发,提供的基于OpenGL ES的iOS框架。 实现思路:...

  • OpenGL ES 学习笔记(一)

    一. 着色器 顶点着色器的输出在OpenGL ES 2.0中称作varying,但是在OpenGL ES 3.0改...

  • ios开发-OpenGL ES 学习一

    前言 学习OpenGL ES的过程,主要是看 《OpenGL ES应用开发指南 ios卷》这本书,这本书里面对于O...

  • OpenGL ES 3.0 | 着色器编译器

    概述 当你要求OpenGL ES 编译和链接着色器时,思考 OpenGL ES 实现 必须要做的事情; 着色器代码...

网友评论

    本文标题:iOS开发OpenGL ES学习 - 深入着色器

    本文链接:https://www.haomeiwen.com/subject/bloxoxtx.html