opengl纹理贴图应该放在纹理左下角为坐标原点。根据查询相关公开信息显示,OpenGL中纹理坐标系是以纹理左下角为坐标原点的,而中像素的存储顺序是从左上到右下的,因此我们需要对我们的坐标系进行一次Y轴的翻转。
3d打印机导入三维模型通常都是obj格式,下面我们来看一下这种文件的格式。为我们进行产品开发提供技术基础储备。
obj格式有4种数据,分别以一下字母开头:
v顶点
vt纹理坐标
vn顶点法向量
f 面
一、顶点
格式:v x y z
意义:每个顶点的坐标
二、纹理坐标
格式:vt u v w
意义:绘制模型的三角面片时,每个顶点取像素点时对应的纹理上的坐标。纹理的坐标指的是,纹理如果被放在屏幕上显示时,以屏幕左下角为原点的坐标。
注意:w一般用于形容三维纹理,大部分是用不到的,基本都为0。
三、顶点法向量
格式:vn x y z
意义:绘制模型三角面片时,需要确定三角面片的朝向,整个面的朝向,是由构成每个面的顶点对应的顶点法向量的做矢量和决定的(xyz的坐标分别相加再除以3得到的)。
四、面
格式 :f v/vt/vn v/vt/vn v/vt/vn(f 顶点索引 / 纹理坐标索引 / 顶点法向量索引)
意义:绘制三角面片的依据,每个三角面片由三个f构成,由f可以确定顶点、顶点的对应的纹理坐标(提取纹理对应该坐标的像素点)、通过三个顶点对应的顶点法向量可以确定三角面的方向。
补充:有些模型可能会出现四边形的绘制方式,那样的模型关于面的数据描述是这样的 f v/vt/vn v/vt/vn v/vt/vn v/vt/vn ,比三角面绘制方式多一项数据。
补充说明:
顶点的个数与顶点法向量的个数一样多。
顶点的个数不一定与纹理坐标的个数一样多,因为有可能很多顶点公用一个纹理坐标的像素。
面索引的个数也与其余数据数量无关。
最终每个三角面的颜色,是由构成这个三角面的三个顶点进行插值计算(有例如:一个三角面其中两个顶点对应的纹理坐标是黑色的,另外一个是白色,那整个面呈现的颜色是由黑变白渐变,而不是三个颜色值的平均值。这就是插值的作用)来确定。所以面的颜色有可能不与每个点的颜色一致。
深度纹理实际就是一张渲染纹理,只不过它里面存储的像素值不是颜色值,而是一个高精度的深度值。由于被存储在一张纹理中,深度纹理里的深度值范围是[0, l], 而且通常是非线性分布的。这些深度值来自于顶点变换后得到的归一化的设备坐标 (Normalized Device Coordinates , 简称NDC) 。一个模型要想最终被绘制在屏幕上,需要把它的顶点从模型空间变换到齐次裁剪坐标系下,这是通过在顶点着色器中乘以 MVP 变换矩阵得到的 。在变换的最后一步,我们需要使用一个投影矩阵来变换顶点,当我们使用的是透视投影类型的摄像机时,这个投影矩阵就是非线性的。
下图 显示了Unity 中透视投影对顶点的变换过程。最左侧的图显示了投影变换前,即观察空间下视锥体的结构及相应的顶点位置,中间的图显示了应用透视裁剪矩阵后的变换结果,即顶点着色器阶段输出的顶点变换结果 ,最右侧的图则是底层硬件进行了透视除法后得到的归一化的设备坐标(NDC)。需要注意的是,这里的投影过程是建立在Unity对坐标系的假定上的,也就是说,针对的是观察空间为右手坐标系,使用列矩阵在矩阵右侧进行相乘,且变换到NDC后 z分量范围将在[-1, l] 之间的情况。而在类似 DirectX 这样的图形接口中,变换后z分量范围将在[0, 1]之间 。如果是在其他图形接口下,需要对一些计算参数做出相应变化。
下图 显示了在使用正交摄像机时投影变换的过程。同样,变换后会得到一个范围为 [-1, 1]的立方体。正交投影使用的变换矩阵是线性的。
在得到NDC后,深度纹理中的像素值就可以很方便地计算得到了,这些深度值就对应了NDC中顶点坐标的z分量的值。由于NDC中 z分量的范围在[-1, I], 为了让这些值能够存储在一张图像中,需要使用下面的公式对其进行映射:
其中,d对应了深度纹理中的像素值, 对应了NDC坐标中的z分量的值。
在Unity中,深度纹理可以直接来自于真正的深度缓存,也可以是由一个单独的 Pass 渲染而得,这取决于使用的渲染路径和硬件。通常来讲,当使用延迟渲染路径(包括遗留的延迟渲染路径)时,深度纹理理所当然可以访问到,因为延迟渲染会把这些信息渲染到 G-buffer 。而当无法直接获取深度缓存时,深度和法线纹理是通过一个单独的Pass渲染而得 。具体实现是Unity会使用着色器替换技术选择那些渲染类型(即 SubShader RenderType 标签)为 Opaque 的物体,判断它们使用的渲染队列是否小于等于2500(内置的 Background Geometry AlphaTest 渲染队列均在此范围内),如果满足条件,就把它渲染到深度和法线纹理中。因此,要想让物体能够出现在深度和法线纹理中,就必须在Shader中设置正确的RenderType标签。
在 Unity中,可以选择让一个摄像机生成一张深度纹理或是一张深度+法线纹理。当选择前者,即只需要 张单独的深度纹理时, Unity 会直接获取深度缓存或是按之前讲到的着色器替换技术,选取需要的不透明物体,并使用它投射阴影时使用的 Pass (即 LightMode 被设置为ShadowCaster Pass)来得到深度纹理。如果 Shader 中不包含这样一个 Pass, 那么这个物体就不会出现在深度纹理中(当然,它也不能向其他物体投射阴影)。深度纹理的精度通常24 位或 16 位,这取决于使用的深度缓存的精度。如果选择生成一张深度+法线纹理, Unity 创建一张和屏幕分辨率相同、精度为 32 位(每个通道为 位)的纹理,其中观察空间下的法线信息会被编码进纹理的 通道,而深度信息会被编码进 通道。法线信息的获取在延迟渲染中是可以非常容易就得到的, Unity 只需要合并深度和法线缓存即可。而在前向渲染中,默认情况下是不会创建法线缓存的,因此 Unity 底层使用了一个单独的 Pass 把整个场景再次渲染一遍来完成。这个 Pass 被包含在 Unity 内置的一个 Unity Shader 中,可以在内置的builtin_shaders-xxx/DefaultResources/Camera-DepthNormaITextureshader 文件中找到这个用于渲染深度和法线信息的 Pass。
获取深度纹理,先设置摄像机的 depthTextureMode:
然后在 Shader 中通过声明_CameraDepthNormalsTexture 变量来访问它。
同理,如果需要获取获取深度+法线纹理,设置摄像机的 depthTextureMode为:
然后在 Shader 中通过声明_CameraDepthN ormalsTexture 变量来访问它。
还可以组合这些模式,让一个摄像机同时产生一张深度和深度+法线纹理:
在 Shader 中访问到深度纹理_CameraDepthTexture 后,我们就可以使用当前像素的纹理坐标对它进行采样。绝大多数情况下,我们直接使用 tex2D 函数采样即可,但在某些平台(例如 PS3 PSP2) 上,我们需要 一些特殊 处理 Unity 为我们提供了一个统一的宏SAMPLE_DEPTH_TEXTURE, 用来处理这些由于平台差异造成的问题。而我们只需要在 Shader中使用 SAMPLE_DEPTH_TEXTURE 宏对深度纹理进行采样,例如:
其中,iscrPos是在顶点着色器中通过调用ComputeScreenPos(opos)得到的屏幕坐标。上述这些宏的定义,可以在Unity 内置的HLSLSupportcginc文件中找到。
当通过纹理采样得到深度值后,这些深度值往往是非线性的,这种非线性来自于透视投影使用的裁剪矩阵。然而,在我们的计算过程中通常是需要线性的深度值,也就是说,我们需要把投影后的深度值变换到线性空间下,例如视角空间下的深度值,我们只需要倒推顶点变换的过程即可。下面以透视投影为例,推导如何由深度纹理中的深度信息计算得到视角空间下的深度值。
当我们使用透视投影的裁剪矩阵 对视角空间下的一个顶点进行变换后,裁剪空间下顶点的z和w分量为:
其中,Far和Near分别是远近裁剪平面的距离。然后,我们通过齐次除法就可以得到NDC下的z分量:
而深度纹理中的深度值是通过下面的公式由NDC 计算而得的:
由上面的这些式子,可以推导出用d表示而得的 的表达式:
由于在Unity 使用的视角空间中,摄像机正向对应的z值均为负值,因此为了得到深度值的正数表示,我们需要对上面的结果取反,最后得到的结果如下:
它的取值范围就是视锥体深度范围,即[Near, Far]。如果我们想得到范围在[0, l]之间的深度值,只需要把上面得到的结果除以Far即可。这样,0就表示该点与摄像机位于同一位置,1表示该点位于视锥体的远裁剪平面上。结果如下:
其实,Unity提供了两个辅助函数来为我们进行上述的计算过程LinearEyeDepth 和LinearOlDepth。LinearEyeDepth 负责把深度纹理的采样结果转换到视角空间下的深度值,也就是我们上面得到的 。而Linear01Depth则会返回一个范围在[0, 1]的线性深度值,也就是我们上面得到的 。这两个函数内部使用了内置的_ZBufferParams变量来得到远近裁剪平面的距离。
如果需要获取深度+法线纹理,可以直接使用tex2D函数对_CameraDepthNormalsTexture 进行采样,得到里面存储的深度和法线信息。Unity提供了辅助函数来为我们对这个采样结果进行解码,从而得到深度值和法线方向。这个函数是DecodeDepthNormal,它在UnityCGcginc 里被定义为:
DecodeDepthNormal 的第一个参数是对深度+法线纹理的采样结果,这个采样结果是 Unity 深度和法线信息编码后的结果 它的 xy 分量存储的是视角空间下的法线信息 而深度信息被编码进了 zw 分量。通过调用 DecodeDepthNormal 函数对采样结果解码后, 我们就可 得到解码后的深度值和法线。这个深度值是范围在[O l] 的线性深度值(这与单独的深度纹理中存储 深度值不同),而得到的法线则是视角空间下的法线方向。同样也可以通过调用 DecodeFloatRG和DecodeViewNormalStereo 来解码深度+法线纹理中的深度和法线信息。
关于wps纹理设置这个问题我之前遇到过,挺容易解决的,接下来就跟大家讲讲应该怎么 *** 作:
工具:联想R9000,wps1。0
第一步,首先我们在电脑中打开wps文档,再点击文件选项。(如下图所示)
第二步,进入文件选项后,在视格式选项菜单中点击背景选项。(如下图所示)
第三步,最后我们再点击选中纹理即可。(如下图所示)
以上就是关于wps纹理设置的所有步骤啦,对你有用的话记得点赞点关注呀~
UE5纹理平铺的贴图一般处理为两种贴图类型,分别是纹理贴图和像素贴图。纹理贴图是将纹理图像拉伸到模型表面,以获得更真实的外观效果,而像素贴图则是将像素图像拉伸到模型表面,以获得更高的细节级别。
3dsMax软件提供了多种贴图坐标来使纹理贴图更加精准和自然。其中,最常用的是UVW映射坐标系统,它是一种基于物体的表面几何形状所创建的坐标,可以确保纹理准确贴在物体的表面上。还有环绕映射坐标,可以让纹理围绕物体表面旋转,根据物体的表面法线的变化来自适应调整。此外,球形、柱面、平面和盒形贴图等坐标系统也可以根据不同场景的需要来进行选择和使用,方便快捷。
格式,如 jpg/png 等
纹理格式,如 ETC1/ETC2/PVRTC/ASTC等
电脑硬盘上的文件用来保存图形或图像的信息,包括大小、颜色等。的格式很多,但总体上可以分为 点阵图 和矢量图两种。
常见的位图格式:
考虑无压缩的 bmp 格式位图,文件在硬盘上的大小和以下几个因素有关
文件被加载到内存后,被转换为显卡能够识别的 纹理 提交到显存中,供 GPU 进行采样,纹理采样是根据 uv 坐标获得对应纹理中 纹素 颜色值的过程。
不同的显卡和图形API对纹理格式的支持不一样,RGBA32被显卡和图形API完全支持,DirectX特有的DXTx只有微软的部分设备支持,Android设备广泛支持ETC系列,iOS则支持 PVRTC 系列。
CPU将从硬盘加载到内存中,进行解码得到 RGBA32 格式位图,然后在 CPU 端进行编码,得到GPU支持的纹理格式,提交到显存供 GPU 采样访问。
这个过程中需要进行解码、重新编码,非常消耗 CPU,为了减少 CPU 的消耗,因此可以把预先转换成某种纹理格式放到硬盘上,CPU 加载后不需要解码和重新编码,直接提交给 GPU。大大节省了纹理从加载到使用的性能。
在Unity中,任何文件格式都存在一个导入过程,导入后的文件格式都是Texture2D,在Texture2D的导入设置选项中需要针对不同平台设置纹理压缩格式,在构建时,会直接将转换后的纹理格式构建到安装包或 assetbundle 中。
使用纹理压缩格式的好处
GPU 通常并行处理若干数据,无法预测纹理中纹素被访问的先后顺序,因此纹理格式必须支持GPU的 随机访问 :
几乎所有的纹理压缩算法都 以块为单位 压缩和存储纹素,可以理解为,每个纹素块(通常为4x4)占用的字节数是确定的,所以当我们需要访问某一个坐标的纹素时,可以明确得到该纹素所在块的数据,GPU纹理采样单元针对该块进行解压,读取对应纹素数据即完成采样。
而jpeg/png这类压缩算法考虑了的整体数据,像素数据之间互相依赖,无法针对其中某一块进行解压,必须全部解压才能正确访问纹素,所以不适宜作为纹理格式。
纹理压缩算法几乎都是有损压缩,通常情况下有限度的信息损失换到的性能上的提升是值得的。
如果使用了硬件不支持的纹理压缩格式,Unity在运行时会对纹理进行解压所到无压缩格式,而这种无压缩格式只是格式上是无压缩的,但是因为原始数据是有损压缩,所以视觉上纹理精度和压缩格式是一致的,因此单从视觉上很难察觉,而且占用的内存是双份纹理的开销,而带宽开销是无压缩格式的纹理大小所占用的开销。
例如:ETC格式在PC端Dx11的显卡是不支持的,如果使用,开销计算如下
1024 x 1024 ETC2 8bit的格式在PC端,会产生5M的内存开销(1M压缩的原图+4M解压出来的RGBA32bit图)
1024 x 1024 ETC 4bit格式在PC端,会产生45M的内存开销(05M压缩的原图+4M解压出来的RGBA32bit图)
而如果贴图格式在目标设备上支持,则不会发生内存中的解压缩 *** 作,压缩过的图大小是多少,在内存中的设备上大小就是多少:
1024 x 1024 ETC2 8bit的格式在Android端,会产生1M的内存开销(1M压缩的原图)
1024 x 1024 ETC 4bit格式在Android端,会产生05M的内存开销(05M压缩的原图)
纹理压缩是一次性的工作,例如 Unity 在导入资源时会有一段转换时间,被处理成对应的纹理格式后存储了下来,此时纹理压缩的速度慢一些是可以接受的
GPU 对纹理进行采样时,通常只会解压一个纹素块,不会全部解压,这个过程本身就是很快的
以上就是关于opengl纹理贴图图片应该放在哪全部的内容,包括:opengl纹理贴图图片应该放在哪、twinmotion导入obj是整体、Unity Shader 获取深度纹理和法线纹理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)