I am implementing a Three.js shader and I have included ThreeX as a way to resize the scene when the window resizes, to deal with changing browser window size and changing orientation on mobile.
When the window width is made smaller it works like a charm; however, when the window is made bigger (either width or height) than when it first loaded the scene does not expand to fill the new space. Also, the resize fails completely when the height of the window is resized smaller. When the hight of the window is shrunk the calculated mouse-location does not change to a address new height and becomes dislocated from the actual mouse location. (see screenshots)
Help! Looking for where I have gone wrong.
UPDATE: Problem reproduced in JSFIDDLE Click to activate shader and resize fiddle to see resizing issues.
Image 01: Shows window resized larger and the shader not expanding to match
Image 02: Shows window with smaller resized height and mismatched mouse / mouse-coordinates (mouse is white dot and color circle should be right on it
<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>
uniforms.res.value
? – pailheadres
and noticed that you do set window values on it. Those values change. When they change, do you update yourres.value
vector? If you can drop threex, or modify it, try adding another line to it, basically justbufferMaterial.uniforms.res.value.set(window.innerWidth,window.innerHeight)
– pailheadres
may have something to do with it, with the shader i would be able to tell you exactly what is going on. – pailhead