Webgl-超级基础随笔3-shader光源叠加与创建球体

目录

 

平行光-漫反射

点光源-漫反射

点光源-漫反射-高光

创建球体


平行光-漫反射

在cude_demo的基础上(以下在啥啥基础上,只是最后的源码扩展,与写的功能实现无关,也可以单独拎出来写)

  1. 在顶点着色器源码中

//定义漫反射顶点着色器传值

'varying vec4 v_Color;\n' +

'varying vec4 v_Normal;\n' +

main函数中

//设置漫反射顶点着色器传值

' v_Color = a_Color;\n' +

' v_Normal = a_Normal;\n' +

  1. 在片元着色器源码中

//fragmentShader精度设置

'#ifdef GL_ES\n' +

'precision mediump float;\n' +

'#endif\n' +

//漫反射传值定义

'uniform vec3 u_LightColor;\n' +

'uniform vec3 u_LightDir;\n' +//方向光

'uniform vec3 u_LightColorAmbient;\n' +//环境光

'varying vec4 v_Color;\n' +

'varying vec4 v_Normal;\n' +//法线

'void main() {\n' +

//漫反射计算公式

' vec3 normal = normalize(vec3(v_Normal));\n' +//法线归一化

' float cos = max(dot(u_LightDir, normal), 0.0);\n' +//角度

' vec3 diffuse = u_LightColor * v_Color.rgb * cos;\n' +

' vec3 ambient = u_LightColorAmbient * v_Color.rgb;\n' +

' vec4 r_Color = vec4(diffuse + ambient, v_Color.a);\n'+

//颜色渲染

' gl_FragColor = r_Color;\n' +

'}\n'

  1. demo_cude_diffuse.js

//方向光设置

var u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor');

gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);//光颜色

var dir = normalizeVector([0.5, 3.0, 4.0]);//方向设置(标准化向量)

var u_LightDir = gl.getUniformLocation(gl.program, 'u_LightDir');//获取着色器中的变量

gl.uniform3f(u_LightDir, dir[0], dir[1], dir[2]);

var u_LightColorAmbient = gl.getUniformLocation(gl.program, 'u_LightColorAmbient');

gl.uniform3f(u_LightColorAmbient, 0.2, 0.2, 0.2);//环境光强度设置

function normalizeVector (vector) {//标准化向量

var len = Math.sqrt(vector[0]**2 + vector[1]**2 + vector[2]**2)

return [vector[0] / len, vector[1] / len, vector[2] / len]

}

点光源-漫反射

在平行光基础上

  1. 在顶点着色器中添加

varying vec4 v_Position;\n'+

//设置漫反射顶点着色器传值片元着色器

' v_Position = a_Position;\n'+

  1. 在片元着色器中

//'uniform vec3 u_LightDir;\n' +//方向光

'uniform vec3 u_LightPosition;\n' +//点光源位置

'varying vec4 v_Position;\n'+

' vec3 lightDirection = normalize(u_LightPosition - vec3(v_Position));\n' +//点光源

' float cos = max(dot(lightDirection, normal), 0.0);\n' +//角度

//' float cos = max(dot(u_LightDir, normal), 0.0);\n' +//角度

  1. pointDiffuse.js

//方向光设置

var u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor');

gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);//光颜色

// var dir = normalizeVector([0.5, 3.0, 4.0]);//方向设置(标准化向量)

// var u_LightDir = gl.getUniformLocation(gl.program, 'u_LightDir');//获取着色器中的变量

// gl.uniform3f(u_LightDir, dir[0], dir[1], dir[2]);

var u_LightColorAmbient = gl.getUniformLocation(gl.program, 'u_LightColorAmbient');

gl.uniform3f(u_LightColorAmbient, 0.2, 0.2, 0.2);//环境光强度设置

//点光源

var u_LightPosition = gl.getUniformLocation(gl.program, 'u_LightPosition');

gl.uniform3f(u_LightPosition, 1.15, 2.0, 1.75);

点光源-漫反射-高光

在pointDiffuse基础上

  1. 片元着色器中

'uniform vec3 u_ViewDir;\n' +//高光设置

//设置高光公式

' vec3 nDotLight = normal * dot(normal, lightDirection);\n' +

' vec3 r = lightDirection - nDotLight - nDotLight;\n' +

' float nDotView = max(dot(r, u_ViewDir), 0.0);\n' +

' float shininess = 3.0;\n' +//高光强度

' float k = 1.0;\n' +

' vec3 specular = k * pow(nDotView, shininess) * v_Color.rgb;\n' +

//效果相加

' vec4 r_Color = vec4(diffuse + ambient + specular, v_Color.a);\n' +

  1. JS中

//高光

var viewDir = normalizeVector([1.15, 2.0, 1.75]);

var u_ViewDir = gl.getUniformLocation(gl.program, 'u_ViewDir');

gl.uniform3f(u_ViewDir, viewDir[0], viewDir[1], viewDir[2]);

创建球体

在创建cude基础上

修改initVertexBuffers方法

function initVertexBuffers(gl) {//加载顶点数据

var SPHERE_DIV = 13;

var aj, sj, cj, ai, si, ci;

var positions = [];

var colors = [];

var indices = [];

// Generate coordinates

for (j = 0; j <= SPHERE_DIV; j++) {

aj = j * Math.PI / SPHERE_DIV;

sj = Math.sin(aj);

cj = Math.cos(aj);

for (i = 0; i <= SPHERE_DIV; i++) {

ai = i * 2 * Math.PI / SPHERE_DIV;

si = Math.sin(ai);

ci = Math.cos(ai);

 

positions.push(si * sj); // X

positions.push(cj); // Y

positions.push(ci * sj); // Z

colors.push(1.0);

colors.push(0.0);

colors.push(0.0);

}

}

// Generate indices

for (j = 0; j < SPHERE_DIV; j++) {

for (i = 0; i < SPHERE_DIV; i++) {

p1 = j * (SPHERE_DIV + 1) + i;

p2 = p1 + (SPHERE_DIV + 1);

indices.push(p1);

indices.push(p2);

indices.push(p1 + 1);

indices.push(p1 + 1);

indices.push(p2);

indices.push(p2 + 1);

}

}

// Create a buffer object

var indexBuffer = gl.createBuffer();

initArrayBuffer(gl, new Float32Array(positions), 3, gl.FLOAT, 'a_Position')

initArrayBuffer(gl, new Float32Array(colors), 3, gl.FLOAT, 'a_Color')

initArrayBuffer(gl, new Float32Array(positions), 3, gl.FLOAT, 'a_Normal')//原点法线就是坐标点

// Write the indices to the buffer object

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);

gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(indices), gl.STATIC_DRAW);

return indices.length;//返回点数

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值