Shader "Unlit/HeatTest" { Properties { //_MainTex ("Texture", 2D) = "white" {} _RampTexture ("_RampTexture", 2D) = "white" {} _UFtexture ("_UFtexture", 2D) = "white" {} _Memorytexture ("_Memorytexture", 2D) = "white" {} _Eyetexture ("_Eyetexture", 2D) = "white" {} _Emotexture ("_Emotexture", 2D) = "white" {} _Logictexture ("_Logictexture", 2D) = "white" {} _Speaktexture ("_Speaktexture", 2D) = "white" {} _headtexture ("_headtexture", 2D) = "white" {} _Temtupre("_Temtupre", float) = 0 // 世界空间中的中心 _ColdBaseColor ("Cold Base Color", Color) = (0.005, 0.02, 0.55, 1) _ColdHighlightColor ("Cold Highlight Color", Color) = (0, 0.3, 1, 1) _ColdNoiseScale ("Cold Noise Scale", Float) = 1.8 _ColdNoiseStrength ("Cold Noise Strength", Range(0, 1)) = 0.45 } SubShader { Tags {"Queue"="Transparent" "RenderType"="Transparent"} Blend SrcAlpha OneMinusSrcAlpha // 设置混合模式为标准透明 LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; //float2 uv : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float3 worldPos : TEXCOORD0; // 用于传递世界空间坐标 }; float3 _Center; // 世界空间中心点,使用 float3 float2 _BoxSize; // 可以调整为 float3,如果需要 //float4 _Time; sampler2D _RampTexture; sampler2D _Noise; uniform float4 _Points[7]; // (x, y) = center z = tempture uniform float4 _Properties[7]; // (x,y) = boxsize sampler2D _UFtexture; sampler2D _Memorytexture; sampler2D _Eyetexture ; sampler2D _Emotexture; sampler2D _Logictexture ; sampler2D _Speaktexture; sampler2D _headtexture; float _Temtupre; fixed4 _ColdBaseColor; fixed4 _ColdHighlightColor; float _ColdNoiseScale; float _ColdNoiseStrength; inline float unity_noise_randomValue (float2 uv) { return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453); } inline float unity_noise_interpolate (float a, float b, float t) { return lerp(a, b, t); } inline float unity_valueNoise (float2 uv) { float2 i = floor(uv); float2 f = frac(uv); f = f * f * (3.0 - 2.0 * f); float2 c0 = i; float2 c1 = i + float2(1.0, 0.0); float2 c2 = i + float2(0.0, 1.0); float2 c3 = i + float2(1.0, 1.0); float r0 = unity_noise_randomValue(c0); float r1 = unity_noise_randomValue(c1); float r2 = unity_noise_randomValue(c2); float r3 = unity_noise_randomValue(c3); float bottom = unity_noise_interpolate(r0, r1, f.x); float top = unity_noise_interpolate(r2, r3, f.x); return unity_noise_interpolate(bottom, top, f.y); } float Unity_SimpleNoise(float2 UV, float Scale) { float noise = 0.0; float amplitude = 0.5; float frequency = 1.0; // 简化循环叠加不同频率的噪波层次 for (int i = 0; i < 3; i++) { noise += unity_valueNoise(UV * Scale * frequency) * amplitude; frequency *= 2.0; amplitude *= 0.5; } return noise; } float remap(float x, float a, float b, float c, float d) { return c + (x - a) * (d - c) / (b - a); } float GetAlphaForTexture(int j, float2 localPos) { if (j == 0) return tex2D(_UFtexture, localPos).a; else if (j == 1) return tex2D(_Memorytexture, localPos).a; else if (j == 2) return tex2D(_Eyetexture, localPos).a; else if (j == 3) return tex2D(_Emotexture, localPos).a; else if (j == 4) return tex2D(_Logictexture, localPos).a; else if (j == 5) return tex2D(_Speaktexture, localPos).a; return 0.0; } v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); // 计算并传递世界空间坐标 o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; return o; } fixed4 frag (v2f i) : SV_Target { float3 worldPos = i.worldPos; // 热成像的无热源区域仍有环境温度,用细微流动的深蓝代替纯黑。 float2 coldNoiseUV = worldPos.xy + float2(_Time.y * 0.012, -_Time.y * 0.009); float coldNoise = Unity_SimpleNoise(coldNoiseUV, _ColdNoiseScale); float coldVariation = saturate(0.18 + coldNoise * _ColdNoiseStrength); fixed4 coldColor = lerp(_ColdBaseColor, _ColdHighlightColor, coldVariation); fixed4 col = coldColor; bool isFind = false; float2 pointPos = _Points[6].xy; float temperature = _Points[6].z; float2 boxSize = _Properties[6].xy; float2 localPos = (worldPos.xy - pointPos) / boxSize + 0.5; float backalpha = tex2D(_headtexture, localPos).a; backalpha *= (temperature); backalpha = clamp(backalpha, 0, 1); backalpha = 1 - backalpha; //backalpha = 0.7; for (int j = 0; j < 6; j++) { float2 pointPos = _Points[j].xy; float temperature = _Points[j].z; float2 boxSize = _Properties[j].xy; float2 localPos = (worldPos.xy - pointPos) / boxSize + 0.5; //float alpha = GetAlphaForTexture(j, localPos); if (localPos.x >= 0.0 && localPos.x <= 1.0 && localPos.y >= 0.0 && localPos.y <= 1.0) { isFind = true; float alpha = GetAlphaForTexture(j, localPos); alpha *= temperature; alpha = clamp(alpha, 0, 1); alpha = 1 - alpha; alpha = clamp(alpha, 0, backalpha); fixed4 rampColor = tex2D(_RampTexture, float2(alpha, 0)); // 保留原有色带映射,只把接近黑色的冷端替换为蓝色。 float brightestChannel = max(rampColor.r, max(rampColor.g, rampColor.b)); float blackMask = 1.0 - smoothstep(0.035, 0.12, brightestChannel); col = lerp(rampColor, coldColor, blackMask); } } // If no point is found, use the default texture (headtexture) if (!isFind) { float2 pointPos = _Points[6].xy; float temperature = _Points[6].z; float2 boxSize = _Properties[6].xy; float2 localPos = (worldPos.xy - pointPos) / boxSize + 0.5; if (localPos.x >= 0.0 && localPos.x <= 1.0 && localPos.y >= 0.0 && localPos.y <= 1.0) { float alpha = tex2D(_headtexture, localPos).a; alpha *= (temperature - 0.4); alpha = clamp(alpha, 0, 1); alpha = 1 - alpha; //alpha=bl alpha=backalpha; fixed4 rampColor = tex2D(_RampTexture, float2(alpha, 0)); float brightestChannel = max(rampColor.r, max(rampColor.g, rampColor.b)); float blackMask = 1.0 - smoothstep(0.035, 0.12, brightestChannel); col = lerp(rampColor, coldColor, blackMask); } } col.a = 1; return col; } ENDCG } } }