Published
Edited
Oct 8, 2022
Fork of Three.js
1 fork
2 stars
Insert cell
Insert cell
renderer.domElement
Insert cell
viewof a_height = Inputs.range([0, 0.3], {label: "a_height", step: 0.01, value: 0.05})
Insert cell
height = 600
Insert cell
// Continuously updates
{
while (true) {
cube.rotation.z += 0.01;
renderer.render(scene, camera);
yield null;
}
}
Insert cell
options = ({
  radius: 1, // 地球的半径
  segments: 640, // 地球的分段数 数量越高 地球精度越高
height: a_height,
  map: 'earthmap1k.jpg', // 地球材质
  bump: 'earthbump1k.jpg' // 生成高度材质
})
Insert cell
earthShader = ({
vertexShader: `
varying vec4 v_color; // 用来存储当前顶点颜色
varying vec2 v_uv; // UV
uniform float u_height; // 生成的高度
uniform float u_radius; // 半径
uniform sampler2D u_bump; // 高度图
// 插值计算
float lerp(float x, float y, float t) {
return (1.0 - t) * x + t * y;
}
// 获得当前向量与中心点的距离
float glength(vec3 p) {
return sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
}
// 传入当前向量 需要返回的长度
vec3 setLength(vec3 p, float length) {
vec3 c_position = p;
float scale = length / glength(c_position);
c_position.x *= scale;
c_position.y *= scale;
c_position.z *= scale;
return c_position;
}
void main() {
v_uv = uv; // uv
v_color = texture2D(u_bump, uv); // 生成当前高度信息
float c_height = v_color.r * u_height; // 生成当前的高度 当前的灰度r值 * 基础高度
vec3 vposition = setLength(position, u_radius + c_height); // 生成新的向量 离中心距离为当前基础半径+生成的高度
// 传递position
vec4 mPosition = modelViewMatrix * vec4(vposition, 1.0);
gl_Position = projectionMatrix * mPosition;
}
`,
fragmentShader: `
uniform float u_opacity; // 透明度
uniform vec3 u_color; // 基础颜色
varying vec2 v_uv; // UV
uniform sampler2D u_map; // 基础材质
void main() {
gl_FragColor = vec4(u_color, u_opacity) * texture2D(u_map, v_uv);
}
`
})

Insert cell
earthbump1k = FileAttachment("earthbump1k.jpg").url()
Insert cell
earthbump4k = FileAttachment("8081_earthbump4k.jpg").url()
Insert cell
earthmap1k = FileAttachment("earthmap1k.jpg").url()
Insert cell
earthmap4k = FileAttachment("8081_earthmap4k.jpg").url()
Insert cell
earthmap10k = FileAttachment("8081_earthmap10k.jpg").url()
Insert cell
earthbump10k = FileAttachment("8081_earthbump10k.jpg").url()
Insert cell
cube = {
const material = new THREE.MeshNormalMaterial();
const geometry = new THREE.BoxGeometry(1, 1, 1);
const cube = new THREE.Mesh(geometry, material);
return cube;
}
Insert cell
plane = {
const geometry = new THREE.SphereBufferGeometry(options.radius, options.segments, options.segments);
// 使用自定义着色器
const material = new THREE.ShaderMaterial({
uniforms: {
u_radius: {
value: options.radius // 半径
},
u_height: {
value: options.height // 生成的高度
},
u_map: {
value: new THREE.TextureLoader().load(earthmap10k) // 贴图
},
u_bump: {
value: new THREE.TextureLoader().load(earthbump10k) // 高度图
},
u_color: {
value: new THREE.Color('rgb(255, 255, 255)')
},
u_opacity: {
value: 1.0
}
},
transparent: true,
vertexShader: earthShader.vertexShader, // 顶点着色器
fragmentShader: earthShader.fragmentShader, // 片元着色器
});
const plane = new THREE.Mesh(geometry, material);
return plane;
}

Insert cell
scene = {
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x001b42);
scene.add(plane);
return scene;
}
Insert cell
camera = {
const fov = 45;
const aspect = width / height;
const near = 0.1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(2, 2, -2)
camera.lookAt(new THREE.Vector3(0, 0, 0));
return camera;
}
Insert cell
renderer = {
const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(width, height);
renderer.setPixelRatio(devicePixelRatio);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", () => renderer.render(scene, camera));
invalidation.then(() => (controls.dispose(), renderer.dispose()));
return renderer;
}
Insert cell
THREE = {
const THREE = window.THREE = await require("three@0.130.0/build/three.min.js");
await require("three@0.130.0/examples/js/controls/OrbitControls.js").catch(() => {});
return THREE;
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more