My fog Shader works fine on the Windows platform but it stopped when I switch to Android platform.
this is a screenshot of scene in windows platform , on android it will be gone
it's my shader:
Shader "Custom/VerticalFogIntersection"
{
Properties
{
_Color("Main Color", Color) = (1, 1, 1, .5)
_IntersectionThresholdMax("Intersection Threshold Max", float) = 1
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType"="Transparent" }
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 scrPos : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _CameraDepthTexture;
float4 _Color;
float4 _IntersectionColor;
float _IntersectionThresholdMax;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.scrPos = ComputeScreenPos(o.vertex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
half4 frag(v2f i) : SV_TARGET
{
float depth = LinearEyeDepth (tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.scrPos)));
float diff = saturate(_IntersectionThresholdMax * (depth - i.scrPos.w));
fixed4 col = lerp(fixed4(_Color.rgb, 0.0), _Color, diff * diff * diff * (diff * (6 * diff - 15) + 10));
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
Auto Graphics API : unchecked.
Unity version: 2019.3.4f.
there is not any error or log.
I also tested builded APK on physical android device.
Related
When trying to build my game to Webgl I receive the following errors:
Shader error in 'Hidden/Universal/CoreBlit': invalid subscript 'positionCS' at /PathToProject/Library/PackageCache/com.unity.render-pipelines.core#12.1.2/Runtime/Utilities/Blit.hlsl(92) (on gles)
Shader error in 'Hidden/kMotion/CameraMotionVectors': SV_VertexID semantic is not supported on GLES 2.0 at line 11 (on gles)
The Shader I am using has the following code:
Shader "Skybox Gradient"
{
Properties
{
_Top("Top", Color) = (1,1,1,0)
_Bottom("Bottom", Color) = (0,0,0,0)
_mult("mult", Float) = 1
_pwer("pwer", Float) = 1
[Toggle(_SCREENSPACE_ON)] _Screenspace("Screen space", Float) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
CGINCLUDE
#pragma target 3.0
ENDCG
Blend Off
Cull Back
ColorMask RGBA
ZWrite On
ZTest LEqual
Offset 0 , 0
Pass
{
Name "Unlit"
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
#ifndef UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX
//only defining to not throw compilation error over Unity 5.5
#define UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input)
#endif
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#include "UnityCG.cginc"
#pragma shader_feature_local _SCREENSPACE_ON
struct appdata
{
float4 vertex : POSITION;
float4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
#ifdef ASE_NEEDS_FRAG_WORLD_POSITION
float3 worldPos : TEXCOORD0;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
float4 ase_texcoord1 : TEXCOORD1;
float4 ase_texcoord2 : TEXCOORD2;
};
uniform float4 _Bottom;
uniform float4 _Top;
uniform float _mult;
uniform float _pwer;
v2f vert ( appdata v )
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
UNITY_TRANSFER_INSTANCE_ID(v, o);
float4 ase_clipPos = UnityObjectToClipPos(v.vertex);
float4 screenPos = ComputeScreenPos(ase_clipPos);
o.ase_texcoord2 = screenPos;
o.ase_texcoord1 = v.vertex;
float3 vertexValue = float3(0, 0, 0);
#if ASE_ABSOLUTE_VERTEX_POS
vertexValue = v.vertex.xyz;
#endif
vertexValue = vertexValue;
#if ASE_ABSOLUTE_VERTEX_POS
v.vertex.xyz = vertexValue;
#else
v.vertex.xyz += vertexValue;
#endif
o.vertex = UnityObjectToClipPos(v.vertex);
#ifdef ASE_NEEDS_FRAG_WORLD_POSITION
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
#endif
return o;
}
fixed4 frag (v2f i ) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
fixed4 finalColor;
#ifdef ASE_NEEDS_FRAG_WORLD_POSITION
float3 WorldPosition = i.worldPos;
#endif
float4 screenPos = i.ase_texcoord2;
float4 ase_screenPosNorm = screenPos / screenPos.w;
ase_screenPosNorm.z = ( UNITY_NEAR_CLIP_VALUE >= 0 ) ? ase_screenPosNorm.z : ase_screenPosNorm.z * 0.5 + 0.5;
#ifdef _SCREENSPACE_ON
float staticSwitch13 = ase_screenPosNorm.y;
#else
float staticSwitch13 = i.ase_texcoord1.xyz.y;
#endif
float4 lerpResult3 = lerp( _Bottom , _Top , pow( saturate( ( staticSwitch13 * _mult ) ) , _pwer ));
finalColor = lerpResult3;
return finalColor;
}
ENDCG
}
}
CustomEditor "ASEMaterialInspector"
}
The error only occurs every second or third time I try to locally build the game.
However, when I am building with Unity Cloud Build it always appears.
In my game I don't need the top and bottom sides of skyboxes, so I removed them from the material. However, according to Frame Debugger, Unity still renders all 6 sides, even though they're never seen and should be occluded. Is there a way to ensure only four sides get rendered?
This is usually done via a certain shader like e.g. the default 6-sided Skybox.
What you can see there is that it contains 6 passes for the 6 sides.
Something you have to render at these points so I think you can't just remove the passes but I guess you could probably create one for only 4-sides which simply returns only a simple color and skipping the texture like e.g.
Shader "Custom/Skybox4"
{
Properties
{
_Tint ("Tint Color", Color) = (.5, .5, .5, .5)
[Gamma] _Exposure ("Exposure", Range(0, 8)) = 1.0
_Rotation ("Rotation", Range(0, 360)) = 0
[NoScaleOffset] _FrontTex ("Front [+Z] (HDR)", 2D) = "grey" {}
[NoScaleOffset] _BackTex ("Back [-Z] (HDR)", 2D) = "grey" {}
[NoScaleOffset] _LeftTex ("Left [+X] (HDR)", 2D) = "grey" {}
[NoScaleOffset] _RightTex ("Right [-X] (HDR)", 2D) = "grey" {}
_TopBottomColor ("Top Bottom Fill Color", Color) = (0, 0, 0, 0)
}
SubShader
{
Tags
{
"Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox"
}
Cull Off ZWrite Off
CGINCLUDE
#include "UnityCG.cginc"
half4 _Tint;
half _Exposure;
float _Rotation;
float3 RotateAroundYInDegrees(float3 vertex, float degrees)
{
float alpha = degrees * UNITY_PI / 180.0;
float sina, cosa;
sincos(alpha, sina, cosa);
float2x2 m = float2x2(cosa, -sina, sina, cosa);
return float3(mul(m, vertex.xz), vertex.y).xzy;
}
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert(appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
o.vertex = UnityObjectToClipPos(rotated);
o.texcoord = v.texcoord;
return o;
}
half4 skybox_frag(v2f i, sampler2D smp, half4 smpDecode)
{
half4 tex = tex2D(smp, i.texcoord);
half3 c = DecodeHDR(tex, smpDecode);
c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb;
c *= _Exposure;
return half4(c, 1);
}
ENDCG
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _FrontTex;
half4 _FrontTex_HDR;
half4 frag(v2f i) : SV_Target { return skybox_frag(i, _FrontTex, _FrontTex_HDR); }
ENDCG
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _BackTex;
half4 _BackTex_HDR;
half4 frag(v2f i) : SV_Target { return skybox_frag(i, _BackTex, _BackTex_HDR); }
ENDCG
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _LeftTex;
half4 _LeftTex_HDR;
half4 frag(v2f i) : SV_Target { return skybox_frag(i, _LeftTex, _LeftTex_HDR); }
ENDCG
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _RightTex;
half4 _RightTex_HDR;
half4 frag(v2f i) : SV_Target { return skybox_frag(i, _RightTex, _RightTex_HDR); }
ENDCG
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
half4 _TopBottomColor;
half4 frag(v2f i) : SV_Target { return _TopBottomColor; }
ENDCG
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
half4 _TopBottomColor;
half4 frag(v2f i) : SV_Target { return _TopBottomColor; }
ENDCG
}
}
}
Which looks like this
(Skybox source: Emil Persson, aka Humus)
This won't fully remove the rendering pass but should be at least faster.
This question already has answers here:
360 viewer in unity, texture appears warped in the top and bottom
(3 answers)
Closed 5 years ago.
I'm trying to make a 360VideoPlayer in unity.
I create a sphere, add a video player, then add Cull Front to its shader (a standard shader).
And when I play the video, it is warped at the top and bottom of that sphere like this:
So what should I do to fix this.
360 viewer in unity, texture appears warped in the top and bottom
here is the answer.
and use this shader:
Shader "Custom/Equirectangular" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Diffuse (RGB) Alpha (A)", 2D) = "gray" {}
}
SubShader{
Pass {
Tags {"LightMode" = "Always"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#pragma glsl
#pragma target 3.0
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 normal : TEXCOORD0;
};
v2f vert (appdata v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.normal = v.normal;
return o;
}
sampler2D _MainTex;
#define PI 3.141592653589793
inline float2 RadialCoords(float3 a_coords)
{
float3 a_coords_n = normalize(a_coords);
float lon = atan2(a_coords_n.z, a_coords_n.x);
float lat = acos(a_coords_n.y);
float2 sphereCoords = float2(lon, lat) * (1.0 / PI);
return float2(1 - (sphereCoords.x * 0.5 + 0.5), 1 - sphereCoords.y);
}
float4 frag(v2f IN) : COLOR
{
float2 equiUV = RadialCoords(IN.normal);
return tex2D(_MainTex, equiUV);
}
ENDCG
}
}
FallBack "VertexLit"
}
I want to merge the functionality of these two shaders for Unity.
First shader is main shader that adds a glitch hologram effect.
The Second shader is making a surface texture flimmer for added visual effect.
I am trying to merge my versions of the code, alternatively different passes that allows me to implement both features on same material, if possible.
I have tried shaderpass function, but cannot make it work.
Is it possible to do?
1st shadercode
Shader "Custom/Cool Hologram Original"
{
Properties
{
//This program takes an existing shader script and builds upon it, by adding the features :
//Tintcolor - allowing for manipulation of colors
//Transparency - Changing opaque in tags to transparency so that the model becomes transparent
//Properties allow defining public manipulative variables
_MainTex ("AlbedoTexture", 2D) = "white" {} //braces are useless leftover braces no longer needed according to Unity developer
_TintColor("Tint Color", Color) = (1,1,1,1) //Public variable appearing in inspector
_Transparency("Transparency", Range(0.0,0.5)) = 0.25
_CutoutTresh("Cutout Threshold", Range(0.0,1.0)) = 0.2
_Distance("Distance", Float) = 1
_Amplitude("Amplitude", Float) = 1
_Speed("Speed", Float) = 1
_Amount("Amount", Range(0.0,1.0)) = 1
}
//The actual shader program
SubShader
{
Tags {"Queue"="Transparent" "RenderType"="Transparent" } //Added queue and transparent elements because order matters (see render order queu tag)
LOD 100 //LOD means level of details and used for when player is close or far away
ZWrite Off //This is related to culling and depth testing, controlling if something is written to depth buffer. Zwrite off is for transparent objects
Blend SrcAlpha OneMinusSrcAlpha //See blend factors in unity doc. It is about render order and how they should blend
Pass //A pass can be made for each type of situation, like Virtual Reality etc
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" //Shaders does not use inheritance, it has got monobehaviour instead, so it must be defined as #included
struct appdata //Structs are objects with 2 objects each. appdata is passed in to v2f vert as argument
{
float4 vertex : POSITION; //Variable with 4 floating point numbers x,y,z,w. POSITION is a semantic binding telling where it is to be used
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION; //SV_Position corresponds to screen position in Unity
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _TintColor;
float _Transparency;
float _CutoutThresh;
float _Distance;
float _Amplitude;
float _Speed;
float _Amount;
v2f vert (appdata v)
{
v2f o;
v.vertex.x += sin(_Time.y * _Speed + v.vertex.y * _Amplitude) * _Distance * _Amount; //Allows sinusoidal movement to vertices in object space b4 translation to clip
o.vertex = UnityObjectToClipPos(v.vertex); //See learnopengl.com to see 5 spaces: local space, world space, view space, clip space, screen space
o.uv = TRANSFORM_TEX(v.uv, _MainTex); //Taking uv data from model and data from maintexture (see the shader texture in inspector)
return o; //Returns struct after it has been build in coordinate system, it will then be passed to fragment function
}
fixed4 frag (v2f i) : SV_Target //Takes in v2f struct calling it i and then bind it to render target, which is frame buffer for screen
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv) + _TintColor; //fixed 4 col is color. Can be fixed rgbA for 3 colors and an alpha channel. tex2D reads in colors from maintex and struct data from i
col.a = _Transparency; //The colors are what actually drawed in this feature with tex3D
clip(col.r - _CutoutThresh); //Not drawing pixels with certain amount of red color
return col;
}
ENDCG
}
}
}
2nd shadercode
Shader "Custom/Offset 1"
{
Properties {
_MainTex ("Texture", 2D) = "white" {}
_ScrollSpeeds ("Scroll Speeds", vector) = (0, -3, 0, 0)
}
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;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
// Declare our new parameter here so it's visible to the CG shader
float4 _ScrollSpeeds;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// Shift the uvs over time.
o.uv += _ScrollSpeeds * _Time.x;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
3rd shadercode
Shader "Custom/Combined"
{
Properties
{
_MainTex ("AlbedoTexture", 2D) = "white" {}
_HoloColor("Hologram Color", Color) = (1,1,1,1)
_Transparency("Transparency", Range(0.0,0.5)) = 0.25
_CutoutTresh("Cutout Threshold", Range(0.0,1.0)) = 0.2
_Distance("Distance", Float) = 1
_Amplitude("Amplitude", Float) = 1
_Speed("Speed", Float) = 1
_ScrollSpeeds("Scroll Speeds", vector) = (0,-3,0,0) //added from offset shader
_Amount("Amount", Range(0.0,1.0)) = 1
}
SubShader {
Tags {"Queue"="Transparent" "RenderType"="Transparent" }
LOD 100
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
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) //added from offset shader
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _HoloColor;
float4 _ScrollSpeeds;
float _Transparency;
float _CutoutThresh;
float _Distance;
float _Amplitude;
float _Speed;
float _Amount;
v2f vert (appdata v)
{
v2f o;
v.vertex.x += sin(_Time.y * _Speed + v.vertex.y * _Amplitude) * _Distance * _Amount;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.uv += _ScrollSpeeds * _Time.x; //Added from offset shader
UNITY_TRANSFER_FOG(o,o.vertex); //added from offset shader
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv) + _HoloColor;
col.a = _Transparency;
clip(col.r - _CutoutThresh);
UNITY_APPLY_FOG(i.fogCoord, col); //Added from offset shader
return col;
}
ENDCG
}
}
Fallback "Diffuse"
}
I am trying to create a shader that can be used to clip 2D sprites in a game, I found this shader in another question
Shader "Sprites/ClipArea"
{
Properties
{
_MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}
_Length ("Length", Range(0.0, 1.0)) = 1.0
_Width ("Width", Range(0.0, 1.0)) = 0.5
}
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 _Width;
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = v.texcoord;
return o;
}
half4 frag (v2f IN) : COLOR
{
if ((IN.texcoord.x<0) || (IN.texcoord.x>_Width) || (IN.texcoord.y<0) || (IN.texcoord.y>_Length))
{
half4 colorTransparent = half4(0,0,0,0) ;
return colorTransparent ;
}
return tex2D(_MainTex, IN.texcoord);
}
ENDCG
}
}
}
which works perfectly on single sprites, but I am using sprite sheets, divided by Unity Sprite editor.
The _Width variable in the shader is covering the whole sprite sheet, not the sprite I am working on. I searched for a way to get the current sprite rect inside the shader but couldnt find anything.
Well, after pulling my hair for three days, I managed to find a workaround.
After searching more about how shaders work and there role in the pipeline, I realized that the sprite rect info will probably be not available in the shader for one simple reason, the functionality of almost all shaders (except mine) does not require this info, because the job of the shader is to take a vertex, modify its position (if needed) through the vertex function and then decide its pixel colour through the fragment function, it does not care about the whole sprite, it only needs to lookup the pixel colour for a certain vertex from the texture using its texture coordinates.
I am sure this is trivial info for people working in shaders, but it took me time to realize it ( This was my first ever shader).
So as a workaround I had to use the shader properties to pass the MinX and MaxX of the current sprite the shader is working on in the sprite sheet, so the shader now looks like this:
Shader "Sprites/ClipArea"
{
Properties
{
_MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}
_Fill ("Fill", Range(0.0, 1.0)) = 1.0
_MinX ("MinX", Float) = 0
_MaxX ("MaxX", Float) = 1
}
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 _MinX;
float _MaxX;
float _Fill;
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = v.texcoord;
return o;
}
half4 frag (v2f IN) : COLOR
{
if ((IN.texcoord.x<_MinX)|| (IN.texcoord.x>(_MinX+_Fill*(_MaxX-_MinX))))
{
half4 colorTransparent = half4(0,0,0,0) ;
return colorTransparent ;
}
return tex2D(_MainTex, IN.texcoord);
}
ENDCG
}
}
}
To use this shader, you need to create a material that uses it, then use that material in the SpriteRenderer, you can change the Fill amount, MinX , and MaxX from the inspector, or call the spriteRenderer.material.setFloat(property, value) from code.
I then faced another issue with animated sprites, I had to keep updating the MinX and MaxX on every frame, but when I did it in the Update function the animation started flickering, and thats because the update was being called after the sprite is rendered, so I had to use the Main Camera OnPreRender event to update the material properties.
Maybe there is a better way to achieve all this but this is the best I could come up with, and I hope this will benefit someone trying to achieve the same effect.
I have improve Khaled-AbuA-lkheir shader adding base sprite color:
Shader "Sprites/ClipArea"
{
Properties
{
_MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}
_Fill ("Fill", Range(0.0, 1.0)) = 1.0
_MinX ("MinX", Float) = 0
_MaxX ("MaxX", Float) = 1
}
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 _MinX;
float _MaxX;
float _Fill;
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
};
struct v2f
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
};
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = v.texcoord;
o.color = v.color;
return o;
}
half4 frag (v2f IN) : COLOR
{
if ((IN.texcoord.x<_MinX)|| (IN.texcoord.x>(_MinX+_Fill*(_MaxX-_MinX))))
{
half4 colorTransparent = half4(0,0,0,0) ;
return colorTransparent ;
}
else
{
return tex2D(_MainTex, IN.texcoord)*IN.color;
}
}
ENDCG
}
}
}
I'm necroing this because I think it can be useful:
I added the possibility to set _MinX greater than _MaxX.
That way, you have a "right to left" clipping, instead of "left to right".
Shader "Sprites/ClipArea"
{
Properties
{
_MainTex("Base (RGB), Alpha (A)", 2D) = "white" {}
_Fill("Fill", Range(0.0, 1.0)) = 1.0
_MinX("MinX", Float) = 0
_MaxX("MaxX", Float) = 1
}
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 _MinX;
float _MaxX;
float _Fill;
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
};
struct v2f
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
};
v2f vert(appdata_t v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = v.texcoord;
o.color = v.color;
return o;
}
half4 frag(v2f IN) : COLOR
{
if (_MinX < _MaxX && ((IN.texcoord.x < _MinX) || (IN.texcoord.x > (_MinX + _Fill * (_MaxX - _MinX)))) ||
_MinX > _MaxX && ((IN.texcoord.x > _MinX) || (IN.texcoord.x < (_MinX + _Fill * (_MaxX - _MinX)))))
{
return half4(0, 0, 0, 0);
}
else
{
return tex2D(_MainTex, IN.texcoord) * IN.color;
}
}
ENDCG
}
}
}