Emissive Material in Unity - unity3d

I am trying to make that a sphere emits light by using a material from the own unity, but no light is being created or emitted. What is wrong?

You can modify the emission in the material, without any special shader
You can then switch off all lights in the scene and you will be able to still see this GameObject
You can test it adding a script that make the ambient light to be dark grey
void Start () {
Color myColor = new Color32( 0x0B, 0x0A, 0x0A, 0xFF );
RenderSettings.ambientLight = myColor;
}
The result would be something like this, a cube which emit yellow light and a cube which is almost in darkness
Now if you want (which I am still not sure) to iluminate other elements in the scene. You should select the object as static in the right top corner.
And the result would be:
If this solution still does´t work for you. You can try with shaders:
Create a new Shader, name it Glow and replace its default code by this:
Script
Shader "Glow" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
_Glow ("Intensity", Range(0, 3)) = 1
}
SubShader {
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
LOD 100
Cull Off
ZWrite On
Blend SrcAlpha OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
sampler2D _MainTex;
half4 _MainTex_ST;
fixed4 _Color;
half _Glow;
struct vertIn {
float4 pos : POSITION;
half2 tex : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
half2 tex : TEXCOORD0;
};
v2f vert (vertIn v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.pos);
o.tex = v.tex * _MainTex_ST.xy + _MainTex_ST.zw;
return o;
}
fixed4 frag (v2f f) : SV_Target {
fixed4 col = tex2D(_MainTex, f.tex);
col *= _Color;
col *= _Glow;
return col;
}
ENDCG
}
}
}
Create a Material
Change its color to what you want and the Shader type select Glow
(the one you created in the fist step). Also choose the intensity you prefer.
The result would be:
With this version, you can not iluminate the nearby objects.
Finally, to make a better glomming effect you can add some effects to the camera.
Go to Assets -> Import Package -> Effects
Select the Main Camera and Add Component: Image Effects -> Bloom and
Glow -> Bloom Optimized
You will have the following component in your camera:
And the result of adding this effect to the camera would be:

The problem was solved only checking all objects in the scene as Static!

Related

Alpha channel on my unity shader is not working

So I am very new to shader programing (basically just started today) and I got this code from a tutorial on Youtube which works great. It just found the pixel on the edge of a texture, and if so, replace it with a plain color. I want to be able to set the transparency of the color i'm returning.
But it does not seems to be working
Shader "Custom/OutlineShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Color("Color", Color) = (1, 1, 1, 1)
_AlphaOffset("Transparency", Range(0,1)) = 1
}
SubShader
{
Tags{ "Queue"="Transparent" "RenderType"="Opaque"}
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag Lambert alpha
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTexelSize;
float _AlphaOffset;
v2f vert (appdata v)
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos(v.vertex);
OUT.uv = v.uv;
return OUT;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
col.rgb *= col.a;
fixed4 outlineColor = _Color;
// This is where I want the shader to be transparent or not based on the _AlphaOffset Value
outlineColor.a *= ceil(col.a) * _AlphaOffset;
// This a code just to check is the current pixel is on the edge of the texture
fixed upAlpha = tex2D(_MainTex, i.uv + fixed2(0, _MainTexelSize.y)).a;
fixed downAlpha = tex2D(_MainTex, i.uv - fixed2(0, _MainTexelSize.y)).a;
fixed leftAlpha = tex2D(_MainTex, i.uv - fixed2(_MainTexelSize.x, 0)).a;
fixed rightAlpha = tex2D(_MainTex, i.uv + fixed2(_MainTexelSize.x, 0)).a;
// If it's on the edge, return the color (+ alpha) else, just return the same pixel
return lerp(outlineColor, col, ceil(upAlpha * downAlpha * leftAlpha * rightAlpha));
}
ENDCG
}
}
}
I would like this line
outlineColor.a *= ceil(col.a) * _AlphaOffset; to set the alpha of the pixel I'm returning.
Thanks !
There are primarily two things which are wrong here - firstly, you have set your RenderType to "Opaque", which expectedly makes it render as non-transparent. This should instead be set to "Transparent". Second, you need to specify a blend mode to determine how the color from this object blends with what's already rendered to the buffer. From the Unity manual on blending:
Blend SrcFactor DstFactor: Configure and enable blending. The
generated color is multiplied by the SrcFactor. The color already on
screen is multiplied by DstFactor and the two are added together.
For regular alpha blending, add this statement inside your subshader:
Blend SrcAlpha OneMinusSrcAlpha
For additive blending, which results in a glow-like effect, use this:
Blend One One

Light Projection passing through objects

I have a light projector with a material attached to it and a script that projects a caustic effect underwater. Inside the script Inspector I have multiple caustics textures generated with by a software and it iterates in each of them changing the material texture of the projector.
How can I make the shader behave more like light and be invisible on shadows?
I have no experience in shaders and the shader is not from me.
Shader "Projector/Caustics" {
Properties {
_Color ("Color", Color) = (1,1,1,0)
[NoScaleOffset]_MainTex ("Texture", 2D) = "black" { }
_Size ("Grid Size", Float) = 10
_Height ("Water Height", Float) = 2.0
_DepthBlend ("Depth Blend", Float) = 10.0
_EdgeBlend ("Edge Blend", Range (0, 100)) = 0.5
_Multiply ("Multiply", Range (1, 2)) = 1.0
_LOD ("LOD Bias", Range (1, 1000)) = 100
}
Subshader {
Tags { "RenderType"="Transparent" "Queue"="Transparent+100" }
Pass {
ZWrite Off
Offset -1, -1
//Blend OneMinusDstColor One //- Soft Additive
//Blend One One //- Linear Dodge
Blend DstColor One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 wPos : TEXCOORD1; // added for height comparisons.
UNITY_FOG_COORDS(2)
};
uniform sampler2D _MainTex;
float4 _MainTex_ST;
float4 _Color;
float4x4 unity_Projector;
float _Size;
float _Height;
float _DepthBlend;
float _EdgeBlend;
float _Multiply;
float _LOD;
float dist;
v2f vert (appdata_tan v) {
v2f o;
o.pos = UnityObjectToClipPos (v.vertex);
o.wPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.uv = TRANSFORM_TEX (mul (unity_Projector, v.vertex).xy, _MainTex);
UNITY_TRANSFER_FOG(o,o.pos);
return o;
}
fixed4 frag (v2f i) : COLOR {
dist = distance(_WorldSpaceCameraPos, i.wPos);
fixed4 c = tex2Dlod (_MainTex, float4(fmod (i.uv, 1 / _Size)*_Size,0,dist/_LOD)); // project tiled texture, set lod.
if (i.wPos.y<_Height)
c = c-(i.wPos.y-_Height)/-_DepthBlend*2;
else
c = lerp(c,0,(i.wPos.y-_Height)/_EdgeBlend);
c = saturate(c);
UNITY_APPLY_FOG_COLOR(i.fogCoord, c, fixed4(0,0,0,0));
return c * _Color *_Multiply ; // apply final color
}
ENDCG
}
}
}
Unfortunately, you can't have shadows with projectors, which is what you would need for this. Unity also doesn't support shadows for transparent object.
There are three options for achieving this effect:
Use deferred decals, which are only supported in deferred mode.
Use a screen-space effect.
Create a custom terrain shader which displays the caustics as part of the terrain rendering based on the world space Y position. You would also need a similar shader modification to all other objects which are to receive caustics.
There are some examples on deferred decals in this post. Unfortunately though, without any knowledge of shader programming, it is not that straightforward to fix. There are some water solutions for Unity which have this feature built-in, though - for instance, LUX uses screen-space caustics which is pretty cool.

Unity 2D: Area Color Inverse Effect

I am trying to create a GameObejct that if active reverses the colors of anything behind it. Ideally, this GameObject expands from its centre point to a certain size radius when it appears/becomes active.
So imagine a circle whose Scale increases from x=0 and y=0 to x=5 and y=5 gradually over 1 or 2 seconds and reverses the colors of anything behind. Doesn't exactly matter how long or how big the actual circle is, just an example of the idea. I tried just creating a GameObect with a mask and a shader I found online, but t didn't work at all and I still wasn't even sure how to animate the expansion.
Does anyone have any idea on how I could make this dream effect of mine a reality?
Here is a shader that does nothing except invert the color.
The important part is Alpha:Blend and Blend OneMinusDstColor Zero.
Shader "Custom/Invert"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent" }
LOD 200
Blend OneMinusDstColor Zero
PASS
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0 Alpha:Blend
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
fixed4 _Color;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = float2(0,0);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return _Color;
}
ENDCG
}
}
FallBack "Diffuse"
}
You can put this on any sprite or 3D object to get this effect:
As for the animation, King's answer is nice and simple. Alternatively you could animate the scale by code:
public class Scale : MonoBehaviour
{
void Update ()
{
var scale = Mathf.Sin(Time.timeSinceLevelLoad / 4f) * 20;
this.transform.localScale = new Vector3(scale, scale, 1);
}
}
This particular code will make the sprite 'pulse'. Like this:
I think you should be able to make your own scaling script from this example.
Select your GameObject->Window->Animation->Animation->Create->Save->Add Property->Transform->Scale. At your 0:00 keyframe set your scale for x,y,z to 1. Click over to your 1:00 keyframe and set your scale for x,y,z to 2. Press play and your animation should loop from scale of 1 to 2.

Unity transparent shadow receiving plane for AR app to receive only shadows and not light reflections

I'm working on a transparent shadow receiving shader for Augmented Reality app in Unity, that is put into a plane which will receive shadows from point light or spotlight. It works fine, but the plane receives light also as you can see in the image.
Output Screenshots
I'm using unity 5.6.3p4. Please tell me what could be the problem in this script or what should I change in this code to receive only shadows and not light reflections on the plane?
The Shader Script is below:
Shader "SP/InvisibleShadowCasterForPLight" {
Properties {
_MainTex("Base (RGB)", 2D) = "white" {}
}
SubShader {
Pass {
Blend One One
Tags { "LightMode" = "ForwardAdd" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma multi_compile_fwdadd_fullshadows
#include "AutoLight.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
struct v2f {
float4 pos : SV_POSITION;
LIGHTING_COORDS(0,1)
float2 uv : TEXCOORD2;
};
v2f vert(appdata_base v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
fixed4 frag(v2f i) : COLOR
{
float attenuation = LIGHT_ATTENUATION(i);
return tex2D (_MainTex, i.uv) * attenuation;
}
ENDCG
}
}
Fallback "VertexLit"
}
Replace:
LIGHTING_COORDS(0,1)
with:
UNITY_SHADOW_COORDS(0)
Then replace:
TRANSFER_VERTEX_TO_FRAGMENT(0)
with:
TRANSFER_SHADOW(o);
Finally, in your fragment function, use this:
half shadow = SHADOW_ATTENUATION(i);
return tex2D (_MainTex, i.uv) * shadow;
That should do it!
Oh, and you may or may not also want to change blendmode to multiplicative... If the above doesn't work, try changing:
Blend One One
with:
Blend DstColor Zero

Sprite disappear shader

i am working on Unity 2D platform game.
i am using a shader i found here, but when i flip my sprite (scale -1),
the sprite disappeared, i have little understand in shader coding,
And i didn't found any help on Google, can any one help fixing the shader?.
here is the shader:
Properties {
[PerRendererData] _MainTex ("Main texture", 2D) = "white" {}
_DissolveTex ("Dissolution texture", 2D) = "gray" {}
_Threshold ("Threshold", Range(0., 1.01)) = 0.
}
SubShader {
Tags { "Queue"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
v2f vert(appdata_base v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
return o;
}
sampler2D _DissolveTex;
float _Threshold;
fixed4 frag(v2f i) : SV_Target {
float4 c = tex2D(_MainTex, i.uv);
float val = tex2D(_DissolveTex, i.uv).r;
c.a *= step(_Threshold, val);
return c;
}
ENDCG
}
}
The sprite is rendered as a rectangle with two triangle of positive index order: clockwise.
You can change the Shading Mode to Shaded Wireframe to inspect that.
And if you flip the sprite (scale -1), the two triangles of the sprite will become counterclockwise. And, counterclockwise triangles will not be rendered by GPU. That's why your sprite disappeared. See also what is a clockwise face in openGL.
If you want to see your sprite even when it is flipped, you can
create two sprites with the same texture: a normal one and a flipped one:
MySprite
|--Normal
|--Flipped (scaled -1)
Then, scale MySprite GameObject to -1 instead.
Turn off backface culling in your shader.
Just add Cull Off to the subshader. See also this.
SubShader {
Tags { "Queue"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
Pass {
Cull Off
...