#javascript #three.js
#javascript #three.js
Вопрос:
За последние два месяца я многое узнал о three.js и javascript. теперь я углубился в обработку шейдеров, и однажды я видел хороший пример создания процедурных планет в Интернете. Я нахожу сферические геометрии интересными, потому что их неевклидова геометрия делает их хорошей проблемой для текстур.
Я показал здесь основной код. моя проблема в том, что рендеринг текстур не работает. Я протестировал отдельные компоненты моей программы. Шейдер и класс planet, все функции работают корректно. проблема в средстве визуализации. Мне это нужно для отображения сцены, а также для создания текстур. Когда в функции 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, 0, 20);
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableZoom = true;
controls.enabled = true;
controls.target.set(0, 0, 0);
//-------------
sunLight = new THREE.PointLight(new THREE.Color(0xffffff), 1.0);
sunLight.position.set(100, 0, 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, -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, 0, resolution, resolution, gl.RGBA, gl.UNSIGNED_BYTE, buffer);
textureMaps.push(texture);
bumpMaps.push({image: {data: buffer, height: resolution, width: resolution}});
}
return {textureMaps: textureMaps, bumpMaps: bumpMaps};
}
Комментарии:
1. Вы проверяли, что сцена в generateTexrures отображается сама по себе, не будучи в текстуре? Вы пробовали заменить текстуру изображением, чтобы посмотреть, сработало ли это?
2. да, у меня есть, и все это работает
Ответ №1:
Хорошо, я нашел решение. Я был убежден, что это зависит от средства визуализации и что оно останется заблокированным в целевой текстуре при первом вызове. В 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, -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, 0, resolution, resolution, 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};
}
В более старых версиях, подобных примеру, который я видел, в этом не было необходимости. Но это не критика. Это чистое решение. Таким образом, three всегда знает, что существует необходимость в действии средства визуализации.
Комментарии:
1. Да, параметр render target в
render()
был удален несколько выпусков назад, поэтому теперь необходимо определить черезsetRenderTarget()
, следует ли использовать цель рендеринга или нет.