Laya实现Stencil模板测试

本文介绍了如何在Laya引擎中通过自定义WebGL接口启用Stencil模板测试,以解决顶点重叠导致的阴影效果不佳问题。通过在ShaderInstance、RenderState和Context中添加相关配置,设置Stencil测试函数、参考值、掩码和操作行为,实现了类似深度测试的功能,确保已绘制区域不再重复绘制,从而提高渲染质量。
摘要由CSDN通过智能技术生成

Stencil模板测试是一个类似于深度测试的功能,由WebGL提供,但Laya没有未开发者打通这个环节。
图1
图2

图1是未使用Stencil的效果,因为顶点重叠,阴影效果不理想。图二使用了Stencil,已绘制阴影的地方不再重复绘制。

Laya引擎版本:2.11.0 ts实验版

1、首先在WebGLContext.ts中添加WebG的Stencil相关接口:

    /**
	 * @internal
	 */
    static setStencilFunc(gl: WebGLRenderingContext, func: number, value: number, mask: number): void {
		gl.stencilFunc(func, value, mask);
    }

	/**
	 * @internal
	 */
    static setStencilOp(gl: WebGLRenderingContext, fail: number, zfail: number, zpass: number): void {
        gl.stencilOp(fail, zfail, zpass);
    }

2、在ShaderInstance.ts的uploadRenderStateBlendDepth方法最后,添加调用上面两个接口的代码:

	WebGLContext.setStencilFunc(gl, renderState.stencilFunc, renderState.stencilRef, renderState.stencilMask);
	WebGLContext.setStencilOp(gl, renderState.stencilOpFail, renderState.stencilOpZFail, renderState.stencilOpPass);

3、接下来,在RenderState.ts中加入Stencil相关的枚举和需要传递给WebGL的参数

	/**stencil测试函数枚举_从不通过。*/
	static STENCIL_NEVER: number = 0x0200;
	/**stencil测试函数枚举_小于时通过。*/
	static STENCIL_LESS: number = 0x0201;
	/**stencil测试函数枚举_等于时通过。*/
	static STENCIL_EQUAL: number = 0x0202;
	/**stencil测试函数枚举_小于等于时通过。*/
	static STENCIL_LEQUAL: number = 0x0203;
	/**stencil测试函数枚举_大于时通过。*/
	static STENCIL_GREATER: number = 0x0204;
	/**stencil测试函数枚举_不等于时通过。*/
	static STENCIL_NOTEQUAL: number = 0x0205;
	/**stencil测试函数枚举_大于等于时通过。*/
	static STENCIL_GEQUAL: number = 0x0206;
	/**stencil测试函数枚举_总是通过。*/
	static STENCIL_ALWAYS: number = 0x0207;

	/**stencil测试操作行为 */
	static STENCIL_ZERO: number = 0;
	/**stencil测试操作值行为 */
	static STENCIL_INVERT: number = 0x150a;
	/**stencil测试操作行为 */
	static STENCIL_KEEP: number = 0x1e00;
	/**stencil测试操作行为 */
	static STENCIL_REPLACE: number = 0x1e01;
	/**stencil测试操作行为 */
	static STENCIL_INCR: number = 0x1e02;
	/**stencil测试操作行为 */
	static STENCIL_DECR: number = 0x1e03;
	/**stencil测试操作行为 */
	static STENCIL_INCR_WRAP: number = 0x8507;
	/**stencil测试操作行为 */
	static STENCIL_DECR_WRAP: number = 0x8508;
	
	/**stencil测试函数 */
	stencilFunc: number;
	/**stencil测试参考值 */
	stencilRef: number;
	/**stencil测试掩码 */
	stencilMask: number;
	/**stencil测试未通过时的行为 */
	stencilOpFail: number;
	/**stencil测试通过但是depth测试未通过时的行为 */
	stencilOpZFail: number;
	/**stencil测试通过且depth测试也通过时的行为 */
	stencilOpPass: number;

4、在RenderState的构造方法最后,给Stencil相关的参数设置默认值

	this.stencilFunc = RenderState.STENCIL_ALWAYS;
	this.stencilRef = 0;
	this.stencilMask = 0;
	this.stencilOpFail = RenderState.STENCIL_KEEP;
	this.stencilOpZFail = RenderState.STENCIL_KEEP;
	this.stencilOpPass = RenderState.STENCIL_KEEP;

5、在Rerder.ts中开始WebGL的Stencil功能
在这里插入图片描述
6、最后一步,渲染2D之前,恢复Stencil设置,以免影响2D渲染,在Context.ts里
在这里插入图片描述
使用方法,创建shader的pass时,设置stencil相关的参数
在这里插入图片描述

参考文章:WebGL绘制详解之五:Stencil Buffer

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值