Improve WebGL leather material
This commit is contained in:
+53
-26
@@ -175,40 +175,44 @@ const materials = {
|
||||
color: 0x25130b,
|
||||
map: leatherTextures.color,
|
||||
normalMap: leatherTextures.normal,
|
||||
normalScale: new THREE.Vector2(0.055, 0.055),
|
||||
roughness: 0.72,
|
||||
normalScale: new THREE.Vector2(0.07, 0.07),
|
||||
roughnessMap: leatherTextures.roughness,
|
||||
roughness: 0.78,
|
||||
metalness: 0.02,
|
||||
envMapIntensity: 0.08,
|
||||
envMapIntensity: 0.1,
|
||||
side: THREE.DoubleSide
|
||||
}),
|
||||
hingeLeather: new THREE.MeshStandardMaterial({
|
||||
color: 0x32180c,
|
||||
map: leatherTextures.color,
|
||||
normalMap: leatherTextures.normal,
|
||||
normalScale: new THREE.Vector2(0.048, 0.048),
|
||||
roughness: 0.78,
|
||||
normalScale: new THREE.Vector2(0.062, 0.062),
|
||||
roughnessMap: leatherTextures.roughness,
|
||||
roughness: 0.82,
|
||||
metalness: 0.015,
|
||||
envMapIntensity: 0.06,
|
||||
envMapIntensity: 0.08,
|
||||
side: THREE.DoubleSide
|
||||
}),
|
||||
spineBaseLeather: new THREE.MeshStandardMaterial({
|
||||
color: 0x2a1209,
|
||||
map: leatherTextures.color,
|
||||
normalMap: leatherTextures.normal,
|
||||
normalScale: new THREE.Vector2(0.042, 0.042),
|
||||
roughness: 0.82,
|
||||
normalScale: new THREE.Vector2(0.055, 0.055),
|
||||
roughnessMap: leatherTextures.roughness,
|
||||
roughness: 0.86,
|
||||
metalness: 0.01,
|
||||
envMapIntensity: 0.04,
|
||||
envMapIntensity: 0.06,
|
||||
side: THREE.DoubleSide
|
||||
}),
|
||||
coverEdge: new THREE.MeshStandardMaterial({
|
||||
color: 0x5b351b,
|
||||
map: leatherTextures.color,
|
||||
normalMap: leatherTextures.normal,
|
||||
normalScale: new THREE.Vector2(0.052, 0.052),
|
||||
roughness: 0.76,
|
||||
normalScale: new THREE.Vector2(0.068, 0.068),
|
||||
roughnessMap: leatherTextures.roughness,
|
||||
roughness: 0.8,
|
||||
metalness: 0.015,
|
||||
envMapIntensity: 0.05,
|
||||
envMapIntensity: 0.07,
|
||||
side: THREE.DoubleSide
|
||||
}),
|
||||
pageBlock: new THREE.MeshStandardMaterial({
|
||||
@@ -252,6 +256,9 @@ const materials = {
|
||||
}),
|
||||
spineCloth: new THREE.MeshStandardMaterial({
|
||||
color: 0x8e1d18,
|
||||
normalMap: leatherTextures.normal,
|
||||
normalScale: new THREE.Vector2(0.04, 0.04),
|
||||
roughnessMap: leatherTextures.roughness,
|
||||
roughness: 0.82,
|
||||
metalness: 0,
|
||||
envMapIntensity: 0.08,
|
||||
@@ -1840,22 +1847,31 @@ function createLeatherTextures() {
|
||||
const size = 1024;
|
||||
const colorCanvas = document.createElement('canvas');
|
||||
const normalCanvas = document.createElement('canvas');
|
||||
const roughnessCanvas = document.createElement('canvas');
|
||||
colorCanvas.width = size;
|
||||
colorCanvas.height = size;
|
||||
normalCanvas.width = size;
|
||||
normalCanvas.height = size;
|
||||
roughnessCanvas.width = size;
|
||||
roughnessCanvas.height = size;
|
||||
const colorContext = colorCanvas.getContext('2d');
|
||||
const normalContext = normalCanvas.getContext('2d');
|
||||
const roughnessContext = roughnessCanvas.getContext('2d');
|
||||
const colorImage = colorContext.createImageData(size, size);
|
||||
const normalImage = normalContext.createImageData(size, size);
|
||||
const roughnessImage = roughnessContext.createImageData(size, size);
|
||||
const heightAt = (x, y) => {
|
||||
const nx = x / size;
|
||||
const ny = y / size;
|
||||
const longGrain = Math.sin((nx * 18 + Math.sin(ny * 18.8495559215) * 0.24) * 6.28318530718);
|
||||
const crossGrain = Math.sin((ny * 42 + Math.sin(nx * 12.5663706144) * 0.16) * 6.28318530718);
|
||||
const poreA = Math.sin((nx * 91 + ny * 37) * 6.28318530718);
|
||||
const poreB = Math.sin((nx * 47 - ny * 83) * 6.28318530718);
|
||||
return longGrain * 0.34 + crossGrain * 0.22 + poreA * poreB * 0.16;
|
||||
const longGrain = Math.sin((nx * 24 + Math.sin(ny * 31.4159265359) * 0.18) * 6.28318530718);
|
||||
const secondaryGrain = Math.sin((nx * 63 + ny * 9 + Math.sin(ny * 50.2654824574) * 0.1) * 6.28318530718);
|
||||
const crossGrain = Math.sin((ny * 39 + Math.sin(nx * 18.8495559215) * 0.12) * 6.28318530718);
|
||||
const poreA = Math.sin((nx * 137 + ny * 71) * 6.28318530718);
|
||||
const poreB = Math.sin((nx * 97 - ny * 113) * 6.28318530718);
|
||||
const pebble = Math.sin((nx * 181 + Math.sin(ny * 25.1327412287) * 0.22) * 6.28318530718) *
|
||||
Math.sin((ny * 167 + Math.sin(nx * 37.6991118431) * 0.18) * 6.28318530718);
|
||||
const pit = Math.max(0, 0.58 - Math.abs(poreA * poreB));
|
||||
return longGrain * 0.22 + secondaryGrain * 0.16 + crossGrain * 0.1 + pebble * 0.18 - pit * 0.24;
|
||||
};
|
||||
|
||||
for (let y = 0; y < size; y += 1) {
|
||||
@@ -1863,34 +1879,44 @@ function createLeatherTextures() {
|
||||
const wrappedX = (x + size) % size;
|
||||
const wrappedY = (y + size) % size;
|
||||
const height = heightAt(wrappedX, wrappedY);
|
||||
const grain = THREE.MathUtils.clamp(0.54 + height * 0.22, 0, 1);
|
||||
const warm = 0.82 + 0.18 * Math.sin((x * 0.07 + y * 0.013));
|
||||
const grain = THREE.MathUtils.clamp(0.58 + height * 0.24, 0, 1);
|
||||
const warm = 0.86 + 0.1 * Math.sin((x * 0.045 + y * 0.011)) + 0.04 * Math.sin((x * 0.009 - y * 0.031));
|
||||
const index = (y * size + x) * 4;
|
||||
colorImage.data[index] = Math.round(132 * grain * warm);
|
||||
colorImage.data[index + 1] = Math.round(66 * grain * warm);
|
||||
colorImage.data[index + 2] = Math.round(29 * grain);
|
||||
colorImage.data[index] = Math.round(118 * grain * warm);
|
||||
colorImage.data[index + 1] = Math.round(54 * grain * warm);
|
||||
colorImage.data[index + 2] = Math.round(22 * grain);
|
||||
colorImage.data[index + 3] = 255;
|
||||
|
||||
const hLeft = heightAt((x - 1 + size) % size, wrappedY);
|
||||
const hRight = heightAt((x + 1) % size, wrappedY);
|
||||
const hDown = heightAt(wrappedX, (y - 1 + size) % size);
|
||||
const hUp = heightAt(wrappedX, (y + 1) % size);
|
||||
const normal = new THREE.Vector3((hLeft - hRight) * 2.8, (hDown - hUp) * 2.8, 1).normalize();
|
||||
const normal = new THREE.Vector3((hLeft - hRight) * 4.1, (hDown - hUp) * 4.1, 1).normalize();
|
||||
normalImage.data[index] = Math.round((normal.x * 0.5 + 0.5) * 255);
|
||||
normalImage.data[index + 1] = Math.round((normal.y * 0.5 + 0.5) * 255);
|
||||
normalImage.data[index + 2] = Math.round((normal.z * 0.5 + 0.5) * 255);
|
||||
normalImage.data[index + 3] = 255;
|
||||
|
||||
const fiberContrast = Math.abs(hLeft - hRight) + Math.abs(hDown - hUp);
|
||||
const roughness = THREE.MathUtils.clamp(0.76 + height * 0.1 + fiberContrast * 1.4, 0.5, 0.96);
|
||||
const roughnessByte = Math.round(roughness * 255);
|
||||
roughnessImage.data[index] = roughnessByte;
|
||||
roughnessImage.data[index + 1] = roughnessByte;
|
||||
roughnessImage.data[index + 2] = roughnessByte;
|
||||
roughnessImage.data[index + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
colorContext.putImageData(colorImage, 0, 0);
|
||||
normalContext.putImageData(normalImage, 0, 0);
|
||||
roughnessContext.putImageData(roughnessImage, 0, 0);
|
||||
const colorTexture = new THREE.CanvasTexture(colorCanvas);
|
||||
const normalTexture = new THREE.CanvasTexture(normalCanvas);
|
||||
[colorTexture, normalTexture].forEach((texture) => {
|
||||
const roughnessTexture = new THREE.CanvasTexture(roughnessCanvas);
|
||||
[colorTexture, normalTexture, roughnessTexture].forEach((texture) => {
|
||||
texture.wrapS = THREE.RepeatWrapping;
|
||||
texture.wrapT = THREE.RepeatWrapping;
|
||||
texture.repeat.set(2.5, 1.6);
|
||||
texture.repeat.set(3.6, 2.2);
|
||||
texture.anisotropy = maxTextureAnisotropy;
|
||||
texture.minFilter = THREE.LinearMipmapLinearFilter;
|
||||
texture.magFilter = THREE.LinearFilter;
|
||||
@@ -1898,7 +1924,8 @@ function createLeatherTextures() {
|
||||
});
|
||||
colorTexture.colorSpace = THREE.SRGBColorSpace;
|
||||
normalTexture.colorSpace = THREE.NoColorSpace;
|
||||
return { color: colorTexture, normal: normalTexture };
|
||||
roughnessTexture.colorSpace = THREE.NoColorSpace;
|
||||
return { color: colorTexture, normal: normalTexture, roughness: roughnessTexture };
|
||||
}
|
||||
|
||||
function createRoomReflectionTexture() {
|
||||
|
||||
Reference in New Issue
Block a user