如何解决多次调用渲染器无效
在过去的两个月中,我学到了很多关于three.js和javascript的知识。我现在已经更深入地处理着色器,并且我曾经看到一个在网络上创建程序化行星的好例子。我发现球形几何体很有趣,因为它们的非欧几里德几何体使它们成为对纹理的很好挑战。
我在这里显示了主要代码。我的问题是纹理渲染不起作用。
我已经测试了程序的各个组件。着色器和行星类,所有功能均正常工作。
问题是渲染器。我需要这个不仅可以显示场景,还可以创建纹理。在功能中
textureGeneratorMaterial
(下)renderer.render(textureScene,textureCamera,texture,true);
被激活,我只得到黑屏。在调用函数renderer.render(scene,camera);
之后,我的意思是应该看到正常的场景。程序是否仍留在纹理场景中?如果在renderer.render(scene,camera)
中也调用了渲染器,为什么textureGeneratorMaterial
不起作用?
我已经尝试创建第二个渲染器,但这也不起作用。目前,我不知道该怎么办,因为我不了解原因。有人知道为什么渲染器不想要我想要的方式吗?
var camera,controls,scene,renderer,container;
var sunLight,ambientlight;
var test1,test2,test3,test4;
function main() {
init();
animate();
}
function init() {
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
container = document.getElementById('container');
renderer.setSize(container.clientWidth,container.clientHeight);
container.appendChild( renderer.domElement );
var aspect = container.clientWidth / container.clientHeight;
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x000000 );
camera = new THREE.PerspectiveCamera( 45,container.clientWidth / container.clientHeight,1,10000 );
camera.position.set(0,20);
controls = new THREE.OrbitControls( camera,renderer.domElement );
controls.enableZoom = true;
controls.enabled = true;
controls.target.set(0,0);
//-------------
sunLight = new THREE.PointLight(new THREE.Color(0xffffff),1.0);
sunLight.position.set(100,0);
scene.add(sunLight);
ambientlight = new THREE.AmbientLight( 0xF0F0F0 ); // soft white light
scene.add( ambientlight );
var maps = generateTextures(); //--here is the problem---
/* -----used ro check "function textureGeneratorMaterial(index)" works------
var plane = new THREE.Mesh(
new THREE.PlaneGeometry(1024,1024),textureGeneratorMaterial(0)
);
scene.add( plane );
*/
/*-----used ro check "Planet class" works------
for(var i = 0; i <6;i++){
maps.textureMaps[i].texture = new THREE.TextureLoader().load("img/Cay_sand.jpeg");
maps.bumpMaps[i].texture = new THREE.TextureLoader().load("img/Cay_sand.jpeg");
}
*/
scene.add(new Planet(5,maps.textureMaps,maps.bumpMaps)); // works correct
}//-------End init----------
function animate() {
requestAnimationFrame( animate );
render();
}//-------End animate----------
function render() {
document.getElementById("demo1").innerHTML = test1;
document.getElementById("demo2").innerHTML = test2;
document.getElementById("demo3").innerHTML = test3;
document.getElementById("demo4").innerHTML = test4;
camera.updateMatrixWorld();
camera.updateProjectionMatrix();
renderer.render(scene,camera);
}//-------End render----------
function generateTextures() {
var textureMaps = [];
var bumpMaps = [];
var resolution = 1024;
for (var index = 0; index < 6; index++) {
var texture = new THREE.WebGLRenderTarget(resolution,resolution,{minFilter: THREE.LinearFilter,magFilter: THREE.LinearFilter,format: THREE.RGBFormat});
var textureCamera = new THREE.OrthographicCamera(-resolution/2,resolution/2,-resolution/2,-100,100);
textureCamera.position.z = 10;
var textureScene = new THREE.Scene();
var plane = new THREE.Mesh(
new THREE.PlaneGeometry(resolution,resolution),textureGeneratorMaterial(index)
);
plane.position.z = -10;
textureScene.add(plane);
// renderer.render(textureScene,true);
var buffer = new Uint8Array(resolution * resolution * 4);
var gl = renderer.getContext();
gl.readPixels( 0,gl.RGBA,gl.UNSIGNED_BYTE,buffer);
textureMaps.push(texture);
bumpMaps.push({image: {data: buffer,height: resolution,width: resolution}});
}
return {textureMaps: textureMaps,bumpMaps: bumpMaps};
}
解决方法
好的,我找到了解决方案。我坚信这取决于渲染器,并且在首次调用它时,它仍将被困在纹理目标中。 在three.js中,可以重置渲染目标,如果这样做,Three.js似乎将其视为需要初始化,并接受对渲染器的调用以渲染主场景。
我添加了以下这一行:renderer.setRenderTarget(null);
见下文
function generateTextures() {
var textureMaps = [];
var bumpMaps = [];
var resolution = 2048;
for (var index = 0; index < 6; index++) {
var texture = new THREE.WebGLRenderTarget(resolution,resolution,{minFilter: THREE.LinearFilter,magFilter: THREE.LinearFilter,format: THREE.RGBFormat});
var textureCamera = new THREE.OrthographicCamera(-resolution/2,resolution/2,-resolution/2,-100,100);
textureCamera.position.z = 10;
var textureScene = new THREE.Scene();
var plane = new THREE.Mesh(
new THREE.PlaneGeometry(resolution,resolution),textureGeneratorMaterial(index)
);
plane.position.z = -10;
textureScene.add(plane);
renderer.render(textureScene,textureCamera,texture,true);
var buffer = new Uint8Array(resolution * resolution * 4);
var gl = renderer.getContext();
gl.readPixels( 0,gl.RGBA,gl.UNSIGNED_BYTE,buffer);
textureMaps.push(texture);
bumpMaps.push({image: {data: buffer,height: resolution,width: resolution}});
renderer.setRenderTarget(null);
}
return {textureMaps: textureMaps,bumpMaps: bumpMaps};
}
在像我看到的示例这样的旧版本中,这不是必需的。但这并不意味着批评。这是一个干净的解决方案。因此,三个人总是知道需要进行渲染器操作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。