Skip to content

Instantly share code, notes, and snippets.

@Gelio
Created November 18, 2017 12:00
Show Gist options
  • Save Gelio/472f01ddcbb59c29d1edad3eb0f3777c to your computer and use it in GitHub Desktop.
Save Gelio/472f01ddcbb59c29d1edad3eb0f3777c to your computer and use it in GitHub Desktop.
function putPixel(x: number, y: number) {
const textureVectorWithLightColor = textureVectorsWithLightColor[x][y];
const distortedNormalVector = distortedNormalVectors[x][y];
// cos theta = v1 * v2 / (norm(v1) * norm(v2))
// Since lightDirectionVersor and distortedNormalVector are unit vectors, cos theta is just
// a dot product
const cosTheta = Vector3.dotProduct(lightDirectionVersor, distortedNormalVector);
const clampedCosTheta = Math.max(0, Math.min(1, cosTheta));
const result = textureVectorWithLightColor
.multiply(clampedCosTheta)
.floor();
const index = (x + y * canvasImageData.width) * 4;
canvasImageData.data[index] = result.x;
canvasImageData.data[index + 1] = result.y;
canvasImageData.data[index + 2] = result.z;
canvasImageData.data[index + 3] = 255;
}
function prepareTextureVectors() {
textureVectors = [];
const backgroundTexture = appFillData.backgroundTexture;
for (let x = 0; x < canvasWidth; x += 1) {
const backgroundTextureX = x % backgroundTexture.width;
textureVectors.push([]);
for (let y = 0; y < canvasWidth; y += 1) {
const backgroundTextureY = y % backgroundTexture.height;
const index = (backgroundTextureX + backgroundTextureY * backgroundTexture.width) * 4;
const r = backgroundTexture.data[index];
const g = backgroundTexture.data[index + 1];
const b = backgroundTexture.data[index + 2];
textureVectors[x].push(new Vector3(r, g, b));
}
}
}
function prepareNormalVectors() {
normalVectors = [];
const normalMap = appFillData.normalMap;
for (let x = 0; x < canvasWidth; x += 1) {
const normalMapX = x % normalMap.width;
normalVectors.push([]);
for (let y = 0; y < canvasWidth; y += 1) {
const normalMapY = y % normalMap.height;
const index = (normalMapX + normalMapY * normalMap.width) * 4;
const r = normalMap.data[index];
const g = normalMap.data[index + 1];
const b = normalMap.data[index + 2];
const normalVector = Vector3.fromNormalMap(r, g, b);
const scale = 1 / normalVector.z; // [Nx, Ny, 1]
normalVectors[x].push(normalVector.multiply(scale));
}
}
}
function prepareBumpVectors() {
bumpVectors = [];
const heightMap = appFillData.heightMap;
const maxHeightMapX = heightMap.width - 1;
const maxHeightMapY = heightMap.height - 1;
for (let x = 0; x < canvasWidth; x += 1) {
const heightMapX = x % heightMap.width;
bumpVectors.push([]);
for (let y = 0; y < canvasWidth; y += 1) {
const heightMapY = y % heightMap.height;
const index = (heightMapX + heightMapY * heightMap.width) * 4;
let dhx = 0; // = H[x + 1, y] - H[x, y]
let dhy = 0; // = H[x, y+1] - H[x, y]
if (heightMapX < maxHeightMapX) {
dhx = heightMap.data[index + 4] - heightMap.data[index];
} else {
// H[0, y] - H[x, y]
dhx = heightMap.data[index - heightMapX * 4] - heightMap.data[index];
}
if (heightMapY < maxHeightMapY) {
dhy = heightMap.data[index + heightMap.width * 4] - heightMap.data[index];
} else {
// H[x, 0] - H[x, y]
dhy = heightMap.data[heightMapX * 4] - heightMap.data[index];
}
const normalVector = normalVectors[x][y];
const t = new Vector3(1, 0, -normalVector.x);
const b = new Vector3(0, 1, -normalVector.y);
const d = Vector3.add(t.multiply(dhx), b.multiply(dhy));
bumpVectors[x].push(d);
}
}
}
function applyBumpVectors() {
distortedNormalVectors = [];
for (let x = 0; x < canvasWidth; x += 1) {
distortedNormalVectors.push([]);
for (let y = 0; y < canvasHeight; y += 1) {
distortedNormalVectors[x].push(
Vector3.add(normalVectors[x][y], bumpVectors[x][y]).normalize()
);
}
}
}
function prepareTextureVectorsWithLightColor() {
textureVectorsWithLightColor = [];
for (let x = 0; x < canvasWidth; x += 1) {
textureVectorsWithLightColor.push([]);
for (let y = 0; y < canvasHeight; y += 1) {
textureVectorsWithLightColor[x].push(
Vector3.multiplyComponents(textureVectors[x][y], appFillData.lightColor).floor()
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment