浏览代码

Adding KuwaharaFilter.hx with distance fading.

clementlandrin 5 月之前
父节点
当前提交
0d44708703
共有 1 个文件被更改,包括 155 次插入0 次删除
  1. 155 0
      hrt/prefab/rfx/KuwaharaFilter.hx

+ 155 - 0
hrt/prefab/rfx/KuwaharaFilter.hx

@@ -0,0 +1,155 @@
+package hrt.prefab.rfx;
+
+class KuwaharaShader extends hrt.shader.PbrShader {
+
+	static var SRC = {
+
+		@param var startDist : Float;
+		@param var endDist : Float;
+		@param var scaledRadius : Int;
+
+		@param var ldrCopy : Sampler2D;
+
+		function fragment() {			
+			var size = ldrCopy.size();
+			var invSize = 1.0 / size;
+			var n = float((scaledRadius + 1) * (scaledRadius + 1));
+			var m0 = vec3(0.0);
+			var m1 = vec3(0.0);
+			var m2 = vec3(0.0);
+			var m3 = vec3(0.0);
+			
+			var s0 = vec3(0.0);
+			var s1 = vec3(0.0);
+			var s2 = vec3(0.0);
+			var s3 = vec3(0.0);
+
+			for ( j in -scaledRadius...1 )  {
+				for ( i in -scaledRadius...1 )  {
+					var c = ldrCopy.get(calculatedUV + vec2(i,j) * invSize).rgb;
+					m0 += c;
+					s0 += c * c;
+				}
+			}
+
+			for ( j in -scaledRadius...1 )  {
+				for ( i in 0...scaledRadius + 1)  {
+					var c = ldrCopy.get(calculatedUV + vec2(i,j) * invSize).rgb;
+					m1 += c;
+					s1 += c * c;
+				}
+			}
+
+			for ( j in 0...scaledRadius + 1 )  {
+				for ( i in 0...scaledRadius + 1)  {
+					var c = ldrCopy.get(calculatedUV + vec2(i,j) * invSize).rgb;
+					m2 += c;
+					s2 += c * c;
+				}
+			}
+
+			for ( j in 0... scaledRadius + 1 )  {
+				for ( i in -scaledRadius...1 )  {
+					var c = ldrCopy.get(calculatedUV + vec2(i,j) * invSize).rgb;
+					m3 += c;
+					s3 += c * c;
+				}
+			}
+
+
+			var minSigma2 = 1e+10;
+			m0 /= n;
+			s0 = abs(s0 / n - m0 * m0);
+
+			var filteredColor = vec3(0.0);
+
+			var sigma2 = s0.r + s0.g + s0.b;
+			if (sigma2 < minSigma2) {
+				minSigma2 = sigma2;
+				filteredColor = vec3(m0);
+			}
+
+			m1 /= n;
+			s1 = abs(s1 / n - m1 * m1);
+
+			sigma2 = s1.r + s1.g + s1.b;
+			if (sigma2 < minSigma2) {
+				minSigma2 = sigma2;
+				filteredColor = vec3(m1);
+			}
+
+			m2 /= n;
+			s2 = abs(s2 / n - m2 * m2);
+
+			sigma2 = s2.r + s2.g + s2.b;
+			if (sigma2 < minSigma2) {
+				minSigma2 = sigma2;
+				filteredColor = vec3(m2);
+			}
+
+			m3 /= n;
+			s3 = abs(s3 / n - m3 * m3);
+
+			sigma2 = s3.r + s3.g + s3.b;
+			if (sigma2 < minSigma2) {
+				minSigma2 = sigma2;
+				filteredColor = vec3(m3);
+			}
+
+			var wPos = getPosition();
+			var dist = distance(camera.position, wPos);
+			var opacity = smoothstep(startDist, endDist, dist);
+			pixelColor = vec4(filteredColor, opacity);
+		}
+	}
+}
+
+@:access(h3d.scene.Renderer)
+class KuwaharaFilter extends RendererFX {
+
+	@:s var radius : Int = 4;
+	@:s var startDist : Float = 0.0;
+	@:s var endDist : Float = 100.0;
+
+	var pass = new h3d.pass.ScreenFx(new KuwaharaShader());
+
+	override function begin(r:h3d.scene.Renderer, step:h3d.impl.RendererFX.Step) {
+		if ( step == AfterTonemapping ) {
+			var ldrCopy = r.allocTarget("ldrCopy", true, 1.0);
+			h3d.pass.Copy.run(r.ctx.engine.getCurrentTarget(), ldrCopy);
+			pass.shader.ldrCopy = ldrCopy;
+
+			pass.shader.scaledRadius = Std.int(radius * hxd.Math.max(ldrCopy.width / 1920, ldrCopy.height / 1080));
+			pass.shader.startDist = startDist;
+			pass.shader.endDist = endDist;
+			pass.pass.setBlendMode(Alpha);
+			pass.render();
+		}
+	}
+
+	#if editor
+
+	override function edit( ctx : hide.prefab.EditContext ) {
+		super.edit(ctx);
+		ctx.properties.add(new hide.Element(
+			'<div class="group" name="Filter">
+				<dl>
+					<dt>Radius</dt><dd><input type="range" min="1" step="1" field="radius"/></dd>
+				</dl>
+			</div>
+			<div class="group" name="Fade">
+				<dl>
+					<dt>Start</dt><dd><input type="range" min="0" field="startDist"/></dd>
+					<dt>End</dt><dd><input type="range" min="0" field="endDist"/></dd>
+				</dl>
+			</div>
+			'), this, function(pname) {
+				ctx.onChange(this, pname);
+		});
+	}
+
+	#end
+
+	static var _ = Prefab.register("rfx.kuwaharaFilter", KuwaharaFilter);
+
+}