Created
November 18, 2017 12:00
-
-
Save Gelio/472f01ddcbb59c29d1edad3eb0f3777c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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