Shader "Cielonos/MeshEffects/Freeze" { Properties { [Header(Base Settings)] [MainColor] _BaseColor("Base Color", Color) = (0.5, 0.8, 1, 0.3) [MainTexture] _BaseMap("Ice Texture (RGB)", 2D) = "white" {} [Header(Normal Map)] _NormalMap("Normal Map", 2D) = "bump" {} _NormalScale("Normal Scale", Range(0, 2)) = 1.0 [Header(Distortion and Flow)] _DistortionMap("Distortion/Flow Map", 2D) = "white" {} _DistortionStrength("Distortion Strength", Range(0, 1)) = 0.1 _FlowSpeed("Flow Speed (X, Y)", Vector) = (0.1, 0.1, 0, 0) [Header(Fresnel Effect)] [HDR] _FresnelColor("Fresnel Color", Color) = (0.8, 0.9, 1, 1) _FresnelPower("Fresnel Power", Range(0.1, 10)) = 4.0 _FresnelScale("Fresnel Strength", Range(0, 5)) = 1.5 [Header(Transparency)] _AlphaScale("Alpha Scale", Range(0, 2)) = 1.0 } SubShader { Tags { "RenderType" = "Transparent" "Queue" = "Transparent" "RenderPipeline" = "UniversalPipeline" "IgnoreProjector" = "True" } Blend SrcAlpha OneMinusSrcAlpha ZWrite Off Cull Back Pass { Name "ForwardLit" Tags { "LightMode" = "UniversalForward" } HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; float2 uv : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; float3 positionWS : TEXCOORD1; float3 normalWS : TEXCOORD2; float4 tangentWS : TEXCOORD3; // xyz: tangent, w: sign float3 viewDirWS : TEXCOORD4; float2 uv : TEXCOORD0; }; CBUFFER_START(UnityPerMaterial) float4 _BaseColor; float4 _BaseMap_ST; float4 _DistortionMap_ST; float4 _FresnelColor; float4 _FlowSpeed; float _FresnelPower; float _FresnelScale; float _NormalScale; float _AlphaScale; float _DistortionStrength; CBUFFER_END TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap); TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap); TEXTURE2D(_DistortionMap); SAMPLER(sampler_DistortionMap); Varyings vert(Attributes input) { Varyings output; VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); output.positionCS = vertexInput.positionCS; output.positionWS = vertexInput.positionWS; // Configure Normal & Tangent (Pass to Fragment for TBN) VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS); output.normalWS = normalInput.normalWS; output.tangentWS = float4(normalInput.tangentWS, input.tangentOS.w * GetOddNegativeScale()); output.viewDirWS = GetWorldSpaceNormalizeViewDir(output.positionWS); output.uv = TRANSFORM_TEX(input.uv, _BaseMap); return output; } half4 frag(Varyings input) : SV_Target { // 1. Calculate Distortion UV float2 flowOffset = _Time.y * _FlowSpeed.xy; // Sample distortion map with scrolling UVs float2 distortionUV = input.uv * _DistortionMap_ST.xy + _DistortionMap_ST.zw + flowOffset; half4 distortionSample = SAMPLE_TEXTURE2D(_DistortionMap, sampler_DistortionMap, distortionUV); // Remap 0..1 to -1..1 for direction float2 distortion = (distortionSample.rg * 2.0 - 1.0) * _DistortionStrength; // 2. Apply Distortion to Main UV float2 finalUV = input.uv + distortion; // 3. Normal Map Calculation float3 viewDirWS = SafeNormalize(input.viewDirWS); float3 normalWS = SafeNormalize(input.normalWS); float3 tangentWS = SafeNormalize(input.tangentWS.xyz); float3 bitangentWS = cross(normalWS, tangentWS) * input.tangentWS.w; // Construct TBN Matrix float3x3 TBN = float3x3(tangentWS, bitangentWS, normalWS); // Sample Normal Map with distorted UV float3 normalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, finalUV), _NormalScale); // Transform to World Space float3 finalNormalWS = mul(normalTS, TBN); finalNormalWS = SafeNormalize(finalNormalWS); // 4. Sample Main Texture with distorted UV half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, finalUV); // 5. Fresnel Calculation using the Normal Map normal float NdotV = saturate(dot(finalNormalWS, viewDirWS)); float fresnelTerm = pow(1.0 - NdotV, _FresnelPower); float3 fresnel = _FresnelColor.rgb * fresnelTerm * _FresnelScale; // 6. Combine float3 albedo = _BaseColor.rgb * texColor.rgb; float3 finalColor = albedo + fresnel; float alpha = (_BaseColor.a * texColor.a) + (fresnelTerm * _FresnelColor.a); alpha = saturate(alpha * _AlphaScale); return half4(finalColor, alpha); } ENDHLSL } } }