图形学 日志

自制简易的软光栅渲染器(1)

playerzhou 无回复

项目地址:https://github.com/OmegaZhou/SimpleRender er

绘制线段

Bresenham’s Line算法

  • 首先要实现的就是在屏幕中画一条线,定义函数drawLine(p1:Vector2,p2:Vector2,color:Color),其中p1p2分别是线段的起点和终点
  • 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得到的同一条直线
  • 可以看到最左边的线段锯齿状明显,中间的线段虽不如右端,但比起左端效果明显变好,缺陷是由于我是对周围线段进行的反走样操作,线段变得较粗

来一发吐槽

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据