Skip to content

Instantly share code, notes, and snippets.

@undefined9071
Last active September 20, 2025 10:35
Show Gist options
  • Save undefined9071/e12b57665a1e83d6d71c99d9200db55c to your computer and use it in GitHub Desktop.
Save undefined9071/e12b57665a1e83d6d71c99d9200db55c to your computer and use it in GitHub Desktop.
ColumbinaVeilShining.shader
Shader "ColumbinaVeilShining"
{
Properties
{
_MainTex ("Alpha Mask", 2D) = "white" {}
_ShiningTiling ("Shining Tiling", Float) = 40.0
_ShiningSize ("Shining Size", Float) = 0.2
_ShiningSizeNear ("Shining Size Near", Float) = 1.0
_ShiningSizeFar ("Shining Size Far", Float) = 1.0
_ShiningFarNearBlend ("Shining Far Near Blend", Float) = 1.0
_ShiningMaxDistance ("Shining Max Distance", Float) = 1.0
_ShiningFrequencncy ("Shining Frequency", Float) = 2.85
_ShiningDensity ("Shining Density", Float) = 0.282
_ShiningIntensity ("Shining Intensity", Float) = 6.0
_ShiningColorBlend ("Shining Color Blend", Float) = 1.0
_ShiningColor ("Shining Color", Color) = (1,1,1,1)
}
SubShader
{
Tags
{
"RenderType" = "Transparent"
"Queue" = "Transparent"
"RenderPipeline" = "UniversalPipeline"
"UniversalMaterialType" = "Unlit"
"IgnoreProjector" = "True"
}
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
Cull Back
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
float4 positionHCS : SV_POSITION;
float3 positionWS : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
float _ShiningTiling;
float _ShiningSize;
float _ShiningSizeNear;
float _ShiningSizeFar;
float _ShiningFarNearBlend;
float _ShiningMaxDistance;
float _ShiningFrequencncy;
float _ShiningDensity;
float _ShiningIntensity;
float _ShiningColorBlend;
float4 _ShiningColor;
CBUFFER_END
Varyings vert (Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.positionHCS = vertexInput.positionCS;
output.positionWS = vertexInput.positionWS;
output.uv = TRANSFORM_TEX(input.uv, _MainTex);
return output;
}
half4 frag (Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half alphaMask = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv).a;
if (alphaMask < 0.99)
{
discard;
}
float3 cameraPos = GetCameraPositionWS();
float3 viewDir = cameraPos - input.positionWS;
float viewDistance = length(viewDir);
float normalizedDistance = saturate(viewDistance / _ShiningMaxDistance);
float blendFactor = saturate(normalizedDistance / _ShiningFarNearBlend);
float tilingNear = (2.0 - _ShiningSizeNear) * _ShiningTiling;
float tilingFar = (2.0 - _ShiningSizeFar) * _ShiningTiling;
float currentTiling = lerp(tilingNear, tilingFar, blendFactor);
float sizeNear = _ShiningSize * _ShiningSizeNear;
float sizeFar = _ShiningSize * _ShiningSizeFar;
float currentSize = lerp(sizeNear, sizeFar, blendFactor);
float2 tiledUV = currentTiling * input.uv;
// Get grid cell and fractional part
float4 gridCell = floor(tiledUV.xyxy);
float2 cellFraction = frac(tiledUV);
// 1st sparkle hash calculation
float4 hash1;
hash1.x = gridCell.z + 0.100000001;
hash1.y = gridCell.w + 0.100000001;
hash1.z = gridCell.z + 0.100000001;
hash1.w = gridCell.w + 0.100000001;
hash1 = hash1 * float4(0.103100002, 0.103, 0.0973000005, 0.0973000005);
hash1 = frac(hash1);
float4 hashAdd1 = hash1.wzxy + float4(33.3300018, 33.3300018, 33.3300018, 33.3300018);
float dotResult1 = dot(hash1, hashAdd1);
float3 hashSum1;
hashSum1.xyz = dotResult1 + hash1.xyz;
float2 offsetPattern1;
offsetPattern1.x = hashSum1.z * 0.618309915;
offsetPattern1.y = hashSum1.y * 0.618309915;
offsetPattern1 = hashSum1.xx * hashSum1.yy + offsetPattern1;
offsetPattern1 = frac(offsetPattern1);
// Convert to signed offset for 1st sparkle
float2 signedOffset = offsetPattern1 * 2.0 + float2(-1.0, -1.0);
// 2nd sparkle hash calculation with different pattern
float4 hash2;
hash2 = float4(gridCell.z * 0.0973000005, gridCell.w * 0.103, gridCell.z * 0.103100002, gridCell.w * 0.0973000005);
hash2 = frac(hash2);
float4 hashAdd2 = hash2.wxzy + float4(33.3300018, 33.3300018, 33.3300018, 33.3300018);
float dotResult2 = dot(hash2.zyxw, hashAdd2);
hash2 = dotResult2 + hash2;
float4 hashMult2 = hash2 * float4(0.618309915, 0.618309915, 0.618309915, 0.524999976);
hash2 = hash2.zzxx * hash2.yyww + hashMult2;
hash2 = frac(hash2);
// Calculate 1st sparkle
float2 sparkleOffset1 = cellFraction - hash2.xy;
float distanceSq1 = dot(sparkleOffset1, sparkleOffset1);
float sizeVariation1 = hash2.z + 0.5;
float sparkleRadius1 = currentSize * sizeVariation1;
float sparkleEdge1 = sparkleRadius1 - sqrt(distanceSq1);
sparkleRadius1 = sparkleRadius1 + 9.99999975e-06;
float sparkleFade1 = saturate(sparkleEdge1 / sparkleRadius1);
// Time anim for 1st sparkle
float densityFactor = 1.0 / _ShiningDensity;
float3 camScaled = cameraPos * float3(2.5, 2.5, 1.0);
float camMagnitude = length(camScaled);
float timeOffset1 = (1.0 - hash2.w) * densityFactor + camMagnitude;
float animationTime = _Time.y * _ShiningFrequencncy;
float timePhase1 = timeOffset1 * 6.28318548 + animationTime;
float timeSin1 = sin(timePhase1);
sparkleFade1 = sparkleFade1 * timeSin1;
float densityThreshold = 1.0 - _ShiningDensity;
float densityMask1 = (hash2.w >= densityThreshold) ? 1.0 : 0.0;
sparkleFade1 = sparkleFade1 * densityMask1;
sparkleFade1 = max(sparkleFade1, 0.0);
// 3rd sparkle calculation (using offset from 1st
float4 gridOffset = signedOffset.xyxy + gridCell;
float4 hash3 = gridOffset * float4(0.0973000005, 0.103, 0.103100002, 0.0973000005);
hash3 = frac(hash3);
float4 hashAdd3 = hash3.wxzy + float4(33.3300018, 33.3300018, 33.3300018, 33.3300018);
float dotResult3 = dot(hash3.zyxw, hashAdd3);
hash3 = dotResult3 + hash3;
float4 hashMult3 = hash3 * float4(0.618309915, 0.618309915, 0.618309915, 0.524999976);
hash3 = hash3.zzxx * hash3.yyww + hashMult3;
hash3 = frac(hash3);
// Calculate 2nd sparkle
float2 sparklePos2 = signedOffset + hash3.xy;
float2 sparkleOffset2 = cellFraction - sparklePos2;
float distanceSq2 = dot(sparkleOffset2, sparkleOffset2);
float sizeVariation2 = hash3.z + 0.5;
float sparkleRadius2 = currentSize * sizeVariation2;
float sparkleEdge2 = sparkleRadius2 - sqrt(distanceSq2);
sparkleRadius2 = sparkleRadius2 + 9.99999975e-06;
float sparkleFade2 = saturate(sparkleEdge2 / sparkleRadius2);
// Time animation for 2nd sparkle
float timeOffset2 = (1.0 - hash3.w) * densityFactor + camMagnitude;
float timePhase2 = timeOffset2 * 6.28318548 + animationTime;
float timeSin2 = sin(timePhase2);
sparkleFade2 = sparkleFade2 * timeSin2;
float densityMask2 = (hash3.w >= densityThreshold) ? 1.0 : 0.0;
sparkleFade2 = sparkleFade2 * densityMask2;
sparkleFade2 = max(sparkleFade2, 0.0);
float3 sparkleColor1 = hash3.xyz * sparkleFade2;
float3 sparkleColor2 = hash2.xyz * sparkleFade1;
float3 combinedSparkle = sparkleColor1 + sparkleColor2;
float3 finalIntensity = _ShiningIntensity * _ShiningColor.xyz;
combinedSparkle = combinedSparkle * finalIntensity;
float luminance = dot(combinedSparkle, float3(0.212500006, 0.715399981, 0.0720999986));
float3 luminanceColor = luminance * _ShiningColor.xyz - combinedSparkle;
combinedSparkle = _ShiningColorBlend * luminanceColor + combinedSparkle;
float finalAlpha = max(sparkleFade1, sparkleFade2);
return half4(combinedSparkle, finalAlpha);
}
ENDHLSL
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment