This shader (copied below) makes a material kind of like a radial gradient. I am trying to modify it to have the shader effect resemble something like a vertical/linear gradient,like this. I don't believe it is creating is a true gradient but rather adding colors and adding alpha between them. It is based off of this awesome project .
Here is picture of the effect I have currently with this shader and the scanlines
effect turned on: https://i.sstatic.net/qMQfE.jpg
And here is picture of what I need the effect to look like: https://i.sstatic.net/XIoNe.jpg
Here is a picture of what editing the shader looks like currently: https://i.sstatic.net/hdzpK.jpg (This appears to be radial,no?)
I have tried modifying the direction, tried applying masks and nothing has worked so far. If anyone has any suggestions, I would be eternally thankful.
Shader "SFHologram/HologramShader"
{
Properties
{
// General
_TopColor ("Top Color", Color) = (1, 0.3, 0.3, 0)
_BottomColor ("Bottom Color", Color) = (0.3, 0.3, 1, 0)
_Up ("Up", Vector) = (0, 1, 0)
_Exp ("Exp", Range(0, 16)) = 1
_Brightness("Brightness", Range(0.1, 6.0)) = 3.0
_Alpha ("Alpha", Range (0.0, 100)) = 1.0
_Direction ("Direction", Vector) = (0,1,0,0)
// Main Color
_MainTex ("MainTexture", 2D) = "white" {}
_MainColor ("MainColor", Color) = (1,1,1,100)
// Rim/Fresnel
_RimColor ("Rim Color", Color) = (1,1,1,1)
_RimPower ("Rim Power", Range(0.1, 10)) = 5.0
// Scanline
_ScanTiling ("Scan Tiling", Range(0.01, 10.0)) = 0.05
_ScanSpeed ("Scan Speed", Range(-2.0, 2.0)) = 1.0
_ScanColor ("ScanColor", Color) = (255,1,1,1)
// Glow
_GlowTiling ("Glow Tiling", Range(0.01, 1.0)) = 0.05
_GlowSpeed ("Glow Speed", Range(-10.0, 10.0)) = 1.0
// Glitch
_GlitchSpeed ("Glitch Speed", Range(0, 50)) = 1.0
_GlitchIntensity ("Glitch Intensity", Float) = 0
// Alpha Flicker
_FlickerTex ("Flicker Control Texture", 2D) = "white" {}
_FlickerSpeed ("Flicker Speed", Range(0.01, 100)) = 1.0
// Settings
[HideInInspector] _Fold("__fld", Float) = 1.0
}
SubShader
{
Tags { "Queue"="Transparent" "RenderType"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
LOD 100
ColorMask RGB
Cull Back
Pass
{
CGPROGRAM
#pragma shader_feature _SCAN_ON
#pragma shader_feature _GLOW_ON
#pragma shader_feature _GLITCH_ON
#pragma vertex vert
#pragma fragment frag
fixed3 _TopColor, _BottomColor;
float3 _Up;
float _Exp;
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float4 worldVertex : TEXCOORD1;
float3 viewDir : TEXCOORD2;
float3 worldNormal : NORMAL;
fixed4 col : COLOR;
};
sampler2D _MainTex;
sampler2D _FlickerTex;
float4 _Direction;
float4 _MainTex_ST;
float4 _MainColor;
float4 _ScanColor;
float4 _RimColor;
float _RimPower;
float _GlitchSpeed;
float _GlitchIntensity;
float _Brightness;
float _Alpha;
float _ScanTiling;
float _ScanSpeed;
float _GlowTiling;
float _GlowSpeed;
float _FlickerSpeed;
v2f vert (appdata v)
{
v2f o;
// Glitches
#if _GLITCH_ON
v.vertex.x += _GlitchIntensity * (step(0.5, sin(_Time.y * 2.0 + v.vertex.y * 1.0)) * step(0.99, sin(_Time.y*_GlitchSpeed * 0.5)));
#endif
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldVertex = mul(unity_ObjectToWorld, v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.viewDir = normalize(UnityWorldSpaceViewDir(o.worldVertex.xyz));
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 texColor = tex2D(_MainTex, i.uv);
fixed4 randomColor = (255,0,0,0);
half dirVertex = (dot(i.worldVertex, normalize(float4(_Direction.xyz, 1.0))) + 1) / 2;
// Glow
float glow = 0.0;
#ifdef _GLOW_ON
glow = frac(dirVertex * _GlowTiling - _Time.x * _GlowSpeed);
#endif
// Flicker
fixed4 flicker = tex2D(_FlickerTex, _Time * _FlickerSpeed);
// Rim Light
half rim = 1.0-saturate(dot(i.viewDir, i.worldNormal));
fixed4 rimColor = _RimColor * pow (rim, _RimPower);
fixed4 col = texColor * _MainColor + (glow * 0.35 * _MainColor) + rimColor;
// Scanlines
float scan = 0.0;
#ifdef _SCAN_ON
scan = step(frac(dirVertex * _ScanTiling + _Time.w * _ScanSpeed), 0.5) * 0.65;
#endif
col.a = texColor.a * _Alpha * (scan);
col.rgb *= _Brightness;
return col;
}
ENDCG
}
}
CustomEditor "HologramShaderGUI"
}
So, the part you want to change is the section involving rim
:
half rim = 1.0-saturate(dot(i.viewDir, i.worldNormal));
fixed4 rimColor = _RimColor * pow (rim, _RimPower);
Currently, it compares the normal of each pixel to the view direction, and the more similar they are, the less the RimColor applies.
Here's an attempt at making this logic work but with "up" and the view direction, so that the more similar they are, the more _TopColor
goes into rimColor
, and the more opposite, the more _BottomColor
goes into rimColor
:
Shader "SFHologram/HologramShader"
{
Properties
{
// General
_TopColor("Top Color", Color) = (1, 0.3, 0.3, 0)
_BottomColor("Bottom Color", Color) = (0.3, 0.3, 1, 0)
_Up("Up", Vector) = (0, 1, 0)
_Exp("Exp", Range(0, 16)) = 1
_Brightness("Brightness", Range(0.1, 6.0)) = 1.0
_Alpha("Alpha", Range(0.0, 100)) = 1.0
_Direction("Direction", Vector) = (0,1,0,0)
// Main Color
_MainTex("MainTexture", 2D) = "white" {}
_MainColor("MainColor", Color) = (1,1,1,100)
// Rim/Fresnel
_RimColor("Rim Color", Color) = (1,1,1,1)
_RimPower("Rim Power", Range(0.1, 10)) = 5.0
_RimGap("Rim Gap", Range(0,1)) = 0.75
_RimChangeRate("Rim Change Rate", Range(0,5)) = 1.0
// Scanline
_ScanTiling("Scan Tiling", Range(0.01, 10.0)) = 0.05
_ScanSpeed("Scan Speed", Range(-2.0, 2.0)) = 1.0
_ScanColor("ScanColor", Color) = (255,1,1,1)
// Glow
_GlowTiling("Glow Tiling", Range(0.01, 1.0)) = 0.05
_GlowSpeed("Glow Speed", Range(-10.0, 10.0)) = 1.0
// Glitch
_GlitchSpeed("Glitch Speed", Range(0, 50)) = 1.0
_GlitchIntensity("Glitch Intensity", Float) = 0
// Alpha Flicker
_FlickerTex("Flicker Control Texture", 2D) = "white" {}
_FlickerSpeed("Flicker Speed", Range(0.01, 100)) = 1.0
// Settings
[HideInInspector] _Fold("__fld", Float) = 1.0
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
LOD 100
ColorMask RGB
Cull Back
Pass
{
CGPROGRAM
#pragma shader_feature _SCAN_ON
#pragma shader_feature _GLOW_ON
#pragma shader_feature _GLITCH_ON
#pragma vertex vert
#pragma fragment frag
float _Exp;
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float4 worldVertex : TEXCOORD1;
float3 viewDir : TEXCOORD2;
float3 worldNormal : NORMAL;
};
sampler2D _MainTex;
sampler2D _FlickerTex;
float4 _Direction;
float4 _MainTex_ST;
float4 _MainColor;
float4 _ScanColor;
float _RimPower;
float _RimGap;
float _RimChangeRate;
float _GlitchSpeed;
float _GlitchIntensity;
float _Brightness;
float _Alpha;
float _ScanTiling;
float _ScanSpeed;
float _GlowTiling;
float _GlowSpeed;
float _FlickerSpeed;
fixed4 _TopColor;
fixed4 _BottomColor;
v2f vert(appdata v)
{
v2f o;
// Glitches
#if _GLITCH_ON
v.vertex.x += _GlitchIntensity * (step(0.5, sin(_Time.y * 2.0 + v.vertex.y * 1.0)) * step(0.99, sin(_Time.y*_GlitchSpeed * 0.5)));
#endif
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldVertex = mul(unity_ObjectToWorld, v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.viewDir = normalize(WorldSpaceViewDir(v.vertex));
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 texColor = tex2D(_MainTex, i.uv);
fixed4 randomColor = fixed4(255,0,0,0);
half dirVertex = (dot(i.worldVertex, normalize(float4(_Direction.xyz, 1.0))) + 1) / 2;
// Glow
float glow = 0.0;
#ifdef _GLOW_ON
glow = frac(dirVertex * _GlowTiling - _Time.x * _GlowSpeed);
#endif
// Flicker
fixed4 flicker = tex2D(_FlickerTex, _Time * _FlickerSpeed);
half rim = dot(i.viewDir, half3(0, 1, 0));
half topRim = saturate(smoothstep(-0.5*_RimGap, -1., rim)*_RimChangeRate);
half bottomRim = saturate(smoothstep( 0.5*_RimGap, 1., rim)*_RimChangeRate);
fixed4 rimColor = _TopColor * topRim + _BottomColor * bottomRim;
fixed4 col = texColor * _MainColor + (glow * 0.35 * _MainColor) + rimColor;
// Scanlines
float scan = 1.0;
#ifdef _SCAN_ON
scan = step(frac(dirVertex * _ScanTiling + _Time.w * _ScanSpeed), 0.5) * 0.65;
#endif
col.a = texColor.a * _Alpha * (scan);
col.rgb *= _Brightness;
return col;
}
ENDCG
}
}
CustomEditor "HologramShaderGUI"
}
Second version lerps between the cylinder color and a pulse color based on time and the uv of the pixel, using a truncated sine curve:
Shader "SFHologram/HologramShader"
{
Properties
{
// General
_Exp("Exp", Range(0, 16)) = 1
_Brightness("Brightness", Range(0.1, 6.0)) = 3.0
_Alpha("Alpha", Range(0.0, 100)) = 1.0
_Direction("Direction", Vector) = (0,1,0,0)
// Main Color
_MainTex("MainTexture", 2D) = "white" {}
_MainColor("MainColor", Color) = (1,1,1,100)
// Pulse
_PulseColor("Pulse Color", Color) = (1, 0.3, 0.3, 1)
_PulseLength("Pulse Length", Float) = 0.5
_PulseFreq("Pulse Frequency",Float) = 20.0
_PulseSpeed("Pulse Speed", Float) = -4.0
_PulseGradient("Pulse Gradient", Float) = 0.8
// Scanline
_ScanTiling("Scan Tiling", Range(0.01, 10.0)) = 0.05
_ScanSpeed("Scan Speed", Range(-2.0, 2.0)) = 1.0
_ScanColor("ScanColor", Color) = (255,1,1,1)
// Glow
_GlowTiling("Glow Tiling", Range(0.01, 1.0)) = 0.05
_GlowSpeed("Glow Speed", Range(-10.0, 10.0)) = 1.0
// Glitch
_GlitchSpeed("Glitch Speed", Range(0, 50)) = 1.0
_GlitchIntensity("Glitch Intensity", Float) = 0
// Alpha Flicker
_FlickerTex("Flicker Control Texture", 2D) = "white" {}
_FlickerSpeed("Flicker Speed", Range(0.01, 100)) = 1.0
// Settings
[HideInInspector] _Fold("__fld", Float) = 1.0
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
LOD 100
ColorMask RGB
Cull Back
Pass
{
CGPROGRAM
#pragma shader_feature _SCAN_ON
#pragma shader_feature _GLOW_ON
#pragma shader_feature _GLITCH_ON
#pragma vertex vert
#pragma fragment frag
float _Exp;
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float4 worldVertex : TEXCOORD1;
float3 viewDir : TEXCOORD2;
float3 worldNormal : NORMAL;
};
sampler2D _MainTex;
sampler2D _FlickerTex;
float4 _Direction;
float4 _MainTex_ST;
float4 _MainColor;
float4 _ScanColor;
float4 _PulseColor;
float _PulseLength;
float _PulseFreq;
float _PulseSpeed;
float _PulseGradient;
float _RimChangeRate;
float _GlitchSpeed;
float _GlitchIntensity;
float _Brightness;
float _Alpha;
float _ScanTiling;
float _ScanSpeed;
float _GlowTiling;
float _GlowSpeed;
float _FlickerSpeed;
fixed4 _TopColor;
fixed4 _BottomColor;
v2f vert(appdata v)
{
v2f o;
// Glitches
#if _GLITCH_ON
v.vertex.x += _GlitchIntensity * (step(0.5, sin(_Time.y * 2.0 + v.vertex.y * 1.0)) * step(0.99, sin(_Time.y*_GlitchSpeed * 0.5)));
#endif
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldVertex = mul(unity_ObjectToWorld, v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.viewDir = normalize(WorldSpaceViewDir(v.vertex));
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 texColor = tex2D(_MainTex, i.uv);
fixed4 randomColor = fixed4(255,0,0,0);
half dirVertex = (dot(i.worldVertex, normalize(float4(_Direction.xyz, 1.0))) + 1) / 2;
// Glow
float glow = 0.0;
#ifdef _GLOW_ON
glow = frac(dirVertex * _GlowTiling - _Time.x * _GlowSpeed);
#endif
// Flicker
fixed4 flicker = tex2D(_FlickerTex, _Time * _FlickerSpeed);
float4 col = (texColor * _MainColor + (glow * 0.35 * _MainColor));
float pulseIntensity = saturate(sin((i.uv.y / _PulseLength - _Time.x*_PulseSpeed) * _PulseFreq) * _PulseGradient);
col = lerp(col, _PulseColor, pulseIntensity);
// Scanlines
float scan = 1.0;
#ifdef _SCAN_ON
scan = step(frac(dirVertex * _ScanTiling + _Time.w * _ScanSpeed), 0.5) * 0.65;
#endif
col.a = texColor.a * _Alpha * (scan);
col.rgb *= _Brightness;
return col;
}
ENDCG
}
}
CustomEditor "HologramShaderGUI"
}
You can test it by creating a fresh project/scene with that shader attached to the holoShader
field in this script placed on the main camera, and using the scene view to navigate the scene:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestScript : MonoBehaviour
{
public Shader holoShader;
private void Start()
{
Material mat = new Material(holoShader);
mat.SetFloat("_Brightness", 1f);
mat.SetColor("_MainColor", new Color(0.9f, 1f, 1f));
mat.SetColor("_PulseColor", new Color(0.9f, .8f, .4f));
GameObject pillar1 = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
pillar1.transform.localScale = new Vector3(0.3f, 20.0f, 0.3f);
pillar1.transform.position = new Vector3(-1f, 5f, 5f);
pillar1.GetComponent<Renderer>().material = mat;
GameObject pillar2 = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
pillar2.transform.localScale = new Vector3(0.5f, 40.0f, 0.5f);
pillar2.transform.position = new Vector3(2f, 13f, 8f);
pillar2.GetComponent<Renderer>().material = mat;
}
}