Skip to content

Commit

Permalink
Initial terrain rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
timkurvers committed Dec 22, 2015
1 parent ce38194 commit 1fed3f3
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 79 deletions.
79 changes: 0 additions & 79 deletions src/lib/pipeline/adt/chunk.js

This file was deleted.

78 changes: 78 additions & 0 deletions src/lib/pipeline/adt/chunk/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import THREE from 'three';

import Material from './material';

class Chunk extends THREE.Mesh {

static SIZE = 33.33333;
static UNIT_SIZE = 33.33333 / 8;

constructor(data, textureNames) {
super();

const size = this.constructor.SIZE;
const unitSize = this.constructor.UNIT_SIZE;

this.position.y = -(data.indexX * size);
this.position.x = -(data.indexY * size);

const vertices = data.MCVT.heights.length;

const positions = new Float32Array(vertices * 3);
const uv = new Float32Array(vertices * 2);
const uvAlpha = new Float32Array(vertices * 2);

// See: http://www.pxr.dk/wowdev/wiki/index.php?title=ADT#MCVT_sub-chunk
data.MCVT.heights.forEach(function(height, index) {
let y = Math.floor(index / 17);
let x = index % 17;

if (x > 8) {
y += 0.5;
x -= 8.5;
}

// Mirror geometry over X and Y axes
positions[index * 3] = -(y * unitSize);
positions[index * 3 + 1] = -(x * unitSize);
positions[index * 3 + 2] = data.position.z + height;

uv[index * 2] = x;
uv[index * 2 + 1] = y;

uvAlpha[index * 2] = x / 8;
uvAlpha[index * 2 + 1] = y / 8;
});

const indices = new Uint32Array(vertices * 3 * 3);

let faceIndex = 0;
const addFace = (index1, index2, index3) => {
indices[faceIndex * 3] = index1;
indices[faceIndex * 3 + 1] = index2;
indices[faceIndex * 3 + 2] = index3;
faceIndex++;
};

for (let y = 0; y < 8; ++y) {
for (let x = 0; x < 8; ++x) {
const index = 9 + y * 17 + x;
addFace(index, index - 9, index - 8);
addFace(index, index - 8, index + 9);
addFace(index, index + 9, index + 8);
addFace(index, index + 8, index - 9);
}
}

const geometry = this.geometry = new THREE.BufferGeometry();
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.addAttribute('uv', new THREE.BufferAttribute(uv, 2));
geometry.addAttribute('uvAlpha', new THREE.BufferAttribute(uvAlpha, 2));

this.material = new Material(data, textureNames);
}

}

export default Chunk;
49 changes: 49 additions & 0 deletions src/lib/pipeline/adt/chunk/material.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import THREE from 'three';

import TextureLoader from '../../texture-loader';
import fragmentShader from './shader.frag';
import vertexShader from './shader.vert';

class Material extends THREE.ShaderMaterial {

constructor(data, textureNames) {
super();

this.layers = data.MCLY.layers;
this.rawAlphaMaps = data.MCAL.alphaMaps;
this.textureNames = textureNames;

this.vertexShader = vertexShader;
this.fragmentShader = fragmentShader;

this.side = THREE.BackSide;

this.uniforms = {
layerCount: { type: 'i', value: this.layers.length },
alphaMaps: { type: 'tv', value: this.alphaMaps },
textures: { type: 'tv', value: this.textures }
};
}

get alphaMaps() {
return this.rawAlphaMaps.map((raw) => {
const texture = new THREE.DataTexture(raw, 64, 64);
texture.format = THREE.LuminanceFormat;
texture.minFilter = texture.magFilter = THREE.LinearFilter;
texture.needsUpdate = true;
return texture;
});
}

get textures() {
return this.layers.map((layer) => {
const filename = this.textureNames[layer.textureID];
const texture = TextureLoader.load(filename);
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
return texture;
});
}

}

export default Material;
33 changes: 33 additions & 0 deletions src/lib/pipeline/adt/chunk/shader.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
uniform int layerCount;
uniform sampler2D alphaMaps[4];
uniform sampler2D textures[4];

varying vec2 vUv;
varying vec2 vUvAlpha;

void main() {
vec4 color = texture2D(textures[0], vUv);

vec4 layer;
vec4 blend;

if (layerCount > 1) {
layer = texture2D(textures[1], vUv);
blend = texture2D(alphaMaps[0], vUvAlpha);
color = mix(color, layer, blend);
}

if (layerCount > 2) {
layer = texture2D(textures[2], vUv);
blend = texture2D(alphaMaps[1], vUvAlpha);
color = mix(color, layer, blend);
}

if (layerCount > 3) {
layer = texture2D(textures[3], vUv);
blend = texture2D(alphaMaps[2], vUvAlpha);
color = mix(color, layer, blend);
}

gl_FragColor = color;
}
15 changes: 15 additions & 0 deletions src/lib/pipeline/adt/chunk/shader.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
precision highp float;

attribute vec2 uvAlpha;

varying vec2 vUv;
varying vec2 vUvAlpha;

void main() {
vUv = uv;
vUvAlpha = uvAlpha;

gl_Position = projectionMatrix *
modelViewMatrix *
vec4(position, 1.0);
}

0 comments on commit 1fed3f3

Please sign in to comment.