雾化(使用w分量)
<html>
<head>11</head>
<body>
<canvas id = "test" width = "800" height = "800">canvas </canvas>
<script src = "webgltest/cuon-matrix.js"></script>
<script >
//顶点着色器
var vertexShaderSource =
'attribute vec4 a_Position;\n' +
'attribute vec4 a_Color;\n' +
'uniform mat4 u_mvpMatrix;\n' +
'uniform mat4 u_ModelMatrix;\n' + //模型矩阵
'uniform vec4 u_Eye;\n' +
'varying vec4 v_Color;\n' + //varying变量
'varying float v_Dist;\n' +
'void main() {\n' +
'gl_Position = u_mvpMatrix * a_Position;\n'+
'v_Color = a_Color;\n' + //将数据传给片元着色器
//计算顶点与视点的距离(<1)
'v_Dist = gl_Position.w;\n' +
'}\n';
//片元着色器
var fragmentShaderSource =
'precision mediump float;\n' +
'uniform vec3 u_FogColor; \n' + //雾的颜色
'uniform vec2 u_FogDist; \n' + //雾化的起点和终点
'varying vec4 v_Color;\n' + //varying变量
'varying float v_Dist;\n' +
'void main() {\n' +
//计算雾化因子
'float fogFactor = clamp((u_FogDist.y - v_Dist ) / (u_FogDist.y - u_FogDist.x ), 0.0, 1.0 ); \n' +
'vec3 color = mix(u_FogColor, vec3(v_Color), fogFactor); \n' +
'gl_FragColor = vec4(color, v_Color.a); \n' +
'}\n';
//创建着色器方法,输入参数:渲染上下文,着色器类型,数据源
function createShader(gl, type, source)
{
//创建着色器对象
var shader = gl.createShader(type);
//提供数据源
gl.shaderSource(shader,source);
//编译着色器
gl.compileShader(shader);
//链接
var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if(success)
{
return shader;
}
console.log(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
//将顶点着色器和像素着色器链接到一个着色程序
function createProgram(gl, vertexShader, fragmentShader)
{
var program = gl.createProgram();
gl.attachShader( program, vertexShader);
gl.attachShader( program, fragmentShader);
gl.linkProgram( program );
var success = gl.getProgramParameter(program, gl.LINK_STATUS);
if(success)
{
console.log("link right");
return program;
}
console.log(gl.getProgramInfoLog(program));
gl.deleteProgram(program);
}
//创建顶点缓冲区和索引缓冲区
function initVertexBuffers(program,gl) {
// Create a cube
// v6----- v5
// /| /|
// v1------v0|
// | | | |
// | |v7---|-|v4
// |/ |/
// v2------v3
var vertices = new Float32Array([ // Vertex coordinates
1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, // v0-v1-v2-v3 front
1.0, 1.0, 1.0, 1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0, // v0-v3-v4-v5 right
1.0, 1.0, 1.0, 1.0, 1.0,-1.0, -1.0, 1.0,-1.0, -1.0, 1.0, 1.0, // v0-v5-v6-v1 up
-1.0, 1.0, 1.0, -1.0, 1.0,-1.0, -1.0,-1.0,-1.0, -1.0,-1.0, 1.0, // v1-v6-v7-v2 left
-1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0,-1.0, 1.0, -1.0,-1.0, 1.0, // v7-v4-v3-v2 down
1.0,-1.0,-1.0, -1.0,-1.0,-1.0, -1.0, 1.0,-1.0, 1.0, 1.0,-1.0 // v4-v7-v6-v5 back
]);
var colors = new Float32Array([ // Colors
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v1-v2-v3 front
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v3-v4-v5 right
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v5-v6-v1 up
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v1-v6-v7-v2 left
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v7-v4-v3-v2 down
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 // v4-v7-v6-v5 back
]);
var normals = new Float32Array([ // Normal
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, // v0-v1-v2-v3 front
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // v0-v3-v4-v5 right
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // v0-v5-v6-v1 up
-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, // v1-v6-v7-v2 left
0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, // v7-v4-v3-v2 down
0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0 // v4-v7-v6-v5 back
]);
var indices = new Uint8Array([ // Indices of the vertices
0, 1, 2, 0, 2, 3, // front
4, 5, 6, 4, 6, 7, // right
8, 9,10, 8,10,11, // up
12,13,14, 12,14,15, // left
16,17,18, 16,18,19, // down
20,21,22, 20,22,23 // back
]);
// Create a buffer object
var indexBuffer = gl.createBuffer();
if (!indexBuffer)
return -1;
// Write the vertex coordinates and color to the buffer object
if (!initArrayBuffer(program,gl, vertices, 3, gl.FLOAT, 'a_Position'))
return -1;
if (!initArrayBuffer(program,gl, colors, 3, gl.FLOAT, 'a_Color'))
return -1;
// Write the indices to the buffer object
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
return indices.length;
}
function initArrayBuffer(program, gl, data, num, type, attribute) {
var buffer = gl.createBuffer(); // Create a buffer object
if (!buffer) {
console.log('Failed to create the buffer object');
return false;
}
// Write date into the buffer object
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
// Assign the buffer object to the attribute variable
var a_attribute = gl.getAttribLocation(program, attribute);
if (a_attribute < 0) {
console.log('Failed to get the storage location of ' + attribute);
return false;
}
gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);
// Enable the assignment of the buffer object to the attribute variable
gl.enableVertexAttribArray(a_attribute);
return true;
}
var canvas = document.getElementById("test");
//创建webgl渲染上下文
var gl = canvas.getContext("webgl");
//var gl = WebGLUtils.setupWebGL(canvas);
if(!gl)
{
console.log("wrong");
}
else
{
console.log("right");
}
//初始化着色器
var vertexShader = createShader(gl,gl.VERTEX_SHADER,vertexShaderSource);
var fragmentShader = createShader(gl,gl.FRAGMENT_SHADER, fragmentShaderSource);
var program = createProgram(gl, vertexShader, fragmentShader);
gl.useProgram(program);
//创建顶点数组
var n = initVertexBuffers(program,gl);
//雾的颜色
var fogColor = new Float32Array([0.137, 0.231, 0.423]);
//雾化的起点和终点与视点间的距离[起点距离,终点距离]
var fogDist = new Float32Array([55, 80]);
//视点在世界坐标系下的坐标
var eye = new Float32Array([25, 65,35, 1.0]);
//获取投影矩阵
var u_mvpMatrix = gl.getUniformLocation(program, 'u_mvpMatrix');
var u_ModelMatrix = gl.getUniformLocation(program, 'u_ModelMatrix');
//雾的参数
var u_FogColor = gl.getUniformLocation(program, 'u_FogColor');
var u_FogDist = gl.getUniformLocation(program, 'u_FogDist');
var u_Eye = gl.getUniformLocation(program, 'u_Eye');
if (!u_mvpMatrix || !u_ModelMatrix || !u_Eye || !u_FogColor || !u_FogDist) {
console.log('Failed to get the storage location');
}
//设置雾的颜色、起点与终点、视点坐标传给相应的Uniform变量
gl.uniform3fv(u_FogColor, fogColor);
gl.uniform2fv(u_FogDist, fogDist);
gl.uniform4fv(u_Eye, eye);
//清除颜色
//在绘制之前,清除深度缓冲区
gl.clearColor(fogColor[0], fogColor[1], fogColor[2], 1.0);
//开启隐藏面消除功能
gl.enable(gl.DEPTH_TEST);
//模型矩阵
var modelMatrix = new Matrix4();
modelMatrix.setScale(10, 10, 10);
gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
var g_near = 1.0, g_far = 1000.0;
//模型视图投影矩阵
var mvpMatrix = new Matrix4();
mvpMatrix.setPerspective(30, canvas.width / canvas.height,g_near, g_far);
mvpMatrix.lookAt(eye[0], eye[1], eye[2], 0, 2, 0, 0, 1, 0 );
mvpMatrix.multiply(modelMatrix);
//将投影矩阵传给u_ProjMatrix变量
gl.uniformMatrix4fv(u_mvpMatrix, false, mvpMatrix.elements);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
//绘制正方体
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0 );
</script>
</body>
</html>