Having trouble with resizing the Three.js shader scene using ThreeX to handle window resizing and changing orientation on mobile devices. When the window width is decreased, everything works perfectly. However, expanding the window either in width or height doesn't cause the scene to fill the new space. Also, resizing the window's height results in a failure, causing the mouse-location calculation to become dislocated from the actual mouse position. Need help troubleshooting where the mistake might be.
UPDATE: The issue can be replicated in JSFIDDLE. Click the link to activate the shader and resize the fiddle to observe the resizing problems.
Image 01: Window resized larger with shader not expanding accordingly
Image 02: Window with decreased height and misaligned mouse/mouse-coordinates (white dot represents mouse, color circle should align perfectly)
https://i.sstatic.net/RROtG.jpg https://i.sstatic.net/N43B4.jpg
<script>
var scene;
var camera;
var renderer;
function scene_setup(){
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
var width = window.innerWidth;
var height = window.innerHeight;
camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );
camera.position.z = 2;
THREEx.WindowResize(renderer, camera);
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.getElementById("curse").appendChild( renderer.domElement );
}
var bufferScene;
var textureA;
var textureB;
var bufferMaterial;
var plane;
var bufferObject;
var finalMaterial;
var quad;
function buffer_texture_setup(){
bufferScene = new THREE.Scene();
textureA = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter});
textureB = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter} );
bufferMaterial = new THREE.ShaderMaterial( {
uniforms: {
bufferTexture: { type: "t", value: textureA },
res : {type: 'v2',value:new THREE.Vector2(window.innerWidth,window.innerHeight)},//Keeps the resolution
smokeSource: {type:"v3",value:new THREE.Vector3(0,0,0)},
time: {type:"f",value:Math.random()*Math.PI*2+Math.PI}
},
fragmentShader: document.getElementById( 'fragS' ).innerHTML
} );
plane = new THREE.PlaneBufferGeometry( window.innerWidth, window.innerHeight );
bufferObject = new THREE.Mesh( plane, bufferMaterial );
bufferScene.add(bufferObject);
//Draw textureB to screen
finalMaterial = new THREE.MeshBasicMaterial({map: textureB});
quad = new THREE.Mesh( plane, finalMaterial );
scene.add(quad);
}
scene_setup();
buffer_texture_setup();
var mouseDown = false;
function UpdateMousePosition(X,Y){
var mouseX = X;
var mouseY = window.innerHeight - Y;
bufferMaterial.uniforms.smokeSource.value.x = mouseX;
bufferMaterial.uniforms.smokeSource.value.y = mouseY;
}
document.onmousemove = function(event){
UpdateMousePosition(event.clientX,event.clientY)
}
document.onmousedown = function(event){
mouseDown = true;
bufferMaterial.uniforms.smokeSource.value.z = 0;
}
document.onmouseup = function(event){
mouseDown = false;
bufferMaterial.uniforms.smokeSource.value.z = 0.02;
}
function render() {
requestAnimationFrame( render );
renderer.render(bufferScene,camera,textureB,true);
var t = textureA;
textureA = textureB;
textureB = t;
quad.material.map = textureB;
bufferMaterial.uniforms.bufferTexture.value = textureA;
bufferMaterial.uniforms.time.value += 0.01;
renderer.render( scene, camera );
}
render();
//shader
</script>
<script id="fragS">
uniform vec2 res;//The width and height of our screen
uniform sampler2D bufferTexture;//Our input texture
uniform vec3 smokeSource;//The x,y are the posiiton. The z is the power/density
uniform float time;
void main() {
vec2 pixel = gl_FragCoord.xy / res.xy;
//Get the distance of the current pixel from the smoke source
float dist = distance(smokeSource.xy,gl_FragCoord.xy);
//Get the color of the current pixel
gl_FragColor = texture2D( bufferTexture, pixel );
//Generate smoke when mouse is pressed
gl_FragColor.rgb += smokeSource.z * max(100.0-dist,0.02);
//Smoke diffuse
float xPixel = 1.0/res.x;//The size of a single pixel
float yPixel = 4.0/res.y;
vec4 rightColor = texture2D(bufferTexture,vec2(pixel.x+xPixel,pixel.y));
vec4 leftColor = texture2D(bufferTexture,vec2(pixel.x-xPixel,pixel.y));
vec4 upColor = texture2D(bufferTexture,vec2(pixel.x,pixel.y+yPixel));
vec4 downColor = texture2D(bufferTexture,vec2(pixel.x,pixel.y-yPixel));
//Handle the bottom boundary
if(pixel.y <= yPixel){
downColor.rgb = vec3(0.0);
}
//Diffuse equation
float factor = 1.0 * 0.020 * (leftColor.r + rightColor.r + downColor.r * 3.0 + upColor.r - 6.0 * gl_FragColor.r);
//Account for low precision of texels
float minimum = 0.003;
if(factor >= -minimum && factor < 0.0) factor = -minimum;
gl_FragColor.rgb += factor;
}
</script>