Unity shader displaying as white - unity3d

An unity shader deferred lighting pass is broken and it displays everything as white, disabling unity HDR and moving view port on camera cause the shader to display "correctly" but I require HDR and I would like to have the shader working.
Shows the issue at hand
Here is the shader:
Pass {
Name "DEFERRED"
LOD 200
Tags { "LIGHTMODE" = "DEFERRED" "XRay" = "MainXrayShader" }
GpuProgramID 190362
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 position : SV_POSITION0;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
float4 texcoord2 : TEXCOORD2;
float4 texcoord3 : TEXCOORD3;
float4 texcoord5 : TEXCOORD5;
};
struct fout
{
float4 sv_target : SV_Target0;
float4 sv_target1 : SV_Target1;
float4 sv_target2 : SV_Target2;
float4 sv_target3 : SV_Target3;
};
// $Globals ConstantBuffers for Vertex Shader
float4 _MainTex_ST;
float4 _EmissionMap_ST;
// $Globals ConstantBuffers for Fragment Shader
float4 _Color;
float _Desaturate;
float _MetallicPower;
float _RoughnessPower;
float _NormalPower;
float _CutOff;
float _EmissionPower;
float4 _EmissionColor1;
// Custom ConstantBuffers for Vertex Shader
// Custom ConstantBuffers for Fragment Shader
// Texture params for Vertex Shader
// Texture params for Fragment Shader
sampler2D _MainTex;
sampler2D _Normal;
sampler2D _Metallic;
sampler2D _Roughness;
sampler2D _EmissionMap;
// Keywords:
v2f vert(appdata_full v)
{
v2f o;
float4 tmp0;
float4 tmp1;
float4 tmp2;
float4 tmp3;
tmp0 = v.vertex.yyyy * unity_ObjectToWorld._m01_m11_m21_m31;
tmp0 = unity_ObjectToWorld._m00_m10_m20_m30 * v.vertex.xxxx + tmp0;
tmp0 = unity_ObjectToWorld._m02_m12_m22_m32 * v.vertex.zzzz + tmp0;
tmp1 = tmp0 + unity_ObjectToWorld._m03_m13_m23_m33;
tmp0.xyz = unity_ObjectToWorld._m03_m13_m23 * v.vertex.www + tmp0.xyz;
tmp2 = tmp1.yyyy * unity_MatrixVP._m01_m11_m21_m31;
tmp2 = unity_MatrixVP._m00_m10_m20_m30 * tmp1.xxxx + tmp2;
tmp2 = unity_MatrixVP._m02_m12_m22_m32 * tmp1.zzzz + tmp2;
o.position = unity_MatrixVP._m03_m13_m23_m33 * tmp1.wwww + tmp2;
o.texcoord.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
o.texcoord.zw = v.texcoord.xy * _EmissionMap_ST.xy + _EmissionMap_ST.zw;
o.texcoord1.w = tmp0.x;
tmp1.y = dot(v.normal.xyz, unity_WorldToObject._m00_m10_m20);
tmp1.z = dot(v.normal.xyz, unity_WorldToObject._m01_m11_m21);
tmp1.x = dot(v.normal.xyz, unity_WorldToObject._m02_m12_m22);
tmp0.x = dot(tmp1.xyz, tmp1.xyz);
tmp0.x = rsqrt(tmp0.x);
tmp1.xyz = tmp0.xxx * tmp1.xyz;
tmp2.xyz = v.tangent.yyy * unity_ObjectToWorld._m11_m21_m01;
tmp2.xyz = unity_ObjectToWorld._m10_m20_m00 * v.tangent.xxx + tmp2.xyz;
tmp2.xyz = unity_ObjectToWorld._m12_m22_m02 * v.tangent.zzz + tmp2.xyz;
tmp0.x = dot(tmp2.xyz, tmp2.xyz);
tmp0.x = rsqrt(tmp0.x);
tmp2.xyz = tmp0.xxx * tmp2.xyz;
tmp3.xyz = tmp1.xyz * tmp2.xyz;
tmp3.xyz = tmp1.zxy * tmp2.yzx + -tmp3.xyz;
tmp0.x = v.tangent.w * unity_WorldTransformParams.w;
tmp3.xyz = tmp0.xxx * tmp3.xyz;
o.texcoord1.y = tmp3.x;
o.texcoord1.x = tmp2.z;
o.texcoord1.z = tmp1.y;
o.texcoord2.x = tmp2.x;
o.texcoord3.x = tmp2.y;
o.texcoord2.z = tmp1.z;
o.texcoord3.z = tmp1.x;
o.texcoord2.w = tmp0.y;
o.texcoord3.w = tmp0.z;
o.texcoord2.y = tmp3.y;
o.texcoord3.y = tmp3.z;
o.texcoord5 = float4(0.0, 0.0, 0.0, 0.0);
return o;
}
// Keywords:
fout frag(v2f inp)
{
fout o;
float4 tmp0;
float4 tmp1;
float4 tmp2;
float4 tmp3;
float4 tmp4;
tmp0 = tex2D(_MainTex, inp.texcoord.xy);
tmp0.w = tmp0.w < _CutOff;
if (tmp0.w) {
discard;
}
tmp0.w = dot(tmp0.xyz, float3(0.3, 0.59, 0.11));
tmp1.xyz = tmp0.www - tmp0.xyz;
tmp0.xyz = _Desaturate.xxx * tmp1.xyz + tmp0.xyz;
tmp1.xyz = tmp0.xyz * _Color.xyz;
tmp2 = tex2D(_Normal, inp.texcoord.xy);
tmp2.x = tmp2.w * tmp2.x;
tmp2.xy = tmp2.xy * float2(2.0, 2.0) + float2(-1.0, -1.0);
tmp0.w = dot(tmp2.xy, tmp2.xy);
tmp0.w = min(tmp0.w, 1.0);
tmp0.w = 1.0 - tmp0.w;
tmp2.z = sqrt(tmp0.w);
tmp3.xyz = float3(0.0, 0.0, 1.0) - tmp2.xyz;
tmp2.xyz = _NormalPower.xxx * tmp3.xyz + tmp2.xyz;
tmp3 = tex2D(_Metallic, inp.texcoord.xy);
tmp0.w = tmp3.x * _MetallicPower;
tmp3 = tex2D(_Roughness, inp.texcoord.xy);
o.sv_target1.w = -tmp3.x * _RoughnessPower + 1.0;
tmp3 = tex2D(_EmissionMap, inp.texcoord.zw);
tmp3.xyz = tmp3.xyz * _EmissionPower.xxx;
tmp3.xyz = tmp3.xyz * _EmissionColor1.xyz;
tmp4.x = dot(inp.texcoord1.xyz, tmp2.xyz);
tmp4.y = dot(inp.texcoord2.xyz, tmp2.xyz);
tmp4.z = dot(inp.texcoord3.xyz, tmp2.xyz);
tmp1.w = dot(tmp4.xyz, tmp4.xyz);
tmp1.w = rsqrt(tmp1.w);
tmp2.xyz = tmp1.www * tmp4.xyz;
tmp0.xyz = tmp0.xyz * _Color.xyz + float3(-0.04, -0.04, -0.04);
o.sv_target1.xyz = tmp0.www * tmp0.xyz + float3(0.04, 0.04, 0.04);
tmp0.x = -tmp0.w * 0.96 + 0.96;
o.sv_target.xyz = tmp0.xxx * tmp1.xyz;
o.sv_target2.xyz = tmp2.xyz * float3(0.5, 0.5, 0.5) + float3(0.5, 0.5, 0.5);
o.sv_target3.xyz = exp(-tmp3.xyz);
o.sv_target.w = 1.0;
o.sv_target2.w = 1.0;
o.sv_target3.w = 1.0;
return o;
}
ENDCG*
I've tried to mess with the shader code to no luck, this is what its supposed to look like with the original game and not my remake
original game

Related

Shader not showing in mobile build

So, I have found this glitch effect shader online which is working fine in the editor but when I'm building it for mobile it does not work it just shows the transparent image. I've added that shader below. I have searched online for answers and applied some of them (like always include shader in graphics settings and all that) but nothing worked.
Shader "Avi/Glitch"
{
Properties
{
[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
__CompressionFX_Value_1("__CompressionFX_Value_1", Range(0, 16)) = 3
//_SpriteFade("SpriteFade", Range(0, 1)) = 1.0
// required for UI.Mask
[HideInInspector]_StencilComp("Stencil Comparison", Float) = 8
[HideInInspector]_Stencil("Stencil ID", Float) = 0
[HideInInspector]_StencilOp("Stencil Operation", Float) = 0
[HideInInspector]_StencilWriteMask("Stencil Write Mask", Float) = 255
[HideInInspector]_StencilReadMask("Stencil Read Mask", Float) = 255
[HideInInspector]_ColorMask("Color Mask", Float) = 15
}
SubShader
{
Tags
{
"Queue" = "Transparent" "IgnoreProjector" = "true" "RenderType" = "Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True"
}
ZWrite Off Blend SrcAlpha OneMinusSrcAlpha Cull Off
// required for UI.Mask
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float2 texcoord : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 color : COLOR;
};
sampler2D _MainTex;
// float _SpriteFade;
float __CompressionFX_Value_1;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texcoord = IN.texcoord;
OUT.color = IN.color;
return OUT;
}
float CMPFXrng2(float2 seed)
{
return frac(sin(dot(seed * floor(50 + (_Time + 0.1) * 12.), float2(127.1, 311.7))) * 43758.5453123);
}
float CMPFXrng(float seed)
{
return CMPFXrng2(float2(seed, 1.0));
}
float4 CompressionFX(float2 uv, sampler2D source, float Value)
{
float2 blockS = floor(uv * float2(24., 19.)) * 4.0;
float2 blockL = floor(uv * float2(38., 14.)) * 4.0;
float r = CMPFXrng2(uv);
float lineNoise = pow(CMPFXrng2(blockS), 3.0) * Value * pow(CMPFXrng2(blockL), 3.0);
float4 col1 = tex2D(source, uv + float2(lineNoise * 0.02 * CMPFXrng(2.0), 0));
float4 result = float4(float3(col1.x, col1.y, col1.z), 1.0);
result.a = col1.a;
return result;
}
float4 frag(v2f i) : COLOR
{
float4 _CompressionFX_1 = CompressionFX(i.texcoord, _MainTex, __CompressionFX_Value_1);
float4 FinalResult = _CompressionFX_1;
FinalResult.rgb *= i.color.rgb;
FinalResult.a = FinalResult.a * i.color.a;
return FinalResult;
}
ENDCG
}
}
Fallback "Sprites/Default"
}

Why does my shader appear static after converting the code from ShaderToy to Unity?

I'm trying to convert some code from ShaderToy to Unity. This is the shader that I'm attempting to convert: https://www.shadertoy.com/view/Ws23WD.
I've successfully compiled my code, however, when I look at my shader on a sphere in Unity, it appears to be a static yellow circle. I've only changed the syntax from ShaderToy to the Unity equivalents; what could be going wrong?
Shader "Unlit/Lava"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
iChannel0 ("iChannel0", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
sampler2D iChannel0;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
#define pi (3.14159265358979323846)
#define EPSILON (0.0001)
float2 rotate(float2 v, float a)
{
float c = cos(a);
float s = sin(a);
return float2(
v.x*c-v.y*s,
v.x*s+v.y*c
);
}
float sphere(float3 p, float r)
{
return length(p)-r;
}
float scene(float3 p)
{
float b = sphere(p, 1.6);
if(b > 0.001) return b; // optimisation
float3 disp = 0;
float f = 0.5;
disp.x = tex2D(iChannel0, p.zy * 0.05 + _Time.y * 0.02).x * f;
disp.z = tex2D(iChannel0, p.xy * 0.05 + _Time.y * 0.03).z * f;
disp.y = tex2D(iChannel0, p.xz * 0.05 + _Time.y * 0.04).y * f;
return sphere(p + disp, 1.0 + sin(_Time.y*2.4) * 0.15);
}
fixed4 frag (v2f i) : SV_Target
{
//float2 uv = float2(fragCoord.x / iResolution.x, fragCoord.y / iResolution.y);
float2 uv = float2(i.uv);
uv -= 0.5;
//uv /= float2(iResolution.y / iResolution.x, 1);
float3 cam = float3(0, -0.15, -3.5);
float3 dir = normalize(float3(uv,1));
float cam_a2 = sin(_Time.y) * pi * 0.1;
cam.yz = rotate(cam.yz, cam_a2);
dir.yz = rotate(dir.yz, cam_a2);
float cam_a = _Time.y * pi * 0.1;
cam.xz = rotate(cam.xz, cam_a);
dir.xz = rotate(dir.xz, cam_a);
float4 color = float4(0.16, 0.12, 0.10, 1.0);
float t = 0.00001;
const int maxSteps = 128;
for(int i = 0; i < maxSteps; ++i) {
float3 p = cam + dir * t;
float d = scene(p);
if(d < 0.0001 * t) {
color = float4(1.0, length(p) * (0.6 + (sin(_Time.y*3.0)+1.0) * 0.5 * 0.4), 0, 0);
break;
}
t += d;
}
//fragColor.rgb = color;
return color;
//fragColor.a = 1.0;
}
ENDCG
}
}
}
You need press PLAY button to see the shader animation.
The shader works.
I made some changes to your shader. Mostly to the UV calculation and alpha blend settings.
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Unlit/Lava"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
iChannel0 ("iChannel0", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="TransparentCutout" }
LOD 100
Blend OneMinusSrcAlpha SrcAlpha // Specify blend mode. This is inverted from usual usage.
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag lambert alpha:blend // Enable alpha blend
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
float4 screenPos : TEXCOORD1;
};
sampler2D _MainTex;
sampler2D iChannel0;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.screenPos = ComputeScreenPos(o.vertex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
#define pi (3.14159265358979323846)
#define EPSILON (0.0001)
float2 rotate(float2 v, float a)
{
float c = cos(a);
float s = sin(a);
return float2(
v.x*c-v.y*s,
v.x*s+v.y*c
);
}
float sphere(float3 p, float r)
{
return length(p)-r;
}
float scene(float3 p)
{
float b = sphere(p, 1.6);
if(b > 0.001) return b; // optimisation
float3 disp = 0;
float f = 0.5;
disp.x = tex2D(iChannel0, p.zy * 0.05 + _Time.y * 0.02).x * f;
disp.z = tex2D(iChannel0, p.xy * 0.05 + _Time.y * 0.03).z * f;
disp.y = tex2D(iChannel0, p.xz * 0.05 + _Time.y * 0.04).y * f;
return sphere(p + disp, 1.0 + sin(_Time.y*2.4) * 0.15);
}
fixed4 frag (v2f i) : SV_Target
{
//float2 uv = float2(fragCoord.x / iResolution.x, fragCoord.y / iResolution.y);
float2 uv = float2(i.screenPos.x , i.screenPos.y); // Unity equivalent of the above
uv -= 0.5;
uv /= float2((_ScreenParams.y / _ScreenParams.x)*0.5, (_ScreenParams.y / _ScreenParams.x)*0.5); // Shrink the globule
float3 cam = float3(0, -0.15, -3.5);
float3 dir = normalize(float3(uv,1));
float cam_a2 = sin(_Time.y) * pi * 0.1;
cam.yz = rotate(cam.yz, cam_a2);
dir.yz = rotate(dir.yz, cam_a2);
float cam_a = _Time.y * pi * 0.1;
cam.xz = rotate(cam.xz, cam_a);
dir.xz = rotate(dir.xz, cam_a);
float4 color = float4(0.16, 0.12, 0.10, 1.0);
float t = 0.00001;
const int maxSteps = 128;
for(int i = 0; i < maxSteps; ++i) {
float3 p = cam + dir * t;
float d = scene(p);
if(d < 0.0001 * t) {
color = float4(1.0, length(p) * (0.6 + (sin(_Time.y*3.0)+1.0) * 0.5 * 0.4), 0, 0);
break;
}
t += d;
}
return color;
}
ENDCG
}
}
}
The result is not perfect, but closer:
I think the issue with the ShaderToy shader is that it is meant for screen space. You will see that when you move the camera, the lava freaks out. I think this is because of the screen space uv calculation. You will need to find a different method.
Good luck

Unity3d - How to show model edges in game?

I want the same effect as the Unity editor when an object clicked, same as the top on the picture.
The camera view at bottom show that no any edges on model.
I google a bit, there are many topic about wireframe and edge detection, but i cant find anything useful about showing the inner edges.
You need a wireframe shader. That link is one of many (and free).
For your specific use-case, you also want...
Rendering the object normally while the wireframe is visible
Be able to enable/disable the wireframe
Which means you need a method of knowing what object is "selected" and enabling either a shader tag which you can set once or rendering the object a second time with a new material, but have to draw the object manually every frame.
Since I had same, I wrote custom shader.
Code Listing :
Shader "DESS/WireframeShader"
{
Properties
{
_WireColor("Edges Color", Color) = (0,0,0,1)
_WireThickness("Edge Thickness", RANGE(0, 800)) = 100
_WireSmoothness("Edge Smoothness", RANGE(0, 20)) = 3
_AlbedoColor("Albedo Color", Color) = (1,1,1,1)
_MainTex("Albedo (RGB)", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 200
Pass
{
CGPROGRAM
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag
#pragma geometry geom
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
struct Input
{
float2 uv_MainTex;
};
fixed4 _WireColor;
fixed4 _AlbedoColor;
uniform float _WireThickness;
uniform float _WireSmoothness;
struct appdata
{
float4 vertex : POSITION;
float2 texcoord0 : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2g
{
float4 projSpaceVertex : SV_POSITION;
float2 uv0 : TEXCOORD0;
float4 worldSpacePosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
struct g2f
{
float4 projSpaceVertex : SV_POSITION;
float2 uv0 : TEXCOORD0;
float4 worldSpacePosition : TEXCOORD1;
float4 dist : TEXCOORD2;
UNITY_VERTEX_OUTPUT_STEREO
};
v2g vert(appdata v)
{
v2g o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.projSpaceVertex = UnityObjectToClipPos(v.vertex);
o.worldSpacePosition = mul(unity_ObjectToWorld, v.vertex);
o.uv0 = TRANSFORM_TEX(v.texcoord0, _MainTex);
return o;
}
[maxvertexcount(3)]
void geom(triangle v2g i[3], inout TriangleStream<g2f> triangleStream)
{
float2 p0 = i[0].projSpaceVertex.xy / i[0].projSpaceVertex.w;
float2 p1 = i[1].projSpaceVertex.xy / i[1].projSpaceVertex.w;
float2 p2 = i[2].projSpaceVertex.xy / i[2].projSpaceVertex.w;
float2 edge0 = p2 - p1;
float2 edge1 = p2 - p0;
float2 edge2 = p1 - p0;
float area = abs(edge1.x * edge2.y - edge1.y * edge2.x);
float wireThickness = 800 - _WireThickness;
g2f o;
o.uv0 = i[0].uv0;
o.worldSpacePosition = i[0].worldSpacePosition;
o.projSpaceVertex = i[0].projSpaceVertex;
o.dist.xyz = float3((area / length(edge0)), 0.0, 0.0) * o.projSpaceVertex.w * wireThickness;
o.dist.w = 1.0 / o.projSpaceVertex.w;
UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(i[0], o);
triangleStream.Append(o);
o.uv0 = i[1].uv0;
o.worldSpacePosition = i[1].worldSpacePosition;
o.projSpaceVertex = i[1].projSpaceVertex;
o.dist.xyz = float3(0.0, (area / length(edge1)), 0.0) * o.projSpaceVertex.w * wireThickness;
o.dist.w = 1.0 / o.projSpaceVertex.w;
UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(i[1], o);
triangleStream.Append(o);
o.uv0 = i[2].uv0;
o.worldSpacePosition = i[2].worldSpacePosition;
o.projSpaceVertex = i[2].projSpaceVertex;
o.dist.xyz = float3(0.0, 0.0, (area / length(edge2))) * o.projSpaceVertex.w * wireThickness;
o.dist.w = 1.0 / o.projSpaceVertex.w;
UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(i[2], o);
triangleStream.Append(o);
}
fixed4 frag(g2f i) : SV_Target
{
float minDistanceToEdge = min(i.dist[0], min(i.dist[1], i.dist[2])) * i.dist[3];
float4 baseColor = _AlbedoColor * tex2D(_MainTex, i.uv0);
// Early out if we know we are not on a line segment.
if (minDistanceToEdge > 0.9)
{
return fixed4(baseColor.rgb,0);
}
// Smooth our line out
float t = exp2(_WireSmoothness * -1.0 * minDistanceToEdge * minDistanceToEdge);
fixed4 finalColor = lerp(baseColor, _WireColor, t);
finalColor.a = t;
return finalColor;
}
ENDCG
}
}
FallBack "Diffuse"
}

How to draw circle in unity by shader and anti-aliasing

I have drawn a circle by shader, but I can't get anti-aliasing to work.
I tried finding an answer here http://answers.unity3d.com/questions/521984/how-do-you-draw-2d-circles-and-primitives.html, but I have to use discard to draw circle.
Here is a picture of my current shader result and the shader code:
Shader "Unlit/CircleSeletor"
{
Properties
{
_BoundColor("Bound Color", Color) = (1,1,1,1)
_BgColor("Background Color", Color) = (1,1,1,1)
_MainTex("Albedo (RGB)", 2D) = "white" {}
_BoundWidth("BoundWidth", float) = 10
_ComponentWidth("ComponentWidth", float) = 100
}
SubShader{
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag Lambert alpha
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
sampler2D _MainTex;
float _BoundWidth;
fixed4 _BoundColor;
fixed4 _BgColor;
float _ComponentWidth;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
float antialias(float w, float d, float r) {
return 1-(d-r-w/2)/(2*w);
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 c = tex2D(_MainTex,i.uv);
float x = i.uv.x;
float y = i.uv.y;
float dis = sqrt(pow((0.5 - x), 2) + pow((0.5 - y), 2));
if (dis > 0.5) {
discard;
} else {
float innerRadius = (_ComponentWidth * 0.5 - _BoundWidth) / _ComponentWidth;
if (dis > innerRadius) {
c = _BoundColor;
//c.a = c.a*antialias(_BoundWidth, dis, innerRadius);
}
else {
c = _BgColor;
}
}
return c;
}
ENDCG
}
}
}
It's really easy to apply anti-alias to a circle.
1.First, you need 3 variables to do this. Get the radius, distance of the circle. Also create a float value(let's called that borderSize) that can be used to determine how far the anti-alias should go. The radius, distance and borderSize are the three variables.
2.Find the t with smoothstep function using those 3 variables from #1.
float t = smoothstep(radius + borderSize, radius - borderSize, distance);
3.Mix the color before returning it.
Let's say that _BoundColor is the circle fill color and _BgColor is the background color.
If using GLSL using the mix function. If using Unity, use the lerp function. Both function are interchanging and the parameters are the-same.
col = lerp(_BoundColor, _BgColor, t);
The t is from #2. You can now return col in the fragment function.
These are the 3 steps put together:
if (dis > radius) {
float t = smoothstep(radius + borderSize, radius - borderSize, distance);
col = lerp(_BoundColor, _BgColor, t);
}
else {
float t = smoothstep(radius + borderSize, radius - borderSize, distance);
col = lerp(_BoundColor, _BgColor, t);
}
return col;
OUTPUT WITHOUT ANTI-ALIASING:
OUTPUT WITH ANTI-ALIASING(4.5 Threshold):
Finally, the whole code(Tested on PC and Android but should work on iOS too)
Shader "Unlit/Circle Anti-Aliasing"
{
Properties
{
_BoundColor("Bound Color", Color) = (0,0.5843137254901961,1,1)
_BgColor("Background Color", Color) = (0.1176470588235294,0,0.5882352941176471,1)
_circleSizePercent("Circle Size Percent", Range(0, 100)) = 50
_border("Anti Alias Border Threshold", Range(0.00001, 5)) = 0.01
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
float _border;
fixed4 _BoundColor;
fixed4 _BgColor;
float _circleSizePercent;
struct v2f
{
float2 uv : TEXCOORD0;
};
v2f vert(
float4 vertex : POSITION, // vertex position input
float2 uv : TEXCOORD0, // texture coordinate input
out float4 outpos : SV_POSITION // clip space position output
)
{
v2f o;
o.uv = uv;
outpos = UnityObjectToClipPos(vertex);
return o;
}
float2 antialias(float radius, float borderSize, float dist)
{
float t = smoothstep(radius + borderSize, radius - borderSize, dist);
return t;
}
fixed4 frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target
{
float4 col;
float2 center = _ScreenParams.xy / 2;
float maxradius = length(center);
float radius = maxradius*(_circleSizePercent / 100);
float dis = distance(screenPos.xy, center);
if (dis > radius) {
float aliasVal = antialias(radius, _border, dis);
col = lerp(_BoundColor, _BgColor, aliasVal); //NOT needed but incluse just incase
}
else {
float aliasVal = antialias(radius, _border, dis);
col = lerp(_BoundColor, _BgColor, aliasVal);
}
return col;
}
ENDCG
}
}
}
Try this:
Shader "Unlit/CircleSeletor"
{
Properties
{
_BoundColor("Bound Color", Color) = (1,1,1,1)
_BgColor("Background Color", Color) = (1,1,1,1)
_MainTex("Albedo (RGB)", 2D) = "white" {}
_BoundWidth("BoundWidth", float) = 10
_ComponentWidth("ComponentWidth", float) = 100
}
SubShader
{
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag Lambert alpha
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
sampler2D _MainTex;
float _BoundWidth;
fixed4 _BoundColor;
fixed4 _BgColor;
float _ComponentWidth;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
float antialias(float w, float d, float r) {
return 1 - (d - r - w / 2) / (2 * w);
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 c = tex2D(_MainTex,i.uv);
float x = i.uv.x;
float y = i.uv.y;
float dis = sqrt(pow((0.5 - x), 2) + pow((0.5 - y), 2));
if (dis > 0.5) {
c.a = 0;
discard;
}
else {
float innerRadius = (_ComponentWidth * 0.5 - _BoundWidth) / _ComponentWidth;
if (dis > innerRadius) {
c = _BoundColor;
//c.a = c.a*antialias(_BoundWidth, dis, innerRadius);
}
else {
c = _BgColor;
}
}
return c;
}
ENDCG
}
GrabPass{
"_MainTex2"
}
Pass
{
Blend One zero
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
fixed4 color : COLOR;
};
struct v2f
{
float4 pos : SV_POSITION;
fixed4 color : COLOR;
float4 scrPos : TEXCOORD0;
};
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.scrPos = ComputeScreenPos(o.pos);
o.color = v.color;
return o;
}
sampler2D _MainTex2;
float4 _MainTex2_TexelSize;
fixed4 frag(v2f i) : SV_Target
{
float2 uv = (i.scrPos.xy / i.scrPos.w);
fixed4 c = tex2D(_MainTex2, uv );
fixed4 up = tex2D(_MainTex2, uv + fixed2(0, _MainTex2_TexelSize.y));
fixed4 down = tex2D(_MainTex2, uv - fixed2(0, _MainTex2_TexelSize.y));
fixed4 left = tex2D(_MainTex2, uv - fixed2(_MainTex2_TexelSize.x, 0));
fixed4 right = tex2D(_MainTex2, uv + fixed2(_MainTex2_TexelSize.x, 0));
c.rgb = (c.rgb + up.rgb + down.rgb + left.rgb + right.rgb) / 5;
c.a = (c.a + up.a + down.a + left.a + right.a) / 5;
return c;
}
ENDCG
}
}
}
After first pass I GrabPass result and apply anti-alias in second pass by averaging border pixels.

No shadows on my mesh becuase of a mistake in my shader Unity3D

I am writing a toon water shader, and I want it to be lit by a directional light. I got it working but I think there is somthing wrong with the normals because there are no shadows between the wave. I hope that someone can find the mistake I made and thank you in advance.
Shader "Custom/NoobShader_03" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_Scale ("Wave Scale", float) = 0.6
_Frequency ("Frequency", float) = 1
_Speed ("Speed", float) = 0.5
_Scale2 ("Wave Scale", float) = 0.6
_Frequency2 ("Frequency", float) = 1
_Speed2 ("Speed", float) = 1
}
SubShader {
Pass{
Tags { "LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 _Color;
float _Scale;
float _Frequency;
float _Speed;
float _Scale2;
float _Frequency2;
float _Speed2;
float4 _LightColor0;
struct VertexOutput
{
float4 pos : SV_POSITION;
float3 nor : NORMAL;
float4 col : COLOR;
};
struct VertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct FragmentOutput
{
float4 color : COLOR;
};
VertexOutput vert (VertexInput i)
{
VertexOutput VOUT;
float randomNum = 1 / _Time;
float newPos = _Scale * sin(_Time.w * _Speed + i.vertex.x * _Frequency);
float newPos2 = _Scale2 * cos(_Time.w * _Speed2 + i.vertex.z * _Frequency2);
//i.vertex.y += newPos;
float4 tempPos = i.vertex;
tempPos.y += newPos * newPos2;
VOUT.pos = mul(UNITY_MATRIX_MVP,tempPos);
VOUT.nor = float3(mul(UNITY_MATRIX_MVP,tempPos).xyz);
float3 normalDirection = normalize( mul( float4( VOUT.nor, 0.0 ), _World2Object).xyz);
float3 lightDirection;
float atten = 1.0;
lightDirection = normalize(_WorldSpaceLightPos0.xyz);
float3 diffuseRefflection = atten * _LightColor0.xyz * _Color.rgb * max( 0.0, dot(normalDirection, lightDirection));
VOUT.col = float4(diffuseRefflection, 0.0);
return VOUT;
}
FragmentOutput frag(VertexOutput v)
{
FragmentOutput FOUT;
FOUT.color = v.col + _Color;
return FOUT;
}
ENDCG
}
}
FallBack "Diffuse"
}
Just a quick answer about your normals
float3 normalDirection = normalize( mul( float4( VOUT.nor, 0.0 ), _World2Object).xyz);
Normals are given in local aka object space. You need to convert to world space. The order of your multiplication is wrong. It should be:
float3 normalDirection = normalize( mul( _World2Object, float4( VOUT.nor, 0.0 )).xyz);
which is equivalent to:
float3 normalDirection = normalize( mul( float4( VOUT.nor, 0.0 ), _Object2World).xyz);
You generally put the transform matrix before the vector you're transforming.