unity3d - 如何在 ShaderLab 中缓存通用(所有像素)变量?
问题描述
假设我有以下着色器:
Shader "Sprites/X"
{
Properties
{
[HideInInspector] _MainTex("Sprite Texture", 2D) = "black" {}
}
SubShader
{
Pass
{
CGPROGRAM
// bla bla
fixed4 frag(v2f i) : SV_Target
{
float a = calculateA();
float b = calculateB();
.
.
.
float z = calculateZ();
// Here the values above mix with x-y position of the pixel
// and then return a color
}
ENDCG
}
}
}
在上面的代码中,我需要从相关函数中 计算变量的值a
(这只是一个泛化示例)。假设这些函数很复杂,并且它们依赖于在每一帧中变化的着色器的其他属性,而不是像素本身。我们知道,每次都为每个像素计算复杂的函数。z
calculateA()
calculateZ()
有没有办法“缓存”这些值以避免每次对每个像素进行计算?在每一帧中,它们的值对于所有像素都是相同的。
目前我正在通过在 C# 脚本中设置值来解决问题:
gameObject.GetComponent<Renderer>().material.SetFloat("a", calculateA());
.
.
.
gameObject.GetComponent<Renderer>().material.SetFloat("z", calculateZ());
但我更喜欢将着色器和 C# 脚本代码分开。
解决方案
好吧,这正是你要做的:)
这取决于您为什么要避免使用 C#
- 如果所述方法仅根据常量计算,则编译器会将其优化掉。
- 如果该方法几乎没有可预测的结果,您可以将它们预先计算到着色器本身中声明的数组中,或者从代码而不是每帧设置一次。
- 如果有很多这些可预测的结果,您可以考虑将它们烘焙到纹理中,或者如果您可以使用现代 GPU,则可以将它们烘焙到结构化缓冲区中。
推荐阅读
- mongodb - Mongoose:findOneAndUpdate 预挂钩不起作用
- ruby-on-rails - How to reload instance variables after an ajax call in ruby on rails
- regex - VBA 正则表达式替换循环
- sql-server - 警告 CS0618 分辨率
- linux - GNUPLOT LINUX 值 y 轴靠近图形的每个点
- android - 自定义工具栏未出现在预览选项卡中
- javascript - 将对象数组发送到 vuejs 中的组件
- javascript - 乘客独立不加载 JS
- python - 模型继承在 Django 模型中如何工作?
- ansible - 在ansible中组合两个哈希