I attempt to write a V-F shader for receiving point light without calculating vertex normal. The resultant color on the mesh changes smoothly per point light intensity, until I change the point light range or their positions. The problem is better demonstrated in the video.
The left sphere uses built-in diffuse shader; the middle particle system and the right sphere use my own shader.
Apparently once the point light range hits the mesh’s or particle system’s bounding boxes, they are instantly lit. I thought the absence of normal were the culprit, so I tried Shade4PointLights from UnityCG.cginc instead, but the result isn’t better either. I tried moving the point light function from vertex shader to fragment shader, but no luck.
Shader "Particles/Receive Point Light" {
Properties {
_TintColor ("Tint Color", Color) = (1,1,1,1)
_MainTex ("Texture", 2D) = "white" {}
_AmbientPow ("Ambient Power", Range(0,1)) = 0.5 // Can be used in HDR effect. Intensity greater than 2 causes glitch in HDR rendering.
_Glow ("Intensity", Range(0, 127)) = 1
}
SubShader {
Tags {"LightMode" = "ForwardBase" "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Opaque" }
LOD 100
Cull Back
ZWrite Off
Lighting On
//Blend SrcAlpha OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
#include "UnityShaderVariables.cginc"
#include "AutoLight.cginc"
#include "UnityDeferredLibrary.cginc"
half4 _TintColor;
sampler2D _MainTex;
half4 _MainTex_ST;
half _AmbientPow;
half _Glow;
struct vertIn {
float4 pos : POSITION;
float4 normal : NORMAL;
half2 uv : TEXCOORD0;
fixed4 color : COLOR;
};
struct v2f {
float4 pos : SV_POSITION;
float4 normal : NORMAL;
half2 uv : TEXCOORD0;
fixed4 color : COLOR;
half4 worldPos : TEXCOORD1;
};
v2f vert (vertIn v) {
v2f o;
o.pos = UnityObjectToClipPos(v.pos);
o.uv = TRANSFORM_TEX(v.uv,_MainTex);
half3 worldNormal = UnityObjectToWorldNormal(v.normal);
o.normal = v.normal;
o.color = v.color * _TintColor;
o.color.rgb += _Glow + ShadeSH9(half4(worldNormal,1)) * _AmbientPow;
o.worldPos = mul(unity_ObjectToWorld, v.pos);
o.color.rgb += unity_LightColor[0].rgb * (1 / distance(float3(unity_4LightPosX0.x, unity_4LightPosY0.x, unity_4LightPosZ0.x), o.worldPos.xyz)) * (1 / unity_4LightAtten0.x);
/*
o.color.rgb += Shade4PointLights(
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
unity_LightColor[0].rgb, unity_LightColor[1].rgb,
unity_LightColor[2].rgb, unity_LightColor[3].rgb,
unity_4LightAtten0, o.worldPos, v.normal
);
*/
return o;
}
fixed4 frag (v2f f) : SV_Target {
fixed4 col = tex2D(_MainTex, f.uv) * f.color;
//col.rgb += unity_LightColor[0].rgb * (1 / distance(float3(unity_4LightPosX0.x, unity_4LightPosY0.x, unity_4LightPosZ0.x), f.worldPos.xyz)) * (1 / unity_4LightAtten0.x);
/*
col.rgb += Shade4PointLights(
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
unity_LightColor[0].rgb, unity_LightColor[1].rgb,
unity_LightColor[2].rgb, unity_LightColor[3].rgb,
unity_4LightAtten0, f.worldPos, f.normal
);
*/
return col;
}
ENDCG
}
}
}