前言

一般,在三维项目添加纹理的时候,经常会看到有和纹理操作的函数,先看一段片元着色器程序:在片元着色器中

#version 450 coreout vec4 FragColor;in vec2 TexCoords;uniform sampler2D depthMap;
uniform float near_plane;
uniform float far_plane;// required when using a perspective projection matrix
float LinearizeDepth(float depth)
{float z = depth * 2.0f - 1.0f; //Back to NDC return (2.0f * near_plane * far_plane) / (far_plane + near_plane - z * (far_plane - near_plane));
}void main()
{float depthValue = texture(depthMap, TexCoords).r;
//  FragColor = vec4(vec3(LinearizeDepth(depthValue) / near_plane), 1.0f);   // perspectiveFragColor = vec4(vec3(depthValue), 1.0f);  // orthographic
}

.cpp文件代码

//plane VAO VBOunsigned int planeVBO;glGenVertexArrays(1, &planeVAO);glGenBuffers(1, &planeVBO);glBindVertexArray(planeVAO);glBindBuffer(GL_ARRAY_BUFFER, planeVBO);glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), &planeVertices, GL_STATIC_DRAW);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));glEnableVertexAttribArray(2);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));glEnableVertexAttribArray(0);// load textures// -------------unsigned int woodTexture = loadTexture(FileSystem::getPath("resources/textures/wood.png").c_str());// configure depth map FBO// -----------------------const unsigned int SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024;unsigned int depthMapFBO;glGenFramebuffers(1, &depthMapFBO);//glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);        //为什么不绑定帧缓冲对象// create depth textureunsigned int depthMap;glGenTextures(1, &depthMap);glBindTexture(GL_TEXTURE_2D, depthMap);/******* 功能:指定一个二维纹理图像,纹理将指定纹理图像的一部分映射到纹理化为活动的每个图形基元上。/******* 当前片段着色器或顶点着色器使用内置纹理查找函数时,纹理处于活动状态/******* 参数1:target:指定活动纹理单元的目标纹理。必须是GL_TEXTURE_2D,/******* GL_TEXTURE_CUBE_MAP_POSITIVE_X,GL_TEXTURE_CUBE_MAP_NEGATIVE_X,/******* GL_TEXTURE_CUBE_MAP_POSITIVE_Y,GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,/******* GL_TEXTURE_CUBE_MAP_POSITIVE_Z,或GL_TEXTURE_CUBE_MAP_NEGATIVE_Z/******* 参数2:level:指定详细程度编号。级别0是基本图像级别。级别n是第n个缩略图缩小图像。/******* 参数3:internalformat指定纹理的内部格式。必须是下列符号常量之一:GL_ALPHA,GL_LUMINANCE,GL_LUMINANCE_ALPHA,GL_RGB,GL_RGBA/******* 这里我们Base Internal Format:包括:GL_DEPTH_COMPONENT,GL_DEPTH_STENCIL,GL_RED,GL_RG,GL_RGB,GL_RGBA,/******* 因为我们只关心深度贴图,所以我们把纹理格式定义为:GL_DEPTH_COMPONENT/******* 参数4:width:深度贴图解析度,指定纹理图像的宽度。所有实现都支持宽度至少为64 texels的2D纹理图像和宽度至少为16 texels的立方体贴图纹理图像。/******* 参数5:height:指定纹理图像的高度所有实现都支持至少64像素高的2D纹理图像和至少16像素高的立方体贴图纹理图像。/******* 参数6:border指定边框的宽度。必须为0。/******* 参数7:format指定纹理数据的格式。必须匹配internalformat。下面的符号值被接受:GL_ALPHA,GL_RGB,GL_RGBA,GL_LUMINANCE,和GL_LUMINANCE_ALPHA/******* 参数8:指定纹理数据的数据类型。下面的符号值被接受:GL_UNSIGNED_BYTE,GL_UNSIGNED_SHORT_5_6_5,GL_UNSIGNED_SHORT_4_4_4_4,和GL_UNSIGNED_SHORT_5_5_5_1/******* 参数9:data指定一个指向内存中图像数据的指针*******/glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);// attach depth texture as FBO's depth bufferglBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);

问题

当看到和纹理操作相关的函数,总是不知其意,理解不了,现在详细说明一下:下面这段是引用以为大神的文章“”

严正声明:
作者:psklf
出处: https://www.cnblogs.com/psklf/p/5762308.html
欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任!

Sampler (GLSL)

Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的。一个sampler和一个texture对应,类型也是对应的,比如sampler2D 的sampler对应的就是GL_TEXTURE_2D类型的纹理对象。Sampler是个变量,但是它是没有值的,或者說是特殊的一种类型,讨论其数值没有意义,只要明确其同一个texture对应即可。sampler变量在shader内使用的地方就是texture函数。这是一个lookup 函数(我不知道该如何翻译,我的理解是这是一个查找/查询的函数,以给定的纹理坐标去纹理的数据中查到相应的颜色的信息),得到颜色信息渲在每一个片元上。例如,一个三角形,我们只要传递三个纹理坐标给顶点着色器就行了,接着片元着色器会为每个像素生成纹理坐标的插值,根据纹理坐标就得到了每一个像素的颜色值。

纹理采样的机制

Texture Wrapping

纹理坐标通常的范围是从(0, 0)到(1, 1),如果我们把纹理坐标设置为范围以外会发生什么?OpenGL默认的行为是重复这个纹理图像(我们简单地忽略浮点纹理坐标的整数部分),但OpenGL提供了更多的选择:

  • GL_REPEAT:纹理的默认行为。重复纹理图像。
  • GL_MIRRORED_REPEAT:和GL_REPEAT一样,除了重复的图片是镜像放置的。
  • GL_CLAMP_TO_EDGE:纹理坐标会在0到1之间。超出的部分会重复纹理坐标的边缘,就是边缘被拉伸。
  • GL_CLAMP_TO_BORDER:超出的部分是用户指定的边缘的颜色。

在生成纹理对象的时候,需要用 glTexParameter() 设置一系列参数,设置的就是这个参数以及下面的 Texture Filtering 的参数。

Texture Filtering

magnification/minification

组成纹理的图片数据和其要贴上去的形状的大小往往是不一样的。两种情况:

  1. magnification:纹理图片小,贴图区域大,需要放大纹理
  2. minification:反过来,纹理图片大,贴图区域小,缩小纹理显示出来

在做放大和缩小的操作的时候的具体的策略如下:

  • GL_NEAREST:直接选择最临近的像素的颜色,magnification(放大)时:由于多个片元会在同一个纹理像素上面取值,故最终得到的图片颗粒度很大,会有锯齿。
  • GL_LINEAR:根据临近四个的像素点的颜色值,做线性的插值计算,得到最终的颜色。magnification(放大)时:不会产生锯齿,显示更加平滑。

在minification(缩小)时,上面的两种方法其实都不理想,无论如何都会丢失很多图片的细节,OpenGL 用Mipmap来解决这个问题。

Mipmap

它就是一系列纹理,每个后面的一个纹理是前一个的二分之一,这一系列的纹理是OpenGL生成的,生成时进行了图像质量的优化,使其拥有更多的细节。这一系列的纹理是提前生成的,程序运行时只需要从中挑出合适大小的纹理应用即可,而不是运行时进行图像大小的处理,效率上会有提高。

OpenGL渲染的时候,两个不同级别的mipmap之间会产生不真实感的生硬的边界。就像普通的纹理过滤一样,也可以在两个不同mipmap级别之间使用NEAREST和LINEAR过滤。指定不同mipmap级别之间的过滤方式可以使用下面四种选项代替原来的过滤方式:

  • GL_NEAREST_MIPMAP_NEAREST:接收最近的mipmap来匹配像素大小,并使用最临近插值进行纹理采样。
  • GL_LINEAR_MIPMAP_NEAREST:接收最近的mipmap级别,并使用线性插值采样。
  • GL_NEAREST_MIPMAP_LINEAR:在两个mipmap之间进行线性插值,通过最邻近插值采样。
  • GL_LINEAR_MIPMAP_LINEAR:在两个相邻的mipmap进行线性插值,并通过线性插值进行采样。

总结一下:magnification和minification的时候都可以设置NEAREST和LINEAR两种方式;minification的时候还可以设置mipmap的方式,该方法效果更好。关于具体的算法的实现,可以参考《OpenGL ES specification》的8.13-8.14内容。

Sampler object

一个texture对象包括了两部分的属性,一部分是具体的图片信息,另一部分是纹理采样的设置,即上文提到的不同的方式。通常生成纹理的时候是将这两部分一起设置好的,但是后面这部分的内容可以单独拿出来,封装成为一个对象,就是 sampler object .

使用 GenSamplers() 函数创建一个新的sampler对象,然后用 BindSampler() 做绑定操作,将sampler和texture对象绑定起来,然后调用 glSamplerParameterf() 这一类的函数来设置sampler的具体的参数。

texture object, sampler object, program object 的关系如图:

另外,看一下texture在openGL整个渲染流程中的位置

官方文档地址

原文以及翻译

Name

texture — retrieves texels from a texture

取出二维纹理中该纹理坐标点上的纹理像素值

Declaration

gvec4 texture( gsampler2D sampler,
vec2 P,
[float bias]);
gvec4 texture( gsampler3D sampler,
vec3 P,
[float bias]);
gvec4 texture( gsamplerCube sampler,
vec3 P,
[float bias]);
float texture( sampler2DShadow sampler,
vec3 P,
[float bias]);
float texture( samplerCubeShadow sampler,
vec4 P,
[float bias]);
gvec4 texture( gsampler2DArray sampler,
vec3 P,
[float bias]);
float texture( sampler2DArrayShadow sampler,
vec4 P);
gvec4 texture( gsamplerCubeArray sampler,
vec4 P,
[float bias]);
float texture( samplerCubeArrayShadow sampler,
vec4 P,
float compare);

Parameters

sampler

Specifies the sampler to which the texture from which texels will be retrieved is bound.

指定纹理绑定到的采样器

P

Specifies the texture coordinates at which texture will be sampled.

指定纹理采样的纹理坐标

bias

Specifies an optional bias to be applied during level-of-detail computation.

指定在详细级别计算期间应用的可选偏差。  (可省略)

compare

When present, specifies the reference for shadow comparisons.

当存在时,指定阴影比较的参考

Description

texture samples texels from the texture bound to sampler at texture coordinate P. An optional bias, specified in bias is included in the level-of-detail computation that is used to choose mipmap(s) from which to sample.

For shadow forms, when compare is present, it is used as DsubDsub and the array layer is specified in P.w. When compare is not present, the last component of P is used as DsubDsub and the array layer is specified in the second to last component of P.

For non-shadow variants, the array layer comes from the last component of P.

在纹理坐标p处,从纹理绑定到采样器的纹理纹理素。一个可选的偏差,在偏差中指定,被包含在详细级别计算中,用于选择从其中取样的mipmap(s)。

对于阴影形式,当compare存在时,它被用作DsubDsub,数组层在P.w中指定。当compare不存在时,P的最后一个组件被用作DsubDsub,数组层在P的倒数第二个组件中指定。

对于非阴影变量,阵列层来自于P的最后一个分量。

Version Support

OpenGL ES Shading Language Version
Function Name 1.00 3.00 3.10 3.20
texture -
texture (gSamplerCubeArray, samplerCubeArrayShadow) - - -

See Also

texelFetch, texelFetchOffset, textureGrad, textureGradOffset, textureLod, textureLodOffset, textureOffset, textureProj, textureProjGrad, textureProjGradOffset, textureProjLod, textureProjLodOffset, textureProjOffset, textureSize

Copyright

Copyright © 2011-2015 Khronos Group. This material may be distributed subject to the terms and conditions set forth in the Open Publication License, v 1.0, 8 June 1999. http://opencontent.org/openpub/.

openGL GLSL texture()函数详解相关推荐

  1. openGL API glGetShaderInfoLog函数详解

    glGetShaderInfoLog详解 官方文档 翻译 例子 代码分析 glGetShaderInfoLog输出错误 工程下载 官方文档 官网文档 Name glGetShaderInfoLog - ...

  2. OpenGL之gluLookAt 函数详解

    本文代码是基于上一篇文章"基于Viusal C++ 2015 MFC单文档程序中搭建OpenGL框架"的基础上运行 void gluLookAt(GLdouble eyex,GLd ...

  3. OpenGL,GLUT,FreeGLUT,GLFW,GLEW,GLAD,GL3W,GLAD,GLM,GLSL的区别详解

    OpenGL,GLUT,FreeGLUT,GLFW,GLEW,GLAD,GL3W,GLAD,GLM,GLSL的区别详解 很多同学在初学计算机图形学时,都要去配置OpenGL环境,其中涉及多个库的选择和 ...

  4. glTexImage2D 函数详解

    glTexImage2D 函数详解 参考 https://blog.csdn.net/jeffasd/article/details/78135588 版权 jeffasd glTexImage2D ...

  5. 什么是渲染目标(render target) 渲染到纹理(Render To Texture, RTT)详解

    渲染到纹理(Render To Texture, RTT)详解 RTT是现在很多特效里面都会用到的一项很基本的技术,实现起来很简单,也很重要.但是让人不解的是网上搜索了半天只找到很少的文章说这个事儿, ...

  6. C语言网络编程:accept函数详解

    文章目录 前言 函数描述 代码实例 如何得到客户端的IP 和 端口号 前言 当使用tcp服务器使用socket创建通信文件描述符,bind绑定了文件描述符,服务器ip和端口号,listen将服务器端的 ...

  7. 【FFmpeg】函数详解(三)

    FFmpeg函数详解 14.av_write_frame 15.av_interleaved_write_frame 16.av_write_trailer 17.avio_close 18.av_i ...

  8. 【FFmpeg】函数详解(二)

    FFmpeg函数详解 9.av_dump_format 10.avio_open 11.avformat_write_header 12.avcodec_send_frame 13.avcodec_r ...

  9. 【FFmpeg】函数详解(一)

    FFmpeg函数详解 一.错误码相关 1.AVERROR 2.av_strerror 3.其他错误码解释 二.编解码 1.获取编解码器 2.申请.释放上下文环境 3.打开编码器avcodec_open ...

最新文章

  1. 菜鸟教程:SQL 通用数据类型
  2. selenium + python自动化测试unittest框架学习(二)
  3. 开关灯效果思路代码分享
  4. Android检查是否自启动,android – 如何检查我的应用程序是否是默认启动器
  5. 推荐一篇文章,.net3.0新特性
  6. 给mysql数据库设计编码_MYSQL数据库编码原理
  7. Spring 7大功能模块的作用[转]
  8. vue 查询框赋值后不可编辑_vue input 赋值无效
  9. java scanner 回车_Java Scanner类用法及nextLine()产生的换行符问题实例分析
  10. iOS开发之来自一线开发者的Swift学习资源推荐
  11. Linux ssh服务开启秘钥和密码认证
  12. kkfile跨域预览_kkFileView开源项目实现office各种格式在线预览
  13. C#做小工具的时候碰到的问题
  14. 神秘邻居把我的信息卖给了诈骗团伙
  15. CentOS安装VMwareTools
  16. 安全进化的终极猜想— 以“AI之盾”对抗“AI之矛”
  17. Vue使用echarts报错提示 vue.runtime.esm.js?2b0e:1897 Error: Initialize failed: invalid dom.
  18. 图形界面 I: 在METATRADER 4终端中使用不同类型的程序来测试界面库 (第五章)
  19. mysql中locat函数,MySQL中的LOCATE和POSITION函数使用方法
  20. RGB与HSV颜色空间转换

热门文章

  1. 关于组建研发团队的招聘
  2. android客户端集成微信登录
  3. PMSM学习(2)——磁链、电压、转矩方程
  4. 《游戏脚本的设计与开发》-(RPG部分)3.5 游戏背包和任务系统
  5. 不要Google,要Stumble!
  6. matlab画转矩图和弯矩图,静定梁的内力计算与内力图绘制的基本方法
  7. 大学计算机专业核显和集显,分不清核显和独显?一分钟带你了解清楚
  8. 城乡供水一体化管控平台-农村供水监管平台-乡村振兴
  9. kafka是如何做到百万级高并发低迟延的?
  10. [附源码]JSP+ssm计算机毕业设计艾儿影楼管理系统18llj【源码、数据库、LW、部署】