自制简易的软光栅渲染器(1)
playerzhou
无回复
项目地址:https://github.com/OmegaZhou/SimpleRender er
绘制线段
Bresenham’s Line算法
- 首先要实现的就是在屏幕中画一条线,定义函数
drawLine(p1:Vector2,p2:Vector2,color:Color)
,其中p1
和p2
分别是线段的起点和终点 - Bresenham’s Line算法就不再阐述了,具体代码如下
drawLine(p1:Vector2,p2:Vector2,color:Color){
let x1=Math.round(p1.x);
let x2=Math.round(p2.x);
let y1=Math.round(p1.y);
let y2=Math.round(p2.y);
let steep=false
if(Math.abs(x1-x2)<Math.abs(y1-y2)){
[x1,y1]=[y1,x1];
[x2,y2]=[y2,x2];
steep=true;
}
if(x1>x2){
[x1,x2]=[x2,x1];
[y1,y2]=[y2,y1];
}
let dx=Math.abs(x2-x1);
let dy=Math.abs(y2-y1);
let derr=dy*2;
let dis=(y1<y2)?1:-1;
let error=0;
for(let x=x1,y=y1;x<=x2;++x){
if(steep){
this.setPixel(x,y,color)
}else{
this.setPixel(y,x,color)
}
error+=derr;
if(error>dx){
y+=dis;
error-=2*dx;
}
}
}
反走样
- 采用Bresenham’s Line算法实现了绘制之后,我发现对于斜线段,锯齿感明显
- 因此需要进行反走样操作,这里我采用的是对线段周围的像素进行模糊操作
- 我使用的模糊操作比较简单,直接令相应像素与周围像素的颜色取平均值
- 以下从左到右依次是未采用反走样、采用反走样以及使用canvas自带绘制API得到的同一条直线
- 可以看到最左边的线段锯齿状明显,中间的线段虽不如右端,但比起左端效果明显变好,缺陷是由于我是对周围线段进行的反走样操作,线段变得较粗
来一发吐槽