浏览代码

[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 ) {
 	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 {
 	public function initLights( ctx : h3d.scene.RenderContext ) @:privateAccess {
 		this.ctx = ctx;
 		this.ctx = ctx;
+		sortLights(ctx);
 		if( shadowLight == null || !shadowLight.allocated) {
 		if( shadowLight == null || !shadowLight.allocated) {
 			var l = ctx.lights;
 			var l = ctx.lights;
 			while( l != null ) {
 			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 shadows : h3d.pass.Shadows;
 	public var isMainLight = false;
 	public var isMainLight = false;
 	public var occlusionFactor : Float;
 	public var occlusionFactor : Float;
+	public var enableForward : Bool = true;
 
 
 	function new(shader,?parent) {
 	function new(shader,?parent) {
 		super(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();
 	public var defaultForwardShader = new h3d.shader.pbr.DefaultForward();
 
 
 	var MAX_DIR_LIGHT = 2;
 	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;
 	var lightInfos : hxd.FloatBuffer;
 	final POINT_LIGHT_INFO_SIZE = 3;
 	final POINT_LIGHT_INFO_SIZE = 3;
@@ -103,7 +103,7 @@ class LightBuffer {
 
 
 			// Dir Light
 			// Dir Light
 			var dl = Std.downcast(l, DirLight);
 			var dl = Std.downcast(l, DirLight);
-			if( dl != null ) {
+			if( dl != null && s.dirLightCount < MAX_DIR_LIGHT ) {
 				var li = s.dirLightCount;
 				var li = s.dirLightCount;
 				var i = li * DIR_LIGHT_INFO_SIZE * 4;
 				var i = li * DIR_LIGHT_INFO_SIZE * 4;
 				var pbr = @:privateAccess dl.pbr;
 				var pbr = @:privateAccess dl.pbr;
@@ -123,7 +123,7 @@ class LightBuffer {
 
 
 			// Point Light
 			// Point Light
 			var pl = Std.downcast(l, PointLight);
 			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 offset = MAX_DIR_LIGHT * DIR_LIGHT_INFO_SIZE * 4;
 				var li = s.pointLightCount;
 				var li = s.pointLightCount;
 				var i = li * POINT_LIGHT_INFO_SIZE * 4 + offset;
 				var i = li * POINT_LIGHT_INFO_SIZE * 4 + offset;
@@ -143,7 +143,7 @@ class LightBuffer {
 
 
 			// Spot Light
 			// Spot Light
 			var sl = Std.downcast(l, SpotLight);
 			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 offset = (MAX_DIR_LIGHT * DIR_LIGHT_INFO_SIZE + MAX_POINT_LIGHT * POINT_LIGHT_INFO_SIZE) * 4 ;
 				var li = s.spotLightCount;
 				var li = s.spotLightCount;
 				var i = s.spotLightCount * SPOT_LIGHT_INFO_SIZE * 4 + offset;
 				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;
 		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 {
 	override function initLights( ctx : h3d.scene.RenderContext ) @:privateAccess {
 		super.initLights(ctx);
 		super.initLights(ctx);
 		lightBuffer.sync(ctx);
 		lightBuffer.sync(ctx);