Javascript 在Three.js中从Base64加载纹理
我目前正在从URL加载纹理,但由于我的后端代码正在生成行星,我需要使用Base64显示它们 (我正在玩程序生成,所以我不希望保存图像,然后通过URL加载它) 这是代码Javascript 在Three.js中从Base64加载纹理,javascript,three.js,Javascript,Three.js,我目前正在从URL加载纹理,但由于我的后端代码正在生成行星,我需要使用Base64显示它们 (我正在玩程序生成,所以我不希望保存图像,然后通过URL加载它) 这是代码 <!DOCTYPE html><html class=''> <head> <style>body { background: black; text-align: center; } </style></head><body> <s
<!DOCTYPE html><html class=''>
<head>
<style>body {
background: black;
text-align: center;
}
</style></head><body>
<script id="vertexShader" type="x-shader/x-vertex">
uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;
void main({
vec3 vNormal = normalize( normalMatrix * normal );
vec3 vNormel = normalize( normalMatrix * viewVector );
intensity = pow( c - dot(vNormal, vNormel), p );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec3 glowColor;
varying float intensity;
void main() {
vec3 glow = glowColor * intensity;
gl_FragColor = vec4( glow, 1.0 );
}
</script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/three.js/r63/three.min.js'></script><script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/orbitcontrols.js'></script>
<script>var container, controls, camera, renderer, scene, light,
rotationSpeed = 0.02,
clock = new THREE.Clock(),
WIDTH = window.innerWidth - 30,
HEIGHT = window.innerHeight - 30;
//cam vars
var angle = 45,
aspect = WIDTH / HEIGHT,
near = 0.1,
far = 10000;
//mesh vars
var earthMesh, Atmos, AtmosMat;
container = document.createElement('div');
document.body.appendChild(container);
//cam
camera = new THREE.PerspectiveCamera(angle, aspect, near, far);
camera.position.set(1380, -17, 394);
//scene
scene = new THREE.Scene();
camera.lookAt(scene.position);
//light
light = new THREE.SpotLight(0xFFFFFF, 1, 0, Math.PI / 2, 1);
light.position.set(4000, 4000, 1500);
light.target.position.set (1000, 3800, 1000);
light.castShadow = true;
//light.shadowCameraNear = 1;
//light.shadowCameraFar = 10000;
//light.shadowCameraFov = 50;
scene.add(light);
//EARTH
var earthGeo = new THREE.SphereGeometry (200, 400, 400),
earthMat = new THREE.MeshPhongMaterial();
earthMesh = new THREE.Mesh(earthGeo, earthMat);
earthMesh.position.set(-100, 0, 0);
earthMesh.rotation.y=5;
scene.add(earthMesh);
//diffuse
earthMat.map = THREE.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/earthmap.jpg');
//bump
earthMat.bumpMap = THREE.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/bump-map.jpg');
earthMat.bumpScale = 8;
//specular
earthMat.specularMap = THREE.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/earthspec1k.jpg');
earthMat.specular = new THREE.Color('#2e2e2e');
earthMesh.castShadow = true;
earthMesh.receiveShadow = true;
//Atmosphere
AtmosMat = new THREE.ShaderMaterial({
uniforms:{
"c": { type: "f", value: 0.3 },
"p": { type: "f", value: 5.2},
glowColor: { type: "c", value: new THREE.Color(0x00dbdb)},
viewVector: { type: "v3", value: camera.position}
},
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent,
side: THREE.BackSide,
blending: THREE.AdditiveBlending,
transparent: true
});
Atmos = new THREE.Mesh(earthGeo, AtmosMat);
Atmos.position = earthMesh.position;
Atmos.scale.multiplyScalar(1.2);
scene.add(Atmos);
//STARS
var starGeo = new THREE.SphereGeometry (3000, 10, 100),
starMat = new THREE.MeshBasicMaterial();
starMat.map = THREE.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/star-field.png');
starMat.side = THREE.BackSide;
var starMesh = new THREE.Mesh(starGeo, starMat);
scene.add(starMesh);
//renderer
renderer = new THREE.WebGLRenderer({antialiasing : true});
renderer.setSize(WIDTH, HEIGHT);
container.appendChild(renderer.domElement);
//controls
controls = new THREE.OrbitControls( camera, renderer.domElement);
controls.addEventListener( 'change', render );
function animate(){
requestAnimationFrame(animate);
controls.update();
render();
}
function render(){
var delta = clock.getDelta();
earthMesh.rotation.y += rotationSpeed * delta;
renderer.clear();
renderer.render(scene, camera);
}
animate();
//# sourceURL=pen.js
</script>
</body></html>
身体{
背景:黑色;
文本对齐:居中;
}
均匀vec3视向量;
均匀浮点数c;
均匀浮动p;
浮动强度变化;
真空总管({
vec3 vNormal=规格化(normalMatrix*normal);
vec3 vNormel=规格化(normalMatrix*viewVector);
强度=功率(c-点(vNormal,vNormal),p);
gl_位置=projectionMatrix*modelViewMatrix*vec4(位置,1.0);
}
颜色均匀;
浮动强度变化;
void main(){
vec3发光=发光颜色*强度;
gl_FragColor=vec4(辉光,1.0);
}
变量容器、控件、摄影机、渲染器、场景、灯光、,
旋转速度=0.02,
时钟=新的三个。时钟(),
宽度=window.innerWidth-30,
高度=窗内高度-30;
//凸轮变量
可变角度=45,
纵横比=宽度/高度,
接近=0.1,
far=10000;
//网格变量
var earthMesh、Atmos、AtmosMat;
container=document.createElement('div');
文件.正文.附件(容器);
//凸轮
摄像头=新的三个透视摄像头(角度、纵横比、近距离、远距离);
摄像机位置设置(1380,-17394);
//场面
场景=新的三个。场景();
摄像机。注视(场景。位置);
//轻的
灯光=新的三个聚光灯(0xFFFFFF,1,0,Math.PI/2,1);
光。位置。设置(4000、4000、1500);
light.target.position.set(100038001000);
light.castShadow=true;
//light.shadowCameraNear=1;
//light.shadowCameraFar=10000;
//light.shadowCameraFov=50;
场景。添加(灯光);
//土
var earthGeo=新的三点球面法(200400400),
earthMat=新的三个。MeshPhongMaterial();
earthMesh=新的三个网格(earthGeo、earthMat);
接地网。位置。设置(-100,0,0);
土网。旋转。y=5;
场景。添加(earthMesh);
//漫
earthMat.map=THREE.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/earthmap.jpg');
//碰撞
earthMat.bumpMap=3.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/bump-map.jpg');
earthMat.bumpScale=8;
//镜面反射
earthMat.specularMap=3.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/earthspec1k.jpg');
earthMat.specular=新的三种颜色(“#2e”);
earthMesh.castShadow=真;
earthMesh.receiveShadow=真;
//气氛
AtmosMat=新的3.ShaderMaterial({
制服:{
“c”:{类型:“f”,值:0.3},
“p”:{类型:“f”,值:5.2},
glowColor:{type:“c”,值:new THREE.Color(0x00dbdb)},
viewVector:{type:“v3”,值:camera.position}
},
vertexShader:document.getElementById('vertexShader').textContent,
fragmentShader:document.getElementById('fragmentShader').textContent,
侧面:三,背面,
混合:3.可加性贷款,
透明:正确
});
Atmos=新的三个网格(earthGeo、AtmosMat);
Atmos.position=earthMesh.position;
大气刻度倍数刻度(1.2);
场景。添加(大气);
//明星
var starGeo=新的三倍比色法(3000,10100),
starMat=新的三个.MeshBasicMaterial();
starMat.map=THREE.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/star-field.png');
starMat.side=3.BackSide;
var starMesh=新的三个网格(starGeo,starMat);
场景。添加(starMesh);
//渲染器
renderer=new THREE.WebGLRenderer({抗锯齿:true});
设置大小(宽度、高度);
container.appendChild(renderer.domeElement);
//控制
控件=新的三个.轨道控件(摄影机、渲染器.doElement);
控件。addEventListener('change',render);
函数animate(){
请求动画帧(动画);
控件更新();
render();
}
函数render(){
var delta=clock.getDelta();
earthMesh.rotation.y+=旋转速度*delta;
.clear();
渲染器。渲染(场景、摄影机);
}
制作动画();
//#sourceURL=pen.js
我试过了
image = document.createElement( 'img' );
document.body.appendChild( image );
earthMat.map = new THREE.Texture( image );
image.addEventListener( 'load', function ( event ) { texture.needsUpdate = true; } );
image.src = 'data:image/png;base64,<?php echo $image_data_base64 ?>';
image=document.createElement('img');
document.body.appendChild(图像);
earthMat.map=新的三点纹理(图像);
addEventListener('load',函数(事件){texture.needsUpdate=true;});
image.src='data:image/png;base64';
但它似乎工作不正常
任何帮助都将不胜感激,谢谢。原来我不得不这么做
earthMat.map = THREE.ImageUtils.loadTexture( image.src );
而不是
earthMat.map = new THREE.Texture( image );
新事件监听器
image.addEventListener( 'load', function ( event ) {
earthMat.map = THREE.ImageUtils.loadTexture( image.src );
earthMat.needsUpdate = true;
});
您是否测试过图像加载是否正确?如果将
>
放在HTML文档中会发生什么情况?加载很好。地图生成有点慢(这可能是问题的一部分)但除此之外,它确实可以加载。我认为依赖于texture.needsUpdate是一种假设。你需要将纹理作为一个新的纹理类实例重铸,将其应用于材质贴图,然后告诉three.js该texture.needsUpdate。否则,我认为它是在重新应用ram中的旧的、空的纹理。你是正确的,我已经发布了一个关于如何加载的答案我修好了。