Hi!
I'm trying to project a texture with transparency on to a surface with the projector/multiply shader. This is working, however I would also like to be able to fade the whole picture in and out through animation. How is this possible?
Cheers!
Hi!
I'm trying to project a texture with transparency on to a surface with the projector/multiply shader. This is working, however I would also like to be able to fade the whole picture in and out through animation. How is this possible?
Cheers!
If you change the main color of the projector's material, the projection will "fade out".
projectorFade.js
var duration : float = 1.0f;
var color : Color = color.white;
var projector : Projector;
function Start() {
projector = GetComponent(Projector);
if(!projector || !projector.material || projector.material.color.a == 0)
return;
color = projector.material.color;
}
function FadeOut() {
if(!projector || !projector.material) return;
var lerp: float = 0.0f;
while(lerp < 1.0f) {
lerp += Time.deltaTime / duration;
projector.material.color = Color.Lerp(color, Color.clear, lerp);
yield;
}
}
function FadeIn() {
if(!projector || !projector.material) return;
var lerp: float = 0.0f;
while(lerp < 1.0f) {
lerp += Time.deltaTime / duration;
projector.material.color = Color.Lerp(Color.clear, color, lerp);
yield;
}
}
This shader doesn't have a main color, making this a bit harder. The simplest way is to modify the shader to get this to do what you want, adding a main color. This will make the above scripts with a few changes work for this shader as well.
Something like lerping the output with a primary color should do the trick, but it won't color the shadow so we're really only using the alpha:
Shader "Projector/Multiply" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_ShadowTex ("Cookie", 2D) = "gray" { TexGen ObjectLinear }
_FalloffTex ("FallOff", 2D) = "white" { TexGen ObjectLinear }
}
Subshader {
Tags { "RenderType"="Transparent-1" }
Pass {
ZWrite Off
Fog { Color (1, 1, 1) }
Color [_Color]
AlphaTest Greater 0
ColorMask RGB
Blend DstColor Zero
Offset -1, -1
SetTexture [_ShadowTex] {
combine texture, ONE - texture
Matrix [_Projector]
}
SetTexture [_ShadowTex] {
combine previous lerp(Primary) Primary
}
SetTexture [_FalloffTex] {
constantColor (1,1,1,0)
combine previous lerp (texture) constant
Matrix [_ProjectorClip]
}
}
}
}
projectorFade.js
var duration : float = 1.0f;
var alpha : float = 1.0f;
var projector : Projector;
function Start() {
projector = GetComponent(Projector);
if(!projector || !projector.material || projector.material.color.a == 0)
return;
alpha = projector.material.color.a;
}
function FadeOut() {
if(!projector || !projector.material) return;
var lerp: float = 0.0f;
while(lerp < 1.0f) {
lerp += Time.deltaTime / duration;
projector.material.color.a = Mathf.Lerp(alpha, 0.0f, lerp);
yield;
}
}
function FadeIn() {
if(!projector || !projector.material) return;
var lerp: float = 0.0f;
while(lerp < 1.0f) {
lerp += Time.deltaTime / duration;
projector.material.color.a = Mathf.Lerp(0.0f, alpha, lerp);
yield;
}
}
You could write a script that would change the texture used in the material with SetPixels, etc, but this would be costly and needless at run-time when a simple shader/material color change will do.
Since the material is shared, any other projectors using this exact material will fade out as well. If you don't want this, you will need to create one or more separate materials for projectors that you don't want sharing the behaviour.
If you wanted to animate this in the animation window for whatever reason (maybe you need it to sync with part of another animation or you want more control over the curves), you would need to approach the problem a little differently because projector materials are not exposed in the animation view.
You can use the effect of the shared material described above. If you were to include some other object (plane or whatever) as a child of your projector with the exact same material as the projector applied to it, you could animate the material. If you disable the renderer on the object, the material should still animate, but this object won't actually be rendered. It's a bit awkward, but it should do the trick.
Or you can use some simple code to set the material's color explicitly every frame and then animate the color in the script:
SetProjectorColor.js
var color : Color = Color.white;
var projector : Projector;
function Start() {
projector = GetComponent(Projector);
}
function Update() {
if(!projector || !projector.material)
return;
projector.material.color = color;
}
or
SetProjectorAlpha.js
var alpha : float = 1.0f;
var projector : Projector;
function Start() {
projector = GetComponent(Projector);
}
function Update() {
if(!projector || !projector.material)
return;
projector.material.color.a = alpha;
}
Having troubles implementing the projector/multiply code to add fade. When I change the shader code to this one, the projector no longer behaves like a projector. Instead of shooting an image with a flat plane across all object’s in its way, it wraps around the obstructed objects according to the object’s UV’s.
Any ideas on how to fix this? Thanks