您的位置:首页 > 房产 > 家装 > 海口做网站供应商_手机开发小程序_重庆关键词排名首页_广州seo优化费用

海口做网站供应商_手机开发小程序_重庆关键词排名首页_广州seo优化费用

2025/1/10 22:49:20 来源:https://blog.csdn.net/weixin_41722662/article/details/145037556  浏览:    关键词:海口做网站供应商_手机开发小程序_重庆关键词排名首页_广州seo优化费用
海口做网站供应商_手机开发小程序_重庆关键词排名首页_广州seo优化费用

前言

回顾:

        黑暗面城市的照明

       

        太阳的反光主要在海洋上可见白天和黑夜之间的部分

        (黄昏)看起来是红色的

        大气在地球周围产生光辉(就像一个体积)

        我们不追求基于物理效果的渲染,这不会阻止最终结果看起来良好且逼真。

        细分球体缓慢旋转

        src/shaders/earth/中的基础着色器

        lil-gui

        vite-plugin-glsl

        轨道控制

        纹理加载器

        在颜色纹理上更改颜色空间

        earthDayTexture.colorSpace = THREE.SRGBColorSpace

        问题

        混合白天 黑天 与太阳位置相比 的颜色?  mix

        我们将使用通常的点状产品,但我们需要一个光的方向。目前,我们将在GLSL中创建太阳方向,稍后我们将使用一个统一的系统来控制

        updateSun()

        云层

        一种做法是在地球上方的一个球体上添加云层,这使得云层具有一些灵活性,例如可以独立旋转云层。将整个云层旋转看起来不好,我们需要稍微增大球体的大小以防止Z轴冲突。

        真实环境下 球体在白天 黑夜和中间得过渡  应该有颜色变化

        还可以添加功能

        添加更多调整

        测试与其他行星纹理

        按照现实中地球相对于太阳的自转来使地球转动通过在UV上添加一些位移来动画化云使用Perin函数或Perlin纹理创建云为太阳添加Lensflare(示例)(在静态/镜头中提供了纹理)

        在后面添加星星或银河系环境图

项目结构


一、代码

three.js

import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import GUI from 'lil-gui'
import earthVertexShader from './shaders/earth/vertex.glsl'
import earthFragmentShader from './shaders/earth/fragment.glsl'
import atmosphereVertexShader from './shaders/atmosphere/vertex.glsl'
import atmosphereFragmentShader from './shaders/atmosphere/fragment.glsl'/*** Base*/
// Debug
const gui = new GUI()// Canvas
const canvas = document.querySelector('canvas.webgl')// Scene
const scene = new THREE.Scene()// Loaders
const textureLoader = new THREE.TextureLoader()/*** Earth 地球*/
const earthParameters = {}
earthParameters.atmosphereDayColor = '#00aaff' // 白天颜色 大气层
earthParameters.atmosphereTwilightColor = '#ff6600' // 傍晚gui.addColor(earthParameters,'atmosphereDayColor').onChange(()=>{earthMaterial.uniforms.uAtmosphereDayColor.value.set(earthParameters.atmosphereDayColor) // 设置颜色atmosphereMaterial.uniforms.uAtmosphereDayColor.value.set(earthParameters.atmosphereDayColor) // 设置颜色})gui.addColor(earthParameters,'atmosphereTwilightColor').onChange(()=>{earthMaterial.uniforms.uAtmosphereTwilightColor.value.set(earthParameters.atmosphereTwilightColor) // 设置颜色atmosphereMaterial.uniforms.uAtmosphereTwilightColor.value.set(earthParameters.atmosphereTwilightColor) // 设置颜色})// texture
const earthDayTexture = textureLoader.load('./earth/day.jpg')
earthDayTexture.colorSpace = THREE.SRGBColorSpace
earthDayTexture.anisotropy = 8  // 边缘处 防止有割裂const earthNightTexture = textureLoader.load('./earth/night.jpg')
earthNightTexture.colorSpace = THREE.SRGBColorSpace
earthNightTexture.anisotropy = 8const earthSpecularCloudsTexture = textureLoader.load('./earth/specularClouds.jpg')
earthSpecularCloudsTexture.anisotropy = 8// Mesh
const earthGeometry = new THREE.SphereGeometry(2, 64, 64)
const earthMaterial = new THREE.ShaderMaterial({vertexShader: earthVertexShader,fragmentShader: earthFragmentShader,uniforms:{uDayTexture:new THREE.Uniform(earthDayTexture),uNightTexture:new THREE.Uniform(earthNightTexture),uSpecularCloudsTexture:new THREE.Uniform(earthSpecularCloudsTexture),uSunDirection:new THREE.Uniform(new THREE.Vector3(0,0,1)),uAtmosphereDayColor: new THREE.Uniform(new THREE.Color(earthParameters.atmosphereDayColor)),uAtmosphereTwilightColor: new THREE.Uniform(new THREE.Color(earthParameters.atmosphereTwilightColor)),}
})
const earth = new THREE.Mesh(earthGeometry, earthMaterial)
scene.add(earth)// Atmosphere 效果大气层周围光晕
const atmosphereMaterial = new THREE.ShaderMaterial({vertexShader:atmosphereVertexShader,fragmentShader:atmosphereFragmentShader,uniforms:{uSunDirection:new THREE.Uniform(new THREE.Vector3(0,0,1)),uAtmosphereDayColor: new THREE.Uniform(new THREE.Color(earthParameters.atmosphereDayColor)),uAtmosphereTwilightColor: new THREE.Uniform(new THREE.Color(earthParameters.atmosphereTwilightColor)),},side:THREE.BackSide, // 只展示后面transparent:true}
)
const atmosphere = new THREE.Mesh(earthGeometry,atmosphereMaterial)
atmosphere.scale.set(1.04,1.04,1.04)
scene.add(atmosphere)/* sun
*/
const sunSpherical = new THREE.Spherical(1,Math.PI * 0.5 * 0.5) // 创建几何体
const sunDirection = new THREE.Vector3()// Debug
const debugSun = new THREE.Mesh(new THREE.IcosahedronGeometry(0.1,2),new THREE.MeshBasicMaterial()
)
scene.add(debugSun)// Update
const updateSun = () =>{// Sun directionsunDirection.setFromSpherical(sunSpherical)// DebugdebugSun.position.copy(sunDirection).multiplyScalar(5) // 设置位置// UniformsearthMaterial.uniforms.uSunDirection.value.copy(sunDirection);atmosphereMaterial.uniforms.uSunDirection.value.copy(sunDirection);
}
updateSun()// Tweaks
gui .add(sunSpherical,'phi').min(0).max(Math.PI).onChange(updateSun)gui .add(sunSpherical,'theta').min(-Math.PI).max(Math.PI).onChange(updateSun)/*** Sizes*/
const sizes = {width: window.innerWidth,height: window.innerHeight,pixelRatio: Math.min(window.devicePixelRatio, 2)
}window.addEventListener('resize', () =>
{// Update sizessizes.width = window.innerWidthsizes.height = window.innerHeightsizes.pixelRatio = Math.min(window.devicePixelRatio, 2)// Update cameracamera.aspect = sizes.width / sizes.heightcamera.updateProjectionMatrix()// Update rendererrenderer.setSize(sizes.width, sizes.height)renderer.setPixelRatio(sizes.pixelRatio)
})/*** Camera*/
// Base camera
const camera = new THREE.PerspectiveCamera(25, sizes.width / sizes.height, 0.1, 100)
camera.position.x = 12
camera.position.y = 5
camera.position.z = 4
scene.add(camera)// Controls
const controls = new OrbitControls(camera, canvas)
controls.enableDamping = true/*** Renderer*/
const renderer = new THREE.WebGLRenderer({canvas: canvas,antialias: true
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(sizes.pixelRatio)
renderer.setClearColor('#000011')// console.log(renderer.antialias)/*** Animate*/
const clock = new THREE.Clock()const tick = () =>
{const elapsedTime = clock.getElapsedTime()earth.rotation.y = elapsedTime * 0.1// Update controlscontrols.update()// Renderrenderer.render(scene, camera)// Call tick again on the next framewindow.requestAnimationFrame(tick)
}tick()

style.css

*
{margin: 0;padding: 0;
}html,
body
{overflow: hidden;
}.webgl
{position: fixed;top: 0;left: 0;outline: none;
}

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Earth</title><link rel="stylesheet" href="./style.css">
</head>
<body><canvas class="webgl"></canvas><script type="module" src="./script.js"></script>
</body>
</html>

earth/fragment.glsl

uniform sampler2D uDayTexture; // texture2D 2D采样器
uniform sampler2D uNightTexture; 
uniform sampler2D uSpecularCloudsTexture; 
uniform vec3 uSunDirection;
uniform vec3 uAtmosphereDayColor;
uniform vec3 uAtmosphereTwilightColor;varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vPosition;/* dot向量x,y之间的点积mix(x, y, a)返回线性混合的x和y,如:x*(1−a)+y*asmoothstep(edge0, edge1, x)如果x <= edge0,返回0.0 ;如果x >= edge1 返回1.0;如果edge0 < x < edge1,则执行0~1之间的平滑埃尔米特差值。如果edge0 >= edge1,结果是未定义的。pow(x,y) x的y次方。如果x小于0,结果是未定义的。同样,如果x=0并且y<=0,结果也是未定义的。*/ void main()
{vec3 viewDirection = normalize(vPosition - cameraPosition);vec3 normal = normalize(vNormal);vec3 color = vec3(0.0);// Sun orientationfloat sunOrientation = dot(uSunDirection,normal);// Day / night colorfloat dayMix = smoothstep(-0.25,0.5,sunOrientation);  // 平滑过渡 限制值vec3 dayColor = texture2D(uDayTexture,vUv).rgb;vec3 nightColor = texture2D(uNightTexture,vUv).rgb;color = mix(nightColor,dayColor,dayMix);// Specular clouds colorvec2 specularCloudsColor = texture2D(uSpecularCloudsTexture,vUv).rg;// Cloudsfloat cloudsMix = smoothstep(0.5,1.0,specularCloudsColor.g); // 改变云得多少cloudsMix *= dayMix;  // 晚上不想要云,相乘这样到了晚上云就会消失color = mix(color,vec3(1.0),cloudsMix); // 将云和原本得混合起来// Fresnel 菲涅尔效果// Fresnel 根据相机角度,进行判断,相同方向1,直角0 ,相反 1// 同样法线应该渲染,vertex.glslfloat fresnel = dot(viewDirection,normal) + 1.0;fresnel = pow(fresnel,2.0);// Atmosphere 得到大气float almosphereDayMix = smoothstep(-0.5,1.0,sunOrientation); // 白天vec3 atmosphereColor = mix(uAtmosphereTwilightColor,uAtmosphereDayColor,almosphereDayMix);color = mix(color,atmosphereColor,fresnel * almosphereDayMix); // 相乘会得到在黄昏只是轻微的// Speculare  太阳的反射光 根据光线计算反射vec3 reflection = reflect(- uSunDirection , normal);  // 镜面折射float specular = - dot(reflection , viewDirection); // 倒影,所以取负数specular = max(specular, 0.0); // 设置界限值specular = pow(specular, 32.0); // 设置值的大小// 大陆和海洋的反射光不应一样 ,specularCloudsColor.rspecular *= specularCloudsColor.r;// 从后面看 白色光太强 应减少 ,应该和大气层结合 在特定角度 改变成大气的颜色// 混合大气颜色,菲涅尔效果vec3 specularColor = mix(vec3(1.0),atmosphereColor,fresnel);// 和 反射光相乘 就可以得到根据 大气颜色反射光颜色改变color += specular * specularColor;// Final colorgl_FragColor = vec4(color, 1.0);#include <tonemapping_fragment>#include <colorspace_fragment>
}

earth/vertex.glsl

varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vPosition;void main()
{// Positionvec4 modelPosition = modelMatrix * vec4(position, 1.0);gl_Position = projectionMatrix * viewMatrix * modelPosition;// Model normalvec3 modelNormal = (modelMatrix * vec4(normal, 0.0)).xyz;// VaryingsvUv = uv;vNormal = modelNormal;vPosition = modelPosition.xyz;
}

atmosphere/fragment.glsl


uniform vec3 uSunDirection;
uniform vec3 uAtmosphereDayColor;
uniform vec3 uAtmosphereTwilightColor;varying vec3 vNormal;
varying vec3 vPosition;/* dot向量x,y之间的点积mix(x, y, a)返回线性混合的x和y,如:x*(1−a)+y*asmoothstep(edge0, edge1, x)如果x <= edge0,返回0.0 ;如果x >= edge1 返回1.0;如果edge0 < x < edge1,则执行0~1之间的平滑埃尔米特差值。如果edge0 >= edge1,结果是未定义的。pow(x,y) x的y次方。如果x小于0,结果是未定义的。同样,如果x=0并且y<=0,结果也是未定义的。*/ void main()
{vec3 viewDirection = normalize(vPosition - cameraPosition);vec3 normal = normalize(vNormal);vec3 color = vec3(0.0);// Sun orientationfloat sunOrientation = dot(uSunDirection,normal);// Atmosphere 得到大气float almosphereDayMix = smoothstep(-0.5,1.0,sunOrientation); // 白天vec3 atmosphereColor = mix(uAtmosphereTwilightColor,uAtmosphereDayColor,almosphereDayMix);color =atmosphereColor; // 相乘会得到在黄昏只是轻微的// Alphafloat edgeAlpha = dot(viewDirection,normal);edgeAlpha = smoothstep(0.0,0.5,edgeAlpha);float dayAlpha = smoothstep(-0.5, 0.0 ,sunOrientation);float alpha = edgeAlpha * dayAlpha;// Final colorgl_FragColor = vec4(color, alpha);#include <tonemapping_fragment>#include <colorspace_fragment>
}

atmosphere/vertex.glsl


varying vec3 vNormal;
varying vec3 vPosition;void main()
{// Positionvec4 modelPosition = modelMatrix * vec4(position, 1.0);gl_Position = projectionMatrix * viewMatrix * modelPosition;// Model normalvec3 modelNormal = (modelMatrix * vec4(normal, 0.0)).xyz;// VaryingsvNormal = modelNormal;vPosition = modelPosition.xyz;
}

二、效果

地球着色器


总结

关于地球着色器的实现!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com