0

我编写了一个着色器,它使用网格的顶点颜色,并且还有一个函数可以裁剪蓝色通道中插值顶点颜色大于 0.5 的所有顶点(丢弃所有蓝色顶点)。

我正在尝试创建一个语音命令,允许用户在准备好时调用该函数。但是,在 Microsoft 的混合现实工具包语音输入处理程序中,它只允许我从我正在引用的游戏对象的组件(网格渲染器、网格过滤器、网格碰撞器等)调用函数,而不是对象的着色器或材质。

我怎样才能使语音命令可以调用我在下面共享的“隐藏”功能?

我试图在着色器之外编写“隐藏”功能,但这似乎不起作用。

Shader "Custom/VertexColor" { // Where it will appear inside of the Shader Dropdown Menu of the Material / Name of the shader
Properties{
    _Toggle ("Toggle context", int) = 0
}
SubShader{
    Tags { "RenderType" = "Opaque" }
    LOD 200


    CGPROGRAM
    #pragma surface surf Lambert vertex:vert
    #pragma target 3.0
    #include "UnityCG.cginc"



    struct Input {
        float4 vertColor;
    };

    void vert(inout appdata_full v, out Input o) {
        UNITY_INITIALIZE_OUTPUT(Input, o);
        o.vertColor = v.color;
    }

    void surf(Input IN, inout SurfaceOutput o) {

        #include "UnityCG.cginc"
        int _Toggle = 0;
        o.Albedo = IN.vertColor.rgb;
        clip(_Toggle * (0.5f - IN.vertColor.b));

    }



    ENDCG
}
    FallBack "Diffuse"
}

我希望语音输入处理程序允许我从着色器调用函数,但它没有。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HoloToolkit.Unity;

public class AnchorScript : MonoBehaviour
{
public Renderer rend;
Vector3 scale;

public WorldAnchorManager worldAnchorManager;
// Start is called before the first frame update
void Start()
{
    transform.localScale = scale;
    TurnOffContext();
}

private void Update()
{
    SaveScale();
}
public void AnchorIt()
{
    worldAnchorManager.AttachAnchor(this.gameObject);
    this.gameObject.GetComponent<Renderer>().material.color = Color.red;
}

public void ReleaseAnchor()
{
    worldAnchorManager.RemoveAnchor(this.gameObject);
    this.gameObject.GetComponent<Renderer>().material.color = Color.green;
}

public void ShowDifferences()
{
    gameObject.GetComponent<Renderer>().enabled = true; 
}

public void HideAugmentations()
{
    gameObject.GetComponent<Renderer>().enabled = false;
}
public void TurnOffContext()
{
    rend.material.SetFloat("_Toggle", 1);
}

public void SaveScale()
{
    scale = gameObject.GetComponent<Transform>().localScale;
}
}

我将 TurnOffContext() 函数放在 Start() 函数中只是为了测试它是否有效。从理论上讲,它应该立即将 _Toggle 属性设置为 1,这应该丢弃所有蓝色像素,但在启动我的应用程序时我仍然看到完整的原始网格。我还尝试不将其放入 Start() 函数中,而仅使用运行 TurnOffContext() 函数的语音命令,但这也不起作用。

这是我的 GameObject 的材质检查器面板的屏幕截图。 https://imgur.com/a/wkVh5Tj

4

1 回答 1

1

您的着色器代码中有冗余#include,并且您_Toggle在错误的位置声明了变量。另外,你不应该初始化int _Toggle,你只想声明它以便统一可以设置它的值。

摆脱 2nd #include "UnityCG.cginc",摆脱int _Toggle = 0;并把int _Toggle;(注意:没有初始化)放在下面的某个地方CGPROGRAM

另外,将Properties块更改为使用大写 I Int

Shader "Custom/VertexColor" { // Where it will appear inside of the Shader Dropdown Menu of the Material / Name of the shader
Properties{
    _Toggle ("Toggle context", Int) = 0
}
SubShader{
    Tags { "RenderType" = "Opaque" }
    LOD 200


    CGPROGRAM
    #pragma surface surf Lambert vertex:vert
    #pragma target 3.0
    #include "UnityCG.cginc"

    int _Toggle;

    struct Input {
        float4 vertColor;
    };

    void vert(inout appdata_full v, out Input o) {
        UNITY_INITIALIZE_OUTPUT(Input, o);
        o.vertColor = v.color;
    }

    void surf(Input IN, inout SurfaceOutput o) {
        o.Albedo = IN.vertColor.rgb;
        clip(_Toggle * (0.5f - IN.vertColor.b));
    }

    ENDCG
}
    FallBack "Diffuse"
}

然后,在您的 c# 代码中,您需要使用SetInt而不是SetFloat因为_Toggle是一个int.

另外,使用renderer.sharedMaterial代替renderer.material

于 2019-06-19T19:36:57.903 回答