制作OBS位移滤镜遇阻:光照图驱动像素位移失效求助
解决OBS滤镜顶点着色器采样纹理失效问题
问题核心
你遇到的问题本质是顶点着色器阶段无法直接采样纹理,这并非代码逻辑错误,而是HLSL渲染管线与OBS滤镜框架的资源限制导致的。
失效原因
- OBS滤镜框架默认仅将输入纹理(源图像、光照图等)绑定到像素着色器阶段,顶点着色器无法访问这些纹理资源,一旦尝试采样就会触发管线错误,直接导致滤镜加载失败(连参数面板都无法显示)。
- 退一步讲,顶点着色器是按顶点执行的,每个顶点的UV是网格顶点的UV,并非逐像素的UV,就算能采样,得到的也只是顶点位置的纹理值,无法实现你需要的逐像素位移效果。
正确实现方案:在像素着色器中修改UV实现位移
逐像素位移效果本来就该放在像素着色器中完成,通过修改源图像的采样UV坐标来实现位移,这是行业常规做法,也完全适配OBS滤镜框架。
修改后的代码示例:
float4 get_displacement(float2 position) { float2 pattern_uv = position / pattern_size; float4 pattern_sample = pattern_texture.Sample(linear_wrap, pattern_uv / scale); return pattern_sample; } float4 pixel_shader(pixel_data pixel) : TARGET { float4 source_sample = image.Sample(linear_wrap, pixel.uv); if (pattern_size.x <= 0){ return source_sample; } // 获取当前像素对应的光照图采样值 float2 position = pixel.uv * float2(width, height); float4 lightmap = get_displacement(position); // 根据光照图红色通道值修改UV,实现水平位移(0.1为缩放因子,可改为参数控制幅度) float2 displaced_uv = pixel.uv + float2(lightmap.r * 0.1, 0); // 采样位移后的源图像 float4 displaced_sample = image.Sample(linear_wrap, displaced_uv); // 保留光照图控制的Alpha值 return float4(displaced_sample.rgb, lightmap.r); }
若坚持使用顶点着色器(不推荐)
如果是要做大面积网格顶点变形(如整体画面扭曲),需要手动配置纹理资源的绑定权限:
- 在滤镜的
obs_source_info中,确保纹理的bind_flags包含D3D11_BIND_VERTEX_SHADER_RESOURCE。 - 在HLSL代码中,将纹理声明为
Texture2D<float4> : register(t0);,确保顶点着色器能访问对应寄存器。
但这种方案仅适合宏观变形,无法实现你预期的逐像素精细位移效果。
内容的提问来源于stack exchange,提问作者OliCo
相关产品推荐
相关产品推荐

