I am working on my water shader but I have run into some problems. It looks like my normals aren't getting the same offset as my vertexes. You can see a white plane belof my water where the shadow of the water is cast upon, exept another white plane which is not a object but most likely the normals of my water mesh that didn't move block a part of the shadow. PLEASE I really need some help with this can't find anyone who knows what this is.
This is my code:
Shader "Custom/NoobShader_04" {
Properties {
_Color ("Color", Color) = (0,0.55,0.83,1)
_Diffuse ("Diffuse Map", 2D) = "white" {}
_Displacement ("Displacement Map", 2D) = "white" {}
_Scale ("Wave Scale", float) = 0.7
_Frequency ("Frequency", float) = 0.6
_Speed ("Speed", float) = 0.5
}
SubShader {
Pass{
Tags { "LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 _Color;
sampler2D _Displacement;
sampler2D _Diffuse;
float _Scale;
float _Frequency;
float _Speed;
float4 _LightColor0;
struct VertexOutput
{
float4 pos : SV_POSITION;
float3 nor : NORMAL;
float4 col : COLOR;
float4 tex : TEXCOORD0;
};
struct VertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct FragmentOutput
{
float4 color : COLOR;
};
VertexOutput vert (VertexInput i)
{
VertexOutput VOUT;
float4 disp = tex2Dlod(_Displacement, float4(i.texcoord.x * _Frequency + (_Time.x * _Speed), i.texcoord.y * _Frequency + (_Time.x * _Speed),0.0,0.0));
float4 newPos = i.vertex;
float3 newNor = i.normal;
newPos.y += _Scale * disp.y;
newNor.y += _Scale * disp.y;
VOUT.nor = newNor;
VOUT.pos = mul(UNITY_MATRIX_MVP,newPos);
VOUT.tex = i.texcoord;
float3 normalDirection = normalize( mul(float4(newNor,0.0),_World2Object).xyz);
float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
float atten = 1.0;
float3 diffuseRefflection = atten * _LightColor0.xyz * _Color.rgb * max( 0.0, dot(normalDirection, lightDirection));
VOUT.col = float4(diffuseRefflection, 1.0);
return VOUT;
}
FragmentOutput frag(VertexOutput v)
{
FragmentOutput FOUT;
float4 tex = tex2D(_Diffuse,float4(v.tex.x * _Frequency + (_Time.x * _Speed), v.tex.y * _Frequency + (_Time.x * _Speed),0.0,0.0));
FOUT.color = tex * v.col + UNITY_LIGHTMODEL_AMBIENT.xyzw;
return FOUT;
}
ENDCG
}
}
FallBack "Diffuse"
}
You can see a white plane belof my water where the shadow of the water
is cast upon, exept another white plane which is not a object but most
likely the normals of my water mesh that didn't move block a part of
the shadow.
I tried your shader and I can't see any plane, except the one I add to a scene to receive the casted shadow. In any case, water's normals don't have anything to do with the plane.
It looks like my normals aren't getting the same offset as my
vertexes
Again, not sure what you mean here. Offset has no effect on normals, because they express an orientation, not a position.
If you mean that the projected shadow on the plane, doesn't account for the vertex offset, it's because the auto generated shadow caster pass, can't take in consideration the vertex offset. So you probably need to explicitly implement it.
Something like:
Pass
{
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
Fog {Mode Off}
ZWrite On ZTest Less Cull Off
Offset 1, 1
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#pragma multi_compile_shadowcaster
#include "UnityCG.cginc"
v2f vert( appdata_full v )
{
v2f o;
//TRANSFER_SHADOW_CASTER(o) this is how default shadow are casted
o.pos = ...;// put here your calculation taking into account the vertex offset. Basically repeating the same calculation you wrote for forward pass in regards to vertex position
return o;
}
float4 frag( v2f i ) : COLOR
{
fixed4 texcol = tex2D( _MainTex, i.uv );
clip( texcol.a - _Cutoff );
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
Related
I'm on v2019.4.30f1, am using the old render pipeline (i.e. not urp nor hdrp) and using the blood decals from this pack: https://assetstore.unity.com/packages/vfx/particles/volumetric-blood-fluids-173863
The blood decals are done at runtime, like when a play dies some blood spurts out and the decal is created.
Here is how the decal looks at FOV 20, and this is good, how I expect it to look:
Next if I merely change the camera FOV to 15 you'll see something goes really weird with the decal. There are parts that look like they are in the wrong place, almost like some parts have been shifted either up or left or whatever and some parts have been clipped off. But then other parts seems like they are still in the correct place:
If I switch back to FOV 20 again it looks normal again, so it doesn't seem like anything is changing with the decal itself when I change FOV, just that viewed from different FOV it looks completely different.
Here is a screenshot from scene view, showing the decal as well as some inspector info about it:
I've been tearing my hair out this entire week over this and can't seem to figure it out :/
Any advice would be much appreciated. Of course I can provide any other info required if there isn't enough to go on here.
edit: here is the decal shader
Shader "KriptoFX/BFX/BFX_Decal"
{
Properties
{
[HDR] _TintColor("Tint Color", Color) = (1,1,1,1)
_MainTex("NormalAlpha", 2D) = "white" {}
_LookupFade("Lookup Fade Texture", 2D) = "white" {}
_Cutout("Cutout", Range(0, 1)) = 1
_CutoutTex("CutoutDepth(XZ)", 2D) = "white" {}
[Space]
_SunPos("Sun Pos", Vector) = (1, 0.5, 1, 0)
}
SubShader
{
Tags{ "Queue" = "AlphaTest"}
Blend DstColor SrcColor
//Blend SrcAlpha OneMinusSrcAlpha
Cull Front
ZTest Always
ZWrite Off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma multi_compile _ USE_CUSTOM_DECAL_LAYERS
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _Flowmap;
sampler2D _LookupFade;
sampler2D _CutoutTex;
float4 _MainTex_ST;
float4 _MainTex_NextFrame;
float4 _CutoutTex_ST;
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_DEFINE_INSTANCED_PROP(half4, _TintColor)
UNITY_DEFINE_INSTANCED_PROP(half, _Cutout)
UNITY_DEFINE_INSTANCED_PROP(float, _LightIntencity)
UNITY_INSTANCING_BUFFER_END(Props)
half4 _CutoutColor;
half4 _FresnelColor;
half4 _DistortionSpeedScale;
sampler2D _CameraDepthTexture;
sampler2D _LayerDecalDepthTexture;
half InterpolationValue;
half _AlphaPow;
half _DistortSpeed;
half _DistortScale;
float4 _SunPos;
half _DepthMul;
struct appdata_t {
float4 vertex : POSITION;
float4 normal : NORMAL;
half4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
half4 color : COLOR;
float4 screenUV : TEXCOORD0;
float3 ray : TEXCOORD1;
float3 viewDir : TEXCOORD2;
float4 screenPos : TEXCOORD3;
UNITY_FOG_COORDS(4)
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert(appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = v.color;
o.ray = UnityObjectToViewPos(v.vertex) * float3(-1, -1, 1);
o.screenUV = ComputeScreenPos(o.vertex);
o.viewDir = normalize(ObjSpaceViewDir(v.vertex));
o.screenPos = ComputeGrabScreenPos(o.vertex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
half4 frag(v2f i) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
i.ray *= (_ProjectionParams.z / i.ray.z);
#if USE_CUSTOM_DECAL_LAYERS
float depth = Linear01Depth(tex2Dproj(_LayerDecalDepthTexture, i.screenUV));
float depthMask = Linear01Depth(tex2Dproj(_CameraDepthTexture, i.screenUV));
float fade = 1- saturate(100000 * (depth - depthMask));
#else
float depth = Linear01Depth(tex2Dproj(_CameraDepthTexture, i.screenUV));
#endif
float3 wpos = mul(unity_CameraToWorld, float4(i.ray * depth, 1)).xyz;
float3 opos = mul(unity_WorldToObject, float4(wpos, 1)).xyz;
float3 stepVal = saturate((0.5 - abs(opos.xyz)) * 10000);
half lookupHeight = tex2D(_LookupFade, float2(opos.y + 0.5, 0));
float projClipFade = stepVal.x * stepVal.y * stepVal.z * lookupHeight;
#if USE_CUSTOM_DECAL_LAYERS
projClipFade *= fade;
#endif
float2 uv = opos.xz + 0.5;
float2 uvMain = uv * _MainTex_ST.xy + _MainTex_ST.zw;
float2 uvCutout = (opos.xz + 0.5) * _CutoutTex_ST.xy + _CutoutTex_ST.zw;
half4 normAlpha = tex2D(_MainTex, uvMain);
half4 res = 0;
res.a = saturate(normAlpha.w * 2);
if (res.a < 0.1) discard;
normAlpha.xy = normAlpha.xy * 2 - 1;
float3 normal = normalize(float3(normAlpha.x, 1, normAlpha.y));
half3 mask = tex2D(_CutoutTex, uvCutout).xyz;
half cutout = 0.5 + UNITY_ACCESS_INSTANCED_PROP(Props, _Cutout) * i.color.a * 0.5;
half alphaMask = saturate((mask.r - (cutout * 2 - 1)) * 20) * res.a;
half colorMask = saturate((mask.r - (cutout * 2 - 1)) * 5) * res.a;
res.a = alphaMask;
res.a = saturate(res.a * projClipFade);
float intencity = UNITY_ACCESS_INSTANCED_PROP(Props, _LightIntencity);
float light = max(0.001, dot(normal, normalize(_SunPos.xyz)));
light = pow(light, 150) * 3 * intencity;
light *= (1 - mask.z * colorMask);
float4 tintColor = UNITY_ACCESS_INSTANCED_PROP(Props, _TintColor);
#if !UNITY_COLORSPACE_GAMMA
tintColor = tintColor * 1.35;
#endif
res.rgb = lerp(tintColor.rgb, tintColor.rgb * 0.25, mask.z * colorMask) + light;
half fresnel = (1 - dot(normal, normalize(i.viewDir)));
fresnel = pow(fresnel + 0.1, 5);
UNITY_APPLY_FOG_COLOR(i.fogCoord, res, half4(1, 1, 1, 1));
return lerp(0.5, res, res.a);
return res;
}
ENDCG
}
}
}
Comparing two pictures, I see that BFXShaderAnamation does some precomputation in the beginning of animation, and the results depend on camera settings and geometry. You should look for the code that does this initialization and call it again each time your camera settings or geometry change.
Idea: check if the decal plugin creates an additional hidden camera to do some computations (look into the hierarchy and search by "Camera" type).
I found this shader online that mimics liquid movement in a container.
Here it is (https://pastebin.com/wRWnHQH2)
Shader "Unlit/SpecialFX/Liquid"
{
Properties
{
_Tint ("Tint", Color) = (1,1,1,1)
_MainTex ("Texture", 2D) = "white" {}
_FillAmount ("Fill Amount", Range(-10,10)) = 0.0
[HideInInspector] _WobbleX ("WobbleX", Range(-1,1)) = 0.0
[HideInInspector] _WobbleZ ("WobbleZ", Range(-1,1)) = 0.0
_TopColor ("Top Color", Color) = (1,1,1,1)
_FoamColor ("Foam Line Color", Color) = (1,1,1,1)
_Rim ("Foam Line Width", Range(0,0.1)) = 0.0
_RimColor ("Rim Color", Color) = (1,1,1,1)
_RimPower ("Rim Power", Range(0,10)) = 0.0
}
SubShader
{
Tags {"Queue"="Geometry" "DisableBatching" = "True" }
Pass
{
Zwrite On
Cull Off // we want the front and back faces
AlphaToMask On // transparency
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;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
float3 viewDir : COLOR;
float3 normal : COLOR2;
float fillEdge : TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _FillAmount, _WobbleX, _WobbleZ;
float4 _TopColor, _RimColor, _FoamColor, _Tint;
float _Rim, _RimPower;
float4 RotateAroundYInDegrees (float4 vertex, float degrees)
{
float alpha = degrees * UNITY_PI / 180;
float sina, cosa;
sincos(alpha, sina, cosa);
float2x2 m = float2x2(cosa, sina, -sina, cosa);
return float4(vertex.yz , mul(m, vertex.xz)).xzyw ;
}
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
// get world position of the vertex
float3 worldPos = mul (unity_ObjectToWorld, v.vertex.xyz);
// rotate it around XY
float3 worldPosX= RotateAroundYInDegrees(float4(worldPos,0),360);
// rotate around XZ
float3 worldPosZ = float3 (worldPosX.y, worldPosX.z, worldPosX.x);
// combine rotations with worldPos, based on sine wave from script
float3 worldPosAdjusted = worldPos + (worldPosX * _WobbleX)+ (worldPosZ* _WobbleZ);
// how high up the liquid is
o.fillEdge = worldPosAdjusted.y + _FillAmount;
o.viewDir = normalize(ObjSpaceViewDir(v.vertex));
o.normal = v.normal;
return o;
}
fixed4 frag (v2f i, fixed facing : VFACE) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv) * _Tint;
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
// rim light
float dotProduct = 1 - pow(dot(i.normal, i.viewDir), _RimPower);
float4 RimResult = smoothstep(0.5, 1.0, dotProduct);
RimResult *= _RimColor;
// foam edge
float4 foam = ( step(i.fillEdge, 0.5) - step(i.fillEdge, (0.5 - _Rim))) ;
float4 foamColored = foam * (_FoamColor * 0.9);
// rest of the liquid
float4 result = step(i.fillEdge, 0.5) - foam;
float4 resultColored = result * col;
// both together, with the texture
float4 finalResult = resultColored + foamColored;
finalResult.rgb += RimResult;
// color of backfaces/ top
float4 topColor = _TopColor * (foam + result);
//VFACE returns positive for front facing, negative for backfacing
return facing > 0 ? finalResult: topColor;
}
ENDCG
}
}
}
it works nicely except that the AlphaToMask ON that works on desktop to mask out the fill part doesn't seem to work at all on mobile, showing black instead of transparency.
Any clue on what's going on or how I could solve this?
For those who want it works on mobile devices, just set AlphaToMask to off (optional), set Zwrite to off and add line Blend SrcAlpha OneMinusSrcAlpha below Zwrite off line,
also set "Queue"="Transparent" or "AlphaTest"
SubShader
{
Tags {"Queue"="Transparent" "DisableBatching" = "True" }
Pass
{
Zwrite off
Blend SrcAlpha OneMinusSrcAlpha
Cull Off // we want the front and back faces
AlphaToMask off CGPROGRAM
#pragma vertex vert
#pragma fragment frag
(Full code)
(Demo image)
See also:
Unity Blend Documentation:https://docs.unity3d.com/Manual/SL-Blend.html
Unity Shader Transparent Tutorial:Making A Transparent Shader [6/8]
I´m trying to make a shader which simulates a warp speed effect, and i think is almost done, only need to know what should i change in the code to make the tunnel effect completely opaque and not see anything behind the tunnel effect.
I have added an alpha slider to see if i can control opacity but still the same result at the end.
Code is here:
Shader "Warp Tunnel Distortion Opaque" {
Properties {
_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
_Speed("UV Speed", Float) = 1.0
_WiggleX("_WiggleX", Float) = 1.0
_WiggleY("_WiggleY", Float) = 1.0
_WiggleDist("Wiggle distance", Float) = 1.0
_Offset("Vertex offset", float) = 0
_TintColor("Tint", Color) = (1.0, 1.0, 1.0, 1.0)
_MainTex("Distortion map", 2D) = "" {}
_Dist("Distortion ammount", Float) = 10.0
}
Category {
Tags { "Queue"="Geometry" "RenderType"="Opaque" }
Cull Back Lighting Off ZWrite Off
Fog { Color (0,0,0,0) }
ZTest LEqual
SubShader {
GrabPass {
Name "BASE"
Tags { "LightMode" = "Always" }
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_particles
#include "UnityCG.cginc"
sampler2D _MainTex;
fixed4 _TintColor;
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 normal : NORMAL;
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 posWorld : TEXCOORD1;
float4 uvgrab : TEXCOORD2;
float4 projPos : TEXCOORD3;
};
float4 _MainTex_ST;
float _Speed;
float _WiggleX, _WiggleY, _WiggleDist;
float _Offset;
float _Dist;
sampler2D _CameraDepthTexture;
float _InvFade;
sampler2D _GrabTexture;
float4 _GrabTexture_TexelSize;
v2f vert (appdata_t v)
{
v2f o;
o.posWorld = mul(unity_ObjectToWorld, v.vertex);
v.vertex.xyz += normalize(v.normal.xyz) * _Offset;
o.vertex = UnityObjectToClipPos(v.vertex);
o.vertex.x += sin(_Time.y * _WiggleX) * _WiggleDist;
o.vertex.y -= sin(_Time.y * _WiggleY) * _WiggleDist;
o.color = v.color;
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
o.projPos = ComputeScreenPos (o.vertex);
COMPUTE_EYEDEPTH(o.projPos.z);
#if UNITY_UV_STARTS_AT_TOP
float scale = -1.0;
#else
float scale = 1.0;
#endif
o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
o.uvgrab.zw = o.vertex.zw;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
i.texcoord.y += _Time.x * _Speed;
float4 packedTex = tex2D(_MainTex, i.texcoord);
float local1 = packedTex.z * 2.4;
float2 local2 = packedTex.rg * 2.25;
packedTex.rg = local1 * local2;
half2 bump = UnpackNormal(packedTex).rg;
float2 offset = bump * _Dist * _GrabTexture_TexelSize.xy;
i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;
half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
return col;
}
ENDCG
}
}
}
}
Thank you in advance.
Well if you want it completely opaque, that's easy.
Right before the return statement, just add:
col.a = 1;
If you want it to actually care about the alpha slider in the input color, then do this:
col.a = _TintColor.a;
In the first case, _TintColor isn't used at all (there are no other references to it besides its declaration, of which there are 2 at the top (you should remove one of them) and one inside the CGprogram block which links the first one to a property that can be used within the CGprogram).
If you actually want to tint things, you'll have to multiply the _TintColor with the computed color coming from the texture and effect. There are multiple ways of doing it, for example:
col.r *= _TintColor.r;
col.g *= _TintColor.g;
col.b *= _TintColor.b;
How you want to handle it is up to you.
This will be my second question regarding my ongoing VR project.
I am making a photosphere cardboard app.
I have added a sphere and inside of it, I have placed the Main camera on 0,0,0 position.
Inside of the cube I have placed a 3d cube. If user gazes towards it for some specific seconds, the equirectangular textures on the sphere will change via script.
Now I am using the GvrReticlePointer in this project, and I can't seem to find the white dot anywhere except when it is on the 3d cube.
I would really like to know what is causing the reticle to disappear on the scene and how to fix it.
Thanks in advance.
Answering this question myself!
Just use this shader. Works like a charm!
Shader "Custom/Equirectangular" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Diffuse (RGB) Alpha (A)", 2D) = "gray" {}
}
SubShader{
Pass {
Cull Front
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 = UnityObjectToClipPos(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(sphereCoords.x * 0.5 + 0.5, 1 - sphereCoords.y);
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 have a shader which generates opacity mask and rotate it.
This is how it looks:
Generated mask looks like this:
I generate a mask via code, but I want to take mask just from a texture2D.
How can I do that?
How do I change mask generating by only texture2D?
Code of my shader:
Shader "Custom/RadialOpacity" {
Properties {
[PerRendererData]_MainTex ("MainTex", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
_OpacityRotator ("Opacity Rotator", Range(-360, 360)) = -360 // 2 full circles
[HideInInspector]_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
}
SubShader {
Tags {
"IgnoreProjector"="True"
"Queue"="Transparent"
"RenderType"="Transparent"
"CanUseSpriteAtlas"="True"
"PreviewType"="Plane"
}
Pass {
Name "FORWARD"
Tags {
"LightMode"="ForwardBase"
}
Blend One OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#include "UnityCG.cginc"
#pragma target 3.0
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform float4 _Color;
uniform float _OpacityRotator;
static const float TAU = float(6.283185); // это 2 * PI
struct VertexInput {
float4 vertex : POSITION;
float2 texcoord0 : TEXCOORD0;
};
struct VertexOutput {
float4 pos : SV_POSITION;
float2 uv0 : TEXCOORD0;
float3 normalDir : TEXCOORD2;
};
VertexOutput vert (VertexInput v) {
VertexOutput o = (VertexOutput)0;
o.uv0 = v.texcoord0;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex );
#ifdef PIXELSNAP_ON
o.pos = UnityPixelSnap(o.pos);
#endif
return o;
}
float4 frag(VertexOutput i) : COLOR {
i.normalDir = normalize(i.normalDir);
float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(i.uv0, _MainTex));
float2 oStart = (i.uv0 - 0.5);
float2 oVector = float2(-1, -1);
float oRotatorNormalized = _OpacityRotator / 360.0;
float oRotator_ang = oRotatorNormalized * -TAU;
float oRotator_cos = cos(oRotator_ang);
float oRotator_sin = sin(oRotator_ang);
float2x2 oRotationMatrix = float2x2(oRotator_cos, -oRotator_sin, oRotator_sin, oRotator_cos);
float2 oRotatorComponent = mul(oVector * oStart, oRotationMatrix);
/* generating opacity mask BEGIN_SECTION */
float2 oMaskHorizOrVert = atan2(oRotatorComponent.g, oRotatorComponent.r);
float oAtan2MaskNormalized = (oMaskHorizOrVert / TAU) + 0.5;
float oAtan2MaskRotatable = oRotatorNormalized - oAtan2MaskNormalized;
float oWhiteToBlackMask = ceil(oAtan2MaskRotatable);
/* generating opacity mask END_SECTION */
float oFinalMultiply = _MainTex_var.a * max(oAtan2MaskNormalized, ceil(oWhiteToBlackMask));
/*** (Emissive) ***/
float3 finalColor = _MainTex_var.rgb * _Color.rgb * oFinalMultiply;
return fixed4(finalColor, oFinalMultiply);
}
ENDCG
}
}
FallBack "Diffuse"
}
And I want to get something like that:
Properties {
...
_OpacityMask ("OpacityMask", 2D) = "white" {}
...
}
...
float oWhiteToBlackMask = ceil(OpacityMask);
float oFinalMultiply = _MainTex_var.a * max(oAtan2MaskNormalized, ceil(oWhiteToBlackMask));
...
https://forum.unity3d.com/threads/rotation-of-texture-uvs-directly-from-a-shader.150482/
Ok if I understand your question correctly, you want to add a texture 2D parameter and have it rotate. You'll need to rotate the UV coordinates over time, which you can probably accomplish using the code in the link above.
I'm not sure how you get that exact fade at the end with a texture 2D but maybe some clever usage of time you can figure out the animation.