예제 #1
0
        public override Vec3 GetColor(BaseLight light, Ray view_ray, HitRecord record, float depth)
        {
            //Phong公式: L = Kd * I * max(0, n·l) + Ks * I * max(0, n·h)^p
            // Kd是散射系数, n是表面法向量,l是光源方向(从相交点指向光源), Ks是高光系数,h是v+l的单位向量,v是视线反方向(从相交点只想视点), I是光强(光在这一点的颜色)
            Vec3  l       = -(light.GetLightRay(record.hit_point, view_ray.DeltaTime).Direction.normalize());
            float n_dot_l = Math.Max(0, Vec3.dot(record.normal, l));

            Vec3  h       = (-view_ray.Direction + l).normalize();
            float n_dot_h = Math.Max(0, Vec3.dot(record.normal, h));

            Vec3 I = Vec3.one;

            Vec3 dif = diffuse * n_dot_l;

            Vec3 spe = specular * (float)Math.Pow(n_dot_h, phong_exp);

            spe *= _smoothstep(0, 0.12f, n_dot_l);//为了解决背光面高光的问题,如果n_dot_l<0直接spe=0会有颜色间断层,需要做插值处理

            Vec3 L = Vec3.product(I, dif + spe);

            //上面有两个bug/疑问
            //(1)背光面也能出现高光,因为公式里n·l<0并不影响 Ks * I * max(0, n·h)^p的值;
            //(2)求出来的L超过(1,1,1)范围了.---暂时强行映射到[0,1]
            //上面两个问题估计都是要改diffuse和specular来处理
            //目前先特殊处理下,以后看看大佬们怎么搞的
            return(L);
        }
예제 #2
0
        public override Vec3 GetColor(BaseLight light, Ray view_ray, HitRecord record, float depth)
        {
            //把光在某一点的颜色,用距离映射到颜色区间
            //[0, depth] -- > [0, 255]不过,len = 0的时候是255, len = depth的时候是0
            float coeffience = 1 - (record.t / depth);

            return(texture.GetColorValue(0, 0, null) * coeffience);
        }
예제 #3
0
        public override Vec3 GetColor(BaseLight light, Ray view_ray, HitRecord record, float depth)
        {
            Vec3 l = -(light.GetLightRay(record.hit_point, view_ray.DeltaTime).Direction.normalize());

            float n_dot_l = Math.Max(0, Vec3.dot(record.normal, l));

            Vec3 I = Vec3.one;

            Vec3 dif = diffuse * n_dot_l;

            Vec3 L = Vec3.product(I, dif);

            return(L);
        }
예제 #4
0
        public override Vec3 GetColor(BaseLight light, Ray view_ray, HitRecord record, float depth)
        {
            Vec3 l = -(light.GetLightRay(record.hit_point, view_ray.DeltaTime).Direction.normalize());

            float n_dot_l = Math.Max(0, Vec3.dot(record.normal, l));

            Vec3 I = Vec3.one;

            Vec3 color = texture == null ? diffuse : texture.GetColorValue(0, 0, record.hit_point);//这里还要改的,下面的material也是,感觉material用来定义反射之类的物理计算公式。颜色映射还是交给texture吧

            Vec3 dif = color * n_dot_l;

            Vec3 L = Vec3.product(I, dif);

            return(L);
        }
예제 #5
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="light">光源</param>
 /// <param name="view_ray">视线</param>
 /// <param name="record">相交信息</param>
 /// <param name="depth">渲染深度</param>
 /// <returns></returns>
 public virtual Vec3 GetColor(BaseLight light, Ray view_ray, HitRecord record, float depth)
 {
     throw new NotImplementedException();
 }