Shader "Cielonos/MeshEffects/Burn" { Properties { [Header(Base Settings)] [MainColor] _BaseColor("Base Color", Color) = (0.2, 0.05, 0.05, 1) [MainTexture] _BaseMap("Char/Ash Texture (RGB)", 2D) = "white" {} [Header(Normal Map)] _NormalMap("Normal Map", 2D) = "bump" {} _NormalScale("Normal Scale", Range(0, 2)) = 1.0 [Header(Emission and Magma)] [HDR] _EmissionColor("Emission Color", Color) = (3, 1, 0, 1) _EmissionMap("Magma/Glow Pattern (RGB)", 2D) = "white" {} _EmissionPower("Emission Power", Range(0, 10)) = 1.0 _EmissionFlowSpeed("Magma Flow Speed (X, Y)", Vector) = (0.1, 0.5, 0, 0) [Header(Distortion and Heat Haze)] _DistortionMap("Distortion/Noise Map", 2D) = "white" {} _DistortionStrength("Distortion Strength", Range(0, 1)) = 0.05 _DistortionSpeed("Distortion Scroll (X, Y)", Vector) = (0.1, 0.1, 0, 0) [Header(Fresnel Effect)] [HDR] _FresnelColor("Fresnel Color", Color) = (4, 1.5, 0.2, 1) _FresnelPower("Fresnel Power", Range(0.1, 10)) = 3.0 _FresnelScale("Fresnel Strength", Range(0, 5)) = 2.0 [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; float3 viewDirWS : TEXCOORD4; float2 uv : TEXCOORD0; }; CBUFFER_START(UnityPerMaterial) float4 _BaseColor; float4 _BaseMap_ST; float4 _EmissionMap_ST; float4 _DistortionMap_ST; float4 _EmissionColor; float4 _FresnelColor; float4 _EmissionFlowSpeed; float4 _DistortionSpeed; float _EmissionPower; float _FresnelPower; float _FresnelScale; float _NormalScale; float _AlphaScale; float _DistortionStrength; CBUFFER_END TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap); TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap); TEXTURE2D(_EmissionMap); SAMPLER(sampler_EmissionMap); 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; 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); // Pass base UV output.uv = TRANSFORM_TEX(input.uv, _BaseMap); return output; } half4 frag(Varyings input) : SV_Target { // 1. Calculate Distortion (Heat Haze) float2 distOffset = _Time.y * _DistortionSpeed.xy; float2 distUV = input.uv * _DistortionMap_ST.xy + _DistortionMap_ST.zw + distOffset; half4 distSample = SAMPLE_TEXTURE2D(_DistortionMap, sampler_DistortionMap, distUV); float2 distortion = (distSample.rg * 2.0 - 1.0) * _DistortionStrength; // 2. Base UVs with Distortion float2 distortedUV = input.uv + distortion; // 3. Normal Map Logic float3 viewDirWS = SafeNormalize(input.viewDirWS); float3 normalWS = SafeNormalize(input.normalWS); float3 tangentWS = SafeNormalize(input.tangentWS.xyz); float3 bitangentWS = cross(normalWS, tangentWS) * input.tangentWS.w; float3x3 TBN = float3x3(tangentWS, bitangentWS, normalWS); float3 normalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, distortedUV), _NormalScale); float3 finalNormalWS = mul(normalTS, TBN); finalNormalWS = SafeNormalize(finalNormalWS); // 4. Sample Base Map (Charcoal) half4 baseTex = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, distortedUV); float3 albedo = _BaseColor.rgb * baseTex.rgb; // 5. Sample Emission Map (Magma flow) // We add separate scrolling for magma on TOP of the distortion float2 emissionFlow = _Time.y * _EmissionFlowSpeed.xy; float2 emissionUV = (input.uv * _EmissionMap_ST.xy + _EmissionMap_ST.zw) + emissionFlow + distortion; half4 emissionTex = SAMPLE_TEXTURE2D(_EmissionMap, sampler_EmissionMap, emissionUV); // Calculate Emission Intensity // If EmissionMap is grayscale, we colorize it. float3 emission = emissionTex.rgb * _EmissionColor.rgb * _EmissionPower; // 6. Fresnel (Rim Light - Glowing Edges) float NdotV = saturate(dot(finalNormalWS, viewDirWS)); float fresnelTerm = pow(1.0 - NdotV, _FresnelPower); float3 fresnel = _FresnelColor.rgb * fresnelTerm * _FresnelScale; // 7. Combine // Base (Dark) + Emission (Bright) + Fresnel (Rim) float3 finalColor = albedo + emission + fresnel; // 8. Alpha Calculation // Base alpha + slightly additive emission/fresnel alpha to ensure glowing parts are visible float alpha = (_BaseColor.a * baseTex.a) + (emissionTex.r * 0.5) + (fresnelTerm * _FresnelColor.a * 0.5); alpha = saturate(alpha * _AlphaScale); return half4(finalColor, alpha); } ENDHLSL } } }