laya自帶的預設材質 blinnphongmaterial 是支援實時陰影的,只需要將directional light 的陰影開啟 ,meshrender 的receiveshadow 設定為 true 就能簡單的在材質上投射陰影了。
但是顯然基礎材質 blinnphong是不夠用的,當需要自定義材質的時候發現實時陰影又沒了。不得已,只能去看laya 的相關原始碼,踩了一些坑,終於調通了。總結的坑點如下:
這個類控制glsl 中shader的巨集定義開關。比如你要使用實時陰影,需要在vs和fs中使用 類似於
#ifdef receiveshaow
...#endif
的巨集定義。那麼還需要在自定義的material 中 加上
this._shadervalues.adddefine(***.shaderdefine_receive_shadow);
,而且別忘記register 初始化,這個是靜態成員變數,需要在所有類初始化之前執行,laya內部是放在scene3d裡面執行的。
***.shaderdefine_receive_shadow = ***.shaderdefines.registerdefine("receiveshadow");
不光是這樣,在初始化subshader時,還要將該material的shaderdefine 作為引數傳入 建構函式。
var sub_shader: laya.subshader = new laya.subshader(attributemap, uiformmap,undefined,***.shaderdefines);
而且別忘記在uniformmap 中加上相關的變數:
var uiformmap = ;
可以看到想在自定義shader中加乙個巨集定義需要注意很多東西。。
考慮到大部分人應該只想知道如何用,這裡給一下詳細步驟吧。
1 開啟directionlight 的投射陰影
let directionlight = new laya.directionlight();
this.m_scene.addchild(directionlight);
directionlight.color = new laya.vector3(0.4, 0.4, 0.4);
directionlight.shadow = true;
directionlight.shadowdistance = 100;
directionlight.shadowresolution = 4096;
directionlight.shadowpssmcount = 1;
directionlight.shadowpcftype = 3;
2 繼承basematerial 自定義material編寫// ***material.ts
// 直接import shader檔案需要定義檔案調整 ,預設不能直接import
// 可以用字串定義shader :)
import ***vs from './shaders/***vs.vs'
import ***fs from './shaders/***fs.fs'
export default class ***material extends laya.basematerial
constructor()
public get diffusetexture() :laya.basetexture
public set diffusetexture( value : laya.basetexture )
public static async initshader() : promise;
var uiformmap = ;
return new promise((resolve)=>);
}}
3 自定義shader編寫 ,參照laya原始碼裡面的blinnphong shader
這裡不貼完整**了,可以直接參照官方的blinnphong.vs
blinnphong.fs
#include "lighting.glsl";
attribute vec4 a_position;
varying float v_posviewz;
#ifdef receiveshadow
#ifdef shadowmap_pssm1
varying vec4 v_lightmvppos;
uniform mat4 u_lightshadowvp[4];
#endif
#endif
void main_normal()
void main()
需要注意的是,直接include glsl 檔案可能會報找不到檔案的錯誤,可以暴力直接把include檔案的內容拷貝到shader中。
4 設定材質,meshrender開啟陰影
let mat = ***material.default;
sprite.meshrenderer.receiveshadow = true;
sprite.meshrenderer.material = mat;
完成!
總結一下,其實這種方案還是用了laya內部的實時陰影機制。想知道為啥這麼做需要看原始碼。
U3D 自定義shader建立Editor擴充套件
工欲善其事,必先利其器 shader學習工具篇 身為乙個程式設計師,必須有懶得氣質,必須乾掉這樣的重複的操作!怎麼能讓我們的可愛同學把寶貴的時間花在做重複的事情上呢?unity編輯器 unity基於模板生成 的原理與應用 學習shader的同學也可以看這位大神的文章,很多中高階的知識。雖然大神的文章...
Unity3D之Shader自定義編輯器功能拓展
一 前言 最近在開發乙個關卡類的遊戲,在匯入一些3d物體的時候,發現很多時候同乙個3d物體需要渲染的方式不一樣,比如這顆樹要雙面渲染 cull off 但在很多情況下是可以剔除背面 cull back 的,之前在寫shader方面找不到什麼好方法直接控制,乾脆就寫了兩個shader,這就造成了無謂的...
Unity3d 自定義滑鼠
我們在用unity3d開發自己的遊戲的時候,自定義遊戲中的滑鼠也是經常要用到的,那我就得學學,其實原理很簡單,先將滑鼠給隱藏,然後在滑鼠的位置上畫出乙個自定義的滑鼠貼圖,這樣看起來就像乙個自定義的滑鼠。當然我這裡利用的是跨平台方案,unity的gui效率不高,如果我們要用特定的某個平台的自定義滑鼠,...