顶点颜色在光照计算中的作用
来源:互联网 发布:linux搭建git服务器 编辑:程序博客网 时间:2024/06/04 08:27
最近在做项目的时候,碰到了使用顶点颜色没有效果的情况,研究了很久,终于把顶点颜色和渲染时的光照计算流程弄清楚了。
首先,光照的计算与顶点的格式有关系,当顶点格式为D3DFVF_XYZ|D3DFVF_DIFFUSE时,因为没有法线信息,也无法进行光照计算,所以不管是否开启光照,渲染时都只会使用顶点颜色作为渲染的结果。
针对D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX3 类型的顶点,当D3DRS_LIGHTING设置为TRUE,同时设置好灯光的各项参数。在这种情况下,我们来探讨一下光照计算的流程。
首先,对于每一个顶点来说,都有一个初始颜色: InitColr = globalAmbient*vMaterialAmbient+vMaterialEmissive;然后,分别计算Diffuse和Specular的颜色值,计算过程不详细讨论,但是要注意,计算最终的值要乘以灯光的颜色并考虑灯光的衰减系数。最后将Diffuse和Specular的颜色叠加在一起: FinalColor = InitColor + Diffuse + Specular.
我们特别需要注意的是,用于光照计算的基础颜色: vDiffuse = vLightDiffuse*vMaterialDiffuse[ vVertexDiffuse ], vSpecular = vLightSpecular*vMaterialSpecular[ vVertexSpecular ].其中第二个参数的选择是通过渲染状态来设定的:D3DRS_DIFFUSEMATERIALSOURCE,D3DRS_SPECULARMATERIALSOURCE分别控制使用材质还是顶点的颜色作为漫反射和镜面反射的颜色。而且以上渲染状态要生效必须先将D3DRS_COLORVERTEX设置为TRUE,否则顶点的颜色仍然不会被光照计算所使用,该渲染状态的详细解释如下:
TRUE to enable per-vertex color or FALSE to disable it. The default value isTRUE. Enabling per-vertex color allows the system to include the color defined for individual vertices in its lighting calculations.
Diffuse color source for lighting calculations. Valid values are members of theD3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_COLOR1. The value for this render state is used only if the D3DRS_COLORVERTEX render state is set to TRUE.
Specular color source for lighting calculations. Valid values are members of theD3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_COLOR2.
Ambient color source for lighting calculations. Valid values are members of theD3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_MATERIAL.
Emissive color source for lighting calculations. Valid values are members of theD3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_MATERIAL.
当D3DRS_DIFFUSEMATERIALSOURCE设置为COLOR1,但是顶点并没有DIFFUSE分量时,将仍使用MATERIAL作为分量。同样,D3DRS_SPECULARMATERIALSOURCE设置为COLOR2时,如果顶点没有SPECUALR分量,仍使用MATERIAL作为分量。当设置D3DRS_LIGHTING为FALSE时,渲染会跳过光照计算的过程,直接将贴图纹理的颜色和顶点颜色的乘积作为最终的结果。当设置D3DRS_LIGHTING为TRUE但是没有设置灯光(SetLightEnable)时,最后叠加的结果将会是黑色。
注:在顶点光照和贴图颜色叠加的时候,要注意一点,环境光加上漫反射的颜色要和贴图的颜色相乘,而镜面反射的颜色是叠加到最终的颜色之上的。如下所示:
finalcolor = (ambient+emmisive+diffuse)*texcolor+specular.
1:DirectX最多支持8重纹理 索引号:0-7
2:第一层默认为D3DTOP_MODULATE,其余为D3DTOP_DISABLE.
3:逐次使用,在前一层使用以后才可启用下一层。必须安装0-1-2-3-4-5-6
-7的顺序。
4:纹理混合是阶段混合,即0和1混合后的结果再和2混合。
5:SetTextureStageState()
6:查询是否支持纹理混合以及支持几层。
if( pCaps->MaxTextureBlendStages <= 1)
return false;
7:设置并关联纹理层
定义:
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
LPDIRECT3DTEXTURE9 g_pTexture1 = NULL; //第一层纹理
LPDIRECT3DTEXTURE9 g_pTexture2 = NULL; //第二层纹理
创建: D3DXCreateTextureFromFile( pd3dDevice, L"Wall.bmp",
&g_pTexture1 );
D3DXCreateTextureFromFile( pd3dDevice, L"light.jpg",
&g_pTexture2 );
关联:
pd3dDevice->SetTexture( 0, g_pTexture1 );
pd3dDevice->SetTexture( 1, g_pTexture2 );
8:设置纹理坐标索引
如果需要使用不同的纹理坐标,在顶点格式中包含多组坐标。
pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
// 定义顶点结构和灵活顶点格式
struct CUSTOMVERTEX
{
FLOAT x, y, z; // 未经过坐标转换的顶点坐标
DWORD color; // 顶点漫反射颜色值
FLOAT u,v ; // 顶点纹理坐标
FLOAT u1,v1 ; // 顶点纹理坐标
};
9:设置纹理混合
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,
D3DTOP_MODULATE );//将下面的纹理层贴图和漫反射颜色相乘
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1,
D3DTA_TEXTURE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2,
D3DTA_DIFFUSE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,
D3DTOP_DISABLE );//禁用0层和1层Alpha通道混合
pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER,
D3DTEXF_LINEAR);//设置线性过滤
pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER,
D3DTEXF_LINEAR);
pd3dDevice->SetTexture( 1, g_pTexture2 );
pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP,
D3DTOP_ADD);
pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1,
D3DTA_TEXTURE );
pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2,
D3DTA_CURRENT);
pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,
D3DTOP_DISABLE );
pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX,
1 );
pd3dDevice->SetSamplerState(1, D3DSAMP_MAGFILTER,
D3DTEXF_LINEAR);
pd3dDevice->SetSamplerState(1, D3DSAMP_MINFILTER,
D3DTEXF_LINEAR);
D3DTSS_COLORARG1:默认为D3DTA_TEXTURE,即纹理颜色
D3DTSS_COLORARG2:默认为D3DTA_CURRENT,即前一纹理层的输出颜色。当
Stage参数为0时,值为D3DTA_DIFFUSE,像素漫反射颜色值。
D3DTSS_ALPHAARG1:默认为D3DTA_TEXTURE
D3DTSS_ALPHAARG2:默认为D3DTA_CURRENT,Stage参数为0时,值为
D3DTA_DIFFUSE,像素漫反射颜色值
ALPHA混合和颜色混合是分别处理的。
10:OnDestroyDevice中:
SAFE_RELEASE(g_pVB);
SAFE_RELEASE(g_pTexture1);
SAFE_RELEASE(g_pTexture2);
11:渲染
pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0,
2);
- 顶点颜色在光照计算中的作用
- D3D中光照,顶点法线,顶点结构,顶点颜色
- OpenGL中的光照[光照计算]
- OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用
- OpenGL中的光照和颜色
- OpenGLES入门笔记 :OpenGLES光照基础总结4 光照的顶点计算与片元计算
- LLC在MRP计算中的控制作用
- 第一章 算法在计算中的作用
- 第一章 算法在计算中的作用
- 第一章 算法在计算中的作用
- 第一章 算法在计算中的作用
- 第一章 算法在计算中的作用
- 第一章 算法在计算中的作用
- OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用_棋盘纹理贴图
- 逐顶点的光照
- Vertex Lit 顶点光照
- 漫反射-逐顶点光照
- opengl 中的光照与颜色 转载
- 有假币
- AsyncSocket
- UCenter同步HDWiki及其他APP用户长度限制
- POJ 1033 模拟
- java.io包 管道流使用案例
- 顶点颜色在光照计算中的作用
- 计算机的引导过程
- GUN tar for windows Practice
- 黑色炫酷网站
- Linux字符设备驱动初探
- Exception(2)
- POJ--1694--An Old Stone Game
- Android系统的reboot之我见
- Apache Hadoop2.0之HDFS均衡操作分析