Prechádzať zdrojové kódy

added Displacement filter

Nicolas Cannasse 10 rokov pred
rodič
commit
8a1ab8c4cd

+ 3 - 2
h2d/RenderContext.hx

@@ -5,7 +5,7 @@ class RenderContext extends h3d.impl.RenderContext {
 	public var buffer : hxd.FloatBuffer;
 	public var bufPos : Int;
 
-	public var textures : h3d.pass.TextureCache;
+	public var textures : h3d.impl.TextureCache;
 
 	public var tmpBounds = new h2d.col.Bounds();
 	var texture : h3d.mat.Texture;
@@ -35,7 +35,7 @@ class RenderContext extends h3d.impl.RenderContext {
 		baseShader.zValue = 0.;
 		baseShaderList = new hxsl.ShaderList(baseShader);
 		targetsStack = [];
-		textures = new h3d.pass.TextureCache();
+		textures = new h3d.impl.TextureCache();
 	}
 
 	public function begin() {
@@ -50,6 +50,7 @@ class RenderContext extends h3d.impl.RenderContext {
 		baseShaderList.next = null;
 		initShaders(baseShaderList);
 		engine.selectMaterial(pass);
+		textures.begin(this);
 	}
 
 	function initShaders( shaders ) {

+ 1 - 2
h2d/Sprite.hx

@@ -428,6 +428,7 @@ class Sprite {
 
 		var t = ctx.textures.allocTarget("filterTemp", ctx, width, height, false);
 		ctx.pushTarget(t, xMin, yMin);
+		ctx.engine.clear(0);
 
 		// reset transform and update childs
 		var oldA = matA, oldB = matB, oldC = matC, oldD = matD, oldX = absX, oldY = absY;
@@ -456,8 +457,6 @@ class Sprite {
 
 		emitTile(ctx, final);
 		ctx.flush();
-		t.dispose();
-		final.dispose();
 	}
 
 	function drawRec( ctx : RenderContext ) {

+ 43 - 0
h2d/filter/Displacement.hx

@@ -0,0 +1,43 @@
+package h2d.filter;
+import hxd.Math;
+
+class Displacement extends Filter {
+
+	public var normalMap : h2d.Tile;
+	public var dispX : Float;
+	public var dispY : Float;
+	public var wrap(default, set) : Bool;
+	var disp = new h3d.pass.ScreenFx(new h3d.shader.Displacement());
+
+	public function new( normalMap : h2d.Tile, dispX : Float = 5., dispY = 5., wrap = true ) {
+		super();
+		this.normalMap = normalMap;
+		this.dispX = dispX;
+		this.dispY = dispY;
+		this.wrap = wrap;
+	}
+
+	function set_wrap(w) {
+		var t = normalMap == null ? null : normalMap.getTexture();
+		if( t != null ) t.wrap = w ? Repeat : Clamp;
+		return wrap = w;
+	}
+
+	override function sync(ctx, s) {
+		boundsExtend = Math.max(Math.abs(dispX), Math.abs(dispY));
+	}
+
+	override function draw( ctx : RenderContext, t : h2d.Tile ) {
+		var out = ctx.textures.allocTarget("displacementOutput", ctx, t.width, t.height, false);
+		ctx.engine.setTarget(out);
+		var s = disp.shader;
+		s.texture = t.getTexture();
+		s.displacement.set(dispX / t.width, dispY / t.height);
+		s.normalMap = normalMap.getTexture();
+		s.normalPos.set(normalMap.u, normalMap.v);
+		s.normalScale.set(normalMap.u2 - normalMap.u, normalMap.v2 - normalMap.v);
+		disp.render();
+		return h2d.Tile.fromTexture(out);
+	}
+
+}

+ 6 - 2
h3d/pass/TextureCache.hx → h3d/impl/TextureCache.hx

@@ -1,4 +1,4 @@
-package h3d.pass;
+package h3d.impl;
 
 class TextureCache {
 
@@ -19,7 +19,7 @@ class TextureCache {
 		return cache[index];
 	}
 
-	public function allocTarget( name : String, ctx : h3d.impl.RenderContext, width : Int, height : Int, hasDepth=true ) {
+	public function begin( ctx : h3d.impl.RenderContext ) {
 		if( frame != ctx.frame ) {
 			// dispose extra textures we didn't use
 			while( cache.length > position ) {
@@ -29,6 +29,10 @@ class TextureCache {
 			frame = ctx.frame;
 			position = 0;
 		}
+	}
+
+	public function allocTarget( name : String, ctx : h3d.impl.RenderContext, width : Int, height : Int, hasDepth=true ) {
+		begin(ctx);
 		var t = cache[position];
 		if( t == null || t.isDisposed() || t.width != width || t.height != height || t.flags.has(hasDefaultDepth ? TargetUseDefaultDepth : TargetDepth) != hasDepth ) {
 			if( t != null ) t.dispose();

+ 2 - 2
h3d/pass/Default.hx

@@ -7,7 +7,7 @@ class Default extends Base {
 	var manager : h3d.shader.Manager;
 	var globals(get, never) : hxsl.Globals;
 	var cachedBuffer : h3d.shader.Buffers;
-	var tcache : TextureCache;
+	var tcache : h3d.impl.TextureCache;
 
 	inline function get_globals() return manager.globals;
 
@@ -29,7 +29,7 @@ class Default extends Base {
 	public function new() {
 		super();
 		manager = new h3d.shader.Manager(getOutputs());
-		tcache = new TextureCache();
+		tcache = new h3d.impl.TextureCache();
 		initGlobals();
 	}
 

+ 2 - 2
h3d/scene/Renderer.hx

@@ -22,12 +22,12 @@ class Renderer {
 	var passGroups : SMap<PassGroup>;
 	var allPasses : Array<{ name : String, p : h3d.pass.Base }>;
 	var ctx : RenderContext;
-	var tcache : h3d.pass.TextureCache;
+	var tcache : h3d.impl.TextureCache;
 
 	public function new() {
 		passes = new SMap();
 		allPasses = [];
-		tcache = new h3d.pass.TextureCache();
+		tcache = new h3d.impl.TextureCache();
 		passGroups = new SMap();
 	}
 

+ 21 - 0
h3d/shader/Displacement.hx

@@ -0,0 +1,21 @@
+package h3d.shader;
+
+class Displacement extends ScreenShader {
+
+	static var SRC = {
+
+		@param var texture : Sampler2D;
+		@param var normalMap : Sampler2D;
+		@param var normalScale : Vec2;
+		@param var normalPos : Vec2;
+		@param var displacement : Vec2;
+
+		function fragment() {
+			var n = unpackNormal(normalMap.get(input.uv * normalScale + normalPos));
+			output.color = texture.get(input.uv + n.xy * displacement);
+		}
+
+	}
+
+
+}

+ 14 - 7
samples/filters/Main.hx

@@ -4,30 +4,30 @@ class Main extends hxd.App {
 
 	var spr : h2d.Sprite;
 	var bmp : h2d.Bitmap;
+	var disp : h2d.Tile;
 
 	override function init() {
 		engine.backgroundColor = 0x002000;
-		var scale = 4;
 
 		spr = new h2d.Sprite(s2d);
 		spr.x = s2d.width * 0.5;
 		spr.y = s2d.height * 0.5;
-		spr.scale(scale);
 
 		bmp = new h2d.Bitmap(hxd.Res.hxlogo.toTile(), spr);
-		bmp.scale(1 / scale);
 		bmp.colorKey = 0xFFFFFF;
 
-		setFilters(3);
+
+		disp = hxd.Res.normalmap.toTile();
+
+		setFilters(4);
 
 		var help = new h2d.Text(hxd.Res.customFont.toFont(), s2d);
 		help.x = help.y = 5;
-		help.text = "1:Blur 2:Glow 3:DropShadow +/-:Scale";
+		help.text = "1:Blur 2:Glow 3:DropShadow 4:Displacement +/-:Scale";
 	}
 
 	override function update(dt:Float) {
-		spr.rotation += 0.01 * dt;
-		for( i in 1...4 )
+		for( i in 1...5 )
 			if( K.isPressed(K.NUMBER_0 + i) )
 				setFilters(i);
 		if( K.isPressed(K.NUMPAD_ADD) ) {
@@ -40,9 +40,11 @@ class Main extends hxd.App {
 		}
 		bmp.x = -bmp.tile.width * 0.5 * bmp.scaleX;
 		bmp.y = -bmp.tile.height * 0.5 * bmp.scaleY;
+		disp.scrollDiscrete(0.01 * dt, 0.02 * dt);
 	}
 
 	function setFilters(i) {
+		var scale = 4;
 		switch( i ) {
 		case 1:
 			spr.filters = [new h2d.filter.Blur(2, 3, 100)];
@@ -50,7 +52,12 @@ class Main extends hxd.App {
 			spr.filters = [new h2d.filter.Glow(0xFF00FF, 100, 1)];
 		case 3:
 			spr.filters = [new h2d.filter.DropShadow()];
+		case 4:
+			scale = 1;
+			spr.filters = [new h2d.filter.Displacement(disp)];
 		}
+		spr.setScale(scale);
+		bmp.setScale(1 / scale);
 	}
 
 	static function main() {

BIN
samples/res/normalmap.png