OGLES顶点着色器

    xiaoxiao2021-03-25  92

    顶点着色器在模型变换到裁剪空间阶段,主要进行几何变换和光照的计算,逐顶点颜色,法线和纹理坐标计算。

    顶点着色器的输入包括

    1)属性 2)统一变量和统一变量缓冲区 3)采样器 4)着色器程序

    顶点着色器内建变量

    1)内建特殊变量

    gl_VertexID gl_Position gl_InstanceID gl_PointSize gl_FrontFacing是否是正面

    2)内建统一状态

    顶点着色器唯一可用的内建统一状态是窗口坐标中的深度范围。由内建统一变量: gl_DepthRange给出,该声明内建定义为: struct gl_DepthRangeParameters { highp float near; highp float far; highp float diff;// far - near } uniform gl_DepthRangeParameters gl_DepthRange;

    3)内建常量

    const mediump int gl_MaxVertexAttribs = 16;//16个vec4输入 const mediump int gl_MaxVertexUniformVectors = 256; const mediump int gl_MaxVertexOutputVectors = 16; // 16个vec4 const mediump int gl_MaxVertexTextureImageUnits = 16; // 顶点着色器中用的纹理最大数 const mediump int gl_MaxCombinedTextureImageUnits = 32;// 顶点和片段中用的纹理最大数

    顶点着色器的应用

    1)光照的计算

    分为平行光,点光源,聚光灯计算。 光源位置,方向,顶点位置方向,转换到统一的相对位置中,例如统一转换到世界坐标系或视图坐标系。 光源和材质的镜面反射,漫反射,环境光,还有材质高光光泽度,材质自发光。 在多光源光照下的计算,还要考虑点光源和聚光灯的衰减,阴影的作用,雾的作用。

    2)纹理坐标生成

    GL_SPHERE_MAP GL_REFLECTION_MAP GL_SPHERE_MAP计算方法为: vec2 sphere_map(vec3 position, vec3 normal) { reflection = reflect(position, normal); m = 2.0 * sqrt(reflection.x * reflection.x + reflection.y*reflection.y + (reflection.z + 1) *(reflection.z + 1)); return vec2((reflection.x / m + 0.5), (reflection.y / m + 0.5)); } GL_REFLECTION_MAP计算方法为: vec3 cube_map(vec3 position, vec3 normal) { return reflect(position, normal); }

    3)骨骼蒙皮动画

    顶点着色器骨骼动画,一般需要计算顶点位置和法向量位置,法向量一般用顶点变换矩阵即可(因为骨骼动画一般不包含非等比缩放),所以(M^-1)^T = M。

    4 ) 变换反馈

    使用变换反馈,可以将顶点着色器的输出到缓冲区对象中,缓冲区可作为后续绘图调用中顶点数据的来源,这种方法对于在GPU上执行动画而无需任何CPU干预的许多技术很有用,例如顶点动画或渲染到顶点缓冲区的物理学模拟。 // 1.设置顶点着色器相关顶点信息输出到指定的变换反馈缓冲区 glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); 例如: const char *feedbackVaryings[5] = { "v_position", "v_velocity", "v_size", "v_curtime", "v_lifetime" }; // Set the vertex shader outputs as transform feedback varyings glTransformFeedbackVaryings ( userData->emitProgramObject, 5, feedbackVaryings, GL_INTERLEAVED_ATTRIBS ); // Link program must occur after calling glTransformFeedbackVaryings glLinkProgram ( userData->emitProgramObject ); // 2.开始变换反馈绘制 glBeginTransformFeedback ( GL_POINTS ); glDrawArrays ( GL_POINTS, 0, NUM_PARTICLES ); glEndTransformFeedback(); // Create a sync object to ensure transform feedback results are completed before the draw that uses them. userData->emitSync = glFenceSync ( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 ); // 3.绑定自己的输出缓冲区到反馈缓冲区 // Set transform feedback buffer glBindBuffer ( GL_TRANSFORM_FEEDBACK_BUFFER, dstVBO ); glBindBufferBase ( GL_TRANSFORM_FEEDBACK_BUFFER, 0, dstVBO ); // Restore state // 4.禁止光栅化,避免片段着色器执行 glDisable ( GL_RASTERIZER_DISCARD ); glUseProgram ( 0 ); // 5.解绑定反馈缓冲区 glBindBufferBase ( GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0 ); glBindBuffer ( GL_ARRAY_BUFFER, 0 ); glBindTexture ( GL_TEXTURE_3D, 0 ); // Block the GL server until transform feedback results are completed glWaitSync ( userData->emitSync, 0, GL_TIMEOUT_IGNORED ); glDeleteSync ( userData->emitSync ); // 6.后续绘制设置使用输出数据 SetupVertexAttributes ( esContext, userData->particleVBOs[ userData->curSrcIndex ] );

    5)顶点纹理

    OES3.0顶点着色器中可以应用纹理,在用纹理数据处理顶点位置偏移的应用中很有用,类似地形和水面。 顶点着色器中执行纹理查找有一些限制: 细节层次不是隐含的计算。 不接受texture查找函数中的偏差参数。 基本纹理用于mip贴图纹理。 地形根据法线贴图进行凹凸设置: void main() { v_color = a_color; float displacement = texture(displacementMap, a_texcoord).a; vec4 displaced_position = a_position + vec4(a_normal*displacement, 0.0); gl_Position = u_mvpMatrix * displaced_position; }
    转载请注明原文地址: https://ju.6miu.com/read-39305.html

    最新回复(0)