如何从脚本访问shader变量?

时间:2022-03-09 16:02:20

The shader:

材质:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Outlined/Silhouetted Diffuse" {
     Properties {
         _Color ("Main Color", Color) = (.5,.5,.5,1)
         _OutlineColor ("Outline Color", Color) = (0,0,0,1)
         _Outline ("Outline width", Range (0.0, 0.03)) = .005
         _MainTex ("Base (RGB)", 2D) = "white" { }
     }

 CGINCLUDE
 #include "UnityCG.cginc"

 struct appdata {
     float4 vertex : POSITION;
     float3 normal : NORMAL;
 };

 struct v2f {
     float4 pos : POSITION;
     float4 color : COLOR;
 };

 uniform float _Outline;
 uniform float4 _OutlineColor;

 v2f vert(appdata v) {
     // just make a copy of incoming vertex data but scaled according to normal direction
     v2f o;
     o.pos = UnityObjectToClipPos(v.vertex);

     float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
     float2 offset = TransformViewToProjection(norm.xy);

     o.pos.xy += offset * o.pos.z * _Outline;
     o.color = _OutlineColor;
     return o;
 }
 ENDCG

     SubShader {
         Tags { "Queue" = "Transparent" }

         // note that a vertex shader is specified here but its using the one above
         Pass {
             Name "OUTLINE"
             Tags { "LightMode" = "Always" }
             Cull Off
             ZWrite Off
             ZTest Always
             ColorMask RGB // alpha not used

             // you can choose what kind of blending mode you want for the outline
             Blend SrcAlpha OneMinusSrcAlpha // Normal
             //Blend One One // Additive
             //Blend One OneMinusDstColor // Soft Additive
             //Blend DstColor Zero // Multiplicative
             //Blend DstColor SrcColor // 2x Multiplicative

 CGPROGRAM
 #pragma vertex vert
 #pragma fragment frag

 half4 frag(v2f i) :COLOR {
     return i.color;
 }
 ENDCG
         }

         Pass {
             Name "BASE"
             ZWrite On
             ZTest LEqual
             Blend SrcAlpha OneMinusSrcAlpha
             Material {
                 Diffuse [_Color]
                 Ambient [_Color]
             }
             Lighting On
             SetTexture [_MainTex] {
                 ConstantColor [_Color]
                 Combine texture * constant
             }
             SetTexture [_MainTex] {
                 Combine previous * primary DOUBLE
             }
         }
     }

     SubShader {
         Tags { "Queue" = "Transparent" }

         Pass {
             Name "OUTLINE"
             Tags { "LightMode" = "Always" }
             Cull Front
             ZWrite Off
             ZTest Always
             ColorMask RGB

             // you can choose what kind of blending mode you want for the outline
             Blend SrcAlpha OneMinusSrcAlpha // Normal
             //Blend One One // Additive
             //Blend One OneMinusDstColor // Soft Additive
             //Blend DstColor Zero // Multiplicative
             //Blend DstColor SrcColor // 2x Multiplicative

             CGPROGRAM
             #pragma vertex vert
             #pragma exclude_renderers gles xbox360 ps3
             ENDCG
             SetTexture [_MainTex] { combine primary }
         }

         Pass {
             Name "BASE"
             ZWrite On
             ZTest LEqual
             Blend SrcAlpha OneMinusSrcAlpha
             Material {
                 Diffuse [_Color]
                 Ambient [_Color]
             }
             Lighting On
             SetTexture [_MainTex] {
                 ConstantColor [_Color]
                 Combine texture * constant
             }
             SetTexture [_MainTex] {
                 Combine previous * primary DOUBLE
             }
         }
     }

     Fallback "Diffuse"
 }

And after attached the shader to a material on a cube I want now to control the Outline width in csharp script so I also attached a script empty for now to the cube:

在将材质贴到立方体上之后,我现在想要控制csharp脚本的轮廓宽度,所以我也把一个空脚本贴到立方体上:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Outline : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

For example I want to change the Outline width value using time or startcoroutine.

例如,我想使用time或startcoroutine更改轮廓宽度值。

If the Outline width range values are 0.0, 0.03 then I want to change this values automatic from 0 to 0.03 using time or startcoroutine.

如果Outline宽度范围值为0.0,0.03,那么我希望使用时间或startcoroutine将这个值自动从0更改为0.03。

Update:

更新:

This is working using Update for changing the _Outline value:

这是使用Update修改_Outline值:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Outline : MonoBehaviour
{
    public float width;

    private Renderer rend;
    private float currentWidth;

    private void Start()
    {
        rend = GetComponent<Renderer>();
        currentWidth = rend.material.GetFloat("_Outline");
    }

    private void Update()
    {
        SetOutLineWidth(width);
    }

    public void SetOutLineWidth(float width)
    {
        rend.material.SetFloat("_Outline", width);
    }
}

But now how can I use startcoroutine to change the _Outline value automatic nonstop from 0.0 to 0.03 and back from 0.03 to 0.0 ?

但是现在我如何使用startcoroutine将_Outline值自动从0.0更改为0.03,从0.03改为0.0 ?

1 个解决方案

#1


2  

You have two options.

你有两个选择。

  1. and the simplest: store your oscillating value in the script (modify, then call material.SetFloat() with the new value).

    最简单的方法是:在脚本中存储振荡值(修改,然后使用新值调用material.SetFloat()))。

  2. Material.GetFloat()

    Material.GetFloat()

#1


2  

You have two options.

你有两个选择。

  1. and the simplest: store your oscillating value in the script (modify, then call material.SetFloat() with the new value).

    最简单的方法是:在脚本中存储振荡值(修改,然后使用新值调用material.SetFloat()))。

  2. Material.GetFloat()

    Material.GetFloat()