소스 검색

[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);