Ðам Ñже должно бÑÑÑ Ð¿Ð¾Ð½ÑÑно,ÑÑо Ñ WebGL Ð½ÐµÑ Ð¼Ð½Ð¾Ð³Ð¾ "вÑÑÑоенного знаниÑ". Ðн пÑоÑÑо вÑполнÑÐµÑ Ð´Ð²Ðµ ÑÑнкÑии, коÑоÑÑе Ð²Ñ Ð½Ð°Ð¿Ð¸Ñали - веÑÑиннÑй ÑÐµÐ¹Ð´ÐµÑ Ð¸ ÑÑагменÑнÑй ÑейдеÑ, а ÑÑнкÑии, коÑоÑÑе ÑиÑÑÑÑ ÑÑÐµÐ½Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð½Ð°Ð¿Ð¸ÑаÑÑ Ð²Ñ Ñами. ÐÑÑгими Ñловами, еÑли Ð²Ñ Ñ Ð¾ÑиÑе добавиÑÑ Ð¾ÑвеÑение, Ñо Ð²Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ ÑаÑÑÑиÑаÑÑ ÐµÐ³Ð¾ ÑамоÑÑоÑÑелÑно. Ð ÑÑаÑÑÑÑ, ÑделаÑÑ ÑÑо не Ñложно. Ð ÑÑой ÑÑаÑÑе Ð¼Ñ Ð¾Ð¿Ð¸Ñем некоÑоÑÑе оÑновÑ.
СимÑлÑÑÐ¸Ñ Ð¾ÑвеÑÐµÐ½Ð¸Ñ Ð¸ заÑÐµÐ½ÐµÐ½Ð¸Ñ Ð² 3DХоÑÑ Ð´ÐµÑали ÑеоÑии, лежаÑей в оÑнове ÑимÑлÑÑии оÑвеÑÐµÐ½Ð¸Ñ Ð² 3D-гÑаÑике Ð»ÐµÐ¶Ð°Ñ Ð´Ð°Ð»ÐµÐºÐ¾ за пÑеделами ÑÑой ÑÑаÑÑи, бÑÐ´ÐµÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñм немного ÑзнаÑÑ Ð¾ Ñом, как ÑÑо ÑабоÑаеÑ. ÐоÑмоÑÑиÑе ÑÑаÑÑÑ ÐаÑенение по Ð¤Ð¾Ð½Ð³Ñ Ð² Ðикипедии, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ñ Ð¾ÑоÑий Ð¾Ð±Ð·Ð¾Ñ Ð½Ð°Ð¸Ð±Ð¾Ð»ÐµÐµ ÑаÑÑо иÑполÑзÑемÑÑ Ð¼Ð¾Ð´ÐµÐ»ÐµÐ¹ оÑвеÑениÑ. Рв ÑÑой ÑÑаÑÑе Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе поÑмоÑÑеÑÑ Ð¾Ð±ÑÑÑнение, оÑнованное на WebGL.
СÑÑеÑÑвÑÐµÑ ÑÑи оÑновнÑÑ Ñипа иÑÑоÑников ÑвеÑа:
ÐкÑÑжаÑÑий ÑÐ²ÐµÑ Ð¾ÑвеÑÐ°ÐµÑ Ð²ÑÑ ÑÑенÑ. Ðн не напÑавленнÑй и оÑвеÑÐ°ÐµÑ Ð²Ñе гÑани вÑÐµÑ Ð¾Ð±ÑекÑов одинаково, не завиÑимо Ð¾Ñ Ð¾ÑиенÑаÑии гÑаней.
ÐапÑавленнÑй ÑÐ²ÐµÑ Ð¸ÑÑ Ð¾Ð´Ð¸Ñ Ð¸Ð· опÑеделÑнного напÑавлениÑ. ÐÑÐ¾Ñ ÑÐ²ÐµÑ Ð¿ÑÐ¸Ñ Ð¾Ð´Ð¸Ñ Ð¾Ñ Ð½Ð°ÑÑолÑко ÑдалÑнного иÑÑоÑника, ÑÑо вÑе ÑоÑÐ¾Ð½Ñ Ð»ÐµÑÑÑ Ð¿Ð°ÑаллелÑно дÑÑг дÑÑгÑ. РпÑимеÑÑ, ÑолнеÑнÑй ÑÐ²ÐµÑ Ð¼Ð¾Ð¶Ð½Ð¾ ÑÑиÑаÑÑ.
ТоÑеÑнÑй ÑÐ²ÐµÑ Ð¸ÑÑ Ð¾Ð´Ð¸Ñ Ð¸Ð· одной ÑоÑки во вÑÐµÑ Ð½Ð°Ð¿ÑавлениÑÑ . Ð ÑеалÑном миÑе многие иÑÑоÑники оÑвеÑÐµÐ½Ð¸Ñ ÑвлÑÑÑÑÑ ÑоÑеÑнÑми, напÑÐ¸Ð¼ÐµÑ ÑлекÑÑиÑеÑÐºÐ°Ñ Ð»Ð°Ð¼Ð¿Ð¾Ñка.
Ð ÑÑой ÑÑаÑÑе Ð¼Ñ ÑпÑоÑÑим Ð¼Ð¾Ð´ÐµÐ»Ñ Ð¾ÑвеÑÐµÐ½Ð¸Ñ Ð¸ бÑдем иÑполÑзоваÑÑ ÑолÑко пÑоÑÑой напÑавленнÑй и окÑÑжаÑÑий ÑвеÑ. ÐÑ Ð½Ðµ бÑдем ÑоздаваÑÑ Ð±Ð»Ð¸ÐºÐ¸ на повеÑÑ Ð½Ð¾ÑÑи обÑекÑов и ÑоÑеÑнÑе иÑÑоÑники ÑвеÑа. ÐмеÑÑо ÑÑого Ð¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ð¼ окÑÑжаÑÑий ÑÐ²ÐµÑ Ð¸ напÑавленнÑй ÑÐ²ÐµÑ Ð² ÑÑÐµÐ½Ñ Ñ Ð²ÑаÑаÑÑимÑÑ ÐºÑбом из пÑедÑдÑÑего пÑимеÑа.
ÐÑли оÑÑавиÑÑ Ð² ÑÑоÑоне блики и ÑоÑеÑнÑе иÑÑоÑники ÑвеÑа, Ñо оÑÑанÑÑÑÑ Ð´Ð²Ð° пÑнкÑа, коÑоÑÑе нÑжно изÑÑиÑÑ Ð¿Ð¾ поÑÑдкÑ:
ÐаÑем Ð¼Ñ Ð¾Ð±Ð½Ð¾Ð²Ð¸Ð¼ веÑÑиннÑй ÑейдеÑ, ÑÑÐ¾Ð±Ñ ÑкоÑÑекÑиÑоваÑÑ ÑÐ²ÐµÑ ÐºÐ°Ð¶Ð´Ð¾Ð¹ веÑÑÐ¸Ð½Ñ Ð² завиÑимоÑÑи Ð¾Ñ Ð¾ÐºÑÑжаÑÑего и напÑавленного оÑвеÑÐµÐ½Ð¸Ñ Ñ ÑÑÑÑом Ñгла Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ Ð½Ð° гÑанÑ. ÐÑ Ñвидим, как ÑÑо делаеÑÑÑ, когда поÑмоÑÑим на код ÑейдеÑа.
ÐоÑÑÑоение ноÑмали Ð´Ð»Ñ Ð²ÐµÑÑинСнаÑала нам нÑжно ÑоздаÑÑ Ð¼Ð°ÑÑив ноÑмалей Ð´Ð»Ñ Ð²ÑÐµÑ Ð²ÐµÑÑин, из коÑоÑÑÑ ÑоÑÑÐ¾Ð¸Ñ Ð½Ð°Ñ ÐºÑб. ÐÑо бÑÐ´ÐµÑ Ð¿ÑоÑÑо, поÑÐ¾Ð¼Ñ ÑÑо кÑб оÑÐµÐ½Ñ Ð¿ÑоÑÑой обÑекÑ. ÐÑевидно, ÑÑо Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ ÑложнÑÑ Ð¾Ð±ÑекÑов ÑаÑÑÑÑ Ð½Ð¾Ñмалей бÑÐ´ÐµÑ Ð±Ð¾Ð»ÐµÐµ заÑÑаÑнÑм.
const normalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
const 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 Float32Array(vertexNormals),
gl.STATIC_DRAW);
...
return {
position: positionBuffer,
normal: normalBuffer,
textureCoord: textureCoordBuffer,
indices: indexBuffer,
};
Ðод Ñже должен вÑглÑдеÑÑ Ñзнаваемо. ÐÑ ÑоздаÑм новÑй бÑÑеÑ, ÑвÑзÑваем его Ñ ÑабоÑим бÑÑеÑом и запиÑÑваем в него маÑÑив ноÑмалей к веÑÑинам пÑи помоÑи bufferData()
.
ÐаÑем добавим в drawScene()
код, коÑоÑÑй ÑвÑÐ¶ÐµÑ Ð¼Ð°ÑÑив ноÑмалей Ñ Ð°ÑÑибÑÑом ÑейдеÑа. Таким обÑазом ÑÐµÐ¹Ð´ÐµÑ ÑÐ¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ðº Ð½ÐµÐ¼Ñ Ð´Ð¾ÑÑÑп:
// УказÑваем WebGL как извлекаÑÑ Ð½Ð¾Ñмали из
// бÑÑеÑа ноÑмалей в аÑÑибÑÑ vertexNormal.
{
const numComponents = 3;
const type = gl.FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.normal);
gl.vertexAttribPointer(
programInfo.attribLocations.vertexNormal,
numComponents,
type,
normalize,
stride,
offset,
);
gl.enableVertexAttribArray(programInfo.attribLocations.vertexNormal);
}
РконÑе нÑжно обновиÑÑ ÐºÐ¾Ð´, коÑоÑÑй ÑÑÑÐ¾Ð¸Ñ Ð¼Ð°ÑÑиÑÑ Ð´Ð»Ñ uniform-пеÑеменнÑÑ , ÑÑÐ¾Ð±Ñ ÑоздаÑÑ Ð¸ пеÑедаÑÑ Ð² ÑÐµÐ¹Ð´ÐµÑ Ð¼Ð°ÑÑиÑÑ Ð½Ð¾Ñмалей, коÑоÑÐ°Ñ Ð¸ÑполÑзÑеÑÑÑ Ð´Ð»Ñ ÑÑанÑÑоÑмаÑии ноÑмалей пÑи ÑаÑÑÑÑе оÑиенÑаÑии кÑба оÑноÑиÑелÑно напÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð° иÑÑоÑник ÑвеÑа:
const normalMatrix = mat4.create();
mat4.invert(normalMatrix, modelViewMatrix);
mat4.transpose(normalMatrix, normalMatrix);
...
gl.uniformMatrix4fv(
programInfo.uniformLocations.normalMatrix,
false,
normalMatrix);
Ðбновление ÑейдеÑов
ТепеÑÑ Ñ Ð½Ð°Ñ ÐµÑÑÑ Ð²Ñе даннÑе Ð´Ð»Ñ ÑейдеÑов. ÐоÑа обновиÑÑ ÐºÐ¾Ð´ ÑÐ°Ð¼Ð¸Ñ ÑейдеÑов.
ÐеÑÑиннÑй ÑейдеÑСнаÑала обновим веÑÑиннÑй ÑейдеÑ, ÑÑÐ¾Ð±Ñ Ð¾Ð½ ÑаÑÑÑиÑÑвал знаÑение оÑвеÑÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ веÑÑÐ¸Ð½Ñ Ð½Ð° оÑнове окÑÑжаÑÑего и напÑавленного ÑвеÑа. ÐоÑмоÑÑим на код:
const vsSource = `
attribute vec4 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
uniform mat4 uNormalMatrix;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
vTextureCoord = aTextureCoord;
// ÐÑименÑем ÑÑÑÐµÐºÑ Ð¾ÑвеÑениÑ
highp vec3 ambientLight = vec3(0.3, 0.3, 0.3);
highp vec3 directionalLightColor = vec3(1, 1, 1);
highp vec3 directionalVector = normalize(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);
}
`;
ÐоÑле ÑаÑÑÑÑа позиÑии веÑÑÐ¸Ð½Ñ Ð¼Ñ Ð¿ÐµÑедаÑм кооÑдинаÑÑ ÑекÑÐµÐ»Ñ (texel), ÑооÑвеÑÑÑвÑÑÑего веÑÑине, во ÑÑагменÑнÑй ÑейдеÑ, и наÑинаем ÑаÑÑÑÑ Ð¾ÑвеÑÐµÐ½Ð¸Ñ Ð²ÐµÑÑинÑ.
СнаÑала нÑжно пÑеобÑазоваÑÑ Ð½Ð¾ÑмалÑ, оÑновÑваÑÑÑ Ð½Ð° ÑекÑÑей оÑиенÑаÑии кÑба - Ñмножив ноÑÐ¼Ð°Ð»Ñ Ð²ÐµÑÑÐ¸Ð½Ñ Ð½Ð° маÑÑиÑÑ Ð½Ð¾Ñмалей. ÐаÑем Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑаÑÑÑиÑаÑÑ ÐºÐ¾Ð»Ð¸ÑеÑÑво ÑвеÑа Ð¾Ñ Ð½Ð°Ð¿Ñавленного иÑÑоÑника, коÑоÑое пÑÐ¸Ñ Ð¾Ð´Ð¸Ñ Ð² веÑÑинÑ, поÑÑиÑав ÑкалÑÑное пÑоизведение пÑеобÑазованной ноÑмали и векÑоÑа напÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ (напÑавлениÑ, Ñ ÐºÐ¾ÑоÑого пÑÐ¸Ñ Ð¾Ð´Ð¸Ñ ÑвеÑ). ÐÑли ÑкалÑÑное пÑоизведение менÑÑе нÑлÑ, Ñо Ð¼Ñ Ð¿Ñинимаем его за нолÑ, поÑÐ¾Ð¼Ñ ÑÑо колиÑеÑÑво ÑвеÑа не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¼ÐµÐ½ÑÑе 0.
ÐоÑле ÑаÑÑÑÑа колиÑеÑÑва падаÑÑего напÑавленного ÑвеÑа Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ поÑÑиÑаÑÑ ÑиналÑное оÑвеÑение, Ñложив окÑÑжаÑÑий ÑÐ²ÐµÑ Ð¸ пÑоизведение колиÑеÑÑва напÑавленного ÑвеÑа на его ÑвеÑ. Ð ÑезÑлÑÑаÑе полÑÑаеÑÑÑ Ð·Ð½Ð°Ñение RGB, коÑоÑое иÑполÑзÑеÑÑÑ ÑÑагменÑнÑм ÑейдеÑом Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑвеÑа каждого пикÑелÑ.
ФÑагменÑнÑй ÑейдеÑФÑагменÑнÑй ÑÐµÐ¹Ð´ÐµÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»Ñн Ñаким обÑазом, ÑÑÐ¾Ð±Ñ Ð¾Ð½ ÑÑиÑÑвал в знаÑение оÑвеÑениÑ, ÑаÑÑÑиÑанное в веÑÑинном ÑейдеÑе:
const fsSource = `
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
uniform sampler2D uSampler;
void main(void) {
highp vec4 texelColor = texture2D(uSampler, vTextureCoord);
gl_FragColor = vec4(texelColor.rgb * vLighting, texelColor.a);
}
`;
ÐдеÑÑ Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем ÑÐ²ÐµÑ ÑекÑелÑ, как и в пÑедÑдÑÑем пÑимеÑе, но пеÑед Ñем, как ÑÑÑановиÑÑ ÑÐ²ÐµÑ ÑÑагменÑа, Ð¼Ñ Ñмножаем ÑÐ²ÐµÑ ÑекÑÐµÐ»Ñ Ð½Ð° знаÑение оÑвеÑениÑ, ÑÑÐ¾Ð±Ñ ÑÑеÑÑÑ Ð²Ð»Ð¸Ñние иÑÑоÑников ÑвеÑа.
ÐÑÑалоÑÑ ÑолÑко поÑмоÑÑеÑÑ Ð½Ð° опÑеделение аÑÑибÑÑа aVertexNormal
и uniform-пеÑеменной uNormalMatrix
.
const programInfo = {
program: shaderProgram,
attribLocations: {
vertexPosition: gl.getAttribLocation(shaderProgram, "aVertexPosition"),
vertexNormal: gl.getAttribLocation(shaderProgram, "aVertexNormal"),
textureCoord: gl.getAttribLocation(shaderProgram, "aTextureCoord"),
},
uniformLocations: {
projectionMatrix: gl.getUniformLocation(shaderProgram, "uProjectionMatrix"),
modelViewMatrix: gl.getUniformLocation(shaderProgram, "uModelViewMatrix"),
normalMatrix: gl.getUniformLocation(shaderProgram, "uNormalMatrix"),
uSampler: gl.getUniformLocation(shaderProgram, "uSampler"),
},
};
Ð ÑÑо вÑÑ!
ÐоÑмоÑÑеÑÑ ÐºÐ¾Ð´ пÑимеÑа полноÑÑÑÑ | ÐÑкÑÑÑÑ Ð´ÐµÐ¼Ð¾ в новом окне
СамоÑÑоÑÑелÑнÑе ÑпÑажнениÑÐÑевидно, ÑÑо ÑÑо пÑоÑÑой пÑимеÑ, показÑваÑÑий базовое веÑÑинное оÑвеÑение. Рболее пÑодвинÑÑой гÑаÑике вам навеÑнÑка Ð·Ð°Ñ Ð¾ÑеÑÑÑ ÑделаÑÑ Ð¿Ð¾Ð¿Ð¸ÐºÑелÑное оÑвеÑение.
Также Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе поÑкÑпеÑименÑиÑоваÑÑ Ñ Ð½Ð°Ð¿Ñавлением на иÑÑоÑник ÑвеÑа, ÑвеÑами окÑÑжаÑÑего и напÑавленного ÑвеÑа, и Ñ. д.
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