<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WebGL Three.js高质量3D旋转地球卫星云图着色器代码</title>
<style>
#glContainer {
position: fixed;
z-index: -1;
margin: 0px;
padding: 0px;
}
body {
margin: 0;
}
</style>
</head>
<body>
<div id="glContainer"></div>
<script src="js/jquery.min.js"></script>
<script src="js/three.min.js"></script>
<script src="js/DDSLoader.js"></script>
<script src="js/OBJLoader.js"></script>
<script src="js/postprocessing.js"></script>
<!-- WebGL shaders -->
<script id="simpleVertex" type="x-shader/x-vertex">
varying vec2 vUv;
varying vec3 v_Normal;
varying vec3 v_Position;
void main() {
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * mvPosition;
v_Normal = normalize(normalMatrix * normal);
v_Position = vec3(mvPosition.xyz);
}
</script>
<script id="horizontalBlurFrag" type="x-shader/x-fragment">
uniform sampler2D tDiffuse;
uniform float h;
varying vec2 vUv;
void main() {
vec4 sum = vec4( 0.0 );
vec4 originalSample = texture2D( tDiffuse, vUv );
sum += texture2D( tDiffuse, vec2( vUv.x - 3.2307 * h, vUv.y ) ) * 0.0702;
sum += texture2D( tDiffuse, vec2( vUv.x - 1.3846 * h, vUv.y ) ) * 0.3162;
sum += originalSample * 0.2270270270;
sum += texture2D( tDiffuse, vec2( vUv.x + 1.3846 * h, vUv.y ) ) * 0.3162;
sum += texture2D( tDiffuse, vec2( vUv.x + 3.2307 * h, vUv.y ) ) * 0.0702;
gl_FragColor = sum;
}
</script>
<script id="verticalBlurFrag" type="x-shader/x-fragment">
uniform sampler2D tDiffuse;
uniform float v;
varying vec2 vUv;
void main() {
vec4 sum = vec4( 0.0 );
vec4 originalSample = texture2D( tDiffuse, vUv );
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.2307 * v ) ) * 0.0702;
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.3846 * v ) ) * 0.3162;
sum += originalSample * 0.2270270270;
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.3846 * v ) ) * 0.3162;
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.2307 * v ) ) * 0.0702;
gl_FragColor = sum;
}
</script>
<script id="overlayFrag" type="x-shader/x-fragment">
uniform sampler2D tDiffuse;
uniform sampler2D tOverlay;
varying vec2 vUv;
void main() {
vec4 regularScene = texture2D( tDiffuse, vUv );
vec4 overlay = texture2D( tOverlay, vUv );
float blurOpacity = 0.5;
overlay.a *= blurOpacity;
gl_FragColor = vec4(regularScene.rgb * (1.0 - overlay.a) + overlay.rgb * overlay.a, 1.0);
}
</script>
<script id="earthFrag" type="x-shader/x-fragment">
uniform sampler2D tEarth;
uniform sampler2D tClouds;
uniform float fTime;
varying vec2 vUv;
varying vec3 v_Normal;
varying vec3 v_Position;
void main() {
vec4 earth = texture2D(tEarth, vec2(vUv.x + fTime * 0.5, vUv.y));
vec4 clouds = texture2D(tClouds, vec2(vUv.x + fTime, vUv.y));
vec4 diffuse = earth + clouds;
vec3 v_LightPos = vec3(-200.0, 200.0, -200.0);
vec3 light_vec = normalize(v_LightPos - v_Position);
float lightStrength = max(dot(v_Normal, light_vec), 0.05);
gl_FragColor = diffuse * lightStrength;
}
</script>
<script>
$(document).ready(function() {
Initialize();
// Instantiate a texture loader.
var loader = new THREE.TextureLoader();
// Allow CORS for loading images from Amazon S3.
loader.crossOrigin = '';
// load a resource
loader.load('images/earth_clouds_low_4096.jpg',
// Function when resource is loaded
function(cloudTexture) {
loader.load('images/earth_color_low_4096.jpg',
function(earthTexture) {
PopulateScenes(earthTexture, cloudTexture);
SetupComposers();
animate();
});
});
});
// Adjust the WebGL content when the browser window is resized.
$(window).resize(function() {
var width = window.innerWidth;
var height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
sceneComposer.setSize(width, height);
blurComposer.setSize(width / 2, height / 2);
});
// Scene-related variables that will be needed throughout various functions.
var camera = null;
var renderer = null;
var scene = null;
var controls = null;
var blurScene = null;
var blurMaskScene = null;
var blurComposer = null;
var sceneComposer = null;
var earthMaterial = null;
var earthGlow = null;
var startTime = new Date().getTime();
// Initialize the scene camera, renderer and composers.
var Initialize = function() {
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 150;
camera.position.y = -80;
renderer = new THREE.WebGLRenderer({
alpha: true,
logarithmicDepthBuffer: true
});
renderer.setClearColor(0x000000, 0.0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.autoClear = false;
$('#glContainer').append(renderer.domElement);
/*
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
*/
scene = new THREE.Scene();
blurScene = new THREE.Scene();
blurMaskScene = new THREE.Scene();
var renderTargetParameters = {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBAFormat,
stencilBufer: true
};
var blurRenderTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParameters);
blurComposer = new THREE.EffectComposer(renderer, blurRenderTarget);
sceneComposer = new THREE.EffectComposer(renderer);
}
// Set up the main scene, blur scene, and blur mask.
var PopulateScenes = function(earthTexture, cloudTexture) {
earthMaterial = CreateEarthMaterial(earthTexture, cloudTexture);
var earthPos = new THREE.Vector3(40, -100, 0);
var sunPos = new THREE.Vector3(20, -5, 0);
// This cube will be the source from which the glow emanates.
var earth = CreateEarth({
size: 50,
color: 0xFFFFFF,
material: earthMaterial,
position: earthPos
});
var sun = CreateSun({
size: 10,
color: 0xFFFFFF,
opacity: 0.5,
position: sunPos
});
// This cube effectively creates a mask in the blur scene. It mirrors the position of the opaque cube.
// If you examine the 'CreateCube' method, you'll see that we are creating a material with an opacity of 0, but a disabled transparent flag.
// This material is equivalent to the following fragment shader: "gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);"
var earthObstruction = CreateEarth({
size: 49,
color: 0xFFFFFF,
opacity: 0.0,
position: earthPos
});
earthObstruction.renderOrder = 1;
// This is the cube that represents the actual glow of the first cube we created.
// Notice its size is slightly bigger than the source cube. The size can be adjusted creating a smaller/larger glow.
earthGlow = CreateEarth({
size: 51.5,
opacity: 0.7,
color: 0x397ebe,
position: earthPos
});
v