CG experiment Ⅱ: Ray tracing

Experiment introduction:


Here comes the new project.This project may be a little difficult.You have 2 choices:
1:Based on last project:Let's your sitck man move
2:Create your own scene,you can place anything in it
Choose one and use at least two different method such as Phong model, Gouraud model to complete this project.



demo:



graphic 2



detail:

Phong光照模型

Phong模型是最常用的局部光照模型,此模型把从表面的光分解为3个独立项:
    环境项:模拟场景的整体光照水平。
    漫反射:模拟直接光源在表面均匀地向各个方向反射。
    镜面反射:在光滑表面均匀反射的高光。

先来看一下phong光照模型的数学公式(单个光源):

I = Ka * LA + LL * Kd * max( ( dot (N,L),0 ) + LL * Ks* max (dot ( R,V )^,shininess,0 )

从公式可以看出,计算表面上某点的phong反射时需要输入一些参数,这些参数包括:
      -环境反射量Ka
      -漫反射量kd
      -镜面反射量Ks
      -镜面光滑度shininess
    此处可以用物体材质结构来描述:
    struct Matrial
    {
        float ka ;
        float kd ;
        float ks ;
        float shininess;
    }
有关向量可以参考下面的图。图中的H向量在这里并没有用到,它是另一个光照模型Blina-Phong中的一个向量。


L:从表面上某点(受到光照的那点)指向光源的方向向量
V:从表面上某点指向摄像机的方向向量
N:表面上某点的法向量
R:L关于N的反射向量

其中R向量的计算方法为:
任何向量都可以表示为切线向量和法线向量之和,例如对于向量L,它可以表示为:
L = Ln + Lt ;
Ln指的是L在法线向量N上的投影长度,它可以这样计算:
Ln = dot ( N, L )N ; (N是个单位向量)
Ln计算出来了,自然的,Lt可以由L与Ln来计算:
Lt = L - Ln;
对于R向量,它是向量L关于法向量N的反射向量,故R与L有同一个法线分量Ln,但又相反的切线分量Lt,因此,我们可以这样求R:
R = Rn + Rt
= Ln - Lt
= Ln - (L- Ln)
= 2Ln - L
= 2( dot ( N , L )N ) - L

依据公式,phong光照模型的CG代码可以编写如下:
        struct Matrial
        {
            float ka ;  //环境反射量
            float kd ;  //漫反射量
            float ks ;  //镜面反射量
            float shininess;    //物体表面光泽度
        }
        struct Light 
        {
            float3 position ; //灯光的位置
            float3 color ;    //灯光的颜色
        }
        void PhongModle (
                        out float3 oposition:POSITION, 
                        out float3 color :COLOR,
                        
                        float4 position:POSITION,
                        float3 normal:NORMAL,
                        
                        uniform float4x4 modelViewPrij,
                        uniform float3 globalAmbient ,
                        uniform float3 eyePosition,
                        uniform Light light ,
                        uniform Material material,
                        
                        )
        {
            oposition = mul (modelViewPrij,P);
            
            float3 P = position.xyz;
            float3 N = normal;
            
            //计算环境光贡献
            float3 ambient = material.ka * globalAmbient;
            //计算向量L
            float3 L = normalize( light.position -P );
            //计算向量V
            float3 V = normalize (eyePosition -P);
            //计算向量R
            float3 R =  2 * (dot (N,L)*N )-L ;
            //计算漫反射贡献
            float3 diffuse = material.kd * light.color  * max (dot (N,L),0);
            //计算镜面反射贡献
            float3 specular = material.ks * light.color * max (dot (R,V)^shininess,0);
            
            //三种光加和
            color.xyz = ambient + diffuse +specular ;
            color .w = 1;
            
        }

Lambert光照模型

Lambert光照模型是最简单的漫反射模型。物体发生理想漫反射时,光线照射到比较粗糙的物体表面,从物体表面向各个方向发生了反射, 从而无论从哪个角度来看表面,表面某点的明暗程度都不随观测者的位置变化而变化。例如你观察黑板时, 黑板上发生的就是漫反射。
Lambert光照模型的数学表达式可以写为:

Ip = Ia * kd + II * kd * ( dot ( N,L ) )

其中:
  1. kd为物体表面的漫反射系数。
  2. Ia为环境光,Ia*kd为环境光对物体表面漫反射所贡献的光照。
  3. II表示环境光外其他光如方向光或点光源。
  4. N为物体表面p点的法向量。
  5. L为P点指向灯源的方向向量。
Lambert光照模型的CG代码为:
//灯光
struct Light 
{
    float3 color ;
    float3 position;
}
//物体
struct Material
{
    float kd ;
}
void LambertModel(
                out float4 oposition:POSITION,
                out float3 color :COLOR,
                loat4 position:POSITION,
                float3 normal:NORMAL,
                
                uniform float4x4 modelViewPrij,
                uniform float3 globalAmbient ,
                uniform float3 eyePosition,
                uniform Light light ,
                uniform Material material,
                )
{

    oposition = mul (modelViewPrij,P);
    float3 P = position.xyz;
    float3 N = normal;
    
    float3 ambient = material.kd * globalAmbient;
    
    float3 L = normalize( light.position -P );
    float3 specular = light.color * material.kd * max( dot(N,L),0 ) ;
    
    color.xyz = ambient + specular ;
    color.w = 1;

}

Other project