国内的libGDX文章很少,特别是libGDX实现灯光效果,所以就开始总结灯光效果的实现

1.Box2dLights库功能简介

库版本:1.5

目前Box2dLights提供了以下几种灯光效果模拟

  1. PointLight:点光源,就是中心点发光,向周围辐射,所以这个光源模拟的效果总是圆形的
  2. ConeLight:圆锥光源,也是从一点发光,但是光照角度和范围可以控制,像手电筒或投影仪那种
  3. DirectionalLight:模拟无限远的光源,光照效果不会随着距离和方向变弱,所以经常用来模拟阳光
  4. ChainLight:链式灯光,我们可以通过定义顶点更灵活的控制灯光模拟形状(比如让一个自定义的Body周围发光)

绿色的框 是为了方便看到Body位置,使用Box2DDebugRenderer渲染的

工欲善其事,必先利其器,工具集合
gdx-setup.jar

1. 从libGDX官网下载项目生成工具

https://libgdx.com/wiki/start/setup

2.配置项目

Output folder和Android SDK设置自己的,扩展库选择Box2dBox2dlights,然后生成项目

3.配置ApplicationConfiguration,初始化ApplicationListener

由于是演示项目,所以直接使用系统创建好的Activity实现类

public class AndroidLauncher extends AndroidApplication {@Overrideprotected void onCreate (Bundle savedInstanceState) {super.onCreate(savedInstanceState);AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();config.a = 8;config.r = 8;config.g = 8;config.b = 8;initialize(new PointLightTest(), config);}
}

initialize的第一个参数后面的每个例子都会改成需要的那个类

4.创建一个PointLight

public class PointLightTest implements ApplicationListener {/** the camera **/OrthographicCamera camera;RayHandler rayHandler;World world;@Overridepublic void create() {// 1. 创建正交投影相机,这里设置的视口直接就是屏幕大小camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());// 2.把相机放到屏幕中心 这两步是为了更直观的看到映射后的效果,不用去计算灯光位置什么// 的,都放到中心显示camera.position.set(Gdx.graphics.getWidth() / 2f,Gdx.graphics.getHeight() / 2f, 0);// 3.更新相机camera.update();// 4.创建物理世界world = new World(new Vector2(0, -10), true);// 5.创建光束处理器(核心)rayHandler = new RayHandler(world);// 6.创建一个点光源new PointLight(rayHandler, 100, Color.RED, 150f, Gdx.graphics.getWidth() / 2f, Gdx.graphics.getHeight() / 2f);}@Overridepublic void resize(int width, int height) {camera.viewportWidth = width;camera.viewportHeight = height;camera.update();}@Overridepublic void render() {Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);world.step(1/60f, 8, 3);rayHandler.setCombinedMatrix(camera);rayHandler.updateAndRender();}@Overridepublic void pause() {}@Overridepublic void resume() {}@Overridepublic void dispose() {rayHandler.dispose();}
}

点光源的参数

  1. rayHandler:我们创建的RayHandler对象
  2. rays:光束个数,数量越大效果越逼真,但是性能消耗也越大,推荐最大不超过128
  3. color:灯光颜色
  4. distance 灯光的辐射距离,越大,灯光辐射的越远
  5. x:灯光在world中的横向中心点
  6. y:灯光在world中的纵向中心点

5.创建一个ConeLight

public class ConeLightTest implements ApplicationListener {/** the camera **/OrthographicCamera camera;RayHandler rayHandler;World world;@Overridepublic void create() {camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());camera.position.set(Gdx.graphics.getWidth() / 2f,Gdx.graphics.getHeight() / 2f, 0);camera.update();world = new World(new Vector2(0, -10), true);rayHandler = new RayHandler(world);new ConeLight(rayHandler, 100, Color.RED, 500f, Gdx.graphics.getWidth() / 2f, Gdx.graphics.getHeight() / 2f, 90, 60);}@Overridepublic void resize(int width, int height) {camera.viewportWidth = width;camera.viewportHeight = height;camera.update();}@Overridepublic void render() {Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);world.step(1 / 60f, 8, 3);rayHandler.setCombinedMatrix(camera);rayHandler.updateAndRender();}@Overridepublic void pause() {}@Overridepublic void resume() {}@Overridepublic void dispose() {rayHandler.dispose();}
}

和点光源一样的配置,将AndroidLauncher的initialize参数改为ConeLightTest,ConeLight的参数和点光源差不多,多了2个参数

  1. directionDegree: 光源方向,逆时针为正方向 示例代码设置的90,0的话就是向右
  2. coneDegree: 锥形光的跨越角度 示例代码设置的60

6. 创建一个DirectionalLight

public class DirectionalLightTest implements ApplicationListener {/** the camera **/OrthographicCamera camera;RayHandler rayHandler;World world;protected Body body;protected Box2DDebugRenderer mWorldDebugger;private int viewportWidth = 0;private int viewportHeight = 0;@Overridepublic void create() {viewportWidth = Gdx.graphics.getWidth();viewportHeight = Gdx.graphics.getHeight();camera = new OrthographicCamera(viewportWidth, viewportHeight);camera.position.set( viewportWidth/ 2f,viewportHeight/ 2f, 0);camera.update();world = new World(new Vector2(0, -10), true);mWorldDebugger = new Box2DDebugRenderer();makeBody();rayHandler = new RayHandler(world);new DirectionalLight(rayHandler, 100, Color.WHITE, 0);}private void makeBody() {CircleShape ballShape = new CircleShape();ballShape.setRadius(50f);FixtureDef fixtureDef = new FixtureDef();fixtureDef.shape = ballShape;BodyDef bodyDef = new BodyDef();bodyDef.type = BodyDef.BodyType.StaticBody;bodyDef.position.x = viewportWidth/ 2f;bodyDef.position.y = viewportHeight / 2f;body = world.createBody(bodyDef);body.createFixture(fixtureDef);ballShape.dispose();}@Overridepublic void resize(int width, int height) {camera.viewportWidth = width;camera.viewportHeight = height;camera.update();}@Overridepublic void render() {Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);world.step(1 / 60f, 8, 3);rayHandler.setCombinedMatrix(camera);rayHandler.updateAndRender();mWorldDebugger.render(world, camera.combined);}@Overridepublic void pause() {}@Overridepublic void resume() {}@Overridepublic void dispose() {rayHandler.dispose();}
}

看到上面的效果图,可能很多疑问,这是什么鬼。
这个光源比较特殊,他就是无限长的光,参数也比较少

  1. rayHandler: 和之前一样,RayHandler对象
  2. rays:光束个数
  3. color:灯光颜色 示例设置的白色
    directionDegree:灯光照射角度,逆时针为正方向

这个光源设置后,如果画面上没有其他东西,就显示一个白屏,这就是这个光的特性,各处都照亮,所以一个屏幕都是白色,所以需要加上一个参照物,也就是示例代码和之前的多了一个body,光线照到body,然后被body遮挡就会显示阴影,也就成了上面示意图的模样,如果设置角度90,阴影就是朝上。

7.创建一个ChainLight

public class ChainLightTest implements ApplicationListener {/** the camera **/OrthographicCamera camera;RayHandler rayHandler;World world;protected Body body;protected Box2DDebugRenderer mWorldDebugger;private int viewportWidth = 0;private int viewportHeight = 0;private ChainLight chainLight;private float bodyWidth = 50;private float bodyHeight = 50;@Overridepublic void create() {RayHandler.setGammaCorrection(true);viewportWidth = Gdx.graphics.getWidth();viewportHeight = Gdx.graphics.getHeight();camera = new OrthographicCamera(viewportWidth, viewportHeight);camera.position.set( viewportWidth/ 2f,viewportHeight/ 2f, 0);camera.update();world = new World(new Vector2(0, -10), true);mWorldDebugger = new Box2DDebugRenderer();makeBody();rayHandler = new RayHandler(world);rayHandler.setAmbientLight(Color.GRAY);float[] vertices = new float[] {-bodyWidth / 2, -bodyHeight / 2,bodyWidth / 2, -bodyHeight / 2,bodyWidth / 2, bodyHeight / 2,-bodyWidth / 2, bodyHeight / 2,-bodyWidth / 2, -bodyHeight / 2};chainLight = new ChainLight(rayHandler, 100, Color.WHITE, 500, -1,vertices);chainLight.attachToBody(body, 0);}private void makeBody() {PolygonShape ballShape = new PolygonShape();ballShape.setAsBox(bodyWidth / 2, bodyHeight / 2);FixtureDef fixtureDef = new FixtureDef();fixtureDef.shape = ballShape;BodyDef bodyDef = new BodyDef();bodyDef.type = BodyDef.BodyType.StaticBody;bodyDef.position.x = viewportWidth/ 2f;bodyDef.position.y = viewportHeight / 2f;body = world.createBody(bodyDef);body.createFixture(fixtureDef);ballShape.dispose();}@Overridepublic void resize(int width, int height) {camera.viewportWidth = width;camera.viewportHeight = height;camera.update();}@Overridepublic void render() {Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);world.step(1 / 60f, 8, 3);rayHandler.setCombinedMatrix(camera);rayHandler.updateAndRender();mWorldDebugger.render(world, camera.combined);}@Overridepublic void pause() {}@Overridepublic void resume() {}@Overridepublic void dispose() {rayHandler.dispose();}
}

ChainLight参数不一样的是

  1. rayDirection: 源码示例给的是1和-1 这个值其实代表发光角度,也可以设置其他数
  2. chain: 顶点数组
    ChainLight根据顶点确定发光体形状,rayDirection和chain的简单规律是
>> 1.1 如果是逆时针加入顶点 -1代表外部发光  1代表内部发光
>> 1.2 如果是顺时针加入顶点 -1代表内部发光  1代表外部发光

ChainLight比较特殊是必须依附于Body,Body决定了他的位置,示例是让一个正方形Body外围发光,顶点按照逆时针顺序添加。
唯一不接的一点是明明最后将原点设置为最后一个顶点,但是左下角却没有发光,不晓得是不是这个库的BUG

如果想定义圆形发光,比矩形麻烦点,需要很多个顶点,这些顶点连线形成这个圆形

RayHandler还有很多属性可以设置来加强模拟效果,可以多出尝试

注意:

  1. 如果没有调用RayHandler的serAmbinetLight设置环境光,而且开启了RayHandler模拟的话,界面是会一团黑的,你界面上绘制其他Actor是看不见的,除非有光照到他们
  2. 除了DirectionalLight,其他灯光都可以attachToBody

文章参考资料

  1. https://github.com/libgdx/box2dlights

libGDX:灯光效果实现一(实现一个点光源)相关推荐

  1. Opengl-阴影(分为定向光的和点光源的)

    前言 我们模拟了光照,发现真的很厉害,加上天空盒子,再加上反射感觉很逼真,但是看着看着你会发现..不对,没影子.是的,光和影分不开的,有光的地方就会有影子,这才是真实的道理.怎么模拟影子呢?这就要用到 ...

  2. Opengl-光照-基本光照-投光物-多光源(现实世界的光可不只有太阳也并不只有一个)

    前言 相信大家看过各种发光的道具,手电筒?看到过吧?灯泡看到过吧?除了太阳生活中还有各种灯红酒绿的地方(说错了)等着你去看啊 各种光源 平行光-太阳或者很远处的光都可以叫做平行光 平行光的光的方向是一 ...

  3. 4.3、Libgdx启动类和配置

    (原文:http://www.libgdx.cn/topic/45/4-3-libgdx%E5%90%AF%E5%8A%A8%E7%B1%BB%E4%B8%8E%E9%85%8D%E7%BD%AE) ...

  4. OpenGL在frag着色器中模拟点光源

    在3D世界中,模拟点光源实现对墙壁的光照.效果还是非常不错的. 思路如下: 准备一张墙壁图像. 自动生成墙壁的法线纹理. 模拟点光源. 添加漫反射. 随着时间变换进行规律性移动. 代码如下: #iCh ...

  5. OpenGL 点光源的多遍阴影贴图

    OpenGL点光源的多遍阴影贴图 OpenGL点光源的多遍阴影贴图简介 源代码剖析 主要源代码 OpenGL点光源的多遍阴影贴图简介 我们学习了阴影贴图的基础知识-第一次从光源位置通过使用光方向作为视 ...

  6. OpenGL 点光源阴影Point Shadows

    OpenGL点光源阴影Point Shadows 点光源阴影Point Shadows简介 生成深度立方体贴图 光空间的变换 深度着色器 万向阴影贴图 显示立方体贴图深度缓冲 PCF 点光源阴影Poi ...

  7. unity 烘焙参数 设置_Unity通用渲染管线(URP)系列(九)——点光源和聚光灯

    200+篇教程总入口,欢迎收藏: 放牛的星星:[教程汇总+持续更新]Unity从入门到入坟--收藏这一篇就够了​zhuanlan.zhihu.com 本文重点内容: 1.支持更多类型的灯光 2.包含实 ...

  8. Three.js - 光源使用详解1(环境光 AmbientLight、点光源 PointLint)

    Three.js 中有许多不同种类的光源,每种光源都有特别的行为和用法.下面通过一个系列文章介绍它们的用法. 一.THREE.AmbientLight(环境光) 1,基本介绍 在创建 THREE.Am ...

  9. WPF 3D 点光源学习

    先画一个平面,物体具有黄色的材质:不添加灯光,显示如下, 加入一个点光源,位置(1,1,1).颜色白色,如下,照亮了物体,看到物体的材质: 点光源是从斜上方照过来的, 如果光源为绿色,则如下, 点光源 ...

最新文章

  1. Matlab与线性代数 -- 矩阵的秩
  2. python精简笔记(五)——函数式编程
  3. 【转】如何用Redis做LRU-Cache
  4. [elixir观察] GenStage 与 Flow
  5. nginx出现404和403错误
  6. tcc读写文本txt文件
  7. tinyxml 读取文本节点_在Windows下使用TinyXML-2读取UTF-8编码包含中文字符的XML文件...
  8. lnmp 清除mysql日志,军哥LNMP 如何关闭 Mysql 日志,并且删除 mysql-bin.0000*日志文件...
  9. Hadoop HDFS 的 Java API 操作方式
  10. Azkaban流2.0
  11. (void __user *)arg 中__user的作用
  12. windows无法新建计算机对象,教您activex部件不能创建对象怎么解决
  13. 浏览器网页自动刷新脚本
  14. 论文笔记: FSA-Net
  15. Rimworld Mod制作教程7 comp组件
  16. 网站中木马病毒了怎么办
  17. 有人说:世间唯一无刺的玫瑰,就是朋友。
  18. vue 用key拿对象value_基于vue--key值的特殊用处详解
  19. IOS 最新邓白氏编码申请
  20. ios15.0.1正式版耗电吗 ios15.0.1正式版值得升级吗

热门文章

  1. 刀工:谈推荐系统特征工程中的几个高级技巧
  2. echarts的学习
  3. 动态电压降问题解决方法总结
  4. UE4 回合游戏项目 15- 生成玩家、控制玩家
  5. python实现批量图片jpg格式转png
  6. 机器人工程毕业设计☞区域覆盖(扫地)
  7. Java400道面试题通关宝典助你进大厂,看这篇足矣了!
  8. 英语写作的常用句型(二)
  9. web站点的ssl安全性检测
  10. 提升自我数据分析能力的根本,是方法论!