gpt4 book ai didi

unity3d - CG:指定顶点和片段着色器之间不插值的变量

转载 作者:行者123 更新时间:2023-12-04 16:26:15 26 4
gpt4 key购买 nike

我正在使用 GC用于在内部编写着色器 Unity3D .

我正在使用顶点颜色属性将一些参数传递给着色器。它们不会用于定义颜色,并且应该从顶点着色器转发到像素着色器而不修改它们。

这是我作为从 Unity3D 到顶点着色器的输入的结构:

struct appdata_full {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
fixed4 color : COLOR;
#if defined(SHADER_API_XBOX360)
half4 texcoord2 : TEXCOORD2;
half4 texcoord3 : TEXCOORD3;
half4 texcoord4 : TEXCOORD4;
half4 texcoord5 : TEXCOORD5;
#endif
};

这是顶点着色器作为片段输入返回的结构:
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
fixed4 col: COLOR;
};

如果我只是将参数转发给片段着色器,当然它会被插值:
v2f vert (appdata_full v)
{

v2f output;
//....
output.col = v.color;
}

我想通过 v.color参数未插入片段着色器。
这可能吗?如果是,如何?

编辑

就像 Tim 指出的那样,这是预期的行为,因为如果这些颜色从顶点着色器传递到片段,着色器除了插入颜色之外不能做任何其他事情。
我会尝试更好地解释我想要实现的目标。我使用每个顶点颜色来存储除颜色之外的其他类型的信息。没有告诉我正在做什么的所有细节,假设您可以将每个颜色顶点视为一个 id(同一个三角形的每个顶点,将具有相同的颜色。实际上是同一个网格的每个顶点)。

所以我使用颜色技巧来屏蔽一些参数,因为我没有其他方法可以做到这一点。现在这条信息必须以某种方式在片段着色器中可用。
如果作为顶点着色器的输出参数传递,则编码为颜色的此信息将插入到无法再使用的片段处。

我正在寻找一种在片段着色器之前不变地传播此信息的方法(也许可以使用全局变量或类似的东西?如果是,如何?)。

最佳答案

我不确定这对答案是否重要,但对于评论来说有点多。正如 Bjorke 指出的那样,片段着色器将始终接收一个内插值。如果/当 Unity 支持 Opengl 4.0,您可能可以访问 Interpolation qualifiers ,即禁用插值的“平坦”,从 provoking vertex 派生所有值.

也就是说,尝试为三角形的所有顶点分配相同的“颜色”值的问题在于顶点着色器迭代顶点一次,而不是每个三角形。总会有一个“边界”区域,其中某些顶点与具有不同“颜色”或“id”的其他顶点共享多条边,请参阅下面我的愚蠢示例。当应用于 (0,0,0) 处的框时,顶部为红色,底部为绿色,中间为蓝色。

Shader "custom/colorbyheight" {
Properties {
_Unique_ID ("Unique Identifier", float) = 1.0
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
fixed4 color : COLOR;
};
uniform float _Unique_ID;
v2f vert (appdata_base v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
float3 worldpos = mul(_Object2World, v.vertex).xyz;
if(worldpos[1] >= 0.0)
o.color.xyz = 0.35; //unique_id = 0.35
else
o.color.xyz = 0.1; //unique_id = 0.1
o.color.w = 1.0;
return o;
}


fixed4 frag (v2f i) : COLOR0 {
// local unique_id's set by the vertex shader and stored in the color
if(i.color.x >= 0.349 && i.color.x <=0.351)
return float4(1.0,0.0,0.0,1.0); //red
else if(i.color.x >= 0.099 && i.color.x <=0.11)
return float4(0.0,1.0,0.0,1.0); //green

// global unique_id set by a Unity script
if(_Unique_ID == 42.0)
return float4(1.0,1.0,1.0,1.0); //white

// Fallback color = blue
return float4(0.0,0.0,1.0,1.0);
}
ENDCG
}
}
}

在您的附录说明中,您说“实际上是同一网格的每个顶点”。如果是这样,为什么不使用可修改的属性,就像我上面提到的那样。每个网格只需要一个脚本来更改 unique_id。
public class ModifyShader : MonoBehaviour {
public float unique_id = 1;
// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
renderer.material.SetFloat( "_Unique_ID", unique_id );
}
}

关于unity3d - CG:指定顶点和片段着色器之间不插值的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13876763/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com