- Home /
Multiple Light Shader 'Light Box' Bug
I have an issue when creating a shader that allows for multiple sources of light. Any point light that is added into the scene has a strange masking effect, where no light from it renders on a model's surface outside it's range. I've tried editing the attenuation, and using an attenuation table to account for the light range, but it ended up barely rendering any light from the point light, and it still has the same issue. This is the code I currently have:
Shader "Tests/Multiple Lights" {
Properties {
_Color ("Color", Color) = (1.0, 1.0, 1.0, 1.0)
_SpecColor ("Specular Color", Color) = (1.0, 1.0, 1.0, 1.0)
_Shininess ("Specular Highlight Strength", Float) = 10
_RimColor ("Rim Lighting Color", Color) = (1.0, 1.0, 1.0, 1.0)
_RimStrength ("Rim Strength", Range(0.1, 10)) = 3.0 //The power function, although mathematically can deal with 0, the function itself cant. DONT.
}
Subshader {
Pass {
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// User defined variables
uniform float4 _Color;
uniform float4 _SpecColor;
uniform float _Shininess;
uniform float4 _RimColor;
uniform float _RimStrength;
// Unity defined variables
uniform float4 _LightColor0;
// Base input structs
struct vertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 posWorld : TEXCOORD0;
float3 normalDir : TEXCOORD1; // Overwriting the texture coordinates because REASONS.
};
// Vertex Function
vertexOutput vert (vertexInput v) {
vertexOutput o;
o.posWorld = mul(_Object2World, v.vertex);
o.normalDir = normalize( mul( float4(v.normal, 0.0), _World2Object).xyz );
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
}
// Fragment Function
float4 frag(vertexOutput i) : COLOR // Assigning the semantic of color because...?
{
float3 normalDirection = i.normalDir;
float3 viewDirection = normalize( _WorldSpaceCameraPos.xyz - i.posWorld.xyz );
float atten = 1.0;
float3 lightDirection;
if (_WorldSpaceLightPos0.w == 0.0) // Directional Light
{
atten = 1.0;
lightDirection = normalize( _WorldSpaceLightPos0.xyz );
}
else {
float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - i.posWorld.xyz;
float distance = length(fragmentToLightSource);
atten = 1/distance;
lightDirection = normalize(fragmentToLightSource);
}
// Lighting
float3 diffuseReflection = atten * _LightColor0.xyz * saturate( dot( normalDirection, lightDirection ) );
float3 specularReflection = atten * _LightColor0.xyz * saturate( dot( normalDirection, lightDirection ) ) * pow( saturate( dot( reflect( -lightDirection, normalDirection), viewDirection ) ), _Shininess );
// Rim Lighting
float rim = 1 - saturate( dot( normalize(viewDirection), normalDirection));
float3 rimLighting = atten * _LightColor0.xyz * _RimColor * saturate( dot(normalDirection, lightDirection)) * pow(rim, _RimStrength);
float3 lightFinal = rimLighting + diffuseReflection + specularReflection + UNITY_LIGHTMODEL_AMBIENT.rgb;
return float4(lightFinal * _Color.rgb, 1.0);
}
ENDCG
}
Pass {
Tags { "LightMode" = "ForwardAdd" }
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// User defined variables
uniform float4 _Color;
uniform float4 _SpecColor;
uniform float _Shininess;
uniform float4 _RimColor;
uniform float _RimStrength;
// Unity defined variables
uniform float4 _LightColor0;
// Base input structs
struct vertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 posWorld : TEXCOORD0;
float3 normalDir : TEXCOORD1; // Overwriting the texture coordinates because REASONS.
};
// Vertex Function
vertexOutput vert (vertexInput v) {
vertexOutput o;
o.posWorld = mul(_Object2World, v.vertex);
o.normalDir = normalize( mul( float4(v.normal, 0.0), _World2Object).xyz );
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
}
// Fragment Function
float4 frag(vertexOutput i) : COLOR // Assigning the semantic of color because...?
{
float3 normalDirection = i.normalDir;
float3 viewDirection = normalize( _WorldSpaceCameraPos.xyz - i.posWorld.xyz );
float atten = 1.0;
float3 lightDirection;
if (_WorldSpaceLightPos0.w == 0.0) // Directional Light
{
atten = 1.0;
lightDirection = normalize( _WorldSpaceLightPos0.xyz );
}
else {
float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - i.posWorld.xyz;
float distance = length(fragmentToLightSource);
atten = 1/distance;
lightDirection = normalize(fragmentToLightSource);
}
// Lighting
float3 diffuseReflection = atten * _LightColor0.xyz * saturate( dot( normalDirection, lightDirection ) );
float3 specularReflection = atten * _LightColor0.xyz * saturate( dot( normalDirection, lightDirection ) ) * pow( saturate( dot( reflect( -lightDirection, normalDirection), viewDirection ) ), _Shininess );
// Rim Lighting
float rim = 1 - saturate( dot( normalize(viewDirection), normalDirection));
float3 rimLighting = atten * _LightColor0.xyz * _RimColor * saturate( dot(normalDirection, lightDirection)) * pow(rim, _RimStrength);
float3 lightFinal = rimLighting + diffuseReflection + specularReflection;
return float4(lightFinal * _Color.rgb, 1.0);
}
ENDCG
}
}
Fallback "Specular"
}
I've uploaded an image of the issue. Any suggestions? :x
[1]: /storage/temp/11697-screen+shot+2013-06-04+at+22.36.30.png
that has to do with light attenuation, when you do (1/distance), the problem is that box works like a collision box so when you change the range of the point light it'll increase the "light box" and so it will "detect" more objects to reflect light, what i don't get is how can unity use the range property to alter the light attenuation
if you do something like (1/(distance*distance)) which is the real world equivalent (stated by nvidia) you get a dimmer lightbox but you still get it, the only way to $$anonymous$$imize it's effect is to blow the range up and then control the range by means of using _LightColor0, something like (_LightColor0/(distance*distance))
i'm still trying to figure out this problem myself, maybe someone has a clear solution
I had the same problem, but I also had Fog turned on in the Render settings. Once I turned the fog off, the light boxes disappeared. I am now researching how to get my shader to actually handle the fog. I'm sure the fog value needs to be worked into the shader somehow.
Your answer
Follow this Question
Related Questions
3D Text Shader with light 0 Answers
Mobile Bumped Specular: Point Lights Only 0 Answers
point light custom falloff 2 Answers
Shader to hide object with no light 0 Answers
Specularity Material Problem 0 Answers