In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Papervision3D's bumpmapping error?->EnvMapShader.renderLayer/renderTri error?

昨日上げたコードは大きすぎてquestionには不向きでした。
基本に立ち返り、ミニマムコードを。 (海面の奴は別の機会にあげます)
オブジェクトにPhongShaderやEnvMapShaderを割り当てて
bumpmapを適用すると、3角ポリゴンのエッジ周辺のbumpの一部にエラー(極端に暗くなる)が
表示されます。
[Question]この原因がわからない(法線ベクトル関連だと思うのですが・・・)ので、
解決法をご存知の方、よろしくお願いします
※昨日のコードでは 3角ポリゴンのエッジ以外にもエラーが出ていましたが、とりあえず3角ポリゴンの
エッジに注目して考えてます。 個人的には法線ベクトル。おそらくスムージング角度の問題じゃない
かと思うのですが、スムージング角度の設定方法がわかりません
※なんかそもそもテクスチャがずれているような・・・このあたりを重点的に調べてみます
※bumpには関係なく、phongshaderを適用した時点でエッジが黒くなっていて、
その影響をbumpが受けている模様
※ShadedMaterialのCompositeModeをShaderCompositeModes.PER_TRIANGLE_IN_BITMAP
にするとエッジの線が消える。・・・・けどbumpmapが消える。 papervisionのソースを見る限り、
現在進行形で修正中のようす。ここまでかな
Get Adobe Flash player
by zendenmushi 20 Apr 2010

    Talk

    zendenmushi at 20 Apr 2010 19:05
    オブジェクトにPhongShaderや EnvMapShaderを割り当ててbumpmapを適用すると、ポリゴン端の方の bumpの一部にエラー(極端に暗くなる)が 表示されます。この原因がわかりません
    zendenmushi at 20 Apr 2010 20:20
    Papervisionのソースを見たところ、どうやらEnvMapShader (PhongShaderの親クラス)の renderLayerで描く3角ポリゴンにエッジが描画されてしまう(座標計算の誤差?)バグがあるもよう。 かといって、renderTriメソッドが使われるように設定すると、バンプが適用されない。 おそらく、現在進行形で修正中の場所のようです。(もう少し調べますが、このままcloseかな)
    zendenmushi at 20 Apr 2010 21:10
    ポリゴン描画をSpriteで行っているようなので、メッシュを描画し終わる前に個別ポリゴンのエッジにAAがかかってしまっているのか?(確証なし) 一旦調査停止

    Tags

    Embed
/**
 * Copyright zendenmushi ( http://wonderfl.net/user/zendenmushi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/4vxP
 */

// 昨日上げたコードは大きすぎてquestionには不向きでした。
// 基本に立ち返り、ミニマムコードを。 (海面の奴は別の機会にあげます)
// 
// オブジェクトにPhongShaderやEnvMapShaderを割り当てて
// bumpmapを適用すると、3角ポリゴンのエッジ周辺のbumpの一部にエラー(極端に暗くなる)が
// 表示されます。
// [Question]この原因がわからない(法線ベクトル関連だと思うのですが・・・)ので、
//  解決法をご存知の方、よろしくお願いします
//
// ※昨日のコードでは 3角ポリゴンのエッジ以外にもエラーが出ていましたが、とりあえず3角ポリゴンの
//   エッジに注目して考えてます。 個人的には法線ベクトル。おそらくスムージング角度の問題じゃない
//   かと思うのですが、スムージング角度の設定方法がわかりません
//
// ※なんかそもそもテクスチャがずれているような・・・このあたりを重点的に調べてみます
//
// ※bumpには関係なく、phongshaderを適用した時点でエッジが黒くなっていて、
//   その影響をbumpが受けている模様
// ※ShadedMaterialのCompositeModeをShaderCompositeModes.PER_TRIANGLE_IN_BITMAP
//   にするとエッジの線が消える。・・・・けどbumpmapが消える。 papervisionのソースを見る限り、
//   現在進行形で修正中のようす。ここまでかな
package  
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;
	import flash.text.TextField;
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.core.geom.renderables.Triangle3D;
	import org.papervision3d.core.geom.renderables.Vertex3D;
	import org.papervision3d.core.geom.TriangleMesh3D;
	import org.papervision3d.core.math.NumberUV;
	import org.papervision3d.core.proto.LightObject3D;
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.MovieMaterial;
	import org.papervision3d.materials.shaders.EnvMapShader;
	import org.papervision3d.materials.shaders.FlatShader;
	import org.papervision3d.materials.shaders.PhongShader;
	import org.papervision3d.materials.shaders.ShadedMaterial;
	import org.papervision3d.materials.shaders.ShaderCompositeModes;
	import org.papervision3d.materials.WireframeMaterial;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
	/**
	 * ...
	 * @author TMaeda
	 */
	[SWF(width = 465, height = 465, backgroundColor = 0xcccccc, frameRate = 60)]
	public class SeaWaveMinimum extends Sprite
	{
		private var smallwave : BitmapData;
		private var scrollwave : BitmapData;
		private var skyback : BitmapData;
		// pv3d
		private var scene : Scene3D;
		private var camera : Camera3D;
		private var renderer : BasicRenderEngine;
		private var viewport : Viewport3D;
		private var sphere : Sphere ;
		private var skyMaterial : BitmapMaterial;
		private var shadedMaterial : ShadedMaterial
		private var phongShader : PhongShader;
		private var light :  PointLight3D;
		private var uvarray : Array = new Array();
		
		private var scrollArea : Rectangle = new Rectangle();
		private var subArea : Rectangle = new Rectangle();
		private var tempRect : Rectangle = new Rectangle();
		private var zeroPoint : Point = new Point(0, 0);
		private var subPoint : Point = new Point(0, 0);
		
		private var loaders : Array;
   		private const url:Array = [
			"http://assets.wonderfl.net/images/related_images/8/89/89a3/89a3940a2099d7fe24a51ddfd49fbb370e43e9ee"
			//"./skyback.png"
			];
			
		public function SeaWaveMinimum() 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e : Event = null) : void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
       		loaders = new Array();
			for (var i : int = 0; i < url.length; i++) {
				loaders[i] = new Loader();
				loaders[i].contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
				loaders[i].load(new URLRequest(url[i]), new LoaderContext(true));
			}
			
		}
		
		private var loaded_count : int = 0;
		private function loaded(e : Event = null) : void
		{
			loaded_count++;
			if (loaded_count < url.length) return;

       		addEventListener(Event.ENTER_FRAME, enterFrame);
			

			var mc : MovieClip = new MovieClip();
			addChild(mc);
			
		
			scrollwave = new BitmapData(stage.stageWidth*2, stage.stageHeight, true, 0xffcccccc);
			scrollwave.perlinNoise(32,32, 4, 0, true, false, 1, true);
			smallwave = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xffcccccc);
			scrollArea.left = 0;
			scrollArea.width = stage.stageWidth;
			scrollArea.top = 0;
			scrollArea.height = stage.stageHeight;
			smallwave.copyPixels(scrollwave, scrollArea, zeroPoint);

			skyback = Bitmap(loaders[0].content).bitmapData;
			mc.addChild(new Bitmap(smallwave));
			
			// pv3d
			scene = new Scene3D();
			camera = new Camera3D();
			camera.x = 0;
			camera.y = 100.0;
			camera.z = 0.0;
			camera.ortho = true;
			camera.orthoScale = 20;
			light = new PointLight3D(false, true);
			light.x = 0;
			light.y = 1;
			light.z = 0.0;
			light.pitch(90);
			
			renderer = new BasicRenderEngine();
			viewport = new Viewport3D(stage.stageWidth, stage.stageHeight, false);
			mc.addChild(viewport); 
			
			skyMaterial = new BitmapMaterial(skyback);
			skyMaterial.doubleSided = true;
			phongShader = new PhongShader(light, 0xFFFFFF, 0x404060 , 1, smallwave, smallwave); 
			shadedMaterial =  new ShadedMaterial(skyMaterial, phongShader);//,ShaderCompositeModes.PER_TRIANGLE_IN_BITMAP );

			sphere = new Sphere(shadedMaterial, 10, 2, 2);
			scene.addChild(sphere);

			camera.pitch(90);
			scene.addChild(light);
			//

		}
		
		private var waveShift : int = 0;
		private var rad : Number = 0;
		private function enterFrame(e : Event) : void 
		{
			scrollArea.left = scrollArea.left + 1;
			if (scrollArea.left > scrollwave.width) scrollArea.left = 0;
			
			var w : int = scrollwave.width - scrollArea.left;
			if (w > smallwave.width) w = smallwave.width;
			
			// バンプのアニメーション
			scrollArea.width = w;
			scrollArea.top = 0;
			scrollArea.height = stage.stageHeight;
			smallwave.copyPixels(scrollwave, scrollArea, zeroPoint);
			if (w < smallwave.width) {
				subArea.left = 0;
				subArea.width = smallwave.width - w;
				subArea.top = 0;
				subArea.height = stage.stageHeight;
				subPoint.x = w;
				subPoint.y = 0;
				smallwave.copyPixels(scrollwave, subArea, subPoint);
			}
			
			sphere.rotationX += 0.2;
			sphere.rotationY += 0.5;
			sphere.rotationZ += 0.1;
			
			phongShader.bumpmap = smallwave;
			renderer.renderScene( scene, camera, viewport );
			
		}
		
	}

}