Как отбросить пиксели в зависимости от цвета вершины и включить или отключить их в MonoBehaviour? - PullRequest
0 голосов
/ 18 июня 2019

Я написал шейдер, который использует цвета вершин сетки, а также имеет функцию, которая обрезает все вершины, которые имеют интерполированный цвет вершин в синем канале больше 0,5 (отбрасывает все синие вершины).

Я пытаюсь создать голосовую команду, которая позволяет пользователю вызывать функцию, когда они готовы. Однако в обработчике ввода речи Microsoft Mixed Reality Toolkit он позволяет мне вызывать функции только из компонентов (Mesh Renderer, Mesh Filter, Mesh Collider и т. Д.) GameObject, на который я ссылаюсь, но не из шейдера или материала объекта.

Как сделать так, чтобы голосовая команда могла вызывать мою функцию «скрыть», которой я поделился ниже?

Я пытался закодировать функцию «скрыть» за пределами шейдера, но, похоже, это не сработало.

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

1 Ответ

1 голос
/ 19 июня 2019

В вашем шейдерном коде есть избыточный #include, и вы объявляете переменную _Toggle в неправильном месте.Кроме того, вы не должны инициализировать int _Toggle, вам нужно только объявить его, чтобы единицы могли установить его значение.

Избавьтесь от 2-го #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!

...