Pārlūkot izejas kodu

rearchicture a bit the passes, added SubPass

Nicolas Cannasse 11 gadi atpakaļ
vecāks
revīzija
e587fd703c
6 mainītis faili ar 142 papildinājumiem un 52 dzēšanām
  1. 29 0
      h3d/pass/Base.hx
  2. 40 8
      h3d/pass/Default.hx
  3. 11 15
      h3d/pass/Distance.hx
  4. 7 20
      h3d/pass/ShadowMap.hx
  5. 30 0
      h3d/pass/SubPass.hx
  6. 25 9
      h3d/scene/Scene.hx

+ 29 - 0
h3d/pass/Base.hx

@@ -0,0 +1,29 @@
+package h3d.pass;
+
+class Base {
+
+	var ctx : h3d.scene.RenderContext;
+	public var priority : Int = 0;
+	public var forceProcessing : Bool = false;
+
+	public function new() {
+	}
+
+	public function compileShader( p : h3d.mat.Pass ) : hxsl.RuntimeShader {
+		throw "Not implemented for this pass";
+		return null;
+	}
+
+	public function setContext( ctx ) {
+		this.ctx = ctx;
+	}
+
+	public function draw( name : String, passes : Object ) {
+		return passes;
+	}
+
+	public function getLightSystem() : Null<LightSystem> {
+		return null;
+	}
+
+}

+ 40 - 8
h3d/pass/Default.hx

@@ -2,15 +2,18 @@ package h3d.pass;
 
 @:build(hxsl.Macros.buildGlobals())
 @:access(h3d.mat.Pass)
-class Default {
+class Default extends Base {
 
-	var ctx : h3d.scene.RenderContext;
 	var manager : h3d.shader.Manager;
 	var globals(get, never) : hxsl.Globals;
-	var priority : Int = 0;
 	var cachedBuffer : h3d.shader.Buffers;
+
+	var hasTargetDepth : Bool;
+	var textureCache : Array<h3d.mat.Texture>;
+	var textureCachePosition : Int = 0;
+	var textureCacheFrame : Int;
+
 	public var lightSystem : LightSystem;
-	public var forceProcessing : Bool = false;
 
 	inline function get_globals() return manager.globals;
 
@@ -29,21 +32,52 @@ class Default {
 	}
 
 	public function new() {
+		super();
 		manager = new h3d.shader.Manager(getOutputs());
 		initGlobals();
 		lightSystem = new LightSystem(globals);
+
+		hasTargetDepth = h3d.Engine.getCurrent().driver.hasFeature(TargetDepthBuffer);
+		textureCache = [];
 	}
 
 	function getOutputs() {
 		return ["output.position", "output.color"];
 	}
 
-	public function compileShader( p : h3d.mat.Pass ) {
+	override function compileShader( p : h3d.mat.Pass ) {
 		var out = [for( s in p.getShadersRec() ) s];
 		out.reverse();
 		return manager.compileShaders(out);
 	}
 
+	override function getLightSystem() {
+		return lightSystem;
+	}
+
+	function getTargetTexture( name : String, width : Int, height : Int, hasDepth=true ) {
+		if( textureCacheFrame != ctx.frame ) {
+			// dispose extra textures we didn't use
+			while( textureCache.length > textureCachePosition ) {
+				var t = textureCache.pop();
+				if( t != null ) t.dispose();
+			}
+			textureCacheFrame = ctx.frame;
+			textureCachePosition = 0;
+		}
+		var t = textureCache[textureCachePosition];
+		if( t == null || t.isDisposed() || t.width != width || t.height != height ) {
+			if( t != null ) t.dispose();
+			var flags : Array<h3d.mat.Data.TextureFlags> = [Target, TargetNoFlipY];
+			if( hasDepth ) flags.push(hasTargetDepth ? TargetDepth : TargetUseDefaultDepth);
+			t = new h3d.mat.Texture(width, height, flags);
+			textureCache[textureCachePosition] = t;
+		}
+		t.setName(name);
+		textureCachePosition++;
+		return t;
+	}
+
 	@:access(h3d.scene)
 	function setupShaders( passes : Object ) {
 		var p = passes;
@@ -98,8 +132,7 @@ class Default {
 	}
 
 	@:access(h3d.scene)
-	public function draw( name : String, ctx : h3d.scene.RenderContext, passes : Object ) {
-		this.ctx = ctx;
+	override function draw( name : String, passes : Object ) {
 		for( k in ctx.sharedGlobals.keys() )
 			globals.fastSet(k, ctx.sharedGlobals.get(k));
 		setGlobals();
@@ -136,7 +169,6 @@ class Default {
 		}
 		log("Pass " + name + " end");
 		ctx.drawPass = null;
-		this.ctx = null;
 		return passes;
 	}
 

+ 11 - 15
h3d/pass/Distance.hx

@@ -1,16 +1,16 @@
 package h3d.pass;
 
-class Distance extends Base {
+class Distance extends Default {
 
-	var texture : h3d.mat.Texture;
-	var hasTargetDepth : Bool;
 	var clear : Clear;
+	var distanceMapId : Int;
+	public var enableSky : Bool = false;
 
-	public function new(name) {
-		super(name);
+	public function new() {
+		super();
 		priority = 10;
 		lightSystem = null;
-		hasTargetDepth = h3d.Engine.getCurrent().driver.hasFeature(TargetDepthBuffer);
+		distanceMapId = hxsl.Globals.allocID("distanceMap");
 		if( !hasTargetDepth )
 			clear = new Clear();
 	}
@@ -19,16 +19,12 @@ class Distance extends Base {
 		return ["output.position", "output.distance"];
 	}
 
-	override function draw(ctx : h3d.scene.RenderContext, passes) {
-		if( texture == null || texture.width != ctx.engine.width || texture.height != ctx.engine.height ) {
-			if( texture != null ) texture.dispose();
-			texture = new h3d.mat.Texture(ctx.engine.width, ctx.engine.height, [Target, hasTargetDepth ? TargetDepth : TargetUseDefaultDepth, TargetNoFlipY]);
-			texture.setName("distanceMap");
-		}
-		ctx.engine.setTarget(texture);
-		passes = super.draw(ctx, passes);
+	override function draw( name : String, passes ) {
+		var texture = getTargetTexture("distanceMap", ctx.engine.width, ctx.engine.height);
+		ctx.engine.setTarget(texture, enableSky ? 0 : 0xFFFF0000);
+		passes = super.draw(name, passes);
 		ctx.engine.setTarget(null);
-
+		ctx.sharedGlobals.set(distanceMapId, texture);
 		if( !hasTargetDepth )
 			clear.apply(1);
 

+ 7 - 20
h3d/pass/ShadowMap.hx

@@ -1,16 +1,13 @@
 package h3d.pass;
 
-class ShadowMap extends Base {
+class ShadowMap extends Default {
 
-	var texture : h3d.mat.Texture;
-	var blurTexture : h3d.mat.Texture;
 	var lightCamera : h3d.Camera;
 	var shadowMapId : Int;
 	var shadowProjId : Int;
 	var shadowColorId : Int;
 	var shadowPowerId : Int;
 	var shadowBiasId : Int;
-	var hasTargetDepth : Bool;
 	var clear : Clear;
 	public var size : Int;
 	public var lightDirection : h3d.Vector;
@@ -20,7 +17,7 @@ class ShadowMap extends Base {
 	public var blur : Blur;
 
 	public function new(size) {
-		super("shadow");
+		super();
 		this.size = size;
 		priority = 9;
 		lightSystem = null;
@@ -32,7 +29,6 @@ class ShadowMap extends Base {
 		shadowColorId = hxsl.Globals.allocID("shadow.color");
 		shadowPowerId = hxsl.Globals.allocID("shadow.power");
 		shadowBiasId = hxsl.Globals.allocID("shadow.bias");
-		hasTargetDepth = h3d.Engine.getCurrent().driver.hasFeature(TargetDepthBuffer);
 		if( !hasTargetDepth )
 			clear = new Clear();
 		color = new h3d.Vector();
@@ -60,26 +56,17 @@ class ShadowMap extends Base {
 		cameraViewProj = lightCamera.m;
 	}
 
-	override function draw( ctx : h3d.scene.RenderContext, passes) {
-		if( texture == null || texture.width != size ) {
-			if( texture != null ) {
-				texture.dispose();
-				blurTexture.dispose();
-				blurTexture = null;
-			}
-			texture = new h3d.mat.Texture(size, size, [Target, hasTargetDepth ? TargetDepth : TargetUseDefaultDepth, TargetNoFlipY]);
-			texture.setName("shadowMap");
-		}
-		if( blur.quality > 0 && blurTexture == null )
-			blurTexture = new h3d.mat.Texture(size, size, [Target, TargetNoFlipY]);
+	override function draw( name : String, passes ) {
+		var texture = getTargetTexture("shadowMap", size, size);
 		var ct = ctx.camera.target;
 		lightCamera.target.set(ct.x, ct.y, ct.z);
 		lightCamera.pos.set(ct.x - lightDirection.x, ct.y - lightDirection.y, ct.z - lightDirection.z);
 		ctx.engine.setTarget(texture, 0xFFFFFFFF);
-		passes = super.draw(ctx, passes);
+		passes = super.draw(name, passes);
 		ctx.engine.setTarget(null);
 
-		blur.apply(texture, blurTexture, true);
+		if( blur.quality > 0 )
+			blur.apply(texture, getTargetTexture("tmpBlur", size, size, false), true);
 
 		if( !hasTargetDepth )
 			clear.apply(1);

+ 30 - 0
h3d/pass/SubPass.hx

@@ -0,0 +1,30 @@
+package h3d.pass;
+
+class SubPass extends Base {
+
+	var sub : Base;
+
+	public function new( sub : Base, priority, forceProcessing = false ) {
+		super();
+		this.sub = sub;
+		this.priority = priority;
+		this.forceProcessing = forceProcessing;
+	}
+
+	override function setContext( ctx ) {
+		sub.setContext(ctx);
+	}
+
+	override function compileShader(pass) {
+		return sub.compileShader(pass);
+	}
+
+	override function draw(name, passes) {
+		return sub.draw(name, passes);
+	}
+
+	override function getLightSystem() {
+		return sub.getLightSystem();
+	}
+
+}

+ 25 - 9
h3d/scene/Scene.hx

@@ -47,13 +47,13 @@ class Scene extends Object implements h3d.IDrawable {
 	function createDefaultPass( name : String ) : h3d.pass.Base {
 		switch( name ) {
 		case "default", "alpha", "additive":
-			return new h3d.pass.Base(name);
+			return new h3d.pass.Default();
 		case "distance":
-			return new h3d.pass.Distance(name);
+			return new h3d.pass.Distance();
 		case "shadow":
 			return new h3d.pass.ShadowMap(1024);
 		default:
-			throw "Don't know how to create pass '" + name + "', use s3d.setRenderPass()";
+			throw "Don't know how to create pass '" + name + "', use s3d.setPass()";
 			return null;
 		}
 	}
@@ -93,7 +93,8 @@ class Scene extends Object implements h3d.IDrawable {
 		ctx.passes = haxe.ds.ListSort.sortSingleLinked(ctx.passes, function(p1, p2) {
 			return p1.pass.passId - p2.pass.passId;
 		});
-		// dispatch to the actual pass implementation
+
+		// group by pass implementation
 		var curPass = ctx.passes;
 		var passes = [];
 		while( curPass != null ) {
@@ -108,15 +109,30 @@ class Scene extends Object implements h3d.IDrawable {
 			passes.push( { render : render, pass : curPass } );
 			curPass = p;
 		}
-		@:privateAccess passes.sort(function(p1, p2) return p2.render.priority - p1.render.priority);
+
+		// sort by priority and assign
+		var allPasses = [for( name in this.passes.keys() ) { name : name, p : this.passes.get(name), content : null } ];
+		@:privateAccess allPasses.sort(function(p1, p2) return p2.p.priority - p1.p.priority);
 		for( p in passes )
-			p.pass = p.render.draw(ctx, p.pass);
+			for( i in 0...allPasses.length )
+				if( allPasses[i].p == p.render ) {
+					allPasses[i].content = p.pass;
+					break;
+				}
+
+		// render
+		for( p in allPasses )
+			if( p.content != null || p.p.forceProcessing ) {
+				p.p.setContext(ctx);
+				p.content = p.p.draw(p.name, p.content);
+			}
 
 		// relink pass objects to reuse
 		var count = 0;
 		var prev : h3d.pass.Object = null;
-		for( p in passes ) {
-			var p = p.pass;
+		for( p in allPasses ) {
+			if( p.content == null ) continue;
+			var p = p.content;
 			if( prev != null )
 				prev.next = p;
 			while( p != null ) {
@@ -124,7 +140,7 @@ class Scene extends Object implements h3d.IDrawable {
 				p = p.next;
 			}
 		}
-		if( passes.length > 0 ) ctx.passes = passes[0].pass;
+		if( allPasses.length > 0 ) ctx.passes = allPasses[0].content;
 		ctx.done();
 		for( p in postPasses )
 			p.render(engine);