浏览代码

[LIGHTS][FORWARD] Fix light buffer light type count. Added light sorting depending on their distance to the camera. Added forward flag on PBR lights (without, they are last when sorting lights, useful for dynamic lights such as torches).

clandrin 4 年之前
父节点
当前提交
bc92e51ed3
共有 4 个文件被更改,包括 44 次插入5 次删除
  1. 24 0
      h3d/scene/LightSystem.hx
  2. 1 0
      h3d/scene/pbr/Light.hx
  3. 5 5
      h3d/scene/pbr/LightBuffer.hx
  4. 14 0
      h3d/scene/pbr/LightSystem.hx

+ 24 - 0
h3d/scene/LightSystem.hx

@@ -13,8 +13,32 @@ class LightSystem {
 	public function initGlobals( globals : hxsl.Globals ) {
 	}
 
+	function sortingCriteria ( l1 : Light, l2 : Light ) {
+		var d1 = l1.getAbsPos().getPosition().sub(ctx.camera.target).length();
+		var d2 = l2.getAbsPos().getPosition().sub(ctx.camera.target).length();
+		return d1 > d2 ? 1 : -1;
+	}
+
+	public function sortLights ( ctx : h3d.scene.RenderContext ) @:privateAccess {
+		var lights = [];
+		var l = ctx.lights;
+		if ( l == null )
+			return;
+		while ( l != null ) {
+			lights.push(l);
+			l = l.next;
+		}
+		lights.sort(function(l1,l2) { return sortingCriteria(l1, l2); });
+		ctx.lights = lights[0];
+		for (i in 0...lights.length - 1) {
+			lights[i].next = lights[i + 1];
+		}
+		lights[lights.length-1].next = null;
+	}
+
 	public function initLights( ctx : h3d.scene.RenderContext ) @:privateAccess {
 		this.ctx = ctx;
+		sortLights(ctx);
 		if( shadowLight == null || !shadowLight.allocated) {
 			var l = ctx.lights;
 			while( l != null ) {

+ 1 - 0
h3d/scene/pbr/Light.hx

@@ -8,6 +8,7 @@ class Light extends h3d.scene.Light {
 	public var shadows : h3d.pass.Shadows;
 	public var isMainLight = false;
 	public var occlusionFactor : Float;
+	public var enableForward : Bool = true;
 
 	function new(shader,?parent) {
 		super(shader,parent);

+ 5 - 5
h3d/scene/pbr/LightBuffer.hx

@@ -5,8 +5,8 @@ class LightBuffer {
 	public var defaultForwardShader = new h3d.shader.pbr.DefaultForward();
 
 	var MAX_DIR_LIGHT = 2;
-	var MAX_SPOT_LIGHT = 6;
-	var MAX_POINT_LIGHT = 6;
+	var MAX_SPOT_LIGHT = 10;
+	var MAX_POINT_LIGHT = 10;
 
 	var lightInfos : hxd.FloatBuffer;
 	final POINT_LIGHT_INFO_SIZE = 3;
@@ -103,7 +103,7 @@ class LightBuffer {
 
 			// Dir Light
 			var dl = Std.downcast(l, DirLight);
-			if( dl != null ) {
+			if( dl != null && s.dirLightCount < MAX_DIR_LIGHT ) {
 				var li = s.dirLightCount;
 				var i = li * DIR_LIGHT_INFO_SIZE * 4;
 				var pbr = @:privateAccess dl.pbr;
@@ -123,7 +123,7 @@ class LightBuffer {
 
 			// Point Light
 			var pl = Std.downcast(l, PointLight);
-			if( pl != null ) {
+			if( pl != null && s.pointLightCount < MAX_POINT_LIGHT ) {
 				var offset = MAX_DIR_LIGHT * DIR_LIGHT_INFO_SIZE * 4;
 				var li = s.pointLightCount;
 				var i = li * POINT_LIGHT_INFO_SIZE * 4 + offset;
@@ -143,7 +143,7 @@ class LightBuffer {
 
 			// Spot Light
 			var sl = Std.downcast(l, SpotLight);
-			if( sl != null ) {
+			if( sl != null && s.spotLightCount < MAX_SPOT_LIGHT ) {
 				var offset = (MAX_DIR_LIGHT * DIR_LIGHT_INFO_SIZE + MAX_POINT_LIGHT * POINT_LIGHT_INFO_SIZE) * 4 ;
 				var li = s.spotLightCount;
 				var i = s.spotLightCount * SPOT_LIGHT_INFO_SIZE * 4 + offset;

+ 14 - 0
h3d/scene/pbr/LightSystem.hx

@@ -34,6 +34,20 @@ class LightSystem extends h3d.scene.LightSystem {
 		return shaders;
 	}
 
+	override function sortingCriteria ( l1, l2 ) {
+		var pbr1 = Std.downcast(l1, h3d.scene.pbr.Light);
+		var pbr2 = Std.downcast(l2, h3d.scene.pbr.Light);
+		var last1 = pbr1 != null && !pbr1.enableForward;
+		var last2 = pbr2 != null && !pbr2.enableForward;
+		if (last1 && !last2) {
+			return 1;
+		}
+		if (last2 && !last1) {
+			return -1;
+		}
+		return super.sortingCriteria(l1, l2);
+	}
+
 	override function initLights( ctx : h3d.scene.RenderContext ) @:privateAccess {
 		super.initLights(ctx);
 		lightBuffer.sync(ctx);