Why is this point light square?
Hey all,
I was writing a shader and thought everything was going great until I added a point light over a larger piece of geometry and noticed that point lights were appearing squared if the geometry didn't fully fit within the range of the light. I was reading that this had to do with the attenuation. However, nothing changes no matter what I do with the attenuation. I've noticed that Unity's default shaders do not do this. Here's an example of the problem:
I decided to take a step back and try to see if I could get this working on a simpler shader. The lighting is being done on the vertex level. The shader code is below.
Shader "Custom/FromScratch" {
Properties {
_Color ("Color", Color) = (1.0, 1.0, 1.0, 1.0)
}
SubShader {
Pass{
Tags {"LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//user defined
uniform float4 _Color;
//Unity Defined
uniform float4 _LightColor0;
struct vertexInput{
float4 vertex: POSITION;
float3 normal: NORMAL;
};
struct vertexOutput{
float4 pos: SV_POSITION;
float4 light : TEXCOORD0;
};
vertexOutput vert(vertexInput v){
vertexOutput o;
float4 posWorld = mul(_Object2World, v.vertex);
float atten;
float3 lightDirection;
float3 normalDir = normalize(mul(float4(v.normal,1.0), _World2Object).xyz);
//lighting
if(_WorldSpaceLightPos0.w == 0.0){
atten = 1.0;
lightDirection = normalize(_WorldSpaceLightPos0.xyz);
} else {
float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - posWorld.xyz;
float distance = length(fragmentToLightSource);
atten = 1 / (distance * distance);
lightDirection = normalize(fragmentToLightSource);
}
float3 diffuseReflection = atten * _LightColor0.xyz * max(0.0, dot(normalDir, lightDirection));
o.light = float4(diffuseReflection.rgb, 1.0);
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
}
float4 frag(vertexOutput i):COLOR{
return i.light;
}
ENDCG
}
Pass{
Tags {"LightMode" = "ForwardAdd"}
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//user defined
uniform float4 _Color;
//Unity Defined
uniform float4 _LightColor0;
struct vertexInput{
float4 vertex: POSITION;
float3 normal: NORMAL;
};
struct vertexOutput{
float4 pos: SV_POSITION;
float4 light : TEXCOORD0;
};
vertexOutput vert(vertexInput v){
vertexOutput o;
float4 posWorld = mul(_Object2World, v.vertex);
float atten;
float3 lightDirection;
float3 normalDir = normalize(mul(float4(v.normal,1.0), _World2Object).xyz);
//lighting
if(_WorldSpaceLightPos0.w == 0.0){
atten = 1.0;
lightDirection = normalize(_WorldSpaceLightPos0.xyz);
} else {
float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - posWorld.xyz;
float distance = length(fragmentToLightSource);
atten = 1 / (distance * distance);
lightDirection = normalize(fragmentToLightSource);
}
float3 diffuseReflection = atten * _LightColor0.xyz * max(0.0, dot(normalDir, lightDirection));
o.light = float4(diffuseReflection.rgb, 1.0);
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
}
float4 frag(vertexOutput i):COLOR{
return i.light;
}
ENDCG
}
}
FallBack "Diffuse"
}
Is there anything I can do to make sure the light falls off before the light's range? Or should I just set the range to a crazy high value? Thanks for any help!
Another note that when using AutoLight.cginc, LIGHT_COORDS, and LIGHT_ATTENUATION, I appear to get the same result.
Your answer
Follow this Question
Related Questions
Is it possible to use an Int64 data type in CG? 0 Answers
Problem with fresnel materials 0 Answers
Storing data from previous shader pass 0 Answers
System.IO.File' does not contain a definition for `ReadAllBytes' 2 Answers
C# Newbie Programming Questions 0 Answers