Explorar el Código

refactor: moved forward renderer specific classes to h3d.scene.fwd package
pbr lights now have factorized code for filterPasses
disable late bounds checks for pbr PointShadowMap

ncannasse hace 6 años
padre
commit
369df94857

+ 3 - 3
h3d/mat/MaterialSetup.hx

@@ -13,11 +13,11 @@ class MaterialSetup {
 	}
 
 	public function createRenderer() : h3d.scene.Renderer {
-		return new h3d.scene.DefaultRenderer();
+		return new h3d.scene.fwd.Renderer();
 	}
 
-	public function createLightSystem() {
-		return new h3d.scene.LightSystem();
+	public function createLightSystem() : h3d.scene.LightSystem {
+		return new h3d.scene.fwd.LightSystem();
 	}
 
 	public function createMaterial() {

+ 3 - 21
h3d/pass/DirShadowMap.hx

@@ -109,7 +109,7 @@ class DirShadowMap extends Shadows {
 		cameraViewProj = getShadowProj();
 	}
 
-	function syncShader(texture) {
+	override function syncShader(texture) {
 		dshader.shadowMap = texture;
 		dshader.shadowMapChannel = format == h3d.mat.Texture.nativeFormat ? PackedFloat : R;
 		dshader.shadowBias = bias;
@@ -173,26 +173,8 @@ class DirShadowMap extends Shadows {
 	}
 
 	override function draw( passes ) {
-
-		if( !ctx.computingStatic ){
-			switch( mode ) {
-			case None:
-				return;
-			case Dynamic:
-				// nothing
-			case Static, Mixed:
-				if( staticTexture == null || staticTexture.isDisposed() ){
-					staticTexture = h3d.mat.Texture.fromColor(0xFFFFFF);
-					staticTexture.name = "defaultDirShadowMap";
-				}
-				if( mode == Static ) {
-					syncShader(staticTexture);
-					return;
-				}
-			}
-		}
-
-		filterPasses(passes);
+		if( !filterPasses(passes) )
+			return;
 
 		var texture = ctx.textures.allocTarget("dirShadowMap", size, size, false, format);
 		if( customDepth && (depth == null || depth.width != size || depth.height != size || depth.isDisposed()) ) {

+ 8 - 86
h3d/pass/PointShadowMap.hx

@@ -53,7 +53,7 @@ class PointShadowMap extends Shadows {
 		cameraPos = lightCamera.pos;
 	}
 
-	function syncShader(texture) {
+	override function syncShader(texture) {
 		var absPos = light.getAbsPos();
 		var pointLight = cast(light, h3d.scene.pbr.PointLight);
 		pshader.shadowMap = texture;
@@ -102,40 +102,22 @@ class PointShadowMap extends Shadows {
 		return true;
 	}
 
-	function createDefaultShadowMap(){
+	override function createDefaultShadowMap() {
 		var tex = new h3d.mat.Texture(1,1, [Target,Cube], format);
-		tex.name = "defaultStaticTexture";
+		tex.name = "defaultCubeShadowMap";
 		for(i in 0 ... 6)
 			tex.clear(0xFFFFFF, i);
 		return tex;
 	}
 
 	override function draw( passes ) {
-
-		if( !ctx.computingStatic ){
-			switch( mode ) {
-			case None:
-				return;
-			case Dynamic:
-				// nothing
-			case Mixed:
-				if( staticTexture == null || staticTexture.isDisposed() )
-					staticTexture = createDefaultShadowMap();
-			case Static:
-				if( staticTexture == null || staticTexture.isDisposed() )
-					staticTexture = createDefaultShadowMap();
-				updateCamera();
-				syncShader(staticTexture);
-				return;
-			}
-		}
-
-		filterPasses(passes);
+		if( !filterPasses(passes) )
+			return;
 
 		var texture = ctx.textures.allocTarget("pointShadowMap", size, size, false, format, true);
 		if(depth == null || depth.width != size || depth.height != size || depth.isDisposed() ) {
-				if( depth != null ) depth.dispose();
-				depth = new h3d.mat.DepthBuffer(size, size);
+			if( depth != null ) depth.dispose();
+			depth = new h3d.mat.DepthBuffer(size, size);
 		}
 		texture.depthBuffer = depth;
 
@@ -146,15 +128,8 @@ class PointShadowMap extends Shadows {
 
 		var pointLight = cast(light, h3d.scene.pbr.PointLight);
 		var absPos = light.getAbsPos();
-		var lightBounds = new h3d.col.Bounds();
-		lightBounds.addPoint( new h3d.col.Point(absPos.tx + pointLight.range, absPos.ty + pointLight.range, absPos.tz + pointLight.range));
-		lightBounds.addPoint( new h3d.col.Point(absPos.tx - pointLight.range, absPos.ty - pointLight.range, absPos.tz - pointLight.range));
 
 		for(i in 0 ... 6){
-
-			var pointLight = cast(light, h3d.scene.pbr.PointLight);
-
-			var absPos = light.getAbsPos();
 			lightCamera.setCubeMap(i, new h3d.Vector(absPos.tx, absPos.ty, absPos.tz));
 			lightCamera.zFar = pointLight.range;
 			lightCamera.zNear = pointLight.zNear;
@@ -162,8 +137,7 @@ class PointShadowMap extends Shadows {
 
 			ctx.engine.pushTarget(texture, i);
 			ctx.engine.clear(0xFFFFFF, 1);
-			customDraw(passes, lightBounds);
-
+			super.draw(passes);
 			ctx.engine.popTarget();
 		}
 
@@ -185,58 +159,6 @@ class PointShadowMap extends Shadows {
 		syncShader(texture);
 	}
 
-	@:access(h3d.scene)
-	function customDraw( passes : h3d.pass.PassList, lightBounds : h3d.col.Bounds) {
-		if( passes == null )
-			return;
-		for( g in ctx.sharedGlobals )
-			globals.fastSet(g.gid, g.value);
-		setGlobals();
-		setupShaders(passes);
-		var shaderStart = shaderCount, textureStart = textureCount;
-		for( p in passes ) {
-			if( shaderIdMap[p.shader.id] < shaderStart #if js || shaderIdMap[p.shader.id] == null #end )
-				shaderIdMap[p.shader.id] = shaderCount++;
-			if( textureIdMap[p.texture] < textureStart #if js || textureIdMap[p.shader.id] == null #end )
-				textureIdMap[p.texture] = textureCount++;
-		}
-		if( sortPasses )
-			passes.sort(function(o1, o2) {
-				var d = shaderIdMap[o1.shader.id] - shaderIdMap[o2.shader.id];
-				if( d != 0 ) return d;
-				return textureIdMap[o1.texture] - textureIdMap[o2.texture];
-			});
-		ctx.uploadParams = uploadParams;
-		var buf = cachedBuffer, prevShader = null;
-		for( p in passes ) {
-
-			if( !lightCamera.frustum.hasBounds(p.obj.getBounds()))
-				continue;
-
-			globalModelView = p.obj.absPos;
-			if( p.shader.hasGlobal(globalModelViewInverse_id.toInt()) )
-				globalModelViewInverse = p.obj.getInvPos();
-			if( prevShader != p.shader ) {
-				prevShader = p.shader;
-				ctx.engine.selectShader(p.shader);
-				if( buf == null )
-					buf = cachedBuffer = new h3d.shader.Buffers(p.shader);
-				else
-					buf.grow(p.shader);
-				manager.fillGlobals(buf, p.shader);
-				ctx.engine.uploadShaderBuffers(buf, Globals);
-			}
-			if( !p.pass.dynamicParameters ) {
-				manager.fillParams(buf, p.shader, p.shaders);
-				ctx.engine.uploadShaderBuffers(buf, Params);
-				ctx.engine.uploadShaderBuffers(buf, Textures);
-				ctx.engine.uploadShaderBuffers(buf, Buffers);
-			}
-			drawObject(p);
-		}
-		ctx.nextPass();
-	}
-
 	function updateCamera(){
 		var absPos = light.getAbsPos();
 		lightCamera.pos.set(absPos.tx, absPos.ty, absPos.tz);

+ 26 - 0
h3d/pass/Shadows.hx

@@ -84,7 +84,32 @@ class Shadows extends Default {
 		throw "Not implemented";
 	}
 
+	function createDefaultShadowMap() {
+		var tex = h3d.mat.Texture.fromColor(0xFFFFFF);
+		tex.name = "defaultShadowMap";
+		return tex;
+	}
+
+	function syncShader( texture : h3d.mat.Texture ) {
+	}
+
 	function filterPasses( passes : h3d.pass.PassList ) {
+		if( !ctx.computingStatic ){
+			switch( mode ) {
+			case None:
+				return false;
+			case Dynamic:
+				// nothing
+			case Mixed:
+				if( staticTexture == null || staticTexture.isDisposed() )
+					staticTexture = createDefaultShadowMap();
+			case Static:
+				if( staticTexture == null || staticTexture.isDisposed() )
+					staticTexture = createDefaultShadowMap();
+				syncShader(staticTexture);
+				return false;
+			}
+		}
 		switch( mode ) {
 		case None:
 			passes.clear();
@@ -98,6 +123,7 @@ class Shadows extends Default {
 			else
 				passes.clear();
 		}
+		return true;
 	}
 
 }

+ 3 - 19
h3d/pass/SpotShadowMap.hx

@@ -50,7 +50,7 @@ class SpotShadowMap extends Shadows {
 		cameraViewProj = getShadowProj();
 	}
 
-	function syncShader(texture) {
+	override function syncShader(texture) {
 		sshader.shadowMap = texture;
 		sshader.shadowMapChannel = format == h3d.mat.Texture.nativeFormat ? PackedFloat : R;
 		sshader.shadowBias = bias;
@@ -89,25 +89,9 @@ class SpotShadowMap extends Shadows {
 	}
 
 	override function draw( passes ) {
+		if( !filterPasses(passes) )
+			return;
 
-		if( !ctx.computingStatic )
-			switch( mode ) {
-			case None:
-				return;
-			case Dynamic:
-				// nothing
-			case Mixed:
-				if( staticTexture == null || staticTexture.isDisposed() )
-					staticTexture = h3d.mat.Texture.fromColor(0xFFFFFF);
-			case Static:
-				if( staticTexture == null || staticTexture.isDisposed() )
-					staticTexture = h3d.mat.Texture.fromColor(0xFFFFFF);
-				updateCamera();
-				syncShader(staticTexture);
-				return;
-			}
-
-		filterPasses(passes);
 		updateCamera();
 
 		var texture = ctx.textures.allocTarget("shadowMap", size, size, false, format);

+ 1 - 1
h3d/scene/Light.hx

@@ -6,7 +6,7 @@ class Light extends Object {
 	var objectDistance : Float; // used internaly
 	@:noCompletion public var next : Light; // used internaly (public to allow sorting)
 
-	@:s var cullingDistance : Float = 1e10;
+	@:s var cullingDistance : Float = -1;
 	@:s public var priority : Int = 0;
 	public var color(get, set) : h3d.Vector;
 	public var enableSpecular(get, set) : Bool;

+ 12 - 62
h3d/scene/LightSystem.hx

@@ -1,42 +1,26 @@
 package h3d.scene;
 
-@:access(h3d.scene.Light)
-@:access(h3d.scene.Object.absPos)
-@:access(h3d.scene.RenderContext.lights)
 class LightSystem {
 
-	public var maxLightsPerObject = 6;
-	var globals : hxsl.Globals;
-	var ambientShader : hxsl.Shader;
-	var lightCount : Int;
-	var ctx : h3d.scene.RenderContext;
+	public var drawPasses(default,null) : Int = 0;
+	public var ambientLight(default,null) : h3d.Vector;
 	public var shadowLight : h3d.scene.Light;
-	public var ambientLight : h3d.Vector;
-	public var perPixelLighting : Bool = true;
 
-	/**
-		In the additive lighting model (by default), the lights are added after the ambient.
-		In the new non additive ligthning model, the lights will be modulated against the ambient, so an ambient of 1 will reduce lights intensities to 0.
-	**/
-	public var additiveLighting(get, set) : Bool;
+	var lightCount : Int;
+	var ctx : RenderContext;
 
 	public function new() {
-		ambientLight = new h3d.Vector(0.5, 0.5, 0.5);
-		ambientShader = new h3d.shader.AmbientLight();
-		additiveLighting = true;
-	}
-
-	function get_additiveLighting() {
-		return Std.instance(ambientShader,h3d.shader.AmbientLight).additive;
+		ambientLight = new h3d.Vector(1,1,1);
 	}
 
-	function set_additiveLighting(b) {
-		return Std.instance(ambientShader,h3d.shader.AmbientLight).additive = b;
+	public function initGlobals( globals : hxsl.Globals ) {
 	}
 
-	public function initLights( ctx : h3d.scene.RenderContext ) {
+	public function initLights( ctx : h3d.scene.RenderContext ) @:privateAccess {
 		lightCount = 0;
 		this.ctx = ctx;
+
+		// remove lights which cullingDistance is outside of frustum
 		var l = ctx.lights, prev : h3d.scene.Light = null;
 		var frustum = new h3d.col.Frustum(ctx.camera.m);
 		var s = new h3d.col.Sphere();
@@ -46,7 +30,7 @@ class LightSystem {
 			s.z = l.absPos._43;
 			s.r = l.cullingDistance;
 
-			if(!ctx.computingStatic && !frustum.hasSphere(s) ) {
+			if( l.cullingDistance > 0 && !ctx.computingStatic && !frustum.hasSphere(s) ) {
 				if( prev == null )
 					ctx.lights = l.next;
 				else
@@ -60,12 +44,11 @@ class LightSystem {
 			prev = l;
 			l = l.next;
 		}
-		if( lightCount <= maxLightsPerObject )
-			ctx.lights = haxe.ds.ListSort.sortSingleLinked(ctx.lights, sortLight);
+
 		if( shadowLight == null || !shadowLight.allocated) {
 			var l = ctx.lights;
 			while( l != null ) {
-				var dir = @:privateAccess l.getShadowDirection();
+				var dir = l.getShadowDirection();
 				if( dir != null ) {
 					shadowLight = l;
 					break;
@@ -75,40 +58,7 @@ class LightSystem {
 		}
 	}
 
-	public function initGlobals( globals : hxsl.Globals ) {
-		globals.set("global.ambientLight", ambientLight);
-		globals.set("global.perPixelLighting", perPixelLighting);
-	}
-
-	function sortLight( l1 : h3d.scene.Light, l2 : h3d.scene.Light ) {
-		var p = l1.priority - l2.priority;
-		if( p != 0 ) return -p;
-		return l1.objectDistance < l2.objectDistance ? -1 : 1;
-	}
-
 	public function computeLight( obj : h3d.scene.Object, shaders : hxsl.ShaderList ) : hxsl.ShaderList {
-		if( lightCount > maxLightsPerObject ) {
-			var l = ctx.lights;
-			while( l != null ) {
-				if( obj.lightCameraCenter )
-					l.objectDistance = hxd.Math.distanceSq(l.absPos._41 - ctx.camera.target.x, l.absPos._42 - ctx.camera.target.y, l.absPos._43 - ctx.camera.target.z);
-				else
-					l.objectDistance = hxd.Math.distanceSq(l.absPos._41 - obj.absPos._41, l.absPos._42 - obj.absPos._42, l.absPos._43 - obj.absPos._43);
-				l = l.next;
-			}
-			ctx.lights = haxe.ds.ListSort.sortSingleLinked(ctx.lights, sortLight);
-		}
-		inline function add( s : hxsl.Shader ) {
-			shaders = ctx.allocShaderList(s, shaders);
-		}
-		add(ambientShader);
-		var l = ctx.lights;
-		var i = 0;
-		while( l != null ) {
-			if( i++ == maxLightsPerObject ) break;
-			add(l.shader);
-			l = l.next;
-		}
 		return shaders;
 	}
 

+ 2 - 2
h3d/scene/DirLight.hx → h3d/scene/fwd/DirLight.hx

@@ -1,4 +1,4 @@
-package h3d.scene;
+package h3d.scene.fwd;
 
 class DirLight extends Light {
 
@@ -28,7 +28,7 @@ class DirLight extends Light {
 	}
 
 	override function getShadowDirection() : h3d.Vector {
-		return absPos.front();	
+		return absPos.front();
 	}
 
 	override function emit(ctx) {

+ 74 - 0
h3d/scene/fwd/LightSystem.hx

@@ -0,0 +1,74 @@
+package h3d.scene.fwd;
+
+class LightSystem extends h3d.scene.LightSystem {
+
+	public var maxLightsPerObject = 6;
+	var globals : hxsl.Globals;
+	var ambientShader : hxsl.Shader;
+	public var perPixelLighting : Bool = true;
+
+	/**
+		In the additive lighting model (by default), the lights are added after the ambient.
+		In the new non additive ligthning model, the lights will be modulated against the ambient, so an ambient of 1 will reduce lights intensities to 0.
+	**/
+	public var additiveLighting(get, set) : Bool;
+
+	public function new() {
+		super();
+		ambientLight.set(0.5, 0.5, 0.5);
+		ambientShader = new h3d.shader.AmbientLight();
+		additiveLighting = true;
+	}
+
+	function get_additiveLighting() {
+		return Std.instance(ambientShader,h3d.shader.AmbientLight).additive;
+	}
+
+	function set_additiveLighting(b) {
+		return Std.instance(ambientShader,h3d.shader.AmbientLight).additive = b;
+	}
+
+	override function initLights(ctx) {
+		super.initLights(ctx);
+		if( lightCount <= maxLightsPerObject )
+			@:privateAccess ctx.lights = haxe.ds.ListSort.sortSingleLinked(ctx.lights, sortLight);
+	}
+
+	override function initGlobals( globals : hxsl.Globals ) {
+		globals.set("global.ambientLight", ambientLight);
+		globals.set("global.perPixelLighting", perPixelLighting);
+	}
+
+	function sortLight( l1 : h3d.scene.Light, l2 : h3d.scene.Light ) {
+		var p = l1.priority - l2.priority;
+		if( p != 0 ) return -p;
+		return @:privateAccess (l1.objectDistance < l2.objectDistance ? -1 : 1);
+	}
+
+	override function computeLight( obj : h3d.scene.Object, shaders : hxsl.ShaderList ) : hxsl.ShaderList @:privateAccess {
+		if( lightCount > maxLightsPerObject ) {
+			var l = ctx.lights;
+			while( l != null ) {
+				if( obj.lightCameraCenter )
+					l.objectDistance = hxd.Math.distanceSq(l.absPos._41 - ctx.camera.target.x, l.absPos._42 - ctx.camera.target.y, l.absPos._43 - ctx.camera.target.z);
+				else
+					l.objectDistance = hxd.Math.distanceSq(l.absPos._41 - obj.absPos._41, l.absPos._42 - obj.absPos._42, l.absPos._43 - obj.absPos._43);
+				l = l.next;
+			}
+			ctx.lights = haxe.ds.ListSort.sortSingleLinked(ctx.lights, sortLight);
+		}
+		inline function add( s : hxsl.Shader ) {
+			shaders = ctx.allocShaderList(s, shaders);
+		}
+		add(ambientShader);
+		var l = ctx.lights;
+		var i = 0;
+		while( l != null ) {
+			if( i++ == maxLightsPerObject ) break;
+			add(l.shader);
+			l = l.next;
+		}
+		return shaders;
+	}
+
+}

+ 1 - 1
h3d/scene/PointLight.hx → h3d/scene/fwd/PointLight.hx

@@ -1,4 +1,4 @@
-package h3d.scene;
+package h3d.scene.fwd;
 
 class PointLight extends Light {
 

+ 2 - 2
h3d/scene/DefaultRenderer.hx → h3d/scene/fwd/Renderer.hx

@@ -1,4 +1,4 @@
-package h3d.scene;
+package h3d.scene.fwd;
 
 private typedef SMap<T> = #if flash haxe.ds.UnsafeStringMap<T> #else Map<String,T> #end
 
@@ -51,7 +51,7 @@ class NormalPass extends h3d.pass.Default {
 
 }
 
-class DefaultRenderer extends Renderer {
+class Renderer extends h3d.scene.Renderer {
 
 	var def(get, never) : h3d.pass.Base;
 	public var depth : h3d.pass.Base = new DepthPass();

+ 1 - 25
h3d/scene/pbr/LightSystem.hx

@@ -3,36 +3,12 @@ package h3d.scene.pbr;
 @:access(h3d.scene.pbr.Light)
 class LightSystem extends h3d.scene.LightSystem {
 
-	public function init( r : h3d.scene.Renderer ) {
-		this.ctx = @:privateAccess r.ctx;
-	}
-
 	override function computeLight( obj : h3d.scene.Object, shaders : hxsl.ShaderList ) : hxsl.ShaderList {
 		var light = Std.instance(obj, h3d.scene.pbr.Light);
 		if( light != null ) {
 			shaders = ctx.allocShaderList(light.shader, shaders);
-			if( light.shadows.shader != null && light.shadows.mode != None ){
-
-				var pointShadow = Std.instance(light.shadows.shader, h3d.shader.PointShadow );
-				if(pointShadow != null && pointShadow.shadowMap == null){
-					throw "Rendering a pbr pointlight with shadows, without the shadowMap";
-					return shaders;
-				}
-
-				var dirShadow = Std.instance(light.shadows.shader, h3d.shader.DirShadow );
-				if(dirShadow != null && dirShadow.shadowMap == null){
-					throw "Rendering a pbr dirLight with shadows, without the shadowMap";
-					return shaders;
-				}
-
-				var spotShadow = Std.instance(light.shadows.shader, h3d.shader.SpotShadow );
-				if(spotShadow != null && spotShadow.shadowMap == null){
-					throw "Rendering a pbr spotLight with shadows, without the shadowMap";
-					return shaders;
-				}
-
+			if( light.shadows.shader != null && light.shadows.mode != None )
 				shaders = ctx.allocShaderList(light.shadows.shader, shaders);
-			}
 		}
 		return shaders;
 	}

+ 3 - 3
h3d/scene/pbr/Renderer.hx

@@ -198,8 +198,6 @@ class Renderer extends h3d.scene.Renderer {
 		ctx.setGlobal("occlusionMap",{ texture : pbr, channel : hxsl.Channel.B });
 		ctx.setGlobal("bloom",null);
 
-		var ls = Std.instance(getLightSystem(), LightSystem);
-		if( ls != null ) ls.init(this);
 		drawShadows();
 
 		setTargets([albedo,normal,pbr,other]);
@@ -291,7 +289,9 @@ class Renderer extends h3d.scene.Renderer {
 
 		// Draw DirLight, screenShader
 		pbrProps.isScreen = true;
-		if( ls != null )  ls.drawScreenLights(this, lpass);
+		var ls = Std.instance(getLightSystem(), LightSystem);
+		if( ls != null )
+			ls.drawScreenLights(this, lpass);
 		// Draw others lights with their primitive
 		pbrProps.isScreen = false;
 		draw(pbrLightPass.name);

+ 9 - 7
hxd/inspect/SceneProps.hx

@@ -81,11 +81,13 @@ class SceneProps {
 
 			var ls = scene.lightSystem;
 			var props = [];
-			props.push(PGroup("LightSystem",[
-				PRange("maxLightsPerObject", 0, 10, function() return ls.maxLightsPerObject, function(s) ls.maxLightsPerObject = Std.int(s), 1),
-				PColor("ambientLight", false, function() return ls.ambientLight, function(v) ls.ambientLight = v),
-				PBool("perPixelLighting", function() return ls.perPixelLighting, function(b) ls.perPixelLighting = b),
-			]));
+			var fls = Std.instance(ls, h3d.scene.fwd.LightSystem);
+			if( fls != null )
+				props.push(PGroup("LightSystem",[
+					PRange("maxLightsPerObject", 0, 10, function() return fls.maxLightsPerObject, function(s) fls.maxLightsPerObject = Std.int(s), 1),
+					PColor("ambientLight", false, function() return fls.ambientLight, function(v) fls.ambientLight = v),
+					PBool("perPixelLighting", function() return fls.perPixelLighting, function(b) fls.perPixelLighting = b),
+				]));
 
 			if( ls.shadowLight != null )
 				props.push(PGroup("DirLight", getObjectProps(ls.shadowLight)));
@@ -247,13 +249,13 @@ class SceneProps {
 		props.push(PColor("color", false, function() return l.color, function(c) l.color.load(c)));
 		props.push(PRange("priority", 0, 10, function() return l.priority, function(p) l.priority = Std.int(p),1));
 		props.push(PBool("enableSpecular", function() return l.enableSpecular, function(b) l.enableSpecular = b));
-		var dl = Std.instance(l, h3d.scene.DirLight);
+		var dl = Std.instance(l, h3d.scene.fwd.DirLight);
 		if( dl != null )
 			props.push(PFloats("direction", function() {
 				var dir = dl.getDirection();
 				return [dl.x, dl.y, dl.z];
 			}, function(fl) dl.setDirection(new h3d.Vector(fl[0], fl[1], fl[2]))));
-		var pl = Std.instance(l, h3d.scene.PointLight);
+		var pl = Std.instance(l, h3d.scene.fwd.PointLight);
 		if( pl != null )
 			props.push(PFloats("params", function() return [pl.params.x, pl.params.y, pl.params.z], function(fl) pl.params.set(fl[0], fl[1], fl[2], fl[3])));
 		return PGroup("Light", props);

+ 2 - 2
samples/Base3D.hx

@@ -46,7 +46,7 @@ class Base3D extends SampleApp {
 		obj2.scale(0.6);
 
 		// adds a directional light to the scene
-		var light = new h3d.scene.DirLight(new h3d.Vector(0.5, 0.5, -0.5), s3d);
+		var light = new h3d.scene.fwd.DirLight(new h3d.Vector(0.5, 0.5, -0.5), s3d);
 		light.enableSpecular = true;
 
 		// set the ambient light to 30%
@@ -55,7 +55,7 @@ class Base3D extends SampleApp {
 		// disable shadows
 		obj1.material.shadows = false;
 		obj2.material.shadows = false;
-		
+
 		if (engine.driver.hasFeature(Wireframe)) {
 			addCheck("Wireframe", function() { return obj2.material.mainPass.wireframe; }, function(v) { obj2.material.mainPass.wireframe = v; });
 		}

+ 1 - 1
samples/CubeTexture.hx

@@ -29,7 +29,7 @@ class CubeTexture extends hxd.App {
 		m.material.shadows = false;
 		m.material.mainPass.addShader(new h3d.shader.CubeMap(skyTexture, true));
 
-		var pt = new h3d.scene.PointLight(s3d);
+		var pt = new h3d.scene.fwd.PointLight(s3d);
 		pt.x = 2;
 		pt.y = 1;
 		pt.z = 4;

+ 3 - 2
samples/Helpers.hx

@@ -2,6 +2,7 @@
 import hxd.Res;
 import h3d.Vector;
 import h3d.scene.*;
+import h3d.scene.fwd.*;
 
 class Helpers extends hxd.App {
 
@@ -35,7 +36,7 @@ class Helpers extends hxd.App {
 
 		var pointLightColors =  [0xEB304D,0x7FC309,0x288DF9];
 		for( i in 0...pointLightColors.length ) {
-			var l = new h3d.scene.PointLight( s3d );
+			var l = new PointLight( s3d );
 			l.enableSpecular = true;
 			l.color.setColor( pointLightColors[i] );
 			pointLights.push( l );
@@ -111,7 +112,7 @@ class GridHelper extends h3d.scene.Graphics {
 
 class PointLightHelper extends h3d.scene.Mesh {
 
-	public function new( light : h3d.scene.PointLight, sphereSize = 0.5 ) {
+	public function new( light : h3d.scene.fwd.PointLight, sphereSize = 0.5 ) {
 		var prim = new h3d.prim.Sphere( sphereSize, 4, 2 );
 		prim.addNormals();
 		prim.addUVs();

+ 3 - 2
samples/Interactive.hx

@@ -3,7 +3,7 @@
 class Interactive extends hxd.App {
 
 	var rnd : hxd.Rand;
-	var light : h3d.scene.DirLight;
+	var light : h3d.scene.fwd.DirLight;
 	var obj : h3d.scene.Object;
 	var b : h2d.Interactive;
 
@@ -37,9 +37,10 @@ class Interactive extends hxd.App {
 	}
 
 	override function init() {
-		light = new h3d.scene.DirLight(new h3d.Vector( 0.3, -0.4, -0.9), s3d);
+		light = new h3d.scene.fwd.DirLight(new h3d.Vector( 0.3, -0.4, -0.9), s3d);
 		light.enableSpecular = true;
 		light.color.set(0.28, 0.28, 0.28);
+
 		s3d.lightSystem.ambientLight.set(0.74, 0.74, 0.74);
 
 		rnd = new hxd.Rand(5);

+ 7 - 2
samples/Lights.hx

@@ -4,8 +4,9 @@ class Lights extends SampleApp {
 
 	var lights : Array<h3d.scene.pbr.Light>;
 	var movingObjects : Array<{ m : h3d.scene.Mesh, pos : Float, ray : Float, speed : Float }> = [];
-	var curLight : Int = 2;
+	var curLight : Int = 0;
 	var bitmap : h2d.Bitmap;
+	var inf : h2d.Text;
 
 	override function init() {
 		super.init();
@@ -16,8 +17,9 @@ class Lights extends SampleApp {
 		var prim = new h3d.prim.Grid(100,100,1,1);
 		prim.addNormals();
 		prim.addUVs();
+		
 		var floor = new h3d.scene.Mesh(prim, s3d);
-		floor.material.removePass(floor.material.getPass("shadow"));
+		floor.material.castShadows = false;
 		floor.x = -50;
 		floor.y = -50;
 
@@ -96,6 +98,8 @@ class Lights extends SampleApp {
 		bitmap = new h2d.Bitmap(null, s2d);
 		bitmap.scale(192 / 1024);
 		bitmap.filter = h2d.filter.ColorMatrix.grayed();
+
+		inf = addText();
 	}
 
 	override function update(dt:Float) {
@@ -108,6 +112,7 @@ class Lights extends SampleApp {
 		var tex = light == null ? null : light.shadows.getShadowTex();
 		bitmap.tile = tex == null || tex.flags.has(Cube) ? null : h2d.Tile.fromTexture(tex);
 		bitmap.x = s2d.width - (bitmap.tile == null ? 0 : bitmap.tile.width) * bitmap.scaleX;
+		inf.text = "Shadows Draw calls: "+ s3d.lightSystem.drawPasses;
 	}
 
 	static function main() {

+ 4 - 4
samples/PointLights.hx

@@ -3,8 +3,8 @@ import hxd.Math;
 class PointLights extends hxd.App {
 
 	var time : Float = 0.;
-	var lights : Array<h3d.scene.PointLight>;
-	var dir : h3d.scene.DirLight;
+	var lights : Array<h3d.scene.fwd.PointLight>;
+	var dir : h3d.scene.fwd.DirLight;
 
 	override function init() {
 		var prim = new h3d.prim.Cube();
@@ -27,7 +27,7 @@ class PointLights extends hxd.App {
 		var colors = [0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF00FF, 0xFFFF00, 0x00FFFF];
 		for( c in colors ) {
 			for( i in 0...3 ) {
-				var l = new h3d.scene.PointLight(s3d);
+				var l = new h3d.scene.fwd.PointLight(s3d);
 				l.x = Math.srand() * 3;
 				l.y = Math.srand() * 3;
 				l.z = Math.srand() * 2 - 0.5;
@@ -44,7 +44,7 @@ class PointLights extends hxd.App {
 		s3d.camera.zNear = 2;
 
 
-		dir = new h3d.scene.DirLight(new h3d.Vector(0.2, 0.3, -1), s3d);
+		dir = new h3d.scene.fwd.DirLight(new h3d.Vector(0.2, 0.3, -1), s3d);
 		dir.color.set(0.1, 0.1, 0.1);
 
 		s3d.lightSystem.ambientLight.set(0, 0, 0);

+ 2 - 2
samples/Sao.hx

@@ -2,7 +2,7 @@ import hxd.Math;
 import h3d.pass.ScalableAO;
 import hxd.Key in K;
 
-class CustomRenderer extends h3d.scene.DefaultRenderer {
+class CustomRenderer extends h3d.scene.fwd.Renderer {
 
 	public var sao : h3d.pass.ScalableAO;
 	public var saoBlur : h3d.pass.Blur;
@@ -99,7 +99,7 @@ class Sao extends SampleApp {
 		s3d.camera.zFar = 150 * wscale;
 
 		s3d.lightSystem.ambientLight.set(0.5, 0.5, 0.5);
-		var dir = new h3d.scene.DirLight(new h3d.Vector( -0.3, -0.2, -1), s3d);
+		var dir = new h3d.scene.fwd.DirLight(new h3d.Vector( -0.3, -0.2, -1), s3d);
 		dir.color.set(0.5, 0.5, 0.5);
 
 		var time = Math.PI * 0.25;

+ 1 - 1
samples/ShaderAdvanced.hx

@@ -152,7 +152,7 @@ class ShaderAdvanced extends hxd.App {
 		prim.setMesh(cube);
 		prim.commands = new h3d.impl.InstanceBuffer(1, bytes.getBytes());
 
-		new h3d.scene.DirLight(new h3d.Vector(-1,-2,-5),s3d);
+		new h3d.scene.fwd.DirLight(new h3d.Vector(-1,-2,-5),s3d);
 		new h3d.scene.CameraController(s3d).loadFromCamera();
 
 		var buf = new hxd.FloatBuffer();

+ 2 - 2
samples/Shadows.hx

@@ -4,7 +4,7 @@ class Shadows extends SampleApp {
 
 	var time : Float = 0.;
 	var spheres : Array<h3d.scene.Object>;
-	var dir : h3d.scene.DirLight;
+	var dir : h3d.scene.fwd.DirLight;
 	var shadow : h3d.pass.DefaultShadowMap;
 
 	override function init() {
@@ -34,7 +34,7 @@ class Shadows extends SampleApp {
 		s3d.camera.zFar = 30;
 		s3d.lightSystem.ambientLight.set(0.5, 0.5, 0.5);
 
-		dir = new h3d.scene.DirLight(new h3d.Vector(-0.3, -0.2, -1), s3d);
+		dir = new h3d.scene.fwd.DirLight(new h3d.Vector(-0.3, -0.2, -1), s3d);
 		dir.enableSpecular = true;
 
 		shadow = s3d.renderer.getPass(h3d.pass.DefaultShadowMap);

+ 1 - 0
samples/Skin.hx

@@ -1,4 +1,5 @@
 import h3d.scene.*;
+import h3d.scene.fwd.*;
 
 class Skin extends SampleApp {
 

+ 1 - 1
samples/Stencil.hx

@@ -54,7 +54,7 @@ class Stencil extends hxd.App {
 		}
 
 		// adds a directional light to the scene
-		var light = new h3d.scene.DirLight(new h3d.Vector(-0.5, -0.5, -0.5), s3d);
+		var light = new h3d.scene.fwd.DirLight(new h3d.Vector(-0.5, -0.5, -0.5), s3d);
 		light.enableSpecular = true;
 		s3d.lightSystem.ambientLight.set(0.3, 0.3, 0.3);
 

+ 1 - 1
samples/World.hx

@@ -17,7 +17,7 @@ class World extends hxd.App {
 		world.done();
 
 		//
-		new h3d.scene.DirLight(new h3d.Vector( 0.3, -0.4, -0.9), s3d);
+		new h3d.scene.fwd.DirLight(new h3d.Vector( 0.3, -0.4, -0.9), s3d);
 		s3d.lightSystem.ambientLight.setColor(0x909090);
 
 		s3d.camera.target.set(72, 72, 0);