Bladeren bron

[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 jaren geleden
bovenliggende
commit
bc92e51ed3
4 gewijzigde bestanden met toevoegingen van 44 en 5 verwijderingen
  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);