Unity shader开发中需要用C#给shader代码传值,我使用全局给shader传值的时候发现并没有起作用,这里记录了容易忽视的问题。
unity中C#向Shader传递参数的方式有以下两种:
1、面向具体Material的SetFloatXXX系列(这个是实例方法)
2、面向全部Shader的SetFloatXXX系列(这个是静态方法)
我这里用的是第二种方法。
1.首先我为了测试,写了一个简单的改变透明度的shader例子,使用透明度_AlphaScale的值来做传递的参数。代码如下:
- Shader "PointCloud" {
- Properties{
- _AlphaScale("Alpha Scale", Range(0, 1)) = 1 //控制整体的透明度
- }
- SubShader{
- Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
- Pass{
- Tags { "LightMode" = "ForwardBase" }
-
- ZWrite Off //关闭深度写入
- Blend SrcAlpha OneMinusSrcAlpha //设置混合模式,为普通的方式
- LOD 200
-
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
-
- fixed _AlphaScale; //有默认的uniform
-
- struct VertexInput {
- float4 v : POSITION;
- float4 color: COLOR;
- };
-
- struct VertexOutput {
- float4 pos : SV_POSITION;
- float4 col : COLOR;
- };
-
- VertexOutput vert(VertexInput v) {
-
- VertexOutput o;
- o.pos = UnityObjectToClipPos(v.v);
- o.col = v.color;
-
- return o;
- }
-
- float4 frag(VertexOutput o) : COLOR{
- return o.col* _AlphaScale;
- }
- ENDCG
- }
- }
-
- }
2.在Unity中创建一个cube,在创建一个新的材质,将这个Shader赋给这个材质,再将这个材质替换cube本身的材质球。
3.在Unity中创建Slider组件,用Slider组件来控制透明度的值。新建C#脚本,把脚本拖拽到Slider组件上。代码如下:
- private Slider slider;
-
- private void Awake()
- {
- slider = GetComponent
(); - }
-
- private void Start()
- {
- slider.onValueChanged.AddListener(SliderClick);
- }
-
- private void SliderClick(float value)
- {
- Shader.SetGlobalFloat("_AlphaScale", value);
- }
4.运行后,拖拽Slider发现cube的透明度并没有发生变化。
首先slider传值到shader是没有问题的,问题在于_AlphaScale在Properties中被定义了,这就需要在材质面板上去修改了,相当于我传递的参数全局修改和材质属性修改冲突了,而Properties结构里参数是由CPU传给GPU的,里面的参数在shader代码是没法修改的。所以办法就是把Properties里的_AlphaScale删除或者注释掉。
- Properties{
- //_AlphaScale("Alpha Scale", Range(0, 1)) = 1 //控制整体的透明度
- }
这样就能用slider正确的改变透明度了。