Aerion Posted December 14, 2014 Share Posted December 14, 2014 Hi all. Just as the title says, I need some help with this Three.js code. I would like to know why "img" is reporting "null" even though the image location is correct, the image is there, and the DIV tag is in the right place. Here's the source html file, and all other files needed to make this work. http://mega.co.nz/#!bokBQZib!FFGspP-lTM4dSG9H_fVJSxgdaweDzajQIViyHL09xhk If you open Developer in Mozilla, you will see that the error that you get is: "img is null". Thank You all so much for all of your help! Sincerely, Mythros Quote Link to comment Share on other sites More sharing options...
Warspawn Posted December 14, 2014 Share Posted December 14, 2014 2 things to get you further along (still isn't rendering for me)#assets { visibility: hidden; }display: none makes it have width of 0$('#landscape-image').ready(function() { console.log('image ready, start it up!'); init(); animate();});need to wait for the image to finish loading, since you have jquery this should work... Quote Link to comment Share on other sites More sharing options...
Aerion Posted December 14, 2014 Author Share Posted December 14, 2014 Hi, thanks for the answer. It DOES load now, but it won't show the terrain.<!doctype html><html lang="en"><head> <title>Shader - Height Map (Three.js)</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <link rel=stylesheet href="css/base.css"/> <style type="text/css"> #canvas { visibility: hidden; } #assets { visibility: hidden; } </style> </head><body><script src="./js/jquery-1.9.1.js"></script><script src="./js/jquery-ui.js"></script><script src="./js/Three.js"></script><script src="./js/Detector.js"></script><script src="./js/Stats.js"></script><script src="./js/OrbitControls.js"></script><script src="./js/KeyboardState.js"></script><script src="./js/THREEx.js"></script><script src="./js/THREEx_002.js"></script><script src="./js/THREEx.FullScreen.js"></script><script src="./js/THREEx.WindowResize.js"></script><!-- ---------------- Custom Shader Code ------------------------ --><script id="vertexShader" type="x-shader/x-vertex">uniform sampler2D bumpTexture;uniform float bumpScale;varying float vAmount;varying vec2 vUV;void main() { vUV = uv; vec4 bumpData = texture2D( bumpTexture, uv ); vAmount = bumpData.g; // assuming map is grayscale it doesn't matter if you use r, g, or b. // move the position along the normal vec3 newPosition = (position + normal * bumpScale * vAmount); gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );}</script><!-- fragment shader a.k.a. pixel shader --><script id="fragmentShader" type="x-shader/x-vertex"> uniform sampler2D oceanTexture;uniform sampler2D sandyTexture;uniform sampler2D grassTexture;uniform sampler2D rockyTexture;uniform sampler2D snowyTexture;varying vec2 vUV;varying float vAmount;void main() { vec4 water = (smoothstep(0.01, 0.25, vAmount) - smoothstep(0.24, 0.26, vAmount)) * texture2D( oceanTexture, vUV * 10.0 ); vec4 sandy = (smoothstep(0.24, 0.27, vAmount) - smoothstep(0.28, 0.31, vAmount)) * texture2D( sandyTexture, vUV * 10.0 ); vec4 grass = (smoothstep(0.28, 0.32, vAmount) - smoothstep(0.35, 0.40, vAmount)) * texture2D( grassTexture, vUV * 20.0 ); vec4 rocky = (smoothstep(0.30, 0.50, vAmount) - smoothstep(0.40, 0.70, vAmount)) * texture2D( rockyTexture, vUV * 20.0 ); vec4 snowy = (smoothstep(0.50, 0.65, vAmount)) * texture2D( snowyTexture, vUV * 10.0 ); gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0) + water + sandy + grass + rocky + snowy; //, 1.0);} </script><!-- ----------------------------------------------------------- --><!-- Code to display an information button and box when clicked. --><link rel=stylesheet href="./css/jquery-ui.css" /><link rel=stylesheet href="./css/info.css"/><script src="./js/info.js"></script><div id="infoButton"></div><!-- ------------------------------------------------------------ --><div id="ThreeJS" style="position: absolute; left:0px; top:0px"></div><script>//To get the pixels, draw the image onto a canvas. From the canvas get the Pixel (R,G,B,A)function getTerrainPixelData(){ var img = document.getElementById("landscape-image"); var canvas = document.getElementById("canvas"); canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height); var data = canvas.getContext('2d').getImageData(0,0, img.height, img.width).data; var normPixels = [] for (var i = 0, n = data.length; i < n; i += 4) { // get the average value of R, G and B. normPixels.push((data[i] + data[i+1] + data[i+2]) / 3); } return {normPixels: normPixels};}function CreateTerrain(geometry, width, height, numSegments){ width = width || 2400; height = height || 2400; numSegments = numSegments || 100; var material = new THREE.MeshLambertMaterial({ color: 0xccccff, wireframe: false }); var terrain = getTerrainPixelData(); // keep in mind, that the plane has more vertices than segments. If there's one segment, there's two vertices, if // there's 10 segments, there's 11 vertices, and so forth. // The simplest is, if like here you have 100 segments, the image to have 101 pixels. You don't have to worry about // "skewing the landscape" then.. // to check uncomment the next line, numbers should be equal console.log("length: " + terrain.length + ", vertices length: " + geometry.vertices.length); for (var i = 0, l = geometry.vertices.length; i < l; i++) { var terrainValue = terrain[i] / 255; geometry.vertices[i].z = geometry.vertices[i].z + terrainValue * 200; } geometry.computeFaceNormals(); geometry.computeVertexNormals(); var plane = new THREE.Mesh(geometry, material); plane.position = new THREE.Vector3(0,0,0); // rotate the plane so up is where y is growing.. var q = new THREE.Quaternion(); q.setFromAxisAngle( new THREE.Vector3(-1,0,0), 90 * Math.PI / 180 ); plane.quaternion.multiplyQuaternions( q, plane.quaternion ); scene.add(plane) return plane;}// standard global variablesvar container, scene, camera, renderer, controls, stats;var keyboard = new KeyboardState();var clock = new THREE.Clock();// custom global variablesvar mesh;$('#landscape-image').ready(function() { console.log('image ready, start it up!'); init(); animate();});// FUNCTIONS function init() { // SCENE scene = new THREE.Scene(); // CAMERA var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight; var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000; camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR); scene.add(camera); camera.position.set(0,100,400); camera.lookAt(scene.position); // RENDERER if ( Detector.webgl ) renderer = new THREE.WebGLRenderer( {antialias:true} ); else renderer = new THREE.CanvasRenderer(); renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); container = document.getElementById( 'ThreeJS' ); container.appendChild( renderer.domElement ); // EVENTS THREEx.WindowResize(renderer, camera); THREEx.FullScreen.bindKey({ charCode : 'm'.charCodeAt(0) }); // CONTROLS controls = new THREE.OrbitControls( camera, renderer.domElement ); // STATS stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.bottom = '0px'; stats.domElement.style.zIndex = 100; container.appendChild( stats.domElement ); // LIGHT var light = new THREE.PointLight(0xffffff); light.position.set(100,250,100); scene.add(light); // SKYBOX var skyBoxGeometry = new THREE.CubeGeometry( 20000, 20000, 20000 ); var skyBoxMaterial = new THREE.MeshBasicMaterial( { color: 0x99ccff, side: THREE.BackSide } ); var skyBox = new THREE.Mesh( skyBoxGeometry, skyBoxMaterial ); scene.add(skyBox); //////////// // CUSTOM // //////////// // texture used to generate "bumpiness" var bumpTexture = new THREE.ImageUtils.loadTexture( './images/heightmap.png' ); bumpTexture.wrapS = bumpTexture.wrapT = THREE.RepeatWrapping; // magnitude of normal displacement var bumpScale = 200.0; var oceanTexture = new THREE.ImageUtils.loadTexture( './images/dirt4-2048.jpg' ); oceanTexture.wrapS = oceanTexture.wrapT = THREE.RepeatWrapping; var sandyTexture = new THREE.ImageUtils.loadTexture( './images/sand-waves-2048.jpg' ); sandyTexture.wrapS = sandyTexture.wrapT = THREE.RepeatWrapping; var grassTexture = new THREE.ImageUtils.loadTexture( './images/grass2-2048.jpg' ); grassTexture.wrapS = grassTexture.wrapT = THREE.RepeatWrapping; var rockyTexture = new THREE.ImageUtils.loadTexture( './images/rock-512.jpg' ); rockyTexture.wrapS = rockyTexture.wrapT = THREE.RepeatWrapping; var snowyTexture = new THREE.ImageUtils.loadTexture( './images/snow-2048.jpg' ); snowyTexture.wrapS = snowyTexture.wrapT = THREE.RepeatWrapping; // use "this." to create global object this.customUniforms = { bumpTexture: { type: "t", value: bumpTexture }, bumpScale: { type: "f", value: bumpScale }, oceanTexture: { type: "t", value: oceanTexture }, sandyTexture: { type: "t", value: sandyTexture }, grassTexture: { type: "t", value: grassTexture }, rockyTexture: { type: "t", value: rockyTexture }, snowyTexture: { type: "t", value: snowyTexture }, }; // create custom material from the shader code above // that is within specially labelled script tags var customMaterial = new THREE.ShaderMaterial( { uniforms: customUniforms, vertexShader: document.getElementById( 'vertexShader' ).textContent, fragmentShader: document.getElementById( 'fragmentShader' ).textContent, side: THREE.DoubleSide } ); var planeGeo = new THREE.PlaneGeometry( 1000, 1000, 100, 100 ); var plane = new THREE.Mesh( planeGeo, customMaterial ); plane.rotation.x = -Math.PI / 2; plane.position.y = -100; scene.add( plane ); var terrain = CreateTerrain(planeGeo, 2400, 2400, 100); var waterGeo = new THREE.PlaneGeometry( 1000, 1000, 1, 1 ); var waterTex = new THREE.ImageUtils.loadTexture( './images/water512.jpg' ); waterTex.wrapS = waterTex.wrapT = THREE.RepeatWrapping; waterTex.repeat.set(5, 5); var waterMat = new THREE.MeshBasicMaterial( {map: waterTex, transparent:true, opacity:0.40} ); var water = new THREE.Mesh( planeGeo, waterMat ); water.rotation.x = -Math.PI / 2; water.position.y = -50; scene.add( water); }function animate() { requestAnimationFrame( animate ); render(); update();}function update(){ if ( keyboard.pressed("z") ) { // do something } controls.update(); stats.update();}function render() { renderer.render( scene, camera );}</script><canvas id="canvas"></canvas><div id="assets"><img id="landscape-image" src="images/heightmap.png" /></div></body></html> Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.