4
\$\begingroup\$

A LineRenderer has both Material and Color properties.
But many shaders do not work, ie the line will not respect the Color property, or the line will show black (regardless of the materials having its own color).

For example the Standard, Diffuse, Mobile/Diffuse shaders all show black. Unlit/Color ignores the LineRenderer color and uses only the Material Color property. Particles>Additive works great, but Particles>Standard Surface does not.

What part of the shader code is important to make a LineRenderer display using its own Color property? When it does work, how should shader code decide how to merge between the two colors?

\$\endgroup\$
3
\$\begingroup\$

Color on a LineRenderer is represented as a color property on the vertices themselves. It behaves just like other vertex properties such as position and UV coordinates. However, vertex colors are uncommon in most models, so you won’t see most shaders support them. To get this data to be transferred to the shader, you need to declare a custom vertex struct and function. Here is an example of a custom standard surface shader which includes vertex colors, taken from the Unity forums:

Shader "Custom/StandardVertex" {
    Properties {
         _Color ("Color", Color) = (1,1,1,1)
         _MainTex ("Albedo (RGB)", 2D) = "white" {}
         _Glossiness ("Smoothness", Range(0,1)) = 0.5
         _Metallic ("Metallic", Range(0,1)) = 0.0
     }
     SubShader {
         Tags { "RenderType"="Opaque" }
         LOD 200

         CGPROGRAM
         #pragma surface surf Standard vertex:vert fullforwardshadows
         #pragma target 3.0
         struct Input {
             float2 uv_MainTex;
             float3 vertexColor; // Vertex color stored here by vert() method
         };

         struct v2f {
           float4 pos : SV_POSITION;
           fixed4 color : COLOR;
         };

         void vert (inout appdata_full v, out Input o)
         {
             UNITY_INITIALIZE_OUTPUT(Input,o);
             o.vertexColor = v.color; // Save the Vertex Color in the Input for the surf() method
         }

         sampler2D _MainTex;

         half _Glossiness;
         half _Metallic;
         fixed4 _Color;

         void surf (Input IN, inout SurfaceOutputStandard o) 
         {
             // Albedo comes from a texture tinted by color
             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
             o.Albedo = c.rgb * IN.vertexColor; // Combine normal color with the vertex color
             // Metallic and smoothness come from slider variables
             o.Metallic = _Metallic;
             o.Smoothness = _Glossiness;
             o.Alpha = c.a;
         }
         ENDCG
     } 
     FallBack "Diffuse"
}

Notice that it combines texture color with material color (fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;) and then later combines it with the vertex color (o.Albedo = c.rgb * IN.vertexColor) to get a final value which takes all three into account.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.