- Home /
Mysterious syntax error with finalcolor function
I'm trying to use the finalcolor function in a surface shader with a custom lighting algorithm. The only problem is that no matter what I do, adding the finalcolor function causes the compiler to fail with:
Shader error in <shader>: Syntax error at line <first line of function>
This holds true even when I copy in functions from the Surface Shader examples page. Even if I have an empty finalcolor function, this still fails to compile with a simple 'syntax error' message:
void mycolor (Input IN, SurfaceOutput o, inout fixed4 color){}
This occurs with or without defining the function as a finalcolor modifier. It seems the compiler just won't accept the syntax for some reason. I have absolutely no idea what's going wrong here. Does anyone have any advice?
This is the shader code in full (please note several functions used her are defined in a custom cginc file):
Shader "Custom/3TermLit_Lined" {
Properties {
_MainTex ("Diffuse (RGB), Specular (A)", 2D) = "white" {}
_BumpMap ("Bumpmap (RGB), Opacity (A)", 2D) = "bump" {}
//_Specular ("Spec Colour (RGB), Spec Opacity (A)", Color) = (1,1,1,1)
//_Gloss ("Gloss", Float) = 50
_S1Mult ("Step 1 Multiplier", Range (0, 1)) = 0.5
_S2Mult ("Step 2 Multiplier", Range (0, 1)) = 0.05 //keep this lower than _S1Mult or you'll get odd results.
_S1Threshold ("Step 1 Threshold", Range (0, 1)) = 0.7
_S2Threshold ("Step 2 Threshold", Range (0, 1)) = 0.2
_Fuzz ("Step Fuzziness", Range (0.01, 0.1)) = 0.05
_Bias ("LGT / HST Bias", Range (0,1)) = 0.5
_FPower ("Fresnel Power", Float) = 5
_RimBoost ("Rim Boost", Float) = 2
_LineTex ("Internal Lines (R)", 2D) = "white" {}
_LineColour ("Line Colour (RGB)", Color) = (0,0,0,1)
_LineMaxDistance ("Line Max Distance", Float) = 25
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Anim finalcolor:linecolour
#include "UnityCG.cginc"
#include "Assets/AnimationShaders/Shaders/AnimShaders.cginc"
#pragma target 3.0
sampler2D _MainTex;
sampler2D _BumpMap;
//fixed4 _Specular;
//float _Gloss;
float _S1Mult;
float _S2Mult;
float _S1Threshold;
float _S2Threshold;
float _Fuzz;
float _Bias;
float _FPower;
float _RimBoost;
sampler2D _LineTex;
fixed4 _LineColour;
float _LineMaxDistance;
void linecolour (Input IN, SurfaceOutput o, inout fixed4 colour) {
float lineInterp = InternalLineTerm(o.Alpha, _LineMaxDistance, _Fuzz);
colour.rgb = lerp(colour.rgb, _LineColour.rgb, lineInterp);
}
half4 LightingAnim (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten){
half4 c;
c.a = 1;
half Fresnel = FresnelTerm(s.Normal, viewDir, _FPower);
half LGT = LightGradientTerm(s.Normal, lightDir, atten);
half HST = HardShadowTerm(LGT, _Fuzz, _S1Threshold, _S2Threshold, _S1Mult, _S2Mult);
half3 RHT = _LightColor0.rgb * RimHighlightTerm(LGT, Fresnel, _RimBoost);
//final composit
c.rgb = (s.Albedo + RHT) * HSTLGTcomposite(HST, LGT, _Bias);
return c;
}
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
float2 uv_LineTex;
float3 viewDir;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
half line = tex2D (_LineTex, IN.uv_LineTex).r;
half4 nrm = tex2D (_BumpMap, IN.uv_BumpMap);
o.Albedo = c.rgb;
//o.Specular = c.a;
//o.Specular = 1;
o.Alpha = line;
o.Normal = UnpackNormal (nrm);
}
ENDCG
}
FallBack "Diffuse"
}
You don't need a final color function if you are doing your own lighting right?
As it transpires, I do. I tried doing it in the surface shader, but it was still being affected by ambient lighting. For example, try returning pure black in the lighting function; you won't get pure black, it will still be affected by light cubes and so on.
Answer by Guessmyname · Apr 19, 2013 at 04:53 PM
Ah, found the cause. You have to define the finalcolor function in code after the surf function.
Not... entirely sure why, must be how things are compiled. Oh well.
Shaders are a subset of C. In C you have to define a function before it's used because the compiler is pretty much top-down only.
You could create a function signature and then define the function later too if necessary (you'd have to do it this way if you had two functions who for some reason pointed at each other).
It's a C paradigm.