zoukankan      html  css  js  c++  java
  • DX 简单阴影

    View Code
    //
    // 在场景中渲染出一个茶壶Mesh以及这个茶壶的影子
    //

    #include "header.h"

    ID3DXMesh *pTeapot = NULL;
    D3DMATERIAL9 teapotMtrl;
    D3DLIGHT9 pointLight; // 点光

    bool DXSetup()
    {
    // 初始化材质
    ::ZeroMemory(&teapotMtrl, sizeof(teapotMtrl));
    teapotMtrl.Ambient = RED;
    teapotMtrl.Diffuse = RED;
    teapotMtrl.Specular = RED;

    // 初始化茶壶Mesh
    D3DXCreateTeapot(g_pd3dDevice, &pTeapot, NULL);

    // 初始化灯光
    ::ZeroMemory(&pointLight, sizeof(pointLight));
    pointLight.Type = D3DLIGHT_POINT; // 点灯类型
    pointLight.Diffuse = WHITE;
    pointLight.Ambient = WHITE * 0.3f;
    pointLight.Specular = WHITE * 0.3f;
    pointLight.Position = D3DXVECTOR3(0.0f, 50.0f, 0.0f);
    pointLight.Range = 200.0f;
    g_pd3dDevice->SetLight(0, &pointLight);
    g_pd3dDevice->LightEnable(0, TRUE);

    // 设置摄影机
    D3DXVECTOR3 position(0.0f, 0.0f, -10.0f);
    D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
    D3DXMATRIX camera;
    D3DXMatrixLookAtLH(&camera,&position, &target, &up);
    g_pd3dDevice->SetTransform(D3DTS_VIEW, &camera);

    // 设置可视体 - 投影矩阵
    D3DXMATRIX proj;
    D3DXMatrixPerspectiveFovLH(
    &proj,
    D3DX_PI * 0.5f, // 90 - degree
    (float)Width / (float)Height,
    1.0f,
    1000.0f);
    g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj);

    return true;
    }

    void Render()
    {
    // 移动视点的位置
    MovePosition();

    g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, D3DCOLOR_XRGB(200,200,200), 1.0f, 0);
    g_pd3dDevice->BeginScene();

    // 渲染茶壶
    D3DXMATRIX priCode;
    D3DXMatrixTranslation(&priCode, 0,0,0); // 将DX设备移动到空间的原点
    g_pd3dDevice->SetTransform(D3DTS_WORLD, &priCode);
    g_pd3dDevice->SetMaterial(&teapotMtrl);
    g_pd3dDevice->SetFVF(DX8Vertex_FVF);
    pTeapot->DrawSubset(0);

    // 在xy面渲染茶壶的影子
    D3DXMATRIX shadowMatrix;
    D3DXPLANE plane(0.0f, 1.0f, 0.0f, 5.0f); // xy plane
    D3DXVECTOR4 lightDirection(0.0f, 5.0f, 0.0f, 1); // 设置产生阴影的灯光的类型及位置(或者方向). w=0是平等光,前三个参数表示方向;w=1是点光,前三个参数表示位置
    D3DXMatrixShadow(&shadowMatrix, &lightDirection, &plane);
    D3DXMATRIX shadowPosMatrix;
    D3DXMatrixTranslation(&shadowPosMatrix, 0.0f, 0.0f, 0.0f);
    D3DXMATRIX w = shadowPosMatrix * shadowMatrix;
    g_pd3dDevice->SetTransform(D3DTS_WORLD, &w);
    g_pd3dDevice->SetMaterial(&BLACK_MTRL);
    pTeapot->DrawSubset(0);

    g_pd3dDevice->EndScene();
    g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
    }

    这是在屏幕上面渲染出一个茶壶以及茶壶的阴影,没有使用模版技术来防止二次混合,就是一个简单的成像.部分代码如上所示.下面记录一下我之前不太理解的东西.


    首先是在空间的原点渲染出一个茶壶,然后在茶壶下面画一出这个茶壶在"地上的阴影".
    设置产生阴影的灯光类型及这个灯光的位置(如果是平行光,那就是设置这个灯光的方向),灯光的位置在正上方(0,5,0)位置.即:D3DXVECTOR4 lightDirection(0.0f, 5.0f, 0.0f, 1);
    设置阴影成像的平面为xy面,面的深度为-5,即,在空间z轴的坐标为-5;即:D3DXPLANE plane(0.0f, 1.0f, 0.0f, 5.0f);
    设置待投影的物体在原点,即,茶壶所在地方,即:D3DXMatrixTranslation(&shadowPosMatrix, 0.0f, 0.0f, 0.0f);

    平面公式是:
    n.p+d=0     表示点在平面上(点在面上);
    n.p+d>0     表示点在平面的上方(点不在面上)
    n.p+d<0     表示点在平面的下方(点不在面上)

    D3DXPLANE 所创建的面,指定的四个参数分别是n这个向量与d这个系数,p这个点来自于D3DXMatrixTranslation设置的后面三个参数.
    这样就可以理解了,0*0 + 1*0 + 0*0 + 5 = 5,这个值是>0的,所以画出来的阴影是在平面上(如果在平面下是看不到的),根据这个公式来调整面与物体的位置即可.
  • 相关阅读:
    Oracle 数据库简介
    Qt 中事件与处理
    npm常用命令总结
    自适应宽度布局
    原生js发送ajax请求
    微信调试本地环境代码
    多行文本溢出显示省略号
    清除浮动
    用JQuery动态为选中元素添加/删除类
    input中加入搜索图标
  • 原文地址:https://www.cnblogs.com/emyueguang/p/2298386.html
Copyright © 2011-2022 走看看