There are three methods for this (that I know), each of which will have similar results.
The first two methods both use cookies for lights:
Be sure to turn off ambient light through edit–>render settings–>ambient light–>“make the texture black aka (0,0,0) for RGB”
[edit:] I forgot to mention, the reason your textures look burned is because you are using a bad shader, and it would be a shame to ignore the cookie solution because of it. Essentially all you want to do is use a special shader that 1) ignores angles 2) does not decrease intensity with distance, only with the input from the cookie.
This makeshift solution is modified from the Default Diffuse shader (and it works on my machine). If you set the range of the light to “999999” and tweak the intensity of the light (~= 1) this should look virtually identical to an “Unlit Diffuse” shader. Also, use a “spotlight”, if that’s what you want.
It renders like this:
Despite the fact that the plane is rotated 82 degrees, the brick wall still seems like it is fully lit. With a normal shader the larger brick wall’s color values would be multiplied by the cosine of 82 or .139 making it 14% as bright as it should be.
Shader "Custom/DistanceOnlyDiffuse"
{
Properties
{
_Color ("Main Color", Color) = (1,1,1,1) //variable _Color of type Color seen as "Main Color" in the inspector
_MainTex ("Base (RGB)", 2D) = "white" {} // Texture2D that will default to white.
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue" = "Geometry" }
CGPROGRAM // a glorified curly brace START
#pragma surface surf Always
//pragma definition: (computer science) A directive inserted into a computer program to prevent the automatic execution of certain error checking and reporting routines which are no longer necessary when the program has been perfected.
//surface--> surface shader
//surf means use the "void surf" function defined later
//Always means use "LightingAlways"
fixed4 LightingAlways (SurfaceOutput s, fixed3 lightDir, fixed atten)
{
//fixed diff = max (0, dot (s.Normal, lightDir)); //this commented out dot product normally makes things dimmer at an angle, which is normally how light works
fixed4 c;
c.rgb = s.Albedo * _LightColor0.rgb * (atten); //diff * used to be multiplied in here to dim the color of the object
c.a = s.Alpha;
return c;
}
sampler2D _MainTex; //tell the CG program code that the shaderlab code has a _MainTex and import it (in Laymans) //sampler2D is a Texture2D
fixed4 _Color; //similarly inform the CG program that shaderlab has a property for color // color has 4 values RGBA, hence fixed (it wont change) 4
struct Input
{
float2 uv_MainTex; //this is a builtin value that will be handled by unity to save you time/redundancy. other values (see: Surface Shader input structure): http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaders.html
};
void surf (Input IN, inout SurfaceOutput o) //use the struct Input as an "IN" (input), the other stuff specifies what happens next
{
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; //texture the object and multiply by the color to tint it. White color does nothing
o.Albedo = c.rgb; //send the calculated value back as an Albedo. Albedo is how something would look without light
o.Alpha = c.a;
}
ENDCG //glorified curly brace END
}
//Fallback "Transparent/VertexLit" //During developement (pre-release) graphics programmers usually comment out fallbacks to find which hardware can handle/support the shader
}
To add this shader to your project, right click in the project panel and click create–>shader, rename it, and copy and paste this exactly into its code (delete the pre-existing code too).
To select this shader click on the material you want to change–>look at it in the inspector–>click the dropdown shader bar–>go into the “Custom” folder–>select “DistanceOnlyDiffuse”.
I wasn’t able to get shadows to work, but I think you can get this shader to use shadows. Shadow-ception if you will. Of course this requires Unity Pro.
For C# Programmers:
A simple programming method would be to get a few cookie textures in an array and manually cycle through them with a script. Essentially this would be:
using UnityEngine;
using System.Collections;
public class SomeClass
{
public Light light;
public Texture2D[] textures;
int index = 0;
int length = 1;
float interval = 0.2f;
float nextSwapTime = 0.2f;
void Start()
{
length = textures.Length;
}
void Update()
{
if(Time.time > nextSwapTime)
{
nextSwapTime += interval;
index++;
if(index == length) index = 0;
light.cookie = textures[index];
}
}
}
The problem is that usually you would want at least 8-16 textures for a reasonable aura effect, and that will take up a lot of space if each texture is 256x256.
For people willing to spend money:
If you would like to use cookies but do not want to make X different texture for the light animation, buy Substance Designer by Allegorithmic. http://www.allegorithmic.com/products/substance-designer
It is a visual scripting knowledge (it uses node based logic). It is often very expensive, but if you can get it on sale it’s a great tool. It does take some knowledge on how their “substances” work. These substance files, set up correctly, will overwrite the texture at runtime, you don’t need to change the texture each frame, but you have to know how to create and integrate the substance. For easy and complex lighting effects this method probably isn’t worth it, but it will definitely look the smoothest since it will update each frame.
I happened to make a tutorial on how to use SD2 so I will gratuitously link it: - YouTube
The cool thing about substances is they use vector images which are dynamically updated at run-time due to any parameters you want (usually time), they are very accurate, and they happen to use up way less file memory (at least 70% less, I think it can go as low as approx. 97% less, which speeds up download time, if that’s an issue for mobile or web-players).
This can create effects from bugs crawling on the floor, to sand moving across sand-dunes, to the aforementioned light cookie manipulations, to dynamic skyboxes for sunrise–>sunset–>night. Anything imaginable that can be explained by vector mathematics (which in my opinion is everything, although depending on what you want it could be difficult).
A laborious alternative for programmers:
The pure programming route is to learn how to use CGPrograms in Shaders. While you are at it, you will also need a rudimentary understanding of ShaderLab as well. What you would essentially do is make a new surface shader.
A example method would be to use the cull() function on all undesired pixels within a #CGPROGRAM → #ENDCG bracket within a custom shader. This would definitely work for a single ellipse, although I have no idea what this mysterious “quad” is. The problem with this method, I realize, is that handling multiple lights could be difficult.
[edit:3] dang that was long.