• D3D学习总结渲染篇(一)基础理论


    在Direct X初始化后,我们当然要在上面画东西。这个过程事实上是极其复杂的,在直接进入API的解释和使用前,先简单说下3D世界转换到2D画面(我们在屏幕上看到的)的一些基本理论。按惯例说明下,本文使用了Introduction to 3D Game Programming with DirectX 10中的理论,代码和图片,在很多部分,笔者只是做了翻译整理工作。

    1.3D视觉效果

    首先,从感性来说,一个平面图形怎么让人眼产生立体感,最简单的其实就是"近大远小"。

    如上图,两条平行的线,由进及远距离原来越小,知道称为同一点(vanishing point),就形成了立体的效果。

    上图描绘了另外一种情况(其实就是之前depth buffer的例子),四种图形相互掩盖,也能让人形成前后的视觉。

    那单个物体,怎么现实立体感呢,看下图:

    左边是个圆,正常人都会这么认为。。。不会把它想成球,右边则相反,怎么看都是个球体。两边差了啥呢?光照(lighting)和着色(shading,注意这个词不是阴影的意思)。

    再看上图,一个飞机,嗯,为什么我们觉得它在空中,因为地上有影子(shadow),从影子我们可以知道两件事情,1.飞机的高度;2. 光照的方向。

    OK,到这里,还没讨论啥高深的东西,你可能觉得这些东西你小学就知道,但后面我们要把这些简单的东西通过计算机图形学表现出来。

    2. 建模

    一个3D模型,或者说一个3D对象,在计算机图形学中,事实上(通常情况下)是一个三角形网格组成的近似模拟。

    如上图,可以看出,越复杂的模型需要越多的三角形来组成(好吧,我承认是废话。。。)。当然了,用代码写出这个么模型,基本是丝路一条,一般我们都用建模工具来完成这些工作,如3ds Max (http://www.autodesk.com/3dsmax), LightWave 3D (http://www.newtek.com/lightwave/), Maya (http://www.autodesk.com/maya), and Softimage | XSI (www.softimage.com)。

    3. 计算机颜色

    计算机一般通过RGB三原色以及每种颜色的灰度来存储一种具体的颜色,随便打开个windows下的选色器就看出。

    一般来说,我们用一个有三个数的结构来表现一个颜色,如(0.25, 0.67, 1.0),表示25%的红,67%的绿以及100%的蓝。由于这个结构很像向量,我们在D3D中还是用向量也表示它,称为颜色向量。

    显然,向量的加减对颜色向量来说是有意义的:

    加法相当于两种颜色重叠产生新颜色。

    减法类似加法,代表我从一种颜色转换为另一种颜色(通过减掉某些颜色的比重)。

    常数乘以一个颜色也同样有意义:

    相当于整个颜色的浓度产生一定程度的变化。

    接下来是点乘和×乘,后者是没有实际意义的,前者的意义是:

    RGB三种颜色分别做了一定程度的变化,事实上,这是很有用的,主要用于模拟光照现象。比如我们有一束光,从远处照过一个平面,这个平面能吸收50%的红光,75%的绿光以及25%的蓝光,那通过一下算式,能得到光通过那个平面的颜色:

    下面说下在D3D中具体的颜色的使用,D3D中,颜色被封装在结构D3DXCOLOR中(博客园的代码插入功能呢。。。):

    typedef struct D3DXCOLOR

    {

    #ifdef __cplusplus

    public:

    D3DXCOLOR() {};

    D3DXCOLOR(UINT argb);

    D3DXCOLOR(CONST FLOAT *);

    D3DXCOLOR(CONST D3DXFLOAT16 *);

    D3DXCOLOR(FLOAT r, FLOAT g, FLOAT b, FLOAT a);

    // casting

    operator UINT () const;

    operator FLOAT* ();

    operator CONST FLOAT* () const;

    // assignment operators

    D3DXCOLOR& operator += (CONST D3DXCOLOR&);

    D3DXCOLOR& operator -= (CONST D3DXCOLOR&);

    D3DXCOLOR& operator *= (FLOAT);

    D3DXCOLOR& operator /= (FLOAT);

    // unary operators

    D3DXCOLOR operator + () const;

    D3DXCOLOR operator - () const;

    // binary operators

    D3DXCOLOR operator + (CONST D3DXCOLOR&) const;

    D3DXCOLOR operator - (CONST D3DXCOLOR&) const;

    D3DXCOLOR operator * (FLOAT) const;

    D3DXCOLOR operator / (FLOAT) const;

    friend D3DXCOLOR operator * (FLOAT, CONST D3DXCOLOR&);

    BOOL operator == (CONST D3DXCOLOR&) const;

    BOOL operator != (CONST D3DXCOLOR&) const;

    #endif //__cplusplus

    FLOAT r, g, b, a;

    } D3DXCOLOR, *LPD3DXCOLOR;

    可以看到上面的结构没有提供点乘的方法,因此,补充下面这个函数来完成此类操作。

    D3DXCOLOR* D3DXColorModulate(

    D3DXCOLOR* pOut, // Returns (cr, cg, cb, ca) (kr, kg, kb, ka)

    CONST D3DXCOLOR* pC1, // (cr, cg, cb, ca)

    CONST D3DXCOLOR* pC2 // (kr, kg, kb, ka)

    );

    从构造函数中,可以发现,有4个float,怎么多了一个呢?不是三原色么?多的那个就是传说中的alpha通道,用于阿尔法混合(blending),这里暂时不展开。

    如果我们通过 D3DXCOLOR(FLOAT r, FLOAT g, FLOAT b, FLOAT a)这个构造函数构造的颜色向量是128bit的一个数据结构,事实上,咋某些情况下,我们认为太大了,有些浪费,但由于颜色总是需要经过复杂的运算,float的高精度可以保证错误不会一直积累导致最后偏差过大,所以,在计算过程中,我们使用浮点数表示颜色(每个颜色元素是0到1)。

    当我们使用 D3DXCOLOR(UINT argb)来构造颜色向量的时候(传入一个32位的无符号整形),我们得到一个32位的颜色,它是这样对应4个子元素的:

    由于32位色基本能满足视觉的要求(windows的桌面设置最高就是32位色),因此,将计算完的结构用32位色表示是最合适的,这里涉及到一个转化的问题,32位色和128位色怎么转化呢,看下面两个例子:

    如上,32位色转化成了128位色。

    最后,用一张图表示图像渲染的过程,具体的解释请期待后文^-^

    Raiden Cheng
  • 相关阅读:
    sqoop 使用场景
    scala 类型和集合图
    scala 格式化操作
    sqoop 基础
    scala import 总结
    shell错误 syntax error: invalid arithmetic operator (error token is "
    C/C++ 隐式申明 问题
    阿里云贾扬清:数据湖正成为企业数据应用创新标配
    云原生时代如何用 Prometheus 实现性能压测可观测Metrics 篇
    基于 KubeVela 的机器学习实践
  • 原文地址:https://www.cnblogs.com/raidencheng/p/1690491.html
Copyright © 2020-2023  润新知