Cocos Creator 2D 光照详解

在 2d 中实现基础光照效果!文末查看完整项目

前言

本文主要讲的是最基础的光照模型(冯氏光照模型(Phong Lighting Model)),是一种光照的简化模型。请务必记住以下几个英文单词,对学习研究非常有帮助。

  • 环境(Ambient)

  • 漫反射(Diffuse)

  • 镜面高光(Specular)

希望我们能大概了解这些知识(但不限于这些):

  • 向量(加法/点乘/叉乘)

  • 着色器(顶点着色器/片元着色器)

  • ...

计算机图形学第一定律:如果它看起是对的,那么它就是对的

影响一个物体的外观颜色一般有以下几个因素:

  • 物体表面的特质,即材质属性。(这次实现忽略材质,默认统一材质)

  • 表面的方位与朝向,朝向常用单位法向量表示。(这次在2d中默认使用朝向屏幕(0,0,1)作为所有法向量)

  • 照射光的各光源性质。(这次简化为只有光源位置)

  • 观察者位置。(这次使用相机的位置)

77ecb8bc87108d750da5bcb3f198ee76.gif

实现

标准光照公式可以简写成:

光 = 环境光 + 漫反射 + 高光

现在逐一去实现。

环境光

环境光(Ambient)是标准光照模型中最简单的一部分,可以理解为光照模型中的常数项。

环境光的颜色并不会随着物体的位置,光的位置,视角的位置而改变。

<环境光> = <全局环境光颜色>x<材质颜色>
965002d0c3f129be22918a46929fad6c.jpeg

材质色这里采用图片的纹理颜色,环境光的主要代码如下:

vec3 ambient = ambientLight.rgb * lightColor.rgb;
o.rgb = amibent * o.rgb;

在只有环境光的情况下,对于不同的全局光的系数,物体的亮度也不一样。

bac72d6e344dc991d497b1e13553cf19.jpeg

漫反射

漫反射(Diffuse)是基础光照模型的第二剑客,它不再是个常量。

漫反射的效果会随着物体与光线的夹角变化而变化。

<漫反射> = <入射光颜色>x<材质颜色>x<光与物体法向量的夹角>
af1179d5e69ef024aa86779c2dcbc46a.jpeg

主要代码如下:

vec3 norm = normalize(v_normal); // 法向量
vec3 lightDir = normalize(lightPos.xyz - v_pos); // 光的方向

// diffuse
float diff = max(dot(norm, lightDir), 0.0); // 夹角
vec3 diffuse = diff * lightColor.rgb;

o.rgb = (amibent + diffuse) * o.rgb; // 环境光+漫反射光

可以看到光在不同的位置下,物体的亮度不同。

792575b8541315be4161d136c2fd257c.gif

镜面高光

镜面高光(Specular)是基础光照模型的最后一道工序,不仅受物体夹角影响,还受观察点的影响。

<镜面高光> = <入射光颜色>x<材质颜色>x<观察向量与入射向量和法向量的某种指数关系>

这里有两种模型去实现镜面高光:

  • phong 模型(用反射向量计算)

  • bliinn 模型(用半向量计算)

c9ee71de070cafdf7bd14859eb48911b.jpeg

主要核心代码如下:

// phong-specular
// vec3 viewDir = normalize(viewPos - v_pos);  // 视角向量
// vec3 reflectDir = reflect(-lightDir, norm); // 反射向量
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess); // 夹角的指数关系
// vec3 specular = spec * lightColor.rgb; // 乘入射光颜色

// blint-phong
vec3 viewDir    = normalize(viewPos - v_pos);  // 视角向量
vec3 halfwayDir = normalize(lightDir + viewDir); // 半向量
float spec = pow(max(dot(norm, halfwayDir), 0.0), shininess); // 夹角的指数关系
vec3 specular = lightColor.rgb * spec; // 乘入射光颜色

o.rgb = (ambient + diffuse + specular) * o.rgb; // 混合环境光 漫反射 高光反射

运行后的结果如下,可以看到有一个小光点,就是高光反射。

511cf4aeb1b95877969bf86f3f1397c6.gif

小结

Cocos Creator 2d 光照!Blinn-Phong ! Ambient ! Diffuse ! Specular !

基础光照模型可分为三项去考虑:

  • 环境(Ambient) [常数,全局环境光]

  • 漫反射(Diffuse) [入射角与法向量]

  • 镜面高光(Specular) [入射角,观察点,指数]

以上为白玉无冰使用 Cocos Creator v2.4 实现 "基础光照 Blinn-Phong" 的技术分享。欢迎分享给身边的朋友!

当然,这只是一种简单的光照模型,进一步探讨的话还有:

  • 法线矩阵

  • 平行光/点光/聚光

  • 基于物理的渲染(Physically Based Rendering)[PBR]

  • 双向反射分布函数(Bidirectional Reflective Distribution Function)[BRDF]

  • 光线追踪

  • ...

更多的拓展见参考资料。

参考

  • 《Fundamentals of Computer Graphics》

  • 《WebGL编程指南》

  • 《3D数学基础:图形与游戏开发》

  • 《光线跟踪算法技术》

  • 《Unity Shader入门精要》

  • https://learnopengl.com/


完整代码(详见readme): 

https://github.com/baiyuwubing/cocos-creator-examples/tree/master/2.4.x


感谢作者「lamyoung」的创作分享!欢迎分享本文给身边的朋友,也欢迎您在评论区或进入作者原文一起交流!

如果您在使用 Cocos 引擎的过程中,获得了独到的开发心得、见解或是方法,并且乐于分享出来,帮助更多开发者解决技术问题,加速游戏开发效率,期待您与我们联系!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值