OpenGL ES 3.0编程指南:第八章. Vertex Shaders---(一)

[TOC]

摘要

本章主要介绍顶点shader,顶点shader可以用来做一些传统的基于顶点的操作,例如:通过矩阵变换位置、计算光照以生成逐顶点颜色、生成或者变换纹理坐标等。
在本章中,首先概述介绍顶点shader,包括其输入和输出。然后通过一些例子来介绍如何编写shader,例如用一个MVP矩阵来变换顶点位置、漫反射和高光反射、纹理坐标生成、顶点蒙皮和位移贴图。最后,介绍一下OpenGL ES 1.1版本中的固定渲染管线的顶点shader。

1. Vertex Shader Overview

顶点shader提供了可对顶点进行操作的编程方法。下图展示了一个顶点shader的输入和输出:


OpenGL ES 3.0编程指南:第八章. Vertex Shaders---(一)_第1张图片

顶点shader的输入包括:

  • Attributes :逐顶点数据
  • Uniforms and uniform buffers : 顶点shader使用的常量数据
  • Samplers(采样器) : 表示纹理的一个特殊类型的uniform
  • Shader program : 顶点shader的源码或可执行文件

Vertex Shader Built-In Variables

Built-In Special Variables
  • gl_VertexID 是一个精度为 highp 的整型输入变量,表示顶点的索引。
  • gl_InstanceID 是一个精度为 highp 的整型输入变量,表示一次实例化draw call 过程中图元的实例编号。如果是常规的 draw call,则该值为0。
  • gl_Position 是一个精度为 highp 的浮点型输出变量,用来输出顶点位置。如果在 vertex shader 中没有写入 gl_Position,那么它的值是未定义的。
  • gl_PointSize 是一个精度为 highp 的浮点型输出变量,用来表示 point sprite 的大小,它的值有一个限制范围,有OpenGL ES的具体实现来限制。
  • gl_FrontFacing 是一个布尔型变量,它不是由vertex shader直接写入,而是根据顶点位置和图元类型自动生成。
Built-In Uniform State

gl_DepthRange是顶点着色器中唯一可用的内建统一变量,它的类型是 gl_DepthRangeParameters

struct gl_DepthRangeParameters
{
    highp float near;
    highp float far;
    highp float diff; // far - near
}
uniform gl_DepthRangeParameters gl_DepthRange;
Built-In Constants
const mediump int gl_MaxVertexAttribs    = 16;
const mediump int gl_MaxVertexUniformVectors    = 256;
const mediump int gl_MaxVertexOutputVectors    = 16;
const mediump int gl_MaxVertexTextureImageUnits    = 16;
const mediump int gl_MaxCombinedTextureImageUnits    = 32;

以上常量值是所有OpenGL ES 3.0实现必须支持的最小值,实际上一些OpenGL ES 3.0实现可能支持更大的值,具体值查询:

GLint maxVertexAttribs, maxVertexUniforms, maxVaryings;
GLint maxVertexTextureUnits, maxCombinedTextureUnits;

glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
glGetIntegerv (GL_MAX_VERTEX_UNIFORM_VECTORS, &maxVaryings);
glGetIntegerv (GL_MAX_VARYING_VECTORS, &maxVaryings);
glGetIntegerv (GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextureUnits);
glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedTextureUnits);

Precision Qualifiers

三种精度 : lowp,mediump,highp
如果一个变量没有指点精度,就使用默认精度,在顶点着色器和片段着色器的顶部可以指定默认精度。在顶点着色器中,如果没有指定默认精度,那么int和float的默认精度都是 highp。

precision highp float;
precision mediump int;

在顶点着色器中进行的操作,最可能需要的精度是 highp。

Number of Uniforms Limitation in a Vertex Shader

Uniform 用于储存如下变量:

  • 用uniform修饰的变量
  • 常量
  • 字面值
  • 特定于实现的变量

对于字面值, OpenGL ES 3.0不做常量传播,也就是说同一个字面值的多个实例会被计数多次,例如:

v_texcoord[0] = vec4 (0.0, 0.0, 0.0, 1.0);
v_texcoord[1] = vec4 (0.0, 0.0, 0.0, 1.0);

为了保证字面值只被计数一次,修改如下:
const int c_zero = 0;
const int c_one = 1;
v_texcoord[c_zero] = vec4 ( float(c_zero), float(c_zero), float(c_zero), float(c_one) );
v_texcoord[c_one] = vec4 ( float(c_zero), float(c_zero), float(c_zero), float(c_one) );

你可能感兴趣的:(OpenGL ES 3.0编程指南:第八章. Vertex Shaders---(一))