Masking 3D object with custom shader in Unity - unity3d

I'm making a 2D mobile game but I want to use 3D objects in shop section. So, in the shop section, I have a scroll rect and a viewport. I can scroll and the mask component works as expected with 2D objects. But when I add 3D objects, the objects getting out of the mask. I researched the forums and I find a custom shader. When I apply the shader to the objects materials, it partially works. But the depth or shadows are not working properly. I know not much about shaders. You can take a look at this Image. Box on the right is the original one, box on the left is the one with custom shader.
My shader code is here;
Shader "Custom/NewSurfaceShader" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_StencilComp("Stencil Comparison", Float) = 8
_Stencil("Stencil ID", Float) = 0
_StencilOp("Stencil Operation", Float) = 0
_StencilWriteMask("Stencil Write Mask", Float) = 255
_StencilReadMask("Stencil Read Mask", Float) = 255
_ColorMask("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags { "RenderType"="UI""Queue"="Transparent" }
LOD 200
ZTest[unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask[_ColorMask]
Stencil
{
Ref 1
Comp LEqual
Pass Keep
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
CGPROGRAM
#pragma surface surf Standard vertex:vert fullforwardshadows
#pragma target 3.0
#include "UnityUI.cginc"
struct Input
{
float2 uv_MainTex;
float4 worldPosition;
};
void vert(inout appdata_full v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input, o);
o.worldPosition = v.vertex;
}
sampler2D _MainTex;
half _Glossiness;
half _Metallic;
fixed4 _Color;
float4 _ClipRect;
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
o.Alpha *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#ifdef UNITY_UI_ALPHACLIP
clip(o.Alpha - 0.001);
#endif
}
ENDCG
}
FallBack "Diffuse"
}

Related

Vertex displacement doesn't affect anything -- Unity

I'm trying to implement a simulation of an ocean based on this tutorial but I can't get my shader to affect my plane. It stays completly flat whatever I do.
This is my shader :
Shader "Custom/Waves"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_NormalMap ("Normal Map", 2D) = "bump" {}
//Wave Properties
_Direction("Direction", Vector) = (1.0, 0.0, 0.0, 1.0)
_Steepness("Steepness", Range(0.1,1.0)) = 0.5
_Freq("Frequency", Range(1.0,10.0)) = 1.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
float _Steepness, _Freq;
float4 _Direction;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void vert(inout appdata_full v){
float3 pos = v.vertex.xyz;
float4 dir = normalize(_Direction);
float defaultWavelength = 2 * UNITY_PI;
float wL = defaultWavelength / _Freq;
float phase = sqrt(9.8/wL);
float disp = wL * (dot(dir, pos) - (phase * _Time.y));
float peak = _Steepness/wL;
pos.x += dir.x * (peak * cos(disp));
pos.y = peak * sin(disp);
pos.z += dir.y * (peak * cos(disp));
v.vertex.xyz = pos;
}
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
I thought that it might be the link between the plane, the material and the shader but it doesn't seem to help. I don't have any idea of what I did wrong. I tried with and without GPU instancing and it does not change anything.
You forgot to declare that you want to use a vertex function.
Add this before or after the other pragma
#pragma vertex vert

Custom shader casts shadows but cannot receive them

I have two shaders for my 2d sprites to cast shadows when they are "stood up" 10 degrees off a flat plane.
This one casts and receives shadows, but I cannot use the alpha channel, transparency is entirely ignored
Shader "Custom/SpriteShadow"
{
Properties {
_Color ("Color", Color) = (1,1,1,1)
[PerRendererData]_MainTex ("Sprite Texture", 2D) = "white" {}
_Cutoff("Shadow alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
Tags
{
"Queue"="Geometry"
"RenderType"="TransparentCutout"
}
LOD 200
Cull Off
CGPROGRAM
// Lambert lighting model, and enable shadows on all light types
#pragma surface surf Lambert addshadow fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
fixed4 _Color;
fixed _Cutoff;
struct Input
{
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
clip(o.Alpha - _Cutoff);
}
ENDCG
}
FallBack "Diffuse"
}
The second shader can cast shadows and works with alpha/transparency, but cannot receive shadows.
Shader "Custom/SpriteShadowWithAlpha"{
Properties
{
[PerRendererData] _MainTex("Texture", 2D) = "white" {}
_EffectColor1("Effect Color", Color) = (1,1,1,1)
_Crossfade("Fade", float) = 0
_FlashColor("Flash Color", Color) = (1,1,1,1)
_FlashAmount("Flash Amount",Range(0.0,1.0)) = 0
_Cutoff("Alpha Cutoff", Range(0,1)) = 0.9
_Color ("Color", Color) = (1,1,1,1)
[Toggle(_ALPHABLEND_ON)] ALPHABLEND_ON("Enable Dithered Shadows", Float) = 0.0
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "TransparentCutOut"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
Cull Off
Lighting Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma surface surf Lambert alpha:blend fullforwardshadows alphatest:_Cutoff
#pragma target 3.0
struct Input {
fixed2 uv_MainTex;
fixed4 color : COLOR;
};
sampler2D _MainTex;
fixed4 _EffectColor1;
fixed _Crossfade;
fixed4 _FlashColor;
float _FlashAmount;
void surf(Input IN, inout SurfaceOutput o)
{
fixed4 col = tex2D(_MainTex, IN.uv_MainTex);
fixed4 returnColor = lerp(col, col * _EffectColor1, _Crossfade) * _EffectColor1.a + col * (1.0 - _EffectColor1.a);
o.Albedo = returnColor.rgb * IN.color.rgb;
o.Alpha = col.a * IN.color.a;
o.Albedo = lerp(o.Albedo,_FlashColor.rgb,_FlashAmount);
}
ENDCG
}
Fallback "Standard"
}
I have tried mixing and matching different parts of the two but can never get shadows to cast and receive and work with the alpha channel.
This may not be the answer anyone in the future wants to see, but it is the one I went with. Originally I was unable to figure out a URP shader to do what I wanted. I was however able to find one that suited my needs later on.
So my solution was to upgrade to URP and ditch the standard shader. Using the following video as a guide and shader source
https://www.youtube.com/watch?v=d_OBjV7c1CY

In Unity Shaderlab, how can you animate towards a value using lerp and deltaTime

How can a Custom Standard Surface Shader be used to animate a value towards a target value?
For Example:
...
float targetAlpha; //Set by the property block, or a C# script
float currrentAlpha; //Used internally only.
void surf (Input IN, inout SurfaceOutputStandard o)
{
currrentAlpha = lerp(currrentAlpha, targetAlpha, unity_DeltaTime.x);
o.Alpha = currrentAlpha;
}
This code does not work but should demonstrate what the goal is: when targetAlpha is set, the shader will fade towards that value.
There are few ways this can be done. One of them is using built-in shader variables:
Shader "Custom/Test" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_TargetAlpha ("TargetAlpha", Range(0, 1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows alpha:fade
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Alpha;
fixed4 _Color;
half _TargetAlpha;
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = lerp(o.Alpha, _TargetAlpha, clamp(_SinTime.w, 0, 1));
}
ENDCG
}
FallBack "Diffuse"
}
The shader in the answer above still works in Unity 2018.2. However, _SinTime oscillates between -1 and 1, while we want the range to be between 0 and 1. The code clamp(_SinTime.w, 0, 1) clamps onto the desired values, however the alpha stays at zero too long. So we need the absolute value, like so: abs(_SinTime.w).
The modified shader:
Shader "Custom/Test" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_TargetAlpha ("TargetAlpha", Range(0, 1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows alpha:fade
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Alpha;
fixed4 _Color;
half _TargetAlpha;
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = lerp(o.Alpha, _TargetAlpha, abs(_SinTime.w));
}
ENDCG
}
FallBack "Diffuse"
}

Simple double sided custom shader looks strange

I'm very new to Shaders programming, I was trying to create a shader which:
Allows to change 2 textures with 2 corresponding normal maps (fade in/fade out)
Doublesided (show mesh from both sides of the surface)
Here is what I end up with:
Shader "Custom/TextureBlend" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_Blend ("Texture Blend", Range(0,1)) = 0.0
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_MainTex2 ("Albedo 2 (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_BumpMap ("Bumpmap", 2D) = "bump" {}
_BumpMap2 ("Bumpmap", 2D) = "bump" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
Cull Off
ZTest LEqual
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
sampler2D _MainTex2;
sampler2D _BumpMap;
sampler2D _BumpMap2;
struct Input {
float2 uv_MainTex;
float2 uv_MainTex2;
float2 uv_BumpMap;
float2 uv_BumpMap2;
};
half _Blend;
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = lerp (tex2D (_MainTex, IN.uv_MainTex), tex2D (_MainTex2, IN.uv_MainTex2), _Blend) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
fixed4 n = lerp (tex2D (_BumpMap, IN.uv_BumpMap), tex2D (_BumpMap2, IN.uv_BumpMap2), _Blend) * _Color;
o.Normal = n.rgb;
}
ENDCG
}
FallBack "Diffuse"
}
It works but for some reason the texture on the surface looks dim (on the other side of the mesh which usually invisible it's even darker), and normal map reflections barely visible.
Here, on the left you can see the plane with my shader, on the right - standard shader:
Also the reflection looks really strange, if I will move Metallic slider to the right you will see it:
Normal maps store vector information while regular textures are unsigned, so you need to use the UnpackNormal() helper method as shown in the samples. You also don't need to multiply by Color.
final code would then be along the lines of:
fixed4 n0 = tex2D(_BumpMap, IN.uv_BumpMap);
fixed4 n1 = tex2D(_BumpMap2, IN.uv_BumpMap2);
o.Normal = UnpackNormal(lerp(n0, n1, _Blend)).xyz;

Combining 2 shader scripts in Unity from the Asset Store

Im a student animation and learning to write c# scripts on my own. Im trying to combine 2 shader scripts from Unity into one: one scripts is a shading effect that lets objects fade due to a range of a gizmo.
You can find it in the Asset store here for details:
World Space Fading Effect
https://assetstore.unity.com/packages/vfx/shaders/world-space-fading-transitions-98207
And the other script adds a cutout from the alpha in the maintex and ignore the lighting settings of the object.
Fading script:
Shader "Fading/Surface/DissolveGlowEdited" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
//_Noise ("noise", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
//_spread ("dissolveSpread", Range(0,1)) = 1.0
_GlowIntensity("Glow Intensity", Range(0.0, 5.0)) = 1
_GlowScale("Glow Size", Range(0.0, 5.0)) = 1.0
_Glow("Glow Color", Color) = (1, 0, 0, 1)
_GlowEnd("Glow End Color", Color) = (1, 1, 0, 1)
_GlowColFac("Glow Colorshift", Range(0.01, 2.0)) = 0.5
_SectionColor ("Section Color", Color) = (1,0,0,1)
[Toggle] _inverse("inverse", Float) = 0
[Toggle] _doubleSided ("doubleSided", Float) = 1
[Toggle(RETRACT_BACKFACES)] _retractBackfaces("retractBackfaces", Float) = 0
[Toggle(DISSOLVE_GLOW)] _glowdissolve("glowdissolve", Float) = 1
}
SubShader {
Tags { "RenderType"="Clipping" }
LOD 200
// ------------------------------------------------------------------
Cull off
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard addshadow vertex:vert
#pragma multi_compile __ FADE_PLANE FADE_SPHERE
#pragma shader_feature RETRACT_BACKFACES
#pragma shader_feature DISSOLVE_GLOW
#include "CGIncludes/section_clipping_CS.cginc"
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.5
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
float3 worldPos;
float myface : VFACE;
};
half _BackfaceExtrusion;
void vert (inout appdata_full v) {
#if RETRACT_BACKFACES
float3 viewDir = ObjSpaceViewDir(v.vertex);
float dotProduct = dot(v.normal, viewDir);
if(dotProduct<0) {
float3 worldPos = mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1)).xyz;
float3 worldNorm = UnityObjectToWorldNormal(v.normal);
worldPos -= worldNorm * _BackfaceExtrusion;
v.vertex.xyz = mul(unity_WorldToObject, float4(worldPos, 1)).xyz;
}
#endif
}
half _Glossiness;
half _Metallic;
fixed4 _Color;
fixed4 _SectionColor;
fixed _doubleSided;
fixed4 _Glow;
fixed4 _GlowEnd;
half _GlowScale;
half _GlowColFac;
half _GlowIntensity;
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 glowCol = fixed4(0,0,0,0);
//if(IN.myface<0&&_doubleSided==0) discard;
#if (FADE_PLANE || FADE_SPHERE)&& DISSOLVE_GLOW
if(IN.myface<0&&_doubleSided==0) discard; else PLANE_CLIP(IN.worldPos);
float4 fade = PLANE_FADE(IN.worldPos);
//Combine texture factor with geometry coefficient from vertex routine.
half dFinal = fade.a;
//Shift the computed raw alpha value based on the scale factor of the glow.
//Scale the shifted value based on effect intensity.
half dPredict = (_GlowScale - dFinal) * _GlowIntensity;
//Change colour interpolation by adding in another factor controlling the gradient.
half dPredictCol = (_GlowScale * _GlowColFac - dFinal) * _GlowIntensity;
//Calculate and clamp glow colour.
glowCol = dPredict * lerp(_Glow, _GlowEnd, clamp(dPredictCol, 0.0f, 1.0f));
glowCol = clamp(glowCol, 0.0f, 1.0f);
#endif
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
if(IN.myface>0)
{
#if (FADE_PLANE || FADE_SPHERE)&& DISSOLVE_GLOW
glowCol = clamp(glowCol, 0.0f, 1.0f);
o.Emission = glowCol;
#endif
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
else
{
#if (FADE_PLANE || FADE_SPHERE)&& DISSOLVE_GLOW
glowCol.rgb = lerp(glowCol.rgb, 0.5*o.Albedo, dFinal);
glowCol = clamp(glowCol, 0.0f, 1.0f);
if(dFinal>1) glowCol.rgb = 0.5*o.Albedo;
o.Emission = glowCol;
#else
o.Emission = 0.5*o.Albedo;
#endif
o.Albedo = float3(0,0,0);
}
}
ENDCG
}
FallBack "Diffuse"
}
Flat shade / cutout script:
Shader "Unlit/Transparent Color CutoutTrans" {
Properties {
_Color ("Color Tint", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="TransparentCutoff"}
Pass {
Alphatest Greater [_Cutoff]
Lighting Off
SetTexture [_MainTex] {
constantColor [_Color]
combine texture * constant DOUBLE
}
}
}
}
The problem I have is if I combine it, it still read one of the scripts at the time, and not the two of them.
Does someone knows why and how it can be fixed? Many thanks!
If all what you want is to use the first shader but with alpha cutoff then according to the optional parameters section in the documentation you can do the following:
In the properties section in the 1st shader add:
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
Then, edit the line:
#pragma surface surf Standard addshadow vertex:vert
to be:
#pragma surface surf Standard addshadow vertex:vert alphatest:_Cutoff