云计算百科
云计算领域专业知识百科平台

叶片浮雕:Sobel 梯度到伪法线

叶片浮雕:Sobel 梯度到伪法线:手账风封面

一张灰度叶片加上一点方向光,就会像压在纸里的浅浮雕。这个效果很好玩,但它没有从照片里恢复真实三维。更准确的说法是:把灰度当作人为指定的高度,再由邻域差分构造一张伪法线图。

从高度差开始

Sobel 的横、纵卷积核分别估计两个方向的变化。下面将结果除以 8,使单位斜坡的内点梯度接近 1,再乘上强度参数。法线取 (-gx,-gy,1) 后归一化,和同样归一化、从表面指向光源的光向量点乘,得到一个简化漫反射亮度。

内图黄色箭头画的是入射光线,与公式中从表面指向光源的 L 方向相反。坐标方向必须说清楚:图像 y 轴向下,光向量也用同一坐标约定。若一边把 y 当屏幕向下,另一边却当世界向上,阴影就会翻转。边界使用钳位采样,不会读取越界数据,但会造成边缘梯度和内点不同。

Canvas 像素接口可以接收最终像素数组。本例刻意先保留一维高度数组,不把图像读取、色彩管理和卷积混在一起。输入若来自 sRGB 照片,还需要决定灰度与高度的映射,不能默认亮的地方一定凸起。

用平面检查方向

纯常量图应该得到朝向正 z 的法线;沿 x 递增的平面,在内点应该得到负 x 分量。这样的例子比“看起来挺立体”更能暴露符号错误。下面生成一个高斯形小丘,只用于观看明暗;它不是植物组织模型,也没有环境遮蔽、镜面反射和投影。

运行 node relief.js 输出 relief.pgm。本地测试覆盖常量、斜坡、单位法线和边界索引,没有测试真实照片、GPU、浏览器上传与性能。把每一步留成独立函数,后面想换高度图或光照,才不会同时打破所有环节。

可独立运行的核心例子

const fs=require('node:fs');
function normalAt(a,w,h,x,y,strength=1) {
const sample=(dx,dy)=>a[Math.max(0,Math.min(h-1,y+dy))*w+Math.max(0,Math.min(w-1,x+dx))];
const gx=(-sample(-1,-1)+sample(1,-1)-2*sample(-1,0)+2*sample(1,0)-sample(-1,1)+sample(1,1))/8;
const gy=(-sample(-1,-1)-2*sample(0,-1)-sample(1,-1)+sample(-1,1)+2*sample(0,1)+sample(1,1))/8;
const v=[-gx*strength,-gy*strength,1],length=Math.hypot(…v);
return v.map(x=>x/length);
}
const flat=Array(25).fill(3),ramp=Array.from({length:25},(_,i)=>i%5);
if(normalAt(flat,5,5,2,2).join(',')!=='0,0,1')throw Error('平面错误');
const n=normalAt(ramp,5,5,2,2);
if(Math.abs(n[0]+1/Math.sqrt(2))>1e-9||Math.abs(Math.hypot(…n)-1)>1e-9)throw Error('梯度错误');
const w=64,h=64,a=Array.from({length:w*h},(_,i)=>10*Math.exp(-((i%w-32)**2+(Math.floor(i/w)-32)**2)/200));
const light=[-.5,-.5,1],ll=Math.hypot(…light),l=light.map(x=>x/ll);
const pixels=a.map((_,i)=>{
const n=normalAt(a,w,h,i%w,Math.floor(i/w),2);
const dot=n.reduce((sum,x,j)=>sum+x*l[j],0);
return Math.round(255*(.2+.8*Math.max(0,dot)));
});
if(pixels.some(x=>!Number.isFinite(x)||x<0||x>255))throw Error('灰度越界');
fs.writeFileSync('relief.pgm',`P2\\n${w} ${h}\\n255\\n`+pixels.join(' '));
console.log('已生成 relief.pgm');

内图借叶片说明流程;代码用高斯小丘验证法线,并未恢复叶片三维。

本文核心结构与边界示意

赞(0)
未经允许不得转载:网硕互联帮助中心 » 叶片浮雕:Sobel 梯度到伪法线
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!