X3Dom V1.2发布

X3DOM v1.2版本已发布,新增Flash11/MoeHill渲染后端,允许在缺少SAI插件或WebGL支持的情况下使用Flash11浏览X3DOM页面。此外,该版本还支持运行时参数传递、直接对X3D元素应用CSS样式等功能,并修复了纹理显示的问题。

主要特性:Flash11/MoeHill 渲染后端

新版本支持另外一种渲染后台。系统现在会在浏览器未提供SAI插件或WebGL接口时搜索Flash11插件,以让用户在IE9中浏览X3DOM页面,当然,带有一些限制。

x3dom.swf文件必须与xhtml/html文件存放在相同的目录,或者利用X3D节点的swfpath参数来声明。利用X3D节点的backend参数,可以将Flash作为默认的后端。

  • 目前Flash作为后端还仅仅是处于早期的beta状态
  • 一些特殊功能如多光源、阴影、表面着色等仍在开发中

 

其它变更

  • 资源内部重新组织。节点类型拥有他们自己的子模型(src/nodes) ,并且按组划分
  • 文本节点部分正常。可以使用浏览器中获取的任意字体,也包括了CSS3中的WebFonts
  • 添加了运行时参数传递功能
  • 在Firefox beata版部分正常运行
  • 可以直接对X3D元素应用CSS样式
  • 修复了纹理的显示问题

原文:http://www.web3d.org/realtime-3d/news/x3dom-v12-released

window.addEventListener(&#39;DOMContentLoaded&#39;, function() { // 初始化场景 const container = document.getElementById(&#39;threeBall&#39;) || document.body; const width = container.offsetWidth || window.innerWidth; const height = container.offsetHeight || window.innerHeight; const scene = new THREE.Scene(); // 相机 const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000); camera.position.z = 8; // 渲染器 const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); renderer.setSize(width, height); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); renderer.outputEncoding = THREE.sRGBEncoding; container.appendChild(renderer.domElement); // 环境光和点光源 scene.add(new THREE.AmbientLight(0xffffff, 0.2)); const pointLight = new THREE.PointLight(0xffffff, 1, 100); pointLight.position.set(5, 5, 5); scene.add(pointLight); // 顶点着色器 const vertexShader = ` uniform float uTime; uniform float uSpeed; uniform float uIntensity; uniform float uFlowIntensity; uniform float uHueSpeed; varying vec3 vNormal; varying vec3 vPosition; varying float vNoise; varying float vFresnel; vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0); const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); vec3 i = floor(v + dot(v, C.yyy)); vec3 x0 = v - i + dot(i, C.xxx); vec3 g = step(x0.yzx, x0.xyz); vec3 l = 1.0 - g; vec3 i1 = min(g.xyz, l.zxy); vec3 i2 = max(g.xyz, l.zxy); vec3 x1 = x0 - i1 + C.xxx; vec3 x2 = x0 - i2 + C.yyy; vec3 x3 = x0 - D.yyy; i = mod289(i); vec4 p = permute(permute(permute( i.z + vec4(0.0, i1.z, i2.z, 1.0)) + i.y + vec4(0.0, i1.y, i2.y, 1.0)) + i.x + vec4(0.0, i1.x, i2.x, 1.0)); float n_ = 0.142857142857; vec3 ns = n_ * D.wyz - D.xzx; vec4 j = p - 49.0 * floor(p * ns.z * ns.z); vec4 x_ = floor(j * ns.z); vec4 y_ = floor(j - 7.0 * x_); vec4 x = x_ * ns.x + ns.yyyy; vec4 y = y_ * ns.x + ns.yyyy; vec4 h = 1.0 - abs(x) - abs(y); vec4 b0 = vec4(x.xy, y.xy); vec4 b1 = vec4(x.zw, y.zw); vec4 s0 = floor(b0) * 2.0 + 1.0; vec4 s1 = floor(b1) * 2.0 + 1.0; vec4 sh = -step(h, vec4(0.0)); vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy; vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww; vec3 p0 = vec3(a0.xy, h.x); vec3 p1 = vec3(a0.zw, h.y); vec3 p2 = vec3(a1.xy, h.z); vec3 p3 = vec3(a1.zw, h.w); vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2,p2), dot(p3,p3))); p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w; vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3))); } vec3 flowNoise(vec3 p) { float eps = 0.1; float n = snoise(p); float nx = snoise(p + vec3(eps, 0.0, 0.0)); float ny = snoise(p + vec3(0.0, eps, 0.0)); float nz = snoise(p + vec3(0.0, 0.0, eps)); vec3 grad = vec3(nx - n, ny - n, nz - n) / eps; vec3 curl; curl.x = grad.z - grad.y; curl.y = grad.x - grad.z; curl.z = grad.y - grad.x; return curl * uFlowIntensity; } void main() { vNormal = normal; vPosition = position; vec3 viewDir = normalize(cameraPosition - position); vFresnel = pow(1.0 - abs(dot(normal, viewDir)), 2.0); vec3 flow = flowNoise(position * 0.8 + uTime * uSpeed * 0.3); vec3 p = position + flow; float noise1 = snoise(p * 1.5 + uTime * uSpeed); float noise2 = snoise(p * 3.0 + uTime * uSpeed * 1.3); float noise3 = snoise(p * 6.0 + uTime * uSpeed * 1.7); vNoise = (noise1 * 0.6 + noise2 * 0.3 + noise3 * 0.1); float displacement = vNoise * uIntensity; vec3 newPosition = position + normal * displacement; gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0); } `; // 片元着色器 const fragmentShader = ` uniform float uTime; uniform float uHueSpeed; uniform float uGlowIntensity; uniform vec3 uColor1; uniform vec3 uColor2; varying vec3 vNormal; varying vec3 vPosition; varying float vNoise; varying float vFresnel; vec3 hsl2rgb(vec3 c) { vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0); return c.z + c.y * (rgb - 0.5) * (1.0 - abs(2.0 * c.z - 1.0)); } vec3 rgb2hsl(vec3 color) { float minVal = min(min(color.r, color.g), color.b); float maxVal = max(max(color.r, color.g), color.b); float delta = maxVal - minVal; float h = 0.0; float s = 0.0; float l = (maxVal + minVal) / 2.0; if (delta != 0.0) { s = l < 0.5 ? delta / (maxVal + minVal) : delta / (2.0 - maxVal - minVal); if (color.r == maxVal) { h = (color.g - color.b) / delta + (color.g < color.b ? 6.0 : 0.0); } else if (color.g == maxVal) { h = (color.b - color.r) / delta + 2.0; } else { h = (color.r - color.g) / delta + 4.0; } h /= 6.0; } return vec3(h, s, l); } void main() { float hueShift = sin(uTime * uHueSpeed) * 0.1; vec3 baseColor = mix(uColor1, uColor2, (vPosition.y + 1.0) * 0.5); vec3 hsl = rgb2hsl(baseColor); hsl.x += hueShift; if(hsl.x > 1.0) hsl.x -= 1.0; if(hsl.x < 0.0) hsl.x += 1.0; hsl.y = min(hsl.y * 1.5, 0.9); vec3 color = hsl2rgb(hsl); float brightness = 0.7 + vNoise * 0.3; color *= brightness; float glow = vFresnel * uGlowIntensity * (1.0 + sin(uTime * 2.0) * 0.2); float core = pow(1.0 - length(vNormal), 2.0) * 0.5; vec3 finalColor = color + glow * vec3(0.8, 1.0, 1.0) + core * vec3(1.0, 0.8, 0.5); gl_FragColor = vec4(finalColor, 1.0); } `; // 创建霓虹能量环 const geometry = new THREE.SphereGeometry(2, 96, 96); const material = new THREE.ShaderMaterial({ vertexShader, fragmentShader, uniforms: { uTime: { value: 0 }, uSpeed: { value: 0.4 }, uIntensity: { value: 0.25 }, uFlowIntensity: { value: 0.3 }, uHueSpeed: { value: 0.2 }, uGlowIntensity: { value: 4.0 }, uColor1: { value: new THREE.Color(0x00ffff) }, uColor2: { value: new THREE.Color(0xff00ff) } }, transparent: true, side: THREE.DoubleSide, wireframe: false }); const neonHalo = new THREE.Mesh(geometry, material); scene.add(neonHalo); // 动画循环 const clock = new THREE.Clock(); function animate() { requestAnimationFrame(animate); const elapsedTime = clock.getElapsedTime(); material.uniforms.uTime.value = elapsedTime; neonHalo.rotation.y = elapsedTime * 0.1; neonHalo.rotation.x = elapsedTime * 0.05; renderer.render(scene, camera); } animate(); // 响应窗口大小变化 window.addEventListener(&#39;resize&#39;, () => { const w = container.offsetWidth || window.innerWidth; const h = container.offsetHeight || window.innerHeight; camera.aspect = w / h; camera.updateProjectionMatrix(); renderer.setSize(w, h); }); });这个能量球的代码有没有可以用到我能量环代码上的地方
最新发布
08-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值