瀏覽代碼

refactor pbr sample using heaps pbr renderer (not final)

Nicolas Cannasse 7 年之前
父節點
當前提交
35d6862663
共有 2 個文件被更改,包括 58 次插入449 次删除
  1. 31 449
      samples/Pbr.hx
  2. 27 0
      samples/SampleApp.hx

+ 31 - 449
samples/Pbr.hx

@@ -1,290 +1,5 @@
+class Pbr extends SampleApp {
 
-class PbrShader extends hxsl.Shader {
-
-	static var SRC = {
-
-		@:import h3d.shader.BaseMesh;
-
-		@param var exposure : Float;
-
-		@param var lightPos : Vec3;
-		@param var lightColor : Vec3;
-
-		@const var specularMode : Bool;
-		var metalness : Float;
-		var roughness : Float;
-		var occlusion : Float;
-		var albedoColor : Vec3;
-		var specularColor : Vec3;
-
-		@param var defMetalness : Float;
-		@param var defRoughness : Float;
-
-		@param var envMap : SamplerCube;
-		@param var irrDiffuse : SamplerCube;
-		@param var irrSpecular : SamplerCube;
-		@param var irrSpecularLevels : Float;
-		@param var irrLut : Sampler2D;
-
-		@const var directLighting : Bool;
-		@const var indirectLighting : Bool;
-		@const var specularLighting : Bool;
-
-		var l : Vec3;
-		var n : Vec3;
-		var v : Vec3;
-		var h : Vec3;
-
-		function vertex() {
-			albedoColor = pixelColor.rgb;
-		}
-
-		function __init__fragment() {
-			metalness = defMetalness;
-			roughness = defRoughness;
-			occlusion = 1.;
-			specularColor = vec3(metalness);
-		}
-
-		function calcG(v:Vec3) : Float {
-			var k = (roughness + 1).pow(2) / 8;// (roughness * roughness) / 2;
-			var NdV = n.dot(v);
-			return NdV / (NdV * (1 - k) + k);
-		}
-
-		function calcLight( lightPos : Vec3 ) : Vec3 {
-
-			var color = vec3(0.);
-			var normal = transformedNormal.normalize();
-			var view = (camera.position - transformedPosition).normalize();
-			var lightDir = (lightPos - transformedPosition).normalize();
-
-			if( specularMode ) {
-
-				var diffuse = lightDir.dot(normal).max(0.);
-
-				var specularPower = metalness * 40.;
-				var r = reflect(-lightDir, normal).normalize();
-				var specular = r.dot(view).max(0.).pow(specularPower);
-				color = albedoColor * (diffuse + specular) * lightColor;
-
-			} else {
-
-				//if( metalness > 0.5 )
-				//	specularColor = diffuseColor;
-
-				l = lightDir;
-				n = normal;
-				v = view;
-				h = (l + v).normalize();
-
-
-
-				// diffuse BRDF
-				var direct : Vec3;
-
-
-				// ------------- DIRECT LIGHT -------------------------
-
-				var F0 = metalness;
-				var diffuse = albedoColor * n.dot(l).saturate() / PI;
-
-				// General Cook-Torrance formula for microfacet BRDF
-				// 		f(l,v) = D(h).F(v,h).G(l,v,h) / 4(n.l)(n.v)
-
-				// formulas below from 2013 Siggraph "Real Shading in UE4"
-				var alpha = roughness.pow(2);
-
-				// D = normal distribution fonction
-				// GGX (Trowbridge-Reitz) "Disney"
-				var D = alpha.pow(2) / (PI * ( n.dot(h).pow(2) * (alpha.pow(2) - 1.) + 1).pow(2));
-
-				// F = fresnel term
-				// Schlick approx
-				// pow 5 optimized with Spherical Gaussian
-				// var F = F0 + (1 - F0) * pow(1 - v.dot(h).min(1.), 5.);
-				var F = F0 + (1.01 - F0) * exp2( ( -5.55473 * v.dot(h) - 6.98316) * v.dot(h) );
-
-				// G = geometric attenuation
-				// Schlick (modified for UE4 with k=alpha/2)
-				var G = calcG(l) * calcG(v);
-
-				var specular = (D * F * G / (4 * n.dot(l) * n.dot(v))).max(0.);
-
-				// custom falloff to prevent infinite when we have n.h ~= 0
-				if( n.dot(l) < 0 ) specular *= (1 + n.dot(l) * 6).saturate();
-
-				if( !specularLighting )
-					specular = 0.;
-
-				direct = (diffuse + specular) * lightColor;
-
-
-				// ------------- INDIRECT LIGHT -------------------------
-
-				var diffuse = irrDiffuse.get(normal).rgb.pow(vec3(2.2)) * albedoColor;
-
-				var envSpec = textureCubeLod(irrSpecular, reflect(-v,n), roughness * irrSpecularLevels).rgb.pow(vec3(2.2));
-
-				var envBRDF = irrLut.get(vec2(roughness, n.dot(v)));
-				var specular = envSpec * (specularColor * envBRDF.x + envBRDF.y);
-
-				if( !specularLighting )
-					specular = vec3(0.);
-
-				var indirect = diffuse * occlusion + specular;
-
-				if( directLighting )
-					color += direct;
-				if( indirectLighting )
-					color += indirect;
-			}
-
-			return color;
-		}
-
-
-		function fragment() {
-			var color = calcLight(lightPos);
-
-			if( !specularMode ) {
-				// reinhard tonemapping
-				color *= exp(exposure);
-				color = color / (color + vec3(1.));
-
-				// gamma correct
-				color = color.pow(vec3(1 / 2.2));
-			}
-
-			pixelColor.rgb = color;
-		}
-
-	}
-
-	public function new() {
-		super();
-		exposure = 0;
-		specularMode = false;
-		directLighting = true;
-		indirectLighting = true;
-		specularLighting = true;
-		lightPos.set(30, 10, 40);
-		lightColor.set(0.1, 0.1, 0.1);
-	}
-
-}
-
-class AdjustShader extends hxsl.Shader {
-
-	static var SRC = {
-		@param var roughnessValue : Float;
-		@param var metalnessValue : Float;
-		var roughness : Float;
-		var metalness : Float;
-		function fragment() {
-			roughness = roughnessValue;
-			metalness = metalnessValue;
-		}
-	}
-
-	public function new(rough, metal) {
-		super();
-		roughnessValue = rough;
-		metalnessValue = metal;
-	}
-
-}
-
-class PbrMaterialShader extends hxsl.Shader {
-
-	static var SRC = {
-
-		@input var input : { uv : Vec2 };
-		@global var camera : { position : Vec3 };
-		@global var global : { modelViewInverse : Mat4 };
-
-		var output : { color : Vec4 };
-
-		@param var albedoMap : Sampler2D;
-		@param var roughnessMap : Sampler2D;
-		@param var metalnessMap : Sampler2D;
-		@param var normalMap : Sampler2D;
-		@param var heightMap : Sampler2D;
-		@param var occlusionMap : Sampler2D;
-
-		@param var normalPower : Float;
-		@param var parallaxScale : Float;
-		@param var occlusionScale : Float;
-
-		var roughness : Float;
-		var metalness : Float;
-		var occlusion : Float;
-		var calculatedUV : Vec2;
-		var albedoColor : Vec3;
-
-		var transformedPosition : Vec3;
-		var transformedNormal : Vec3;
-
-		function vertex() {
-			calculatedUV = input.uv;
-		}
-
-		function fragment() {
-
-
-			var n = transformedNormal;
-			var up = abs(n.z) < 0.999 ? vec3(0, 0, 1) : vec3(0, 1, 0);
-			var tanX = normalize(cross(up, n));
-			var tanY = normalize(cross(n, tanX));
-
-			var uv = calculatedUV;
-			var height = heightMap.get(calculatedUV).r;
-
-			var viewWS = (camera.position - transformedPosition).normalize();
-			var viewNS = vec3(viewWS.dot(tanX), viewWS.dot(tanY), viewWS.dot(n)).normalize();
-
-			uv -= viewNS.xy * height * parallaxScale;
-
-			occlusion = mix(1., occlusionScale * occlusionMap.get(uv).r, occlusionScale);
-			albedoColor = albedoMap.get(uv).rgb.pow(vec3(2.2));
-			roughness = roughnessMap.get(uv).r;
-			metalness = metalnessMap.get(uv).r;
-
-			var nf = unpackNormal(normalMap.get(uv));
-
-			nf.xy *= normalPower;
-			nf = nf.normalize();
-
-			transformedNormal = (-nf.x * tanX - nf.y * tanY + nf.z * n).normalize();
-		}
-	}
-
-}
-
-class CubeMap extends hxsl.Shader {
-
-	static var SRC = {
-
-		var pixelColor : Vec4;
-		var transformedNormal : Vec3;
-		@param var texture : SamplerCube;
-		@param var lod : Float;
-		function fragment() {
-			pixelColor.rgb *= textureCubeLod(texture,transformedNormal,lod).rgb;
-		}
-
-	}
-
-	public function new(texture) {
-		super();
-		this.texture = texture;
-	}
-}
-
-class Pbr extends hxd.App {
-
-	var fui : h2d.Flow;
-	var font : h2d.Font;
 	var hue : Float;
 	var saturation : Float;
 	var brightness : Float;
@@ -292,26 +7,25 @@ class Pbr extends hxd.App {
 	var sphere : h3d.scene.Mesh;
 	var grid : h3d.scene.Object;
 
-	var shader : PbrShader;
-	var material : PbrMaterialShader;
-
 	var envMap : h3d.mat.Texture;
 	var irrad : h3d.scene.pbr.Irradiance;
+	var renderer : h3d.scene.pbr.Renderer;
+
+	function new() {
+		h3d.mat.MaterialSetup.current = new h3d.mat.PbrMaterialSetup();
+		super();
+	}
 
 	override function init() {
+		super.init();
 
 		new h3d.scene.CameraController(5.5, s3d);
 
-
-		font = hxd.res.DefaultFont.get();
-
 		#if flash
 		new h2d.Text(font, s2d).text = "Not supported on this platform (requires render to mipmap target and fragment textureCubeLod support)";
 		return;
 		#end
 
-		shader = new PbrShader();
-
 		var sp = new h3d.prim.Sphere(1, 128, 128);
 		sp.addNormals();
 		sp.addUVs();
@@ -319,6 +33,7 @@ class Pbr extends hxd.App {
 		var bg = new h3d.scene.Mesh(sp, s3d);
 		bg.scale(10);
 		bg.material.mainPass.culling = Front;
+		bg.material.mainPass.setPassName("overlay");
 
 		fui = new h2d.Flow(s2d);
 		fui.y = 5;
@@ -328,23 +43,8 @@ class Pbr extends hxd.App {
 		envMap = new h3d.mat.Texture(512, 512, [Cube]);
 		envMap.name = "envMap";
 		inline function set(face:Int, res:hxd.res.Image) {
-			#if flash
-			// all mipmap levels required
-			var bmp = res.toBitmap();
-			var level = 0;
-			while( true ) {
-				envMap.uploadBitmap(bmp, level++, face);
-				if( bmp.width == 1 ) break;
-				var sub = new hxd.BitmapData(bmp.width >> 1, bmp.height >> 1);
-				sub.drawScaled(0, 0, sub.width, sub.height, bmp, 0, 0, bmp.width, bmp.height);
-				bmp.dispose();
-				bmp = sub;
-			}
-			bmp.dispose();
-			#else
 			var pix = res.getPixels();
 			envMap.uploadPixels(pix, 0, face);
-			#end
 		}
 		set(0, hxd.Res.front);
 		set(1, hxd.Res.back);
@@ -363,45 +63,36 @@ class Pbr extends hxd.App {
 		axis.moveTo(0, 0, 0);
 		axis.lineTo(0, 0, 2);
 
-		axis.lineStyle(2, 0xFFFFFF, 0.5);
-		axis.moveTo(shader.lightPos.x, shader.lightPos.y, shader.lightPos.z);
-		axis.lineTo(shader.lightPos.x * 0.1, shader.lightPos.y * 0.1, shader.lightPos.z * 0.1);
-		axis.material.blendMode = Alpha;
+		axis.material.props = h3d.mat.MaterialSetup.current.getDefaults("ui");
 		axis.visible = false;
+		axis.material.mainPass.depthWrite = true;
 
 		irrad = new h3d.scene.pbr.Irradiance(envMap);
 		irrad.compute();
 
-		shader.envMap = envMap;
-		shader.irrDiffuse = irrad.diffuse;
-		shader.irrSpecular = irrad.specular;
-		shader.irrLut = irrad.lut;
-		shader.irrSpecularLevels = irrad.specLevels;
+		renderer = cast(s3d.renderer, h3d.scene.pbr.Renderer);
+		renderer.irrad = irrad;
 
-		var cubeShader = bg.material.mainPass.addShader(new CubeMap(envMap));
+		var cubeShader = bg.material.mainPass.addShader(new h3d.shader.pbr.CubeLod(envMap));
+		var light = new h3d.scene.pbr.PointLight(s3d);
+		light.setPos(30, 10, 40);
+		light.range = 100;
+		light.power = 2;
 
-		shader.defMetalness = 0.2;
-		shader.defRoughness = 0.5;
-		shader.exposure = 2.;
+		var pbrValues = new h3d.shader.pbr.PropsValues(0.2,0.5,0);
 		hue = 0.2;
 		saturation = 0.2;
-		brightness = -1;
+		brightness = 0;
 
 		function addSphere(x,y) {
 			var sphere = new h3d.scene.Mesh(sp, s3d);
 			sphere.x = x;
 			sphere.y = y;
-			sphere.material.mainPass.addShader(shader);
 			return sphere;
 		}
 
 		sphere = addSphere(0, 0);
-		material = new PbrMaterialShader();
-		material.normalPower = 1;
-		material.parallaxScale = 1 / 64;
-		material.occlusionScale = 1;
-
-		//loadMaterial("mat/harshbricks-");
+		sphere.material.mainPass.addShader(pbrValues);
 
 		grid = new h3d.scene.Object(s3d);
 		var max = 5;
@@ -410,38 +101,26 @@ class Pbr extends hxd.App {
 				var s = addSphere(x - (max - 1) * 0.5, y - (max - 1) * 0.5);
 				grid.addChild(s);
 				s.scale(0.4);
-				s.material.mainPass.addShader(new AdjustShader( Math.pow(x / (max - 1), 1), Math.pow(y / (max - 1), 2)));
+				s.material.mainPass.addShader(new h3d.shader.pbr.PropsValues( Math.pow(x / (max - 1), 1), Math.pow(y / (max - 1), 1)));
 			}
 		grid.visible = false;
 
-		addCheck("PBR", function() return !shader.specularMode, function(b) shader.specularMode = !b);
-
 		// camera
-		addSeparator();
-		addSlider("Exposure", -3, 3, function() return shader.exposure, function(v) shader.exposure = v);
-		addSlider("Light", 0, 10, function() return shader.lightColor.x, function(v) shader.lightColor.set(v, v, v));
+		addSlider("Exposure", function() return renderer.exposure, function(v) renderer.exposure = v, -3, 3);
+		addSlider("Light", function() return light.power, function(v) light.power = v, 0, 10);
+
 
 		// material color
 		color = new h2d.Bitmap(h2d.Tile.fromColor(0xFFFFFF, 30, 30), fui);
 		fui.getProperties(color).paddingLeft = 150;
-		addSlider("Hue", 0, Math.PI*2, function() return hue, function(v) hue = v);
-		addSlider("Saturation", 0, 1, function() return saturation, function(v) saturation = v);
-		addSlider("Brightness", -1, 1, function() return brightness, function(v) brightness = v);
+		addSlider("Hue", function() return hue, function(v) hue = v, 0, Math.PI*2);
+		addSlider("Saturation", function() return saturation, function(v) saturation = v);
+		addSlider("Brightness", function() return brightness, function(v) brightness = v, -1, 1);
 
-		addSlider("Metalness", 0.02, 0.99, function() return shader.defMetalness, function(v) shader.defMetalness = v);
-		addSlider("Roughness", 0, 1, function() return shader.defRoughness, function(v) shader.defRoughness = v);
-
-		// material properties
-		addSeparator();
-		addSlider("NormalPower", 0, 2, function() return material.normalPower, function(v) material.normalPower = v);
-		addSlider("Parallax", 0, 1, function() return material.parallaxScale * 64, function(v) material.parallaxScale = v / 64);
-		addSlider("Occlusion", 0, 1, function() return material.occlusionScale, function(v) material.occlusionScale = v);
+		addSlider("Metalness", function() return pbrValues.metalness, function(v) pbrValues.metalness = v);
+		addSlider("Roughness", function() return pbrValues.roughness, function(v) pbrValues.roughness = v);
 
 		// debug
-		addSeparator();
-		addCheck("Direct", function() return shader.directLighting, function(b) shader.directLighting = b);
-		addCheck("Indirect", function() return shader.indirectLighting, function(b) shader.indirectLighting = b);
-		addCheck("Specular", function() return shader.specularLighting, function(b) shader.specularLighting = b);
 		addCheck("Axis", function() return axis.visible, function(b) axis.visible = b);
 		addCheck("Grid", function() return grid.visible, function(b) {
 			grid.visible = !grid.visible;
@@ -458,7 +137,7 @@ class Pbr extends hxd.App {
 		addChoice("Prim", ["Sphere","Cube"], function(i) sphere.primitive = prims[i], prims.indexOf(sphere.primitive));
 
 		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);
+		addSlider("EnvLod", function() return cubeShader.lod, function(v) cubeShader.lod = v, 0, irrad.specLevels);
 
 	}
 
@@ -466,103 +145,6 @@ class Pbr extends hxd.App {
 		fui.getProperties(fui.getChildAt(fui.numChildren - 1)).paddingBottom += 20;
 	}
 
-	function loadMaterial( filePath : String ) {
-		var mat = material;
-		function load(name) {
-			var t = hxd.Res.load(filePath + name+".png").toTexture();
-			t.wrap = Repeat;
-			return t;
-		}
-		sphere.material.mainPass.removeShader(mat);
-		mat.albedoMap = load("albedo");
-		mat.normalMap = load("normal");
-		mat.roughnessMap = load("roughness");
-		mat.metalnessMap = load("metalness");
-		mat.heightMap = load("height");
-		mat.occlusionMap = load("ao");
-		sphere.material.mainPass.addShader(mat);
-	}
-
-	function addCheck( text, get : Void -> Bool, set : Bool -> Void ) {
-		var i = new h2d.Interactive(110, font.lineHeight, fui);
-		i.backgroundColor = 0xFF808080;
-
-		fui.getProperties(i).paddingLeft = 20;
-
-		var t = new h2d.Text(font, i);
-		t.maxWidth = i.width;
-		t.text = text+":"+(get()?"ON":"OFF");
-		t.textAlign = Center;
-
-		i.onClick = function(_) {
-			var v = !get();
-			set(v);
-			t.text = text + ":" + (v?"ON":"OFF");
-		};
-		i.onOver = function(_) {
-			t.textColor = 0xFFFFFF;
-		};
-		i.onOut = function(_) {
-			t.textColor = 0xEEEEEE;
-		};
-		i.onOut(null);
-	}
-
-	function addChoice( text, choices, callb, value = 0 ) {
-		var i = new h2d.Interactive(110, font.lineHeight, fui);
-		i.backgroundColor = 0xFF808080;
-		fui.getProperties(i).paddingLeft = 20;
-
-		var t = new h2d.Text(font, i);
-		t.maxWidth = i.width;
-		t.text = text+":"+choices[value];
-		t.textAlign = Center;
-
-		i.onClick = function(_) {
-			value++;
-			value %= choices.length;
-			callb(value);
-			t.text = text + ":" + choices[value];
-		};
-		i.onOver = function(_) {
-			t.textColor = 0xFFFFFF;
-		};
-		i.onOut = function(_) {
-			t.textColor = 0xEEEEEE;
-		};
-		i.onOut(null);
-	}
-
-	function addSlider( text, min : Float, max : Float, get : Void -> Float, set : Float -> Void ) {
-		var f = new h2d.Flow(fui);
-
-		f.horizontalSpacing = 5;
-
-		var tf = new h2d.Text(font, f);
-		tf.text = text;
-		tf.maxWidth = 100;
-		tf.textAlign = Right;
-
-		var sli = new h2d.Slider(100, 10, f);
-		sli.minValue = min;
-		sli.maxValue = max;
-		sli.value = get();
-
-		var tf = new h2d.TextInput(font, f);
-		tf.text = "" + hxd.Math.fmt(sli.value);
-		sli.onChange = function() {
-			set(sli.value);
-			tf.text = "" + hxd.Math.fmt(sli.value);
-			f.needReflow = true;
-		};
-		tf.onChange = function() {
-			var v = Std.parseFloat(tf.text);
-			if( Math.isNaN(v) ) return;
-			sli.value = v;
-			set(v);
-		};
-	}
-
 	override function update(dt:Float) {
 
 		if( grid == null ) return;

+ 27 - 0
samples/SampleApp.hx

@@ -101,6 +101,33 @@ class SampleApp extends hxd.App {
 		return i;
 	}
 
+	function addChoice( text, choices, callb, value = 0 ) {
+		var font = getFont();
+		var i = new h2d.Interactive(110, font.lineHeight, fui);
+		i.backgroundColor = 0xFF808080;
+		fui.getProperties(i).paddingLeft = 20;
+
+		var t = new h2d.Text(font, i);
+		t.maxWidth = i.width;
+		t.text = text+":"+choices[value];
+		t.textAlign = Center;
+
+		i.onClick = function(_) {
+			value++;
+			value %= choices.length;
+			callb(value);
+			t.text = text + ":" + choices[value];
+		};
+		i.onOver = function(_) {
+			t.textColor = 0xFFFFFF;
+		};
+		i.onOut = function(_) {
+			t.textColor = 0xEEEEEE;
+		};
+		i.onOut(null);
+		return i;
+	}
+
 	function addText(text="") {
 		var tf = new h2d.Text(getFont(), fui);
 		tf.text = text;