使用OpenGL怎么实现ES透视投影?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
<强>剪裁坐标强>
当顶点着色器写入一个值到gl_Position时,这个点要求必须在剪裁空间中,即它的x, y, z坐标必须在[- w w]之间,任何这个范围之外的点都是不可见的。
这里需要注意以下,对于属性类型的属性量.OpenGL会用默认的值替换属性中未指定的分量,前三个分量会被设定为0,最后一个分量w会被设定为1。
站在gl_Position的角度来说,(- w w)之间的坐标点才是可见的,否则都是不可见会被剪裁掉。往前看,在做投影变换的时候我们说,在视景体内的物体有效,视景体外的会被剪裁,实际上是对应的,剪裁就是发生在图元装配阶段判断所有的坐标是否在[- w w]之间。
剪裁实际上就是判断每一个最小三角形,直线,点单元的坐标是否规范。
<强>透视除法强>
对上面的剪裁坐标的点的x, y, z坐标除以它的w分量,除以w的坐标叫做归一化设备坐标。如果w分量大,除以w后的点就接近(0,0,0),在三维空间中,距离我们较远的坐标如果它的w分量较大,进行透视除法后,就距离原点越近,原点作为远处物体的消失点,就有三维场景的效果。
<强>视口变换强>
前面已经使用过视口变换的函数glViewport了,视口是一个而为矩形窗口区域。是OpenGL渲染操作最终显示的地方。
public static native void glViewport ( int x,才能 int y,才能 int w,才能 int 才能;h 之前,);>从归一化设备坐标(x, y, z)到窗口坐标(x, y, z)的转换公式
public static native void glDepthRangef ( float n,才能 float 才能;f ,);
n、f指定所需的深度范围,n, f的取值限于(0.0,1.0)之间,n, f的默认值为0.0和1.0
glDepthRangef函数和glViewport函数指定的值用于将顶点位置从归一化设备坐标转换为窗口坐标。
<>强利用w分量产生三维效果强>
在前面的代码中,修改传入的顶点坐标,增加w分量
浮动[],vertexArray =, new 浮动[],{ ,,(浮动),-0.5,(浮动),-0.5,0,1, ,,(浮动),0.5,(浮动),-0.5,0,1, ,,(浮动),-0.5,(浮动),0.5,0,,3, ,,(浮动),0.5,(浮动),0.5,0,,3 ,,},
同时修改顶点着色器:
private String vertexShaderCode =,“uniform mat4 uMVPMatrix;“ ,,+,“attribute vec4 立场;“ ,,+,“void 主要(){“; ,,+,“gl_Position =, uMVPMatrix *,立场;“ ,+,才能“}”
以及获取uProjectionMatrix以及传入顶点数据对应的代码,就可以看到如下所示效果
<强>透视投影强>
然而这样让物体产生三维效果的做法太死板了,如果我们还要让物体平移缩放旋转,这样固定的指定w的值就不太好了。
透视投影这个时候就能派上用场了,利用透视投影矩阵自动生成w的值。投影矩阵主要是为w产生正确的值,这样在渲染管线的后续操作中做透视除法,远处的物体就看起来比进出物体小,很容易想的到,可以利用顶点位置的z分量,将这个距离映射到w分量上,z越大,w也越大。
有两个函数可以生成透视投影矩阵frustumM和perspectiveM。参数具体含义可以参考下面的图
public static void perspectiveM(浮动[],m,,//,生成的投影矩阵 ,,,,,,,int 偏移量, ,,,,,,,float fovy,,//,视角角度 ,,,,,,,float 方面,,//,近平面的宽高比 ,,,,,,,float zNear,,//,近平面 ,,,,,,,float zFar),//,远平面
frustumM函数原型
public static void frustumM(浮动[],m, int 偏移量, ,float 左,float ,, float ,, float ,,//,近平面左右下上部与中心点的距离 ,float 近,float far //近平面和元平面与摄像机观察点的距离, 之前,)>
使用OpenGL怎么实现ES透视投影