如何使用 MonoBehaviour 在运行时设置着色器 setting/property?
How do I set a shader setting/property at runtime using MonoBehaviour?
我有一个着色器可以显示网格的顶点颜色并能够剪裁蓝色的顶点。我希望用户能够在使用该应用程序时启用此设置 on/off。
我已经尝试过此处提供的建议 and here
但到目前为止 none 对我有用。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HoloToolkit.Unity;
using System;
public class AnchorScript : MonoBehaviour
{
private Renderer rend;
Vector3 scale;
public WorldAnchorManager worldAnchorManager;
// Start is called before the first frame update
void Start()
{
rend = gameObject.GetComponent<Renderer>();
// transform.localScale = scale;
TurnOffContext();
}
private void Update()
{
SaveScale();
TurnOffContext();
}
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);
Debug.Log("Toggle ");
}
public void SaveScale()
{
scale = gameObject.GetComponent<Transform>().localScale;
}
}
我希望这个脚本会导致我的网格的蓝色部分被丢弃,因为在我的着色器片段中我有
clip(_Toggle * (0.5f - IN.vertColor.b));
特别是行不通的部分是
rend.material.Setfloat("_Toggle", 1);
正在调用该函数,但它没有按预期将 _Toggle 值设置为 1。
如果我手动将检查器面板中的 _Toggle 设置从 0 更改为 1,网格的蓝色部分将被丢弃,这是预期的结果。我上面粘贴的脚本应该与在检查器面板中手动更改设置具有相同的结果。
我不知道为什么您当前的解决方案不起作用(对我来说看起来不错),但我知道您可以使用着色器变体解决整个问题。
在您的着色器中,将此行添加到 pragmas:
#pragma multi_compile __ DISCARD_BLUE
然后将您的 clip
语句更改为:
#ifdef DISCARD_BLUE
clip(0.5f - IN.vertColor.b);
#endif
要启用和禁用此功能,只需将 C# 脚本更改为分别使用 rend.material.EnableKeyword("DISCARD_BLUE")
和 rend.material.DisableKeyword("DISCARD_BLUE")
。这有一个额外的好处,即在禁用关键字时可以节省一些指令。您也可以像这样 enable/disable 全局关键字:
Shader.Find("Custom/VertexColor").EnableKeyword("DISCARD_BLUE");
除此之外,您是否绝对确定您的脚本引用了正确的渲染器?
我有一个着色器可以显示网格的顶点颜色并能够剪裁蓝色的顶点。我希望用户能够在使用该应用程序时启用此设置 on/off。
我已经尝试过此处提供的建议
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HoloToolkit.Unity;
using System;
public class AnchorScript : MonoBehaviour
{
private Renderer rend;
Vector3 scale;
public WorldAnchorManager worldAnchorManager;
// Start is called before the first frame update
void Start()
{
rend = gameObject.GetComponent<Renderer>();
// transform.localScale = scale;
TurnOffContext();
}
private void Update()
{
SaveScale();
TurnOffContext();
}
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);
Debug.Log("Toggle ");
}
public void SaveScale()
{
scale = gameObject.GetComponent<Transform>().localScale;
}
}
我希望这个脚本会导致我的网格的蓝色部分被丢弃,因为在我的着色器片段中我有
clip(_Toggle * (0.5f - IN.vertColor.b));
特别是行不通的部分是
rend.material.Setfloat("_Toggle", 1);
正在调用该函数,但它没有按预期将 _Toggle 值设置为 1。
如果我手动将检查器面板中的 _Toggle 设置从 0 更改为 1,网格的蓝色部分将被丢弃,这是预期的结果。我上面粘贴的脚本应该与在检查器面板中手动更改设置具有相同的结果。
我不知道为什么您当前的解决方案不起作用(对我来说看起来不错),但我知道您可以使用着色器变体解决整个问题。
在您的着色器中,将此行添加到 pragmas:
#pragma multi_compile __ DISCARD_BLUE
然后将您的 clip
语句更改为:
#ifdef DISCARD_BLUE
clip(0.5f - IN.vertColor.b);
#endif
要启用和禁用此功能,只需将 C# 脚本更改为分别使用 rend.material.EnableKeyword("DISCARD_BLUE")
和 rend.material.DisableKeyword("DISCARD_BLUE")
。这有一个额外的好处,即在禁用关键字时可以节省一些指令。您也可以像这样 enable/disable 全局关键字:
Shader.Find("Custom/VertexColor").EnableKeyword("DISCARD_BLUE");
除此之外,您是否绝对确定您的脚本引用了正确的渲染器?