Laya2.0 实现模拟物体影子shader

LayaAir中开启实时阴影性能消耗偏高,如果美术要求不那么逼真,那么物体可以用shader添加一个pass来模拟影子,效果整体可以接受,可以通过调整参数修改物体shader渲染影子的长短、方向、颜色等。
效果如下,物体偏亮,因为我使用了半兰伯特光照模型。

在这里插入图片描述

上代码:ShadowMaterial.ts

export default class ShadowMaterial extends Laya.BaseMaterial {
    static DIFFUSETEXTURE = Laya.Shader3D.propertyNameToID("u_Texture");
    static readonly NAME = "ShadowShader";
    constructor() {
        super();
        this.initShader();
    }
    private initShader(): void {
        var attributeMap = {
            'a_Position': Laya.VertexMesh.MESH_POSITION0, 
            'a_Normal': Laya.VertexMesh.MESH_NORMAL0,
            'a_Texcoord': Laya.VertexMesh.MESH_TEXTURECOORDINATE0
        };
        var uniformMap = {
            'u_MvpMatrix': Laya.Shader3D.PERIOD_SPRITE, 
            'u_WorldMat': Laya.Shader3D.PERIOD_SPRITE,
            'u_Texture': Laya.Shader3D.PERIOD_MATERIAL,
            'u_DirectionLight.Direction': Laya.Shader3D.PERIOD_SCENE, 
            'u_DirectionLight.Color': Laya.Shader3D.PERIOD_SCENE
        };
        var vs:string = '#include "Lighting.glsl";\n' + 
            "attribute vec4 a_Position;\n"+
            "attribute vec2 a_Texcoord;\n"+
            "attribute vec3 a_Normal;\n"+

            "uniform mat4 u_MvpMatrix;\n"+
            "uniform mat4 u_WorldMat;\n"+

            "varying vec2 v_Texcoord;\n"+
            "varying vec3 v_Normal;\n"+

            "void main()\n"+
            "{\n"+
                "gl_Position = u_MvpMatrix * a_Position;\n"+
                "mat3 worldMat=mat3(u_WorldMat);\n"+
                "v_Normal=worldMat*a_Normal;\n"+
                "v_Texcoord=a_Texcoord;\n"+
            "}";
            var vs_shadow:string = '#include "Lighting.glsl";\n' + 
            "attribute vec4 a_Position;\n"+
            "attribute vec2 a_Texcoord;\n"+
            "attribute vec3 a_Normal;\n"+

            "uniform mat4 u_MvpMatrix;\n"+
            "uniform mat4 u_WorldMat;\n"+

            "varying vec2 v_Texcoord;\n"+
            "varying vec3 v_Normal;\n"+

            "void main()\n"+
            "{\n"+
                "vec4 new_Position = vec4(a_Position.x+a_Position.y*0.5, a_Position.y*0.5, a_Position.z, a_Position.w);\n"+
                "gl_Position = u_MvpMatrix * new_Position;\n"+
                "mat3 worldMat=mat3(u_WorldMat);\n"+
                "v_Normal=worldMat*a_Normal;\n"+
                "v_Texcoord=a_Texcoord;\n"+
            "}";
        var ps:string = "#ifdef FSHIGHPRECISION\n"+
            "precision highp float;\n"+
            "#else\n"+
            "precision mediump float;\n"+
            "#endif\n"+
            "#include \"Lighting.glsl\";\n"+
            "varying vec3 v_Normal;\n" +
            "varying vec2 v_Texcoord;\n"+
            "uniform sampler2D u_Texture;\n"+
            "uniform DirectionLight u_DirectionLight;\n"+
            "void main()\n"+
            "{\n"+
                "vec3 normal=normalize(v_Normal);\n"+
                "vec3 diffuse = (dot(u_DirectionLight.Direction, normal)*0.5+0.5)*u_DirectionLight.Color;\n"+ 
                "gl_FragColor = texture2D(u_Texture, v_Texcoord)+vec4(diffuse,1.0);\n"+
            "}";    
            var ps_shadow:string = "#ifdef FSHIGHPRECISION\n"+
            "precision highp float;\n"+
            "#else\n"+
            "precision mediump float;\n"+
            "#endif\n"+
            "varying vec3 v_Normal;\n" +
            "varying vec2 v_Texcoord;\n"+
            "uniform sampler2D u_Texture;\n"+
            "void main()\n"+
            "{\n"+
                "gl_FragColor=vec4(0,0,0,1);\n"+
            "}";      

		var customShader:Laya.Shader3D = Laya.Shader3D.add(ShadowMaterial.NAME);
		var subShader:Laya.SubShader =new Laya.SubShader(attributeMap, uniformMap,Laya.SkinnedMeshSprite3D.shaderDefines, ShadowMaterial.shaderDefines);
		
        subShader.addShaderPass(vs, ps);
        subShader.addShaderPass(vs_shadow, ps_shadow);
        customShader.addSubShader(subShader);
        this.setShaderName(ShadowMaterial.NAME);
    }
    set diffuseTexture(texture2D : Laya.Texture2D){
        this._shaderValues.setTexture(ShadowMaterial.DIFFUSETEXTURE, texture2D);
    }
}

然后在你要渲染的物体添加ShadowShader材质即可:

        Laya.Mesh.load(resUrl,Laya.Handler.create(this,(mesh : Laya.Mesh)=>{
            let sprite3D = new Laya.MeshSprite3D(mesh);
            sprite3D.meshRenderer.material = new ShadowMaterial();
        }
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值