Reputation: 2069
I'm trying to get a basic render target working where I render to 1 scene and then use it as a texture to render over a quad. I've got a basic demo but when I run it the result is all pixelated, as if it's being rendered to a tiny screen and then being stretched across the quad.
Here's my code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title></title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="three.min.js" type="text/javascript"></script>
<style>
body {
color: #ffffff;
font-family:Monospace;
font-size:13px;
text-align:center;
font-weight: bold;
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 0px; width: 100%;
padding: 5px;
}
a {
color: #ffffff;
}
</style>
</head>
<body>
<div id="container"></div>
<script id="vertex-shader-test" type="x-shader/x-vertex">
void main() {
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
}
</script>
<script id="fragment-shader-test" type="x-shader/x-vertex">
void main() {
gl_FragColor = vec4(1,1,1,1);
}
</script>
<script id="vertex-shader-screen" type="x-shader/x-vertex">
varying vec2 vertexUV;
void main() {
vertexUV = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script id="fragment-shader-screen" type="x-shader/x-fragment">
precision highp float;
varying vec2 vertexUV;
uniform sampler2D rtTexture;
void main() {
gl_FragColor = texture2D(rtTexture, vertexUV);
}
</script>
<script>
var scene = null,
rtScene = null,
camera = null,
cameraRTT = null,
renderer = null,
plane = null;
var rtTexture;
init();
render();
function init()
{
container = document.getElementById( 'container' );
scene = new THREE.Scene();
rtScene = new THREE.Scene();
rtTexture = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBFormat });
camera = new THREE.PerspectiveCamera(20, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 1;
rtCamera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
rtCamera.position.z = 100;
rtCamera.position.y = 10;
var material2 = new THREE.ShaderMaterial({
vertexShader: document.getElementById('vertex-shader-test').textContent,
fragmentShader: document.getElementById('fragment-shader-test').textContent,
});
var geometry = new THREE.PlaneBufferGeometry(100, 100, 200, 200);
plane = new THREE.Mesh(geometry, material2);
plane.rotateX(-Math.PI / 2);
rtScene.add(plane);
var geometry = new THREE.PlaneBufferGeometry(1, 1);
var material = new THREE.ShaderMaterial({
uniforms: {
rtTexture: { type: "t", value: rtTexture }
},
vertexShader: document.getElementById('vertex-shader-screen').textContent,
fragmentShader: document.getElementById('fragment-shader-screen').textContent,
});
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.autoClear = false;
container.appendChild( renderer.domElement );
}
function render() {
requestAnimationFrame(render);
camera.lookAt(new THREE.Vector3(0,0,0));
rtCamera.lookAt(new THREE.Vector3(0,0,0));
renderer.render(rtScene, rtCamera, rtTexture, true);
renderer.render(scene, camera);
}
</script>
</body>
</html>
Any ideas?
Upvotes: 1
Views: 932
Reputation: 187
You are using a perspective camera when rendering the plane that has your render target mapped to it. This will cause the rendered output to vary in size based on the field of view.
For example, if you reduce your cameras field of view from 20 to 10, the camera will be further zoomed in and you will get even more pronounced stepping (because the image has been scaled up further). Similarly, increasing the field of view, will zoom out and reduce the stepping.
However, for what is in this example, I would use an orthographic projection for the main scene where you output the render target.
Upvotes: 2