Unity3D HLSL Shader热编辑后UV异常无限镜像问题求助
问题描述
之前能正常实时更新HLSL Shader代码,但近期每次热编辑Shader后,挂载该Shader的所有平面都会出现UV错乱,呈现无限镜像效果。已将Shader精简至最简结构,甚至回滚到之前可正常运行的代码版本,问题仍未解决。
硬编码颜色值可正常显示,推测可能是材质/纹理相关问题,但从未使用过sharedMaterial。
运行环境
- Windows 11
- Unity 2021.3.8f1
最简Shader代码
Shader "Custom/MapTile" { SubShader{ Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; struct test_appdata { float4 pos : POSITION; float2 uv : TEXCOORD0; float4 normal : NORMAL; }; struct test_v2f { float4 pos : SV_POSITION; half2 uv : TEXCOORD0; }; test_v2f vert(test_appdata v) { test_v2f o; o.pos = UnityObjectToClipPos(v.pos); o.uv = v.uv; return o; } float4 frag(test_v2f i) : COLOR { return tex2D(_MainTex, i.uv); } ENDHLSL } } FallBack "VertexLit" }
问题前后对比
- 编辑Shader前的地图:

- 编辑Shader后的地图:

疑问
该问题产生的原因是什么?该如何解决?
可能原因及解决方案
1. Unity 2021.3.x 热重载的UV缓存Bug
Unity 2021.3系列部分版本存在Shader热重载时,纹理采样器的UV寻址模式被意外重置的问题——即便Shader代码未指定寻址模式,热编辑后材质的纹理寻址会被自动改成Mirror(镜像),而非原本的Repeat或Clamp。
解决方法:
在Shader中显式声明纹理属性及采样器,避免热重载时Unity篡改参数:
Shader "Custom/MapTile" { // 新增属性块 Properties { _MainTex ("Main Texture", 2D) = "white" {} } SubShader{ Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" // 改用HLSL规范的纹理与采样器声明 TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); struct test_appdata { float4 pos : POSITION; float2 uv : TEXCOORD0; float4 normal : NORMAL; }; struct test_v2f { float4 pos : SV_POSITION; half2 uv : TEXCOORD0; }; test_v2f vert(test_appdata v) { test_v2f o; o.pos = UnityObjectToClipPos(v.pos); o.uv = v.uv; return o; } float4 frag(test_v2f i) : COLOR { // 使用对应采样器采样 return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); } ENDHLSL } } FallBack "VertexLit" }
2. 材质实例的隐形缓存污染
即便未调用sharedMaterial,Unity热重载Shader时仍可能意外修改材质实例的内部缓存,导致UV采样参数异常。
解决方法:
- 热编辑Shader后,手动选中所有挂载该材质的对象,在Inspector面板中重新选择一次纹理,或点击材质的
Reimport按钮强制刷新参数; - 若问题频繁出现,可在
Project Settings -> Graphics中关闭Shader Hot Reload选项,改用手动点击Shader的Reimport按钮编译,规避热重载Bug。
3. Windows 11文件系统缓存干扰
Windows 11的快速文件访问缓存可能导致Unity读取Shader编译后的缓存文件异常,进而影响材质参数。
解决方法:
- 打开
Edit -> Preferences -> Cache Server,点击Clear Cache清理Unity缓存; - 删除项目目录下的
Library文件夹(删除前备份项目),重新打开项目让Unity重新生成缓存。
内容的提问来源于stack exchange,提问作者Jacksonkr
相关产品推荐
相关产品推荐

