SetReplacementShader大法好

 
今天用了一下SetReplacementShader,遇到不少坑,一定要Mark一下!
效果如上图,可以通过Shader快速切换材质球的显示方式;
之前不会Shader,用的方法是遍历所有物体,然后再遍历所有物体的多维子材质球,再把他们统统换成目标材质球,不同的物体类型还要对应着不同的新材质球,这还没完,为了可以顺利切换回原来材质,每个材质球都要用Dictionary<GameObject, Material>保存着,回想起来HOLY NB!!

好了,言归正传,说下这个怎么用
关键是Shader里的这句话:Tags { "RenderType"="XXX" }
[C#]  纯文本查看  复制代码
?
void Start() {
     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#]  纯文本查看  复制代码
?
void Update ()
{
     if (Input.GetKeyDown (KeyCode.J)) {
         //必须把 Shader 放到 Resources 文件夹下
         myCamera.SetReplacementShader (Shader.Find ( "Ryan/ReplaceShader" ), "RenderType" );
         myCamera.SetReplacementShader (Resources.Load ( "RyanShader" ) as Shader, "RenderType" );
         //直接拖到Public参数中,不用放 Resources 文件夹下
         myCamera.SetReplacementShader (RyanShader, "RenderType" );
     } else if (Input.GetKeyDown (KeyCode.K)) {
         myCamera.ResetReplacementShader ();
     }
}


PS:有人多此一举把它写在了OnPostRender()中,其实不用那么麻烦,写哪都一样。
https://docs.unity3d.com/Manual/SL-ShaderReplacement.html
你可以使用Unity自带的RenderTexture来将ToonShader的效果输出为PNG图片。下面是一个简单的示例代码: ```csharp using UnityEngine; public class ToonShaderExporter : MonoBehaviour { public Shader toonShader; public RenderTexture renderTexture; public string outputFileName = "output.png"; private void Start() { // 创建RenderTexture,用于将ToonShader效果渲染到其中 renderTexture = new RenderTexture(Screen.width, Screen.height, 24); renderTexture.format = RenderTextureFormat.ARGB32; renderTexture.Create(); // 将相机的TargetTexture设置为renderTexture Camera.main.targetTexture = renderTexture; // 将ToonShader赋给相机的Material Camera.main.SetReplacementShader(toonShader, ""); // 渲染相机 Camera.main.Render(); // 恢复相机的TargetTexture为空 Camera.main.targetTexture = null; // 从renderTexture中读取像素数据 Texture2D texture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGB24, false); RenderTexture.active = renderTexture; texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); texture.Apply(); RenderTexture.active = null; // 将像素数据保存为PNG图片 byte[] bytes = texture.EncodeToPNG(); System.IO.File.WriteAllBytes(outputFileName, bytes); // 销毁renderTexture和texture Destroy(renderTexture); Destroy(texture); } } ``` 将上述代码添加到一个空物体上,并将ToonShader赋给toonShader变量。然后运行游戏,代码会将ToonShader的效果渲染到RenderTexture,并将RenderTexture保存为PNG图片。最终的PNG图片会保存在Unity项目的根目录下,文件名为output.png。你可以根据需要修改输出文件名和路径。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值