stage3d中的模板缓冲

模板缓冲在传统的DirectX中,广泛使用在镜面反射,遮罩,投影等效果.
在stage3d中同样可以使用,而且API被极大的整合了.
DirectX中的API:略

模板缓冲的区域就是用户的屏幕大小,它可以用来做一些检测,然后设置像素的填充方式.
简单说来,当缓冲为空时,我们可以让程序做一些事情,当缓冲被填满时,我们可以做另一些事情.做完后,考虑清空缓冲.

以龙书中镜面效果来说
我们先设置模板缓冲为空.
然后我们在屏幕上画一面镜子,镜子的像素将被绘制到缓冲中.
我们在镜子的表面画一个茶壶,茶壶的投影仅在缓冲区中有镜子的像素的位置进行替换.
最后清空缓冲.

当然,在绘制中还有很多注意事项的,比如为了让茶壶紧贴镜子,必须关闭深度缓冲.待投影绘制完毕后,开启深度缓冲.

下面是一个简单的demo.
先开启模板缓冲,当绘制三角形后,缓冲在有像素的地方从0递增到1
我们先绘制一个矩形,并随便贴一张图.
在值为1的缓冲区域绘制一个三角形.

结果就是,三角形仅在有矩形的区域内被绘制了.
地址如下:http://www.dreamfairy.cn/blog/work/flash/3d/stage3dStencilTest/StencilTest0.html

完全的镜面效果,就下篇文章再发了,也许明天心情好的话~
主要代码如下:

[cc lang=”actionscript” nowrap=”false”]
private function renderScene() : void
{
m_context.setDepthTest(false,Context3DCompareMode.LESS);
m_context.setStencilReferenceValue(0);
m_context.setStencilActions(Context3DTriangleFace.FRONT_AND_BACK,
Context3DCompareMode.EQUAL, Context3DStencilAction.INCREMENT_SATURATE);

drawCube();

m_context.setStencilReferenceValue(1);

drawTriangle();
}

private function drawTriangle() : void
{
m_modelMatrix.identity();
m_finalMatrix.identity();
m_finalMatrix.append(m_modelMatrix);
m_finalMatrix.append(m_viewMatrix);
m_finalMatrix.append(m_projMatrix);

m_context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX,0,m_finalMatrix,true);

m_context.setProgram(m_shader);
m_context.setTextureAt(0,null);
m_context.setVertexBufferAt(0, m_triangleVertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
m_context.setVertexBufferAt(1,null);
m_context.drawTriangles(m_triangleIndexBuffer,0,1);
}

private var t : Number = 0.0;
private function drawCube() : void
{
t += .1;
m_modelMatrix.identity();
m_modelMatrix.appendTranslation(Math.sin(t),0,0);
m_finalMatrix.identity();
m_finalMatrix.append(m_modelMatrix);
m_finalMatrix.append(m_viewMatrix);
m_finalMatrix.append(m_projMatrix);

m_context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX,0,m_finalMatrix,true);

m_context.setProgram(m_textureShader);
m_context.setTextureAt(0,texture);
m_context.setVertexBufferAt(0, m_rectVertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
m_context.setVertexBufferAt(1,m_rectVertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
m_context.drawTriangles(m_rectIndexBuffer,0,2);
}
[/cc]

发表评论

电子邮件地址不会被公开。 必填项已用*标注