Hei*_*bug 5 shader interpolation cg unity-game-engine
我正在使用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
};
Run Code Online (Sandbox Code Playgroud)
这是顶点着色器返回的结构作为片段的输入:
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
fixed4 col: COLOR;
};
Run Code Online (Sandbox Code Playgroud)
如果我只是将参数转发到片段着色器,当然它将被插值:
v2f vert (appdata_full v)
{
v2f output;
//....
output.col = v.color;
}
Run Code Online (Sandbox Code Playgroud)
我想将v.color未插入的参数传递给片段着色器.这可能吗?如果是的话怎么样?
编辑
像Tim指出的那样,这是预期的行为,因为如果从顶点着色器传递到片段,着色器除了插值颜色之外什么也做不了.我会试着更好地解释一下我想要实现的目标.我使用每个顶点颜色来存储除颜色之外的其他信息.在没有详细说明我正在做什么的情况下,假设您可以将每个颜色顶点视为一个id(同一个三角形的每个顶点,将具有相同的颜色.实际上是同一网格的每个顶点).
所以我使用颜色技巧来掩盖一些参数,因为我没有其他方法可以做到这一点.现在,必须以某种方式在片段着色器中提供这条信息.如果传递作为顶点着色器的out参数,则编码为颜色的该信息将在片段处内插到达,该片段不能再使用它.
我正在寻找一种方法来传播这些信息,直到片段着色器(也许可以使用全局变量或类似的东西?如果是的话怎么样?).
Jer*_*dak 10
我不确定这是否适用于答案,但对于评论来说这有点多了.正如Bjorke指出的那样,片段着色器将始终接收插值.如果/当Unity支持Opengl 4.0时,您可以访问Interpolation限定符,即禁用插值的"flat",从激发顶点派生所有值.
也就是说,尝试为三角形的所有顶点分配相同的"颜色"值的问题是顶点着色器在顶点上迭代一次,而不是每个三角形.总会有一个"边界"区域,其中一些顶点与不同"颜色"或"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
}
}
}
Run Code Online (Sandbox Code Playgroud)
在你的附录中你会说"实际上是同一个网格的每个顶点".如果是这种情况,为什么不使用可修改的属性,就像我上面所包含的那样.每个网格只需要一个脚本然后更改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 );
}
}
Run Code Online (Sandbox Code Playgroud)
我知道这是一个旧线程,但无论如何它都值得回答,因为这是谷歌的最佳结果之一。您现在可以在常规 CG 着色器中对变量使用 nointerpolation 选项。IE
nointerpolation fixed3 diff : COLOR0;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10266 次 |
| 最近记录: |