Is it possible to use vertex color in a tessellation surface shader like the example provided in the unity docs? How do the new vertices from the tessellation interpolate the color? Basically I want to know if I can use dx11 tessalation and still use vertex color to blend between diffuse textures and normal maps in the pixel / surface shader for a terrain shader. Thanks.
I was about to open a thread regarding the same topic. I’m also looking for a way to simply include the vertex color information into the default Unity tessellation shaders.
Could anyone help, please?
For info, here’s the default displacement tessellation shader code:
Shader "Tessellation/Bumped Specular (displacement)" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
_Shininess ("Shininess", Range (0.03, 1)) = 0.078125
_Parallax ("Height", Range (0.0, 1.0)) = 0.5
_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_ParallaxMap ("Heightmap (A)", 2D) = "black" {}
_EdgeLength ("Edge length", Range(3,50)) = 10
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 800
CGPROGRAM
#pragma surface surf BlinnPhong addshadow vertex:disp tessellate:tessEdge
#include "Tessellation.cginc"
struct appdata {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
};
float _EdgeLength;
float _Parallax;
float4 tessEdge (appdata v0, appdata v1, appdata v2)
{
return UnityEdgeLengthBasedTessCull (v0.vertex, v1.vertex, v2.vertex, _EdgeLength, _Parallax * 1.5f);
}
sampler2D _ParallaxMap;
void disp (inout appdata v)
{
float d = tex2Dlod(_ParallaxMap, float4(v.texcoord.xy,0,0)).a * _Parallax;
v.vertex.xyz += v.normal * d;
}
sampler2D _MainTex;
sampler2D _BumpMap;
fixed4 _Color;
half _Shininess;
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = tex.rgb * _Color.rgb;
o.Gloss = tex.a;
o.Alpha = tex.a * _Color.a;
o.Specular = _Shininess;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
}
ENDCG
}
FallBack "Bumped Specular"
}
you can change the v.vertex.xyz += v.normal * d; to v.vertex.xyz += v.normal * d * v.color.r; to add a vertex color to controll displacement in the void disp{} section. Also be sure to add float4 color : COLOR; in the appdata struct. However I am wondering how to get vertex colors into the pixel shader and am wondering how they will be interpolated with the new vertices from displacement.
@Airship: Thanks! But I’m a bit confused by the vertex color being mixed with the normals. I’m not trying to get vertex color to influence displacement, but rather simply to see vertex colors.
oh gotcha, then we are in the same situation ![]()
Dam. That’s a shame. It looks like the Unity team want to promote Unity as a full DX11 application, yet we still can’t see vertex colors in DX11 shaders. That’s a bit… puzzling. Anyway, I hope someone can help us with that…
Have you lookd at Aras’s example Unity package for Dx11? It has a bunch of shaders that do tessellation and the tessellation code within them, instead of using the helper functions defined in the CGIncludes. You may find with the tessellation code more exposed (though you can just check out the Tessellation.cginc file), that you could vertex colours into the mix.
You can find Aras DX11 example package here or in this thread.
Thanks Noisecrime! I’ve had a look but still I’m just not experienced enough to be able to add the lines for vertex color support.
So I have just PMed Aras to tell him about the situation. I hope he can help…
I hope someone can one day help the community with this…
I’ve constantly been hitting this problem as well. I haven’t fully tested this, but if all you need to do is read and display vertex colors in the tessellation shader, you ought to be able to do so by placing the following in your input method struct…
// To get vertex colors in the vertex section using v.color
struct appdata {
float4 color : COLOR;
}
// To get vertex colors in the surface section using IN.color
struct Input {
float4 color : COLOR;
};
This automatically inherits the vertex color, without having to define it in the vertex program through mechanisms like o.color output (which I can’t get to work with tessellation shaders at all). Then in your surface struct you can just directly decode it…
half4 vertexColor = IN.color;
As noted, this only allows you to read it and display it… I have yet to find a method to alter it in the vertex section.
I just encountered the same problem. Any solutions since summer 2015?
EDIT: Holy moly! After fiddling with it for an hour I got it working. Perhaps Unity fixed the problem. I just had to add “: COLOR” to float4 color in my Input struct.