Sprite disappear shader - unity3d

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
...

Related

Making 2D water look like 3d

I don't know much about shader :( if someone could help
I am using this free 2d water asset it contains a water shader. I want to edit that shader so it looks more like 2.5d or 3d.
Currently, it looks like this
I want to make it look like
Adding a foam type thing on top and make it little reflective
shader used in the asset to make 2d water
Shader "Water2D/Metaballs_Simple" {
Properties {
_MainTex ("Texture", 2D) = "white" { }
_Color ("Main color", Color) = (1,1,1,1)
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
_Stroke ("Stroke alpha", Range(0,1)) = 0.1
_StrokeColor ("Stroke color", Color) = (1,1,1,1)
}
/// <summary>
/// Multiple metaball shader.
/// </summary>
SubShader {
Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
GrabPass{}
Pass {
Blend SrcAlpha OneMinusSrcAlpha
// Blend One One // Additive
// Blend One OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float4 _Color;
sampler2D _MainTex;
fixed _Cutoff;
fixed _Stroke;
half4 _StrokeColor;
float2 _screenPos;
float4 _CameraDepthTexture_TexelSize;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
float4 _MainTex_ST;
v2f vert (appdata_base v){
v2f o;
o.pos = UnityObjectToClipPos (v.vertex);
o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
return o;
};
half4 frag (v2f i) : COLOR{
half4 texcol= tex2D (_MainTex, i.uv);
//half4 finalColor = texcol;
clip(texcol.a - _Cutoff);
if (texcol.a < _Stroke) {
texcol = _StrokeColor;
} else {
texcol = _Color;
}
return texcol;
}
ENDCG
}
}
Fallback "VertexLit"
}
Judging by your shader, it appears as if the fluid has a texture containing an alpha gradient based on the distance to the edge. If this is anything similar to a distance field, then you can use it to reconstruct a screen-space normal based on the derivatives.
float3 normal;
normal.x = ddx(texcol.a);
normal.y = ddy(texcol.a);
normal.z = sqrt(1 - normal.x*normal.x - normal.y * normal.y);
Then, you can use this value to calculate some basic blinn-phong specular lighting. This involves using the sum of the vector to the light and the vector to the camera to get a half-way vector.
Since our normal is in camera space, we might want to do all other calculations in camera space too. Ideally, we want to do as many calculations as we can inside the vertex shader and then pass them over to the fragment shader:
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 viewDir : TEXCOORD1;
float3 lightDir : TEXCOORD2;
};
float4 _MainTex_ST;
v2f vert (appdata_base v){
v2f o;
o.pos = UnityObjectToClipPos (v.vertex);
o.viewDir = mul((float3x3)UNITY_MATRIX_MVP, ObjSpaceViewDir(v.vertex));
o.lightDir = mul((float3x3)UNITY_MATRIX_MVP, ObjSpaceLightDir (v.vertex));
o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
return o;
};
I'm assuming that ObjSpaceLightDir works for 2D lights, but i'm not sure.
Inside the fragment shader, we can now get the specular highlights:
float3 lightDir = normalize(i.lightDir);
float3 viewDir = normalize(i.viewDir);
float3 halfDir = normalize(lightDir + viewDir);
float spec = pow(saturate(dot(normal, halfDir)), _Glossiness * 128);
return saturate(_BaseColor + spec);
You can also add some subtle lambert shading to create shadows underneath:
float diff = saturate(dot(normal, lightDir));
// 20% diffuse contribution, because lots of light passes through the liquid.
// Can be tweaked based on artistic needs.
return saturate(_BaseColor * (0.8 + 0.2 * diff) + spec);
Be aware though that this will not properly give the illusion of thickness that your reference has. For this, you need to simulate the thickness of the fluid into a heightmap and generate normals based on that. You can break up the shape of the specular by adding some procedural noise to it, though i haven't tried this. A big challenge when writing shaders is that the GPU doesn't know anything about the context of the pixel other than what you give to it, so things like the distance to the nearest edge have to be pre-computed and fed into the material as textures. I'm honestly not sure how they manage to produce the foam on top - it might be a part of the water texture or a separate sprite rendered in the background.

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

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.

Emissive Material in Unity

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!

clip area shader in Unity3D

First of all, I don't have any idea about shader programming but I need it for my game so I found a clip area shader on the internet then I was trying to modify it and add some features to it ! I added shader to my sprite and checked it on my PC and some android devices but after that I've checked it on HTC One (My friend mobile) but weird problem was happening !
As you see the left side is not clipping visually.
The first shader I found just had width and length for clipping sprite then I added width from left and width from right and color tint to the shader.
There is a code :
Shader "Sprites/ClipAreaWithAlpha"
{
Properties
{
_Color ("Color Tint", Color) = (1,1,1,1)
_MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}
_Length ("Length", Range(0.0, 1.0)) = 1.0
_WidthR("Width from right", Range(0.0, 1.0)) = 1.0
_WidthL ("Width from left", Range(0.0, 1.0)) = 0.0
}
SubShader
{
LOD 200
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
}
Pass
{
Cull Off
Lighting Off
ZWrite Off
Offset -1, -1
Fog { Mode Off }
ColorMask RGB
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
float _Length;
float _WidthR;
float _WidthL;
half4 _Color;
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
half4 color : COLOR;
};
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = v.texcoord;
o.color = _Color;
return o;
}
half4 frag (v2f IN) : COLOR
{
if ((IN.texcoord.x<_WidthL) || (IN.texcoord.x>_WidthR) || (IN.texcoord.y<0) || (IN.texcoord.y>_Length))
{
half4 colorTransparent = half4(0,0,0,0) ;
return colorTransparent;
}
else
{
half4 tex = tex2D(_MainTex, IN.texcoord);
tex.a = IN.color.a;
return tex;
}
}
ENDCG
}
}
}
As I said before this shader is ok on another android devices that I checked but on HTC One it doesn't work nicely and correctly. I don't know where the problem is! I'm thankful for solution.
And this shader has this warning : MaterialPropertyBlock is used to modify these values
I have had the same problem. Try setting the value of Generate Mip Maps to off, then the shader works correctly.