I am building a tile game using Pixi.js. The game features dynamically-generated terrain and a day/night cycle. I'd like to use a normal map to give the sense of sloping hills or mountains.
Luckily pixi.js supports normals. I've recreated a demo app from their examples here:
var viewWidth = 1024 // /2;
var viewHeight = 1024 //512 /2;
// Create a pixi renderer
var renderer = PIXI.autoDetectRenderer(viewWidth, viewHeight);
renderer.view.className = "rendererView";
// add render view to DOM
document.body.appendChild(renderer.view);
// create an new instance of a pixi stage
var stage = new PIXI.Stage(0xFFFFFF);
//EXPERIMENTAL: Trying to dynamically create textures. Doesn't work.
//If using this method, comment out line 24.
/*var rect = new PIXI.Graphics();
rect.beginFill(0xFFFFFF);
rect.drawRect(0,0,600,600);
rect.endFill();
var pondFloorTexture = rect.generateTexture();*/
// create a background texture
var pondFloorTexture = PIXI.Texture.fromImage("http://www.goodboydigital.com/pixijs/examples/20/counch_norm.jpg");
// create a new background sprite
//var pondFloorSprite = new PIXI.Sprite(pondFloorTexture);
//stage.addChild(pondFloorSprite);
var filter = new PIXI.NormalMapFilter(pondFloorTexture);
var sprite = PIXI.Sprite.fromImage("http://www.goodboydigital.com/pixijs/examples/20/couch.jpg"); //(pondFloorTexture);
sprite.filters = [filter];
stage.addChild(sprite);
var tick = 0;
requestAnimationFrame(animate);
function animate() {
// increment the ticker
tick += 0.1;
var mouse = stage.interactionManager.mouse;
if (mouse.global.x < 0) mouse.global.x = 0;
else if (mouse.global.x > viewWidth) mouse.global.x = viewWidth;
if (mouse.global.y < 0) mouse.global.y = 0;
else if (mouse.global.y > viewHeight) mouse.global.y = viewHeight;
filter.uniforms.LightPos.value[0] = mouse.global.x;
filter.uniforms.LightPos.value[1] = mouse.global.y;
// time to render the state!
renderer.render(stage);
// request another animation frame..
requestAnimationFrame(animate);
}
<script src="http://www.goodboydigital.com/pixijs/examples/20/pixi.js"></script>
<script src="http://www.goodboydigital.com/pixijs/examples/20/NormalMapFilter.js"></script>
Note that at line 15 I've added a bit of code that attempts to replace the normal map with a dynamically created rectangle. But for some reason this results in everything appearing black. Am I doing something wrong? Is there a better way to do this?
But more importantly, should I be creating normal maps dynamically? Obviously generating them on the fly will be computationally expensive, but how else would I get a normal map for something I won't know the shape of until last minute?

