å¨ä½¿ç¨ç¯å ä¹åï¼é¦å æä»¬éè¦äºè§£ï¼ä¸å®ä¹æ´å¹¿æ³ç OpenGL ä¸åï¼WebGL 并没æç»§æ¿ OpenGL ä¸ç¯å çæ¯æãæä»¥ä½ åªè½ç±èªå·±å®å ¨å¾æ§å¶ç¯å ã幸è¿å¾æ¯ï¼è¿ä¹å¹¶ä¸æ¯å¾é¾ï¼æ¬ææ¥ä¸æ¥å°±ä¼ä»ç»å®æç¯å çåºç¡ã
å¨ 3D 空é´ä¸æ¨¡æç°å®ç¯å å¨ 3D 空é´ä¸æ¨¡æç°å®ä¸ççç¯å çå ·ä½åçåç»èç»éæ¬ç¯æç« è½å¤æè¿°æ¸ æ¥çï¼ä½æ¯å¯¹ç¯å 模åæä¸å®çäºè§£å¯¹æä»¬çå¦ä¹ è¿æ¯å¾æå¸®å©çãè½ç¶è¿éæ²¡åæ³æ·±å ¥è®²è§£ï¼ä½æ¯ç»´åºç¾ç§ä¸çPhong çè²æ³ç»åºäºä¸ä¸ªä¸éçæ¦è¦ä»ç»ï¼å ¶ä¸å å«äºæå¸¸ç¨çå ç§å ç §æ¨¡åã
å æºç±»åå¯ä»¥æ¦æ¬æå¦ä¸ä¸ç§ï¼
ç¯å¢å æ¯ä¸ç§å¯ä»¥æ¸éå°åºæ¯çæ¯ä¸ä¸ªè§è½çå ã宿¯éæ¹åå å¹¶ä¸ä¼ååå°ç §å°ç©ä½çæ¯ä¸ä¸ªé¢ï¼æ 论è¿ä¸ªé¢æ¯æååªä¸ªæ¹åçã
æ¹åå æ¯ä¸æä»ä¸ä¸ªåºå®çæ¹åç §å°è¿æ¥çå ãè¿ç§å çç¹ç¹å¯ä»¥çè§£ä¸ºå¥½åæ¯ä»ä¸ä¸ªå¾é¥è¿çå°æ¹ç §å°è¿æ¥çï¼ç¶åå 线ä¸çæ¯ä¸ä¸ªå åä¸å ¶ä»å å齿¯å¹³è¡è¿å¨çã举个ä¾åæ¥è¯´ï¼é³å å°±å¯ä»¥è®¤ä¸ºæ¯æ¹åå ã
ç¹å æºå æ¯æå 线æ¯ä»ä¸ä¸ªç¹åå°åºæ¥çï¼æ¯åçåé¢å «æ¹åå°çãè¿ç§å 卿们çç°å®çæ´»ä¸æ¯æå¸¸è¢«ç¨å°çã举个ä¾åæ¥è¯´ï¼çµç¯æ³¡å°±æ¯åå个æ¹ååå°å 线çã
以æä»¬çéè¦æ¥çï¼æä»¬ä¼ç®åå ç §æ¨¡åï¼åªèèç®åçæ¹åå åç¯å¢å ï¼ä¸ä¼èèä»»ä½éé¢åå°åç¹å æºãè¿æ ·çè¯ï¼æä»¬åªéè¦å¨æä»¬ä½¿ç¨çç¯å¢å ä¸å ä¸ç §å°å°æè½¬ç«æ¹ä½çæ¹åå å°±å¯ä»¥äºãå¨è¿éå¯ä»¥çå°ä¹åçæè½¬ç«æ¹ä½çä¾åã
è½ç¶å¯ä»¥æå¼äºç¹å æºåéé¢åå°ï¼ä½æ¯å ³äºæ¹åå è¿æ¯æä¸¤ç¹éè¦æ³¨æä¸ä¸ï¼
æ¥çï¼æä»¬ä¼æ´æ°é¡¶ç¹çè²å¨ï¼èèå°ç¯å¢å ï¼åèèå°æ¹åå ï¼æ¹åå çä½ç¨ä¼å 为å 线æ¹åä¸é¢ç夹è§å ³ç³»èä¸åï¼ï¼è®¡ç®æ¯ä¸ä¸ªé¡¶ç¹çé¢è²ãå®ç°è¿ä¸ç®æ ç代ç å¦ä¸ã
建ç«é¡¶ç¹æ³çº¿é¦å æä»¬éè¦åçæ¯å»ºç«ä¸ä¸ªæ°ç»æ¥åæ¾ç«æ¹ä½ææé¡¶ç¹çæ³çº¿ãç±äºç«æ¹ä½æ¯ä¸ä¸ªå¾ç®åçç©ä½ï¼æä»¥å¾å®¹æå®ç°ï¼æ¾ç¶å¦ææ¯å¯¹å¤æç©ä½ï¼åæ³çº¿çè®¡ç®æ¹æ³éè¦æ´æ·±å ¥çç ç©¶ã(注ï¼è¯è è°è¯ååç°æ¤å¤ new WebGLFloatArray(...) å¯è½åºè¯¥ä½¿ç¨ new Float32Array())
cubeVerticesNormalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer);
var vertexNormals = [
// Front
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
// Back
0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0,
// Top
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
// Bottom
0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0,
// Right
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
// Left
-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
];
gl.bufferData(
gl.ARRAY_BUFFER,
new WebGLFloatArray(vertexNormals),
gl.STATIC_DRAW,
);
ç°å¨æä»¬åºè¯¥å¯¹æ¤é常çæäºï¼å建æ°ç bufferï¼å°å®å gl.ARRAR_BUFFER ç»å®å¨ä¸èµ·ï¼ç¶åéè¿è°ç¨ bufferData() ææä»¬çé¡¶ç¹æ³çº¿æ°ç»ä¸èµ·ä¼ å ¥ã
ç¶åæä»¬å¨ drawScene() 䏿·»å 代ç ï¼å°æ³çº¿æ°ç»åçè²å¨ç attribute ç»å®èµ·æ¥ä»¥ä¾¿çè²å¨è½å¤è·åå°æ³çº¿æ°ç»çä¿¡æ¯ã
ï¼æ¤å¤åé vertexNormalAttribute åºè¯¥å¨ initShader() 彿°ä¸å£°æï¼å¹¶èµå¼ï¼vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal"ï¼; gl.enableVertexAttribArray(vertexNormalAttribute);)
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer);
gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
æåï¼æä»¬ï¼ä¸ºäºè¯»è 便äºçè§£ï¼æ¤å¤ä»£ç åºè¯¥å¨ setMatrixUniforms() 彿°ä¸æ·»å ï¼éè¦æ´æ°ä¸ä»£ç ï¼å¨çè²å¨ä¸å»ºç«åä¼ éæ³çº¿åéç©éµï¼ç¨è¿ä¸ªç©éµæ¥å¤çå½åç«æ¹ä½ç¸å¯¹äºå æºä½ç½®æ³çº¿åéçè½¬æ¢ (注ï¼è¯è è°è¯ååç°æ¤å¤ new WebGLFloatArray(...) åºè¯¥ä½¿ç¨ new Float32Array())ï¼
var normalMatrix = mvMatrix.inverse();
normalMatrix = normalMatrix.transpose();
var nUniform = gl.getUniformLocation(shaderProgram, "uNormalMatrix");
gl.uniformMatrix4fv(
nUniform,
false,
new WebGLFloatArray(normalMatrix.flatten()),
);
æ´æ°çè²å¨
ç°å¨çè²å¨éè¦çæææ°æ®å·²ç»å ¨é¨å¯ä»¥è·åå°äºï¼æè è¯´å ¨é¨åå¤å¥½äºï¼ï¼æä»¬éè¦æ´æ°ä¸çè²å¨æ¬èº«ç代ç ã
é¡¶ç¹çè²å¨é¦å æ´æ°é¡¶ç¹çè²å¨ï¼è®©å®ç»æ¯ä¸ä¸ªåºäºç¯å¢å åæ¹åå çé¡¶ç¹ä¸ä¸ªçè²å¨å¼ã让æä»¬çä¸ä»£ç ï¼
<script id="shader-vs" type="x-shader/x-vertex">
attribute highp vec3 aVertexNormal;
attribute highp vec3 aVertexPosition;
attribute highp vec2 aTextureCoord;
uniform highp mat4 uNormalMatrix;
uniform highp mat4 uMVMatrix;
uniform highp mat4 uPMatrix;
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
// Apply lighting effect
highp vec3 ambientLight = vec3(0.6, 0.6, 0.6);
highp vec3 directionalLightColor = vec3(0.5, 0.5, 0.75);
highp vec3 directionalVector = vec3(0.85, 0.8, 0.75);
highp vec4 transformedNormal = uNormalMatrix * vec4(aVertexNormal, 1.0);
highp float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0);
vLighting = ambientLight + (directionalLightColor * directional);
}
</script>
䏿¦é¡¶ç¹ä½ç½®è®¡ç®å®æ¯ï¼æä»¬å°±å¯ä»¥è·å¾çº¹ç对åºäºé¡¶ç¹çåæ ï¼ä»è计ç®åºé¡¶ç¹çé´å½±ã
æä»¬å æ ¹æ®ç«æ¹ä½ä½ç½®åæåï¼éè¿é¡¶ç¹æ³çº¿ä¹ä»¥æ³çº¿ç©éµæ¥è½¬æ¢æ³çº¿ãæ¥çæä»¬å¯ä»¥éè¿è®¡ç®è½¬æ¢è¿åçæ³çº¿ä¸æ¹ååéï¼å³ï¼å æ¥èªçæ¹åï¼çç¹ç§¯æ¥è®¡ç®å¾åºé¡¶ç¹åå°æ¹åå çéãå¦æè®¡ç®åºçè¿ä¸ªå¼å°äº 0ï¼åæä»¬æå¼åºå®è®¾ä¸º 0ï¼å ä¸ºä½ ä¸ä¼æå°äº 0 çå ã
彿¹åå çé计ç®å®ï¼æä»¬å¯ä»¥éè¿è·åç¯å¢å 并䏿·»å æ¹åå çé¢è²åè¦æä¾çå®åå ç鿥çæå ç §å¼ï¼lighting valueï¼ãæç»ç»ææä»¬ä¼å¾å°ä¸ä¸ª RGB å¼ï¼ç¨äºç段çè²å¨è°æ´æä»¬æ¸²æçæ¯ä¸ä¸ªåç´ çé¢è²ã
çæ®µçè²å¨ç段çè²å¨ç°å¨éè¦æ ¹æ®é¡¶ç¹çè²å¨è®¡ç®åºçå ç §å¼æ¥æ´æ°ï¼
<script id="shader-fs" type="x-shader/x-fragment">
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
uniform sampler2D uSampler;
void main(void) {
mediump vec4 texelColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
gl_FragColor = vec4(texelColor.rgb * vLighting, texelColor.a);
}
</script>
åå åæä»¬åçä¾å䏿 ·ï¼æä»¬è·å纹ççé¢è²ï¼åæâcolor of the texelâ? æ¤å¤ä¸ªäººè§å¾åºè¯¥å°±æ¯æçº¹ççé¢è²ï¼ï¼ä¸åçæ¯å¨è®¾ç½®ç段é¢è²ä¹åï¼æä»¬å°çº¹ççé¢è²ä¹ä»¥å ç §å¼æ¥è°æ´çº¹çä»¥è¾¾å°æä»¬å æºçææã
ææå°±æ¯è¿æ ·ï¼
æ¥ç宿´çæºç | 卿°æ ç¾é¡µä¸æ¥çæ¼ç¤º
读è ç»ä¹æ¾ç¶è¿æ¯ä¸ä¸ªå¾ç®åçä¾åï¼å®ç°äºåºæ¬çæ¯ä¸ªé¡¶ç¹çç §æãå¯¹äºæ´é«çº§çå¾å½¢ï¼ä½ å°å¯è½éè¦å®ç°æ¯ä¸ªåç´ ï¼æè 说æ´å¤åç´ ï¼çç §æï¼ä½è¿ä¼å¸®å©ä½ æçæ£ç¡®çæ¹ååè¡ã
ä½ ä¹å¯ä»¥å°è¯å æºæ¹åé¢è²ççã
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4