新闻详情

新闻详情

首页 / 资讯中心 / 详情

Three.js 水天一色教程

发布时间:2026/11/3 21:26:20来源:尧图网络
Three.js 水天一色教程
水天一色 ·Water Sky· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么ShaderMaterial 自定义着色器实现核心视觉效果OrbitControls 相机轨道交互requestAnimationFrame渲染循环与resize自适应效果说明本案例演示水天一色效果基于 WebGL 实现「水天一色」可视化效果附完整可运行源码核心用到 ShaderMaterial、OrbitControls。建议先打开文首在线案例查看动态画面再对照下方源码逐步理解。核心概念Scene / Camera / WebGLRenderer构成最小渲染闭环大场景可开logarithmicDepthBuffer缓解 Z-fighting。ShaderMaterial通过uniforms 自定义 GLSL 控制逐像素/逐点效果透明粒子常配合depthTest: false。OrbitControls提供轨道旋转/缩放开启enableDamping后需在 animate 中controls.update()。实现步骤搭建 Scene、PerspectiveCamera、WebGLRenderer挂载 canvas 并处理resize定义 uniforms / onBeforeCompile 或 ShaderMaterial编写 GLSL 与材质参数创建 OrbitControls及 Raycaster 等交互控件若源码包含在requestAnimationFrame循环中更新状态并 renderCesium 为viewer.render或自动渲染代码要点import * as THREE from three;import { OrbitControls } from three/examples/jsm/controls/OrbitControls.jsconst DOM document.getElementById(box)const scene new THREE.Scene()const camera new THREE.PerspectiveCamera(50,DOM.clientWidth / DOM.clientHeight, 0.1, 100000) camera.position.set(10,10,10) scene.add(camera);const renderer new THREE.WebGLRenderer({ antialias:true, alpha: true, logarithmicDepthBuffer: true }) renderer.setSize(DOM.clientWidth, DOM.clientHeight) renderer.setPixelRatio( window.devicePixelRatio * 2) renderer.setClearColor( 0x000000 ) DOM.appendChild(renderer.domElement) new OrbitControls(camera, renderer.domElement)const uniforms { Mouse: { type: v2, value: new THREE.Vector2(0, 0) }, Resolution: { type: v2, value: new THREE.Vector2(window.innerWidth, window.innerHeight) }, Time: { type: f, value: 1.0 } } DOM.addEventListener(mousemove,(event) uniforms.Mouse.value new THREE.Vector2( (event.offsetX / event.target.clientWidth) * 2 - 1, -(event.offsetY / event.target.clientHeight) * 2 1 )) const geometry new THREE.PlaneGeometry( 10, 10 );var material new THREE.ShaderMaterial( { uniforms: uniforms, vertexShader:void main() { gl_Position vec4( position, 1.0 ); }, fragmentShader:uniform vec2 Mouse; uniform vec2 Resolution; uniform float Time;const float DRAG_MULT 0.048; const int ITERATIONS_RAYMARCH 13; const int ITERATIONS_NORMAL 48;vec2 wavedx(vec2 position, vec2 direction, float speed, float frequency, float timeshift) { float x dot(direction, position)frequency timeshiftspeed; float wave exp(sin(x) - 1.0); float dx wave * cos(x); return vec2(wave, -dx); }float getwaves(vec2 position, int iterations){ float iter 0.0; float phase 6.0; float speed 2.0; float weight 1.0; float w 0.0; float ws 0.0; for(int i0;ires.yweight * DRAG_MULT; w res.x * weight; iter 12.0; ws weight; weight mix(weight, 0.0, 0.2); phase * 1.18; speed * 1.07; } return w / ws; }float raymarchwater(vec3 camera, vec3 start, vec3 end, float depth){ vec3 pos start; float h 0.0; float hupper depth; float hlower 0.0; vec2 zer vec2(0.0); vec3 dir normalize(end - start); for(int i0;i318;i){ h getwaves(pos.xz0.1, ITERATIONS_RAYMARCH)depth - depth; if(h 0.01 pos.y) { return distance(pos, camera); } pos dir * (pos.y - h); } return -1.0; }float H 0.0; vec3 normal(vec2 pos, float e, float depth){ vec2 ex vec2(e, 0); H getwaves(pos.xy0.1, ITERATIONS_NORMAL)depth; vec3 a vec3(pos.x, H, pos.y); return normalize(cross((a-vec3(pos.x - e, getwaves(pos.xy0.1 - ex.xy0.1, ITERATIONS_NORMAL) * depth, pos.y)), (a-vec3(pos.x, getwaves(pos.xy0.1 ex.yx0.1, ITERATIONS_NORMAL) * depth, pos.y e)))); } mat3 rotmat(vec3 axis, float angle) { float s sin(angle); float c cos(angle); float oc 1.0 - c; return mat3(ocaxis.xaxis.x c, ocaxis.xaxis.y - axis.zs, ocaxis.zaxis.x axis.ys, ocaxis.xaxis.y axis.zs, ocaxis.yaxis.y c, ocaxis.yaxis.z - axis.xs, ocaxis.zaxis.x - axis.ys, ocaxis.yaxis.z axis.xs, ocaxis.zaxis.z c); }vec3 getRay(vec2 uv){ uv (uv2.0 - 1.0)vec2(Resolution.x / Resolution.y, 1.0); vec3 proj normalize(vec3(uv.x, uv.y, 1.0) vec3(uv.x, uv.y, -1.0)pow(length(uv), 2.0)0.05); if(Resolution.x 600.0) return proj; vec3 ray rotmat(vec3(0.0, -1.0, 0.0), 3.0((Mouse.x 0.5)2.0 - 1.0))rotmat(vec3(1.0, 0.0, 0.0), 0.5 1.5((Mouse.y1.5)2.0 - 1.0)) * proj; return ray; }float intersectPlane(vec3 origin, vec3 direction, vec3 point, vec3 normal) { return clamp(dot(point - origin, normal) / dot(direction, normal), -1.0, 9991999.0); }vec3 extra_cheap_atmosphere(vec3 raydir, vec3 sundir){ sundir.y max(sundir.y, -0.07); float special_trick 1.0 / (raydir.y * 1.0 0.1); float special_trick2 1.0 / (sundir.y * 11.0 1.0); float raysundt pow(abs(dot(sundir, raydir)), 2.0); float sundt pow(max(0.0, dot(sundir, raydir)), 8.0); float mymie sundtspecial_trick0.2; vec3 suncolor mix(vec3(1.0), max(vec3(0.0), vec3(1.0) - vec3(5.5, 13.0, 22.4) / 22.4), special_trick2); vec3 bluesky vec3(5.5, 13.0, 22.4) / 22.4 * suncolor; vec3 bluesky2 max(vec3(0.0), bluesky - vec3(5.5, 13.0, 22.4)0.002(special_trick -6.0sundir.ysundir.y)); bluesky2 special_trick(0.24 raysundt * 0.24); return bluesky2(1.0 1.0pow(1.0 - raydir.y, 3.0)) mymie * suncolor; } vec3 getatm(vec3 ray){ return extra_cheap_atmosphere(ray, normalize(vec3(1.0))) * 0.5; }float sun(vec3 ray){ vec3 sd normalize(vec3(1.0)); return pow(max(0.0, dot(ray, sd)), 528.0) * 110.0; } vec3 aces_tonemap(vec3 color){ mat3 m1 mat3( 0.59719, 0.07600, 0.02840, 0.35458, 0.90834, 0.13383, 0.04823, 0.01566, 0.83777 ); mat3 m2 mat3( 1.60475, -0.10208, -0.00327, -0.53108, 1.10813, -0.07276, -0.07367, -0.00605, 1.07602 ); vec3 v m1 * color; vec3 a v * (v 0.0245786) - 0.000090537; vec3 b v(0.983729v 0.4329510) 0.238081; return pow(clamp(m2 * (a / b), 0.0, 1.0), vec3(1.0 / 2.2)); } void main() { vec2 uv gl_FragCoord.xy / Resolution.xy; float waterdepth 2.1; vec3 wfloor vec3(0.0, -waterdepth, 0.0); vec3 wceil vec3(0.0, 0.0, 0.0); vec3 orig vec3(0.0, 2.0, 0.0); vec3 ray getRay(uv); float hihit intersectPlane(orig, ray, wceil, vec3(0.0, 1.0, 0.0)); if(ray.y -0.01){ vec3 C getatm(ray) * 2.0 sun(ray); //tonemapping C aces_tonemap(C); gl_FragColor vec4( C,1.0); return; } float lohit intersectPlane(orig, ray, wfloor, vec3(0.0, 1.0, 0.0)); vec3 hipos orig ray * hihit; vec3 lopos orig ray * lohit; float dist raymarchwater(orig, hipos, lopos, waterdepth); vec3 pos orig ray * dist;vec3 N normal(pos.xz, 0.001, waterdepth); vec2 velocity N.xz * (1.0 - N.y); N mix(vec3(0.0, 1.0, 0.0), N, 1.0 / (distdist0.01 1.0)); vec3 R reflect(ray, N); float fresnel (0.04 (1.0-0.04)*(pow(1.0 - max(0.0, dot(-N, ray)), 5.0))); vec3 C fresnelgetatm(R)2.0 fresnel * sun(R) vec3(0.0293, 0.0698, 0.1717); //tonemapping C aces_tonemap(C); gl_FragColor vec4(C,1.0); }} );material.side THREE.DoubleSidevar mesh new THREE.Mesh( geometry, material ); scene.add( mesh );render() function render() { uniforms.Time.value 0.03 renderer.render(scene,camera) requestAnimationFrame(render) }完整源码GitHub小结本文提供水天一色完整 Three.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/3 7:07:39

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/3 12:09:35

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/3 12:09:38

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/3 12:09:41

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/2 5:53:27

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/2 5:53:27

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉