zoukankan      html  css  js  c++  java
  • games101

    games101 - 2 - Shading

    GAMES101:现代计算机图形学入门 – 计算机图形学与混合现实研讨会 (games-cn.org)

    涉及到的课程有:Lecture 7 ~ Lecture 10

    可见性/遮挡

    物体在三维空间中的位置是有前后关系的。位于前面的物体会遮挡后面的物体,那么如何保证渲染结果有正确的遮挡关系呢?

    画家算法

    绘制油画的时候,是从后往前进行绘制的。如下图所示:

    该算法在绘制前,需要对物体按照深度关系进行排序,而当对象之间的深度关系有交叠的时候(如下图),该算法将会得到错误的结果。

    Z-Buffer算法

    该算法的基本思想如下:对于每个像素位置,存储当前最小的深度值(min z value),当绘制一个像素位置的时候,首先得到该位置的深度值,然后和深度缓存中记录的最小深度值进行比较,如果当前的深度值更小,更新深度值,并将颜色绘制到颜色缓冲区。伪代码如下:

    initialize depth buffer to +inifinity;
    for (each triangle T)
        for (each sample(x,y,z) in T)
            if (z < zbuffer[x,y])             // closest sample so far
                framebuffer[x,y] = rgb;       // update color
    			zbuffer[x,y] = z;             // update depth
    

    光照、shading

    如上图所示,左边是没有光照的效果,右边是待光照着色的效果。可见想要获得立体的视觉效果,必须加入光照。

    shadering:往一个对象上应用材质的过程。

    Blinn-Phong Reflection Model

    先来直观的感受下什么是镜面反射,什么是漫反射,什么是环境光照。

    该光照模型也是从镜面反射,漫反射,环境光出发。先给结果:

    漫反射

    漫反射与视野方向无关.

    点光源的光在传播的时候,会随着距离的平方成反比进行衰减。

    下图是漫反射的效果:

    镜面反射

    镜面反射和视角相关,可以想象下,太阳光照射到一扇镜子上进行反射,只有从特定的视角上看去才能够看到刺眼的阳光。

    参数变化对应的效果变化图如下:

    环境光

    shading frequencies

    Gourand shading:传入每个顶点对应的颜色,然后插值确定三角形每个位置的颜色;

    Blinn-Phone shading:传入每个顶点对应的法向量,然后插值确定三角形每个位置的法向量,然后通过着色模型计算确定每个位置的颜色;

    Face shading:每个三角形的颜色都是一致的。参见:【OpenGL4.0】GLSL-Flat Shading平面着色_江南烟雨-CSDN博客

    图形管线

    纹理映射

    通过光照和着色,可以得到绘制结果,那么为了绘制的结果和真实场景更加接近,或者说更加好看,如何更好的给出k_d这个参数呢?通常采用的方法为,传入k_d纹理。三维空间中物体的表面都是可以拆分成二维的图像,那么也就是说,2D中的图像可以映射回3D表面上特定的位置。如下图所示:

    应用纹理

    通常情况下传入的纹理用于漫反射系数。具体伪代码如下:

    for each rasterized screen sample (x,y):         // 通常是像素中心
    	(u,v) = evaluate texture coordinate at (x,y) // 计算当前像素位置所在三角形的重心坐标,
    	                                             // 然后利用重心坐标进行对纹理坐标进行插值
    	texcolor = texture.sample(u,v)
    	set sample's color to texcolor;
    

    如果纹理本身太小:需要对纹理进行放大

    该问题的处理方式很简单,只需要对纹理本身进行放大处理即可。放大的方法有,最邻近插值,双线性插值,双三次插值。Lanczos插值,最邻近插值,双线性二次插值,三次插值_Jensen Lee的博客-CSDN博客

    如何纹理本身太大?- mipmap

    该问题的处理方式相对而言就比较难了。

    对纹理进行点采样的时候,可能出现锯齿和摩尔纹的现象,如下图所示:

    为什么为出现这种现象呢?考虑到我们绘制的时候采用的是透视投影,那么在近处,一个像素覆盖的纹理区域很小,而在远处一个像素会覆盖很大的一片纹理区域,如下图所示:

    当一个覆盖纹理较小区域的时候,用像素位置的颜色值表示区域中的值是没有什么问题的,而当一个像素表示纹理很大的一片区域的时候,从直觉上理解,用一个像素点表示区域的特征是存在问题的。这个从采样的角度理解,这是一个欠采样的问题,必然会存在走样的结果。那么怎么处理这个问题呢?可选的方法有:

    首先来看下如果采用512x的超采样,得到的结果对比图如下:

    这种方式是通过增加采样点,提高采样频率。虽然能够得到比较高质量的结果,但是有很大的开销。那么我们能不能不用一个点表征一个区域的颜色,而是用一个区域的平均色来表征这个区域呢?这个方法就是mipmap。

    通过mipmap允许进行范围查找,这个方法是快速的,近似的,并且要求纹理的形状是正方形。mipmap技术的示意图如下:

    Level 0表示原始的纹理图像,每增加一级,纹理大小会对应的缩减一半。那么如何计算图像中的像素对应的mipmap等级呢?

    那么此时计算得到的mipmap level是连续的,怎么从非连续的预制mipmap中获取对应的像素值呢?这需要用到三线性插值。先获取(left lfloor D ight floor)(left lfloor D ight floor +1)整数等级的颜色值,然后再进行插值,获取D对应的颜色。示意图如下:

    但是通过mipmap技术得到的结果可能会出现overblur的现象:

    那么为什么会出现这种问题呢?从采样角度理解就是欠采样,从之前的表征方式理解,就是用了不合适的区域特征替代了目标区域的特征,如下图所示:

    通过anisotropic filtering可以解决映射后axis-aligned矩形区域的显示问题。anisotropic filtering预制的图形及效果如下:

    更多Filter相关内容参见:http://resources.mpi-inf.mpg.de/departments/d4/teaching/ws200708/cg/slides/CG09-Textures+Filtering.pdf

    纹理的应用

    版权说明

    作者: grassofsky

    出处: http://www.cnblogs.com/grass-and-moon

    本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(grass-of-sky@163.com)咨询.

  • 相关阅读:
    c# 网络编程
    .net基础------抽象类和接口区别
    自己开发插件-------- 待续...........
    js 学习笔记 (this ,扩展方法,匿名函数)
    meta
    微信公众号支付接口-JSAPI
    跨境电商-311xml报文生成 更新到2018-10
    MooTools 异步请求验证
    微信JS-SDK 接口调用与 php 遇到的坑
    php 与 jquery中$.post()与attr()方法的简单实例 amaze modal 模态窗口
  • 原文地址:https://www.cnblogs.com/grass-and-moon/p/15235446.html
Copyright © 2011-2022 走看看