SetReplacementShader大法好

来源:互联网 发布:下载acfun视频软件 编辑:程序博客网 时间:2024/05/18 08:31
 
今天用了一下SetReplacementShader,遇到不少坑,一定要Mark一下!
效果如上图,可以通过Shader快速切换材质球的显示方式;
之前不会Shader,用的方法是遍历所有物体,然后再遍历所有物体的多维子材质球,再把他们统统换成目标材质球,不同的物体类型还要对应着不同的新材质球,这还没完,为了可以顺利切换回原来材质,每个材质球都要用Dictionary<GameObject, Material>保存着,回想起来HOLY NB!!

好了,言归正传,说下这个怎么用
关键是Shader里的这句话:Tags { "RenderType"="XXX" }
[C#] 纯文本查看 复制代码
?
voidStart() {
    camera.SetReplacementShader (RyanShader, "RenderType");
}


对,就是这么使用的,"RenderType"是一个标签,内容随便贴!
就像一部车可以有一个或多个标签,铁的、红色的、带轮子的……
当我在 SetReplacementShader 中说到带铁标签的Shader替换材质,除了车,还有坦克,船,飞机,都被点名了。
而拖鞋和玻璃杯不会被替换,因为没点到他们,嗯,大概就是这个意思……
[Objective-C] 纯文本查看 复制代码
?
Shader"RyanShader"{
     SubShader {
         Tags { "RenderType"="R0"}
         Pass {
             ...
         }
     }
     SubShader {
         Tags { "RenderType"="R1"}
         Pass {
             ...
         }
     }
 ...
 }


当然这个EffectShader Shader可以复杂一些,把所有铁的、红色的、带轮子的都囊括进去,也就是一个Shader搞定场景中说有物体!听起来很赞吧p
有便利当然就会有坑:
 

1. 切换后物体变成了黑色
这是目前看下来遇到最多的问题了,困扰了我一个下午,最后发现是Properties参数的问题;
当旧Shader没有新Shader的一些参数时,因为没赋值,替代时候就会乱来,会使用垃圾数据来赋值!
所以当我们遇到这种黑色的情况,比对一下新老Shader的Properties;

2. 切换后,场景空无一物了:
那是因为camera.SetReplacementShader (RyanShader, "RenderType");
"RenderType"名字可能被我们写成了"铁的"..


3. 幸苦弄完,一键发布,木有任何效果,吐血……
怀疑是不是平台不支持,是不是系统不支持,是不是渲染设置不对,是不是电脑坏了……
别想那么多,那是因为加载时 Shader 没有打包进来,这问题之前项目也遇到过,也是蛮坑的……
所以我们只要把 Shader 放到 Resources 文件夹下面就行了,代码如下:
[C#] 纯文本查看 复制代码
?
voidUpdate ()
{
    if(Input.GetKeyDown (KeyCode.J)) {
        //必须把 Shader 放到 Resources 文件夹下
        myCamera.SetReplacementShader (Shader.Find ("Ryan/ReplaceShader"),"RenderType");
        myCamera.SetReplacementShader (Resources.Load ("RyanShader")asShader, "RenderType");
        //直接拖到Public参数中,不用放 Resources 文件夹下
        myCamera.SetReplacementShader (RyanShader, "RenderType");
    }elseif (Input.GetKeyDown (KeyCode.K)) {
        myCamera.ResetReplacementShader ();
    }
}


PS:有人多此一举把它写在了OnPostRender()中,其实不用那么麻烦,写哪都一样。
https://docs.unity3d.com/Manual/SL-ShaderReplacement.html
原创粉丝点击