一、剪裁测试
核心代码
二、Alpha测试GLES20.glEnable(GL10.GL_SCISSOR_TEST); //启用剪裁测试
GLES20.glScissor(0,0,100,200); //设置区域
GLES20.glDisable(GL10.GL_SCISSOR_TEST); //禁用剪裁测试
第二行glscissor方法中前两个参数为剪裁区域左下角的X、Y坐标,后两个参数为剪裁区域的宽度和高度。
原理
核心代码当绘制一个片元时,首先检测其Alpha值,若Alpha值满足要求,则通过测试,绘制此片元,否则丢弃此片元,不进行绘制
三、模板测试(蒙板测试)vec4 bcolor = texture2D(sTexture, vTextureCoord);//给此片元从纹理中采样出颜色值 if(bcolor.a<0.6) { discard; } else { gl_FragColor=bcolor; }
核心代码
四、任意剪裁平面//清除模板缓存 GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT); //允许模板测试 GLES20.glEnable(GLES20.GL_STENCIL_TEST); //设置模板测试参数 GLES20.glStencilFunc(GLES20.GL_ALWAYS, 1, 1); //设置模板测试后的操作 GLES20.glStencilOp(GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_REPLACE); //绘制反射面地板 texRect.drawSelf(textureFloor); //设置模板测试参数 GLES20.glStencilFunc(GLES20.GL_EQUAL,1, 1); //设置模板测试后的操作 GLES20.glStencilOp(GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_KEEP); //绘制镜像体 bfd.drawSelfMirror( textureBallId); //禁用模板测试 GLES20.glDisable(GLES20.GL_STENCIL_TEST);
1、给出用于定义剪裁平面的4个参数A、B、C、D,这4个参数分别是平面解析(Ax+By+Cz+D=0)中的4 个系数;
float e[] = { 1, countE - 1, -countE + 1, 0 };//定义裁剪平面
2、将剪裁平面的4个参数传入渲染管线,以备着色器使用;
//获取程序中剪裁平面引用 muClipHandle=GLES20.glGetUniformLocation(mProgram, "u_clipPlane"); //将剪裁平面传入shader程序 GLES20.glUniform4fv(muClipHandle, 1, fromArrayToBuff(clipPane)); public FloatBuffer fromArrayToBuff(float[] a) { ByteBuffer llbb = ByteBuffer.allocateDirect(a.length*4); llbb.order(ByteOrder.nativeOrder());//设置字节顺序 FloatBuffer result=llbb.asFloatBuffer(); result.put(a); result.position(0); return result; }
3、在顶点着色器中判断顶点是否在平面某的一侧,具体的方法为:将顶点位置(x0,y0,z0)代入平面方程Ax+By+Cz+D=0,完成计算后将得到的值传入片元着色器;
//将顶点位置(x0,y0,z0)代入平面方程Ax+By+Cz+D=0, //若Ax0+By0+Cz0+D>0,则顶点在平面的上侧,反之在平面的下侧 u_clipDist = dot(aPosition.xyz, u_clipPlane.xyz) +u_clipPlane.w;
4、片元着色器中根据接收到的Ax+By+Cz+D表达式的值与0之间的关系就可以得出顶点与剪裁平面之间的位置关系,以决定是否丢弃片元
if(u_clipDist < 0.0) discard;