国内的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. 何向南教授团队最新综述:对话推荐系统中的进展与未来挑战
  2. v3s 全志_基于全志V3s的开源开发板,提供pcb和系统源码和资料
  3. android 剪切板广播发送者,Android使用剪切板传递数据
  4. TS Decorator
  5. java压缩传输gzip_服务器使用Gzip压缩数据,加快网络传输(Java 例子)
  6. Linux内核源代码分析——中断(一鞭一条痕)(下)
  7. vuex模块相互调用
  8. 解决delphi7在win10上安装后无法正常使用的问题
  9. 需求跟踪矩阵和需求评审
  10. Domain Driven Design(领域驱动设计)
  11. word2010中插入脚注和尾注
  12. nginx实现https与http共存方案
  13. 微信又更新啦,再也不怕错过女朋友的消息
  14. Python学习,用python制作字符版gif图
  15. hdu 5535 Cake 构造+记忆化搜索
  16. C语言:输入字符并将它们输出
  17. wps 每页显示50行
  18. 富士康员工盗卖iPhone部件3年赚3亿;张朝阳称工作只为赚钱太low;国产统一操作系统 UOS 正全面适配 | EA周报...
  19. 职业经理人管理素养提升课程
  20. ViewPager按比例显示图片(显示下一张图片的一部分)

热门文章

  1. 开源不是免费的午餐,新变化背后的趋势是什么?
  2. 弘辽科技:淘宝如何运营店铺?运营步骤是什么?
  3. 小马哥----高仿米2主板型号m8219刷机拆机主板图与开机界面图 多图展示 刷机谨慎
  4. 【fraud detection】秒针系统发布《互联网广告反作弊技术白皮书》
  5. 解决SQL Server 2000安装文件挂起
  6. java播放器_java音频播放器
  7. SKU逻辑 vue实现一起学习交流
  8. 仿微信手机端支付页面代码可改余额
  9. 使用异步爬虫爬取网络小说
  10. 主板性能的好坏可以影响计算机的整体性能,关于电脑主板的小小闲谈