着色器和效果——2.4 样例应用程序:散射光照(上)

2.4 样例应用程序:散射光照(上)

阅读此文表明您已同意文末的声明

作为创建并使用顶点着色器的热身,我们写一个顶点着色器,它用一个方向(平行)光对每个顶点进行标准的散射光照。简而言之,散射光照根据顶点法线和光线向量(它指向光源方向)的角度计算顶点接收到的光线的数量。角度越小,则顶点接收到的光线就越多;而角度越大,则顶点接收到的光线就越少。如果角度大于等于90度,顶点就接收不到光线了。

我们以检阅着色器代码作为开始:

// File: diffuse.txt

// Desc: Vertex shader that does diffuse lighting.

 

//

// Global variables we use to hold the view matrix, projection matrix,

// ambient material, diffuse material, and the light vector that

// describes the direction to the light source. These variables are

// initialized from the application.

//

matrix ViewMatrix;

matrix ViewProjMatrix;

 

vector AmbientMtrl;

vector DiffuseMtrl;

 

vector LightDirection;

 

//

// Global variables used to hold the ambient light intensity (ambient

// light the light source emits) and the diffuse light

// intensity (diffuse light the light source emits). These

// variables are initialized here in the shader.

//

 

vector DiffuseLightIntensity = {0.0f, 0.0f, 1.0f, 1.0f};

vector AmbientLightIntensity = {0.0f, 0.0f, 0.2f, 1.0f};

 

//

// Input and Output structures.

//

 

struct VS_INPUT

{

     vector position : POSITION;

     vector normal   : NORMAL;

};

 

struct VS_OUTPUT

{

     vector position : POSITION;

     vector diffuse  : COLOR;

};

 

//

// Main

//

 

VS_OUTPUT Main(VS_INPUT input)

{

     // zero out all members of the output instance.

     VS_OUTPUT output = (VS_OUTPUT)0;

 

     //

     // Transform position to homogeneous clip space

     // and store in the output.position member.

     //

     output.position = mul(input.position, ViewProjMatrix);

 

     //

     // Transform lights and normals to view space. Set w

     // components to zero since we're transforming vectors

     // here and not points.

     //

     LightDirection.w = 0.0f;

     input.normal.w   = 0.0f;

     LightDirection   = mul(LightDirection, ViewMatrix);

     input.normal     = mul(input.normal, ViewMatrix);

 

     //

     // Compute cosine of the angle between light and normal.

     //

     float s = dot(LightDirection, input.normal);

 

     //

     // Recall that if the angle between the surface and light

     // is greater than 90 degrees the surface receives no light.

     // Thus, if the angle is greater than 90 degrees we set

     // s to zero so that the surface will not be lit.

     //

     if( s < 0.0f )

         s = 0.0f;

 

     //

     // Ambient light reflected is computed by performing a

     // component-wise multiplication with the ambient material

     // vector and the ambient light intensity vector.

     //

     // Diffuse light reflected is computed by performing a

     // component-wise multiplication with the diffuse material

     // vector and the diffuse light intensity vector. Further

     // we scale each component by the shading scalar s, which

     // shades the color based on how much light the vertex received

     // from the light source.

     //

     // The sum of both the ambient and diffuse components give

     // us our final vertex color.

     //

 

     output.diffuse = (AmbientMtrl * AmbientLightIntensity) +

                      (s * (DiffuseLightIntensity * DiffuseMtrl));

     return output;

}

[声明]:本文译自Frank Luna的《Introduction to 3D Game Programming with DirectX 9.0》,限于译者水平,文中难免错漏之处,欢迎各位网友批评指正;本文仅用于学习交流与参考用途,不得用于任何形式的商业用途;如需转载需事先征得作者本人和译者的同意,保持文章的完整性,并注明作者、译者和出处,作者保留对译文的所有权利。对于违反以上条款造成的后果,译者对此不负任何责任。我的MSNRaymond_King123@hotmail.com,欢迎热爱3D图形和游戏,并有一定图形编程经验的朋友与我进行交流。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值