Ver código fonte

cleanup : use h3d.scene.pbr.Irradiance

ncannasse 7 anos atrás
pai
commit
ab3f3b6906
1 arquivos alterados com 9 adições e 308 exclusões
  1. 9 308
      samples/Pbr.hx

+ 9 - 308
samples/Pbr.hx

@@ -261,169 +261,6 @@ class PbrMaterialShader extends hxsl.Shader {
 
 }
 
-class IrradBase extends h3d.shader.ScreenShader {
-
-	static var SRC = {
-
-		@const var samplesBits : Int;
-		@const var useTable : Bool;
-		@const(1024) var SamplesCount : Int;
-		@param var hammerTbl : Array<Vec4,SamplesCount>;
-		function _reversebits( i : Int ) : Int {
-			var r = (i << 16) | (i >>> 16);
-			r = ((r & 0x00ff00ff) << 8) | ((r & 0xff00ff00) >>> 8);
-			r = ((r & 0x0f0f0f0f) << 4) | ((r & 0xf0f0f0f0) >>> 4);
-			r = ((r & 0x33333333) << 2) | ((r & 0xcccccccc) >>> 2);
-			r = ((r & 0x55555555) << 1) | ((r & 0xaaaaaaaa) >>> 1);
-			return r;
-		}
-
-		function hammersley( i : Int, max : Int ) : Vec2 {
-			if( useTable )
-				return hammerTbl[i].xy;
-			var ri = _reversebits(i) * 2.3283064365386963e-10;
-			return vec2(float(i) / float(max), ri);
-		}
-
-		function importanceSampleGGX( roughness : Float, p : Vec2, n : Vec3 ) : Vec3 {
-			var a = roughness * roughness;
-			var phi = 2 * PI * p.x;
-			var cosT = sqrt((1 - p.y) / (1 + (a * a - 1) * p.y)).min(1.);
-			var sinT = sqrt(1 - cosT * cosT);
-			var ltan = vec3(sinT * cos(phi), sinT * sin(phi), cosT);
-
-			var up = abs(n.z) < 0.999 ? vec3(0, 0, 1) : vec3(1, 0, 0);
-			var tanX = normalize(cross(up, n));
-			var tanY = normalize(cross(n, tanX));
-			return tanX * ltan.x + tanY * ltan.y + n * ltan.z;
-		}
-
-
-	};
-
-}
-
-
-class Irradiance extends IrradBase {
-
-	static var SRC = {
-
-		@const var face : Int;
-		@param var envMap : SamplerCube;
-
-		@const var isSpecular : Bool;
-		@param var roughness : Float;
-
-		@param var cubeSize : Float;
-		@param var cubeScaleFactor : Float;
-
-		function cosineWeightedSampling( p : Vec2, n : Vec3 ) : Vec3 {
-			var sq = sqrt(1 - p.x);
-			var alpha = 2 * PI * p.y;
-			var ltan = vec3( sq * cos(alpha),  sq * sin(alpha), sqrt(p.x));
-
-			var up = abs(n.z) < 0.999 ? vec3(0, 0, 1) : vec3(1, 0, 0);
-			var tanX = normalize(cross(up, n));
-			var tanY = normalize(cross(n, tanX));
-			return tanX * ltan.x + tanY * ltan.y + n * ltan.z;
-		}
-
-		function getNormal() : Vec3 {
-			var d = input.uv * 2. - 1.;
-			if( isSpecular ) {
-				// WRAP edge fixup
-				// https://seblagarde.wordpress.com/2012/06/10/amd-cubemapgen-for-physically-based-rendering/
-				d += cubeScaleFactor * (d * d * d);
-			}
-			#if hldx
-			d.y *= -1;
-			#end
-			var n : Vec3;
-			switch( face ) {
-			case 0: n = vec3(1, d.y, -d.x);
-			case 1: n = vec3(-1, d.y, d.x);
-			case 2: n = vec3(d.x, 1, -d.y);
-			case 3: n = vec3(d.x, -1, d.y);
-			case 4: n = vec3(d.x, d.y, 1);
-			default: n = vec3(-d.x, d.y,-1);
-			}
-			return n.normalize();
-		}
-
-		function fragment() {
-			var color = vec3(0.);
-			var n = getNormal();
-			var totalWeight = 1e-10;
-			var numSamples = 1 << samplesBits;
-			for( i in 0...numSamples ) {
-				var p = hammersley(i, numSamples);
-				var l : Vec3;
-				if( isSpecular ) {
-					var h = importanceSampleGGX(roughness, p, n);
-					var v = n; // approx
-					l = reflect(-v, h).normalize();
-				} else {
-					l = cosineWeightedSampling(p, n);
-				}
-				var amount = n.dot(l).saturate();
-				if( amount > 0 ) {
-					color += envMap.get(l).rgb.pow(vec3(2.2)) * amount;
-					totalWeight += amount;
-				}
-			}
-			output.color = vec4((color / totalWeight).pow(vec3(1/2.2)), 1.);
-		}
-
-	}
-
-}
-
-class IrradianceLut extends IrradBase {
-
-	static var SRC = {
-
-		function GGX( NdotV : Float, roughness : Float ) : Float {
-			var k = (roughness * roughness) * 0.5; // only in IBL, use (r + 1)² / 8 for lighting
-			return NdotV / (NdotV * (1.0 - k) + k);
-		}
-
-		function G_Smith(roughness : Float, nDotV : Float, nDotL : Float) : Float {
-			return GGX(nDotL, roughness) * GGX(nDotV, roughness);
-		}
-
-		function fragment() {
-			var roughness = input.uv.x;
-			var NoV = input.uv.y;
-			var v = vec3( sqrt( 1.0 - NoV * NoV ), 0., NoV );
-			var n = vec3(0, 0, 1.);
-			var numSamples = 1 << samplesBits;
-			var a = 0., b = 0.;
-			for( i in 0...numSamples ) {
-				var xi = hammersley(i, numSamples);
-				var h = importanceSampleGGX( roughness, xi, n );
-				var l = reflect(-v, h);
-				var NoL = saturate( dot(n, l) );
-				var NoH = saturate( dot(n, h) );
-				var VoH = saturate( dot(v, h) );
-				if( NoL > 0 ) {
-					var g = G_Smith( roughness, NoV, NoL );
-					var gvis = g * VoH / (NoH * NoV);
-					var fresnel = pow( 1 - VoH, 5. );
-					a += (1 - fresnel) * gvis;
-					b += fresnel * gvis;
-				}
-			}
-			output.color = vec4(a / numSamples, b / numSamples, 0, 1);
-		}
-	}
-
-	public function new() {
-		super();
-		samplesBits = 10;
-	}
-
-}
-
 class CubeMap extends hxsl.Shader {
 
 	static var SRC = {
@@ -455,14 +292,11 @@ class Pbr extends hxd.App {
 	var sphere : h3d.scene.Mesh;
 	var grid : h3d.scene.Object;
 
-	var sampleBits : Int;
-
 	var shader : PbrShader;
 	var material : PbrMaterialShader;
 
 	var envMap : h3d.mat.Texture;
-	var irradDiffuse : h3d.mat.Texture;
-	var irradSpecular : h3d.mat.Texture;
+	var irrad : h3d.scene.pbr.Irradiance;
 
 	override function init() {
 
@@ -535,23 +369,14 @@ class Pbr extends hxd.App {
 		axis.material.blendMode = Alpha;
 		axis.visible = false;
 
-		var size, ssize;
-		size = 64;
-		ssize = 256;
-		sampleBits = 10;
-
-		computeIrradLut();
-
-		irradDiffuse = new h3d.mat.Texture(size, size, [Cube, Target]);
-		irradDiffuse.name = "irradDiffuse";
-		irradSpecular = new h3d.mat.Texture(ssize, ssize, [Cube, Target, MipMapped, ManualMipMapGen]);
-		irradSpecular.name = "irradSpecular";
-		irradSpecular.mipMap = Linear;
-		computeIrradiance();
+		irrad = new h3d.scene.pbr.Irradiance(envMap);
+		irrad.compute();
 
 		shader.envMap = envMap;
-		shader.irrDiffuse = irradDiffuse;
-		shader.irrSpecular = irradSpecular;
+		shader.irrDiffuse = irrad.diffuse;
+		shader.irrSpecular = irrad.specular;
+		shader.irrLut = irrad.lut;
+		shader.irrSpecularLevels = irrad.specLevels;
 
 		var cubeShader = bg.material.mainPass.addShader(new CubeMap(envMap));
 
@@ -632,8 +457,8 @@ class Pbr extends hxd.App {
 		var prims : Array<h3d.prim.Primitive> = [sp, cube];
 		addChoice("Prim", ["Sphere","Cube"], function(i) sphere.primitive = prims[i], prims.indexOf(sphere.primitive));
 
-		addChoice("EnvMap", ["Default", "IDiff", "ISpec"], function(i) cubeShader.texture = [envMap, irradDiffuse, irradSpecular][i]);
-		addSlider("EnvLod", 0, 10, function() return cubeShader.lod, function(v) cubeShader.lod = v);
+		addChoice("EnvMap", ["Default", "IDiff", "ISpec"], function(i) cubeShader.texture = [envMap, irrad.diffuse, irrad.specular][i]);
+		addSlider("EnvLod", 0, irrad.specLevels, function() return cubeShader.lod, function(v) cubeShader.lod = v);
 
 	}
 
@@ -658,52 +483,6 @@ class Pbr extends hxd.App {
 		sphere.material.mainPass.addShader(mat);
 	}
 
-	function computeIrradLut() {
-		var irradLut = new h3d.mat.Texture(128, 128, [Target], RGBA16F);
-		irradLut.name = "irradLut";
-		var screen = new h3d.pass.ScreenFx(new IrradianceLut());
-		screen.shader.samplesBits = sampleBits;
-
-		engine.driver.setRenderTarget(irradLut);
-		screen.render();
-		engine.driver.setRenderTarget(null);
-		shader.irrLut = irradLut;
-	}
-
-	function computeIrradiance() {
-
-		var screen = new h3d.pass.ScreenFx(new Irradiance());
-		screen.shader.samplesBits = sampleBits;
-		screen.shader.envMap = envMap;
-
-		for( i in 0...6 ) {
-			screen.shader.face = i;
-			engine.driver.setRenderTarget(irradDiffuse, i);
-			screen.render();
-		}
-
-		screen.shader.isSpecular = true;
-
-		var mipLevels = 1;
-		while( irradSpecular.width > 1 << (mipLevels - 1) )
-			mipLevels++;
-
-		shader.irrSpecularLevels = mipLevels - 5;
-
-		for( i in 0...6 ) {
-			screen.shader.face = i;
-			for( j in 0...mipLevels ) {
-				var size = irradSpecular.width >> j;
-				screen.shader.cubeSize = size;
-				screen.shader.cubeScaleFactor = size == 1 ? 0 : (size * size) / Math.pow(size - 1, 3);
-				screen.shader.roughness = j / shader.irrSpecularLevels;
-				engine.driver.setRenderTarget(irradSpecular, i, j);
-				screen.render();
-			}
-		}
-		engine.driver.setRenderTarget(null);
-	}
-
 	function addCheck( text, get : Void -> Bool, set : Bool -> Void ) {
 		var i = new h2d.Interactive(110, font.lineHeight, fui);
 		i.backgroundColor = 0xFF808080;
@@ -804,84 +583,6 @@ class Pbr extends hxd.App {
 
 	}
 
-
-	// ----- DEBUG
-
-
-	function _reversebits( i : Int ) : Int {
-		var r = (i << 16) | (i >>> 16);
-		r = ((r & 0x00ff00ff) << 8) | ((r & 0xff00ff00) >>> 8);
-		r = ((r & 0x0f0f0f0f) << 4) | ((r & 0xf0f0f0f0) >>> 4);
-		r = ((r & 0x33333333) << 2) | ((r & 0xcccccccc) >>> 2);
-		r = ((r & 0x55555555) << 1) | ((r & 0xaaaaaaaa) >>> 1);
-		return r;
-	}
-
-	function hammersley( i : Int, max : Int ) : h3d.Vector {
-		var ri = _reversebits(i) * 2.3283064365386963e-10;
-		return new h3d.Vector(i / max, ri);
-	}
-
-	function cosineWeightedSampling( p : h3d.Vector ) : h3d.Vector {
-		var sq = Math.sqrt(1 - p.x);
-		var alpha = 2 * Math.PI * p.y;
-		return new h3d.Vector( sq * Math.cos(alpha),  sq * Math.sin(alpha), Math.sqrt(p.x));
-	}
-
-	function displaySampling( max : Int, n : h3d.Vector, ?roughness : Float ) {
-		n.normalize();
-		var up = n.z < 0.999 ? new h3d.Vector(0, 0, 1) : new h3d.Vector(1, 0, 0);
-		var tanX = up.cross(n);
-		tanX.normalize();
-		var tanY = n.cross(tanX);
-		tanY.normalize();
-
-		var sp = new h3d.prim.Sphere(0.01, 4, 4);
-		for( i in 0...max ) {
-			var h = hammersley(i, max);
-
-			var l = new h3d.Vector();
-			if( roughness != null ) {
-
-				var a = roughness * roughness;
-				var phi = 2 * Math.PI * h.x;
-				var cosT = Math.min(Math.sqrt((1 - h.y) / (1 + (a * a - 1) * h.y)), 1.);
-				var sinT = Math.sqrt(1 - cosT * cosT);
-				var ltan = new h3d.Vector(sinT * Math.cos(phi), sinT * Math.sin(phi), cosT);
-
-				var h = new h3d.Vector(
-					tanX.x * ltan.x + tanY.x * ltan.y + n.x * ltan.z,
-					tanX.y * ltan.x + tanY.y * ltan.y + n.y * ltan.z,
-					tanX.z * ltan.x + tanY.z * ltan.y + n.z * ltan.z
-				);
-
-				var v = n; // approx
-
-				var hDotV = v.dot3(h);
-				// reflect(-v,h)
-
-				l.x = 2 * hDotV * h.x - v.x;
-				l.y = 2 * hDotV * h.y - v.y;
-				l.z = 2 * hDotV * h.z - v.z;
-
-			} else {
-
-				var c = cosineWeightedSampling(h);
-				l.x = tanX.x * c.x + tanY.x * c.y + n.x * c.z;
-				l.y = tanX.y * c.x + tanY.y * c.y + n.y * c.z;
-				l.z = tanX.z * c.x + tanY.z * c.y + n.z * c.z;
-
-			}
-
-			l.normalize();
-
-			var s = new h3d.scene.Mesh(sp, s3d);
-			s.x = l.x;
-			s.y = l.y;
-			s.z = l.z;
-		}
-	}
-
 	// ---------------------