Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
To keep snippets of code for Shaders. Just some stuff that I often use but also often forget because brain=poo
//https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html
//https://github.com/TwoTailsGames/Unity-Built-in-Shaders/blob/master/CGIncludes/UnityCG.cginc - Most interesting stuff ;)
//https://github.com/TwoTailsGames/Unity-Built-in-Shaders/tree/master/CGIncludes
//https://docs.unity3d.com/Manual/SL-Shader.html
//http://developer.download.nvidia.com/CgTutorial/cg_tutorial_appendix_e.html
//https://unity3d.com/how-to/shader-profiling-and-optimization-tips
//https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html
//http://www.deepskycolors.com/archive/2010/04/21/formulas-for-Photoshop-blending-modes.html
//http://www.iquilezles.org/blog/
//https://www.youtube.com/channel/UCcAlTqd9zID6aNX3TzwxJXg
//Properties
[PerRendererData][NoScaleOffset]_MainTex("Albedo", 2D) = "white" {}
// Image UI elements throw error in Build if Material(It's Shader) doesn't have _MainTex, so keep it here even if not used.
// [PerRendererData] - For UI, to hide it from material inspector;
// [NoScaleOffset] - To Hide scale and offset editing window - usefult if the are not utilized in shader
// Alternative Default Values: "white", "black", "gray", "bump", "red"
_Color("Color", Color) = (1,1,1,1)
_SomeSlider("Reflectiveness or something", Range(0,1)) = 0
[HideInInspector]_ProjTexPos("Screen Space Position", Vector) = (0,0,0,0)
// [HideInInspector] - no need to show this in inspector
_Test("Any value", float) = 1
// MULTICOMPILE & SHADER FEATURE
[KeywordEnum(None, Regular, Combined)] _BUMP ("Bump Map", Float) = 0
#pragma shader_feature ___ _BUMP_NONE _BUMP_REGULAR _BUMP_COMBINED
//Toggle
[Toggle(_BLABLA)] thisDoesntMatter ("Some Bla Bla BLa", Float) = 0
#pragma multi_compile ____ _BLABLA // Will Build all variations. (For changing via script) (___ = Also compile a version without any defines )
#pragma shader_feature _FEATUREA _FEATUREB // Will Build only used variations. (To configure materials in Editor only)
//Management
// From script you can set this keywords
renderer.material.EnableKeyword("_BLABLABLA");
// or globally (Shader shouldn't have it in it's properties to read the global value)
Shader.EnableKeyword("_BLABLABLA")
//*****COMMON OPERATORS/FUNCTIONS*****
fwidth(x), ddx(x), ddy(x) // The only operation that lets you get info from pixels "Next Door". It tells how diffrent (+-) X is in the next pixel.
y = saturate(x); // Clamp x between 0 and 1
floor(); // return smallest int part
x % 1 // get fraction part
log(Y)/log(X); // LOGxY (LOGxY = Z | means that X to the power of Z equals Y | Log base X of Y is the power you need to raise X to get Y)
atan(x,y) // returns an angle in [-Pi +Pi] range)
smoothstep (a, b , t); // Basically allows us to remap t from ab space to 01 space but with smoothing;
// Returns 0 if t<a<b; 1 if t>b>a, interpolates in-between; Will reverse if b<a;
x*x*(3.0 - (2.0*x)); // To apply smoothing when 0<=x<=1. (When applied to the function below will produce smoothstep).
sharpstep(a, b, x) => saturate((x - a)/(b - a)); // Remap X to [A,B] sharply.
float cheapstep(float x) { // https://www.shadertoy.com/view/4ldSD2
x = 1.0 - x*x; // MAD
x = 1.0 - x*x; // MAD
return x;
}
step(a, x) // returns 1 if x>a, 0 - otherwise
//*****COOL MATH*****
// Random ()Hash
float hash11(float p) {
p = fract(p * .1031);
p *= p + 33.33;
p *= p + p;
return fract(p);
}
// Distance to a line:
inline float DistToLine(float3 pos, float3 a, float3 b) {
float3 pa = pos - a;
float3 ba = b - a;
float t = saturate(dot(pa, ba)/dot(ba,ba));
return length(pa - ba * t);
}
// Rotation (Pivot in center)
float2 Rot(float2 uv, float angle) {
float si = sin(angle);
float co = cos(angle);
return float2(co * uv.x - si * uv.y, si * uv.x + co * uv.y);
}
// Get Angle:
float angle = (atan2(uv.x, uv.y) + pii) / pi2
// Get Angle in 01 space
const float PI2 = 3.14159265359 * 2;
float angle = atan2(-uv.x, -uv.y)+0.001;
angle = saturate(max(angle,
PI2 + min(0, angle)
- max(0, angle*999999)
)/ PI2);
// Cos/Sin to 01 space
float lerp = (_CosTime.z + 1) * 0.5; // Time.x,y,z,w - from slowest to fastest
//*****SAMPLING*****
// Screen Position
float4 screenPos : TEXCOORD1; // v2f (TEXCOORD can be 0,1,2, etc - the obly rule is to avoid duplication)
o.screenPos = ComputeScreenPos(o.pos); // vert
float2 screenUV = i.screenPos.xy / i.screenPos.w; // frag (Returns in 01 range (if on screen))
// To Apply Offset
//#define TRANSFORM_TEX(uv,_NameTex) (uv.xy * _NameTex_ST.xy + _NameTex_ST.zw)
uv = uv*_MainTex_ST.xy + _MainTex_ST.zw; // _MainTex_ST needs to be defined in the variables section (not the Parameters section)
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); // Tile Offset needs to be declared (the line above)
// To do POINT Sampling (undo bilinear filtering):
float4 _MainTex_TexelSize; // Texture Size (zw = width,heigth ; xy = 1/width, 1/height)
float2 pointUV = (floor(uv * _MainTex_TexelSize.zw) + 0.5) * _MainTex_TexelSize.xy;
// Smooth Pixelation Sampling (Looks really cool)
const float sharpness = 40;
float2 perfTex = (floor(IN.uv_MainTex.xy*_MainTex_TexelSize.z) + 0.5) * _MainTex_TexelSize.x;
float2 off = (IN.uv_MainTex.xy - perfTex);
float2 diff = (abs(off) * _MainTex_TexelSize.z);
float2 edge = saturate((diff * 2 - 1)*sharpness + 1);
perfTex += off * edge;
float2 diff = (abs(off) * _MainTex_TexelSize.z);
// To Also get the border:
edge = saturate((diff * 2 - 1)*sharpness*0.1 + 1); // In some usages the are between pixels contains other pixels, then border needs to be less sharp to fully cover that area.
float border = max(edge.x, edge.y);
// To Get MipLevel
_MainTex_TexelSize.zw *= modifier; // Optional
float2 px = _MainTex_TexelSize.z * ddx(uv);
float2 py = _MainTex_TexelSize.w * ddy(uv);
return (max(0, 0.5 * log2(max(dot(px, px), dot(py, py)))));
// Lerp between two transparent textures
float rgbLerp = col2.a*lerp;
rgbLerp = saturate(rgbLerp * 2 / (col.a + rgbLerp + 0.0001)); // Add some value to avoid division by 0
col.a = col2.a * lerp + col.a * (1 - lerp);
col.rgb = col2.rgb * rgbLerp + col.rgb * (1 - rgbLerp);
// Parallax
//vert:
float3x3 objectToTangent = float3x3(
v.tangent.xyz,
cross(v.normal, v.tangent.xyz) * v.tangent.w,
v.normal
);
tangentViewDir = mul(objectToTangent, ObjSpaceViewDir(v.vertex));
//frag
tangentViewDir = normalize(tangentViewDir);
i.tangentViewDir.xy /= (i.tangentViewDir.z + 0.42);
i.uv.xy += tangentViewDir.xy;
//********** SCREEN SPACE EFFECTS
// Tile a square to fill the screen:
//f2v
float2 screenParams : TEXCOORD1;
float4 screenPos : TEXCOORD2;
//vert:
o.screenParams = float2(max(_ScreenParams.x / _ScreenParams.y, 1), max(1, _ScreenParams.y / _ScreenParams.x));
o.screenPos = ComputeScreenPos(o.pos);
//frag:
i.screenPos.xy /= i.screenPos.w;
float2 fitToScreen = i.screenPos.xy * i.screenParams;
float4 col = tex2D(_MainTex, fitToScreen * tilsesCount);
// Fit Sprite Sampling to Fill Screen Without stretching the texture:
// In script (Could also be done in vert function):
float screenAspect = ((float)Screen.width) / Screen.height;
float texAspect = ((float)bgTex.width) / bgTex.height;
Vector2 aspectCorrection = Vector2.one;
if (screenAspect > texAspect)
aspectCorrection.y = (texAspect / screenAspect);
else
aspectCorrection.x = (screenAspect / texAspect);
// In Shader
float2 uv = (screenUV.xy - 0.5)*aspectCorrection.xy + 0.5;
// **** FOR LIGHT/COLOR SHADING
// View Direction
float3 viewDir : TEXCOORD0; //v2f
o.viewDir.xyz = (WorldSpaceViewDir(v.vertex)); // vert
i.viewDir.xyz = normalize(i.viewDir.xyz); //frag
// World Normal
o.normal.xyz = normalize(UnityObjectToWorldNormal(v.normal)); // vert
// World Position
float3 wpos : TEXCOORD3;
o.wpos = mul(unity_ObjectToWorld, v.vertex).xyz;
// ------- To Modify In World Space:
v.vertex += mul(unity_WorldToObject, offx,offy,offz, 0);
// Reflect:
float dotprod = max(0, dot(worldNormal, i.viewDir.xyz));
float3 reflected = normalize(i.viewDir.xyz - 2 * (dotprod)*worldNormal);
// Tangent Transformation:
float3 tspace0 : TEXCOORD3;
float3 tspace1 : TEXCOORD4;
float3 tspace2 : TEXCOORD5;
// ...... vert
float3 wTangent = UnityObjectToWorldDir(v.tangent.xyz);
float tangentSign = v.tangent.w * unity_WorldTransformParams.w;
float3 wBitangent = cross(wNormal, wTangent) * tangentSign;
o.tspace0 = half3(wTangent.x, wBitangent.x, wNormal.x);
o.tspace1 = half3(wTangent.y, wBitangent.y, wNormal.y);
o.tspace2 = half3(wTangent.z, wBitangent.z, wNormal.z);
// ..... frag
float3 tnormal = UnpackNormal(tex2D(_BumpMap, TRANSFORM_TEX(i.texcoord, _BumpMap)));
worldNormal.x = dot(i.tspace0, tnormal);
worldNormal.y = dot(i.tspace1, tnormal);
worldNormal.z = dot(i.tspace2, tnormal);
// Shadow
SHADOW_COORDS(2)
TRANSFER_SHADOW(o);
float shadow = SHADOW_ATTENUATION(i);
// Color Bleed (https://www.quizcanners.com/single-post/2018/04/02/Color-Bleeding-in-Shader)
float3 mix = col.gbr + col.brg;
col.rgb += mix * mix*amount;
// Color Light Bleed Effect
float3 mix = col.gbr + col.brg;
col.rgb += mix * mix*0.02; // Arbitrary value
@MostHated

This comment has been minimized.

Copy link

@MostHated MostHated commented Nov 13, 2019

This is great, thanks for sharing. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.