私はThreejsでタイルシステムを実行しようとしています。シェイダーの断片が失われました
私はPlaneBufferGeometryでシェーダーを使用しています。ここで
は、私がこれまで持っているものです。
関連するコード:
- JS:変数
chunk
と機能DoPlaneStuff()
(両方とも冒頭)- HTML:頂点とフラグメントシェーダ
var chunk = {
// number of width and height segments for PlaneBuffer
segments: 32,
// Heightmap: 0 = water, 1 = ground
heightmap: [
[1, 0, 0],
[1, 1, 0],
[1, 0, 1],
],
// size of the plane
size: 40
};
function DoPlaneStuff() {
var uniforms = {
heightmap: {
type: "iv1",
// transform the 2d Array to a simple array
value: chunk.heightmap.reduce((p, c) => p.concat(c), [])
},
hmsize: {
type: "f",
value: chunk.heightmap[0].length
},
coord: {
type: "v2",
value: new THREE.Vector2(-chunk.size/2, -chunk.size/2)
},
size: {
type: "f",
value: chunk.size
}
};
console.info("UNIFORMS GIVEN :", uniforms);
var shaderMaterial = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: document.getElementById("v_shader").textContent,
fragmentShader: document.getElementById("f_shader").textContent
});
var plane = new THREE.Mesh(
new THREE.PlaneBufferGeometry(chunk.size, chunk.size, chunk.segments, chunk.segments),
shaderMaterial
);
plane.rotation.x = -Math.PI/2;
scene.add(plane);
}
// --------------------- END OF RELEVANT CODE
window.addEventListener("load", Init);
function Init() {
Init3dSpace();
DoPlaneStuff();
Render();
}
var camera_config = {
dist: 50,
angle: (5/8) * (Math.PI/2)
}
var scene, renderer, camera;
function Init3dSpace() {
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({
antialias: true,
logarithmicDepthBuffer: true
});
camera = new THREE.PerspectiveCamera(
50,
window.innerWidth/window.innerHeight,
0.1,
1000
);
this.camera.position.y = camera_config.dist * Math.sin(camera_config.angle);
this.camera.position.x = 0;
this.camera.position.z = 0 + camera_config.dist * Math.cos(camera_config.angle);
this.camera.rotation.x = -camera_config.angle;
var light = new THREE.HemisphereLight(0xffffff, 10);
light.position.set(0, 50, 0);
scene.add(light);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function Render() {
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js"></script>
<!-- VERTEX SHADER -->
<script id="v_shader" type="x-shader/x-vertex">
// size of the plane
uniform float size;
// coordinates of the geometry
uniform vec2 coord;
// heightmap size (=width and height of the heightmap)
uniform float hmsize;
uniform int heightmap[9];
varying float colorValue;
void main() {
int xIndex = int(floor(
(position.x - coord.x)/(size/hmsize)
));
int yIndex = int(floor(
(-1.0 * position.y - coord.y)/(size/hmsize)
));
// Get the index of the corresponding tile in the array
int index = xIndex + int(hmsize) * yIndex;
// get the value of the tile
colorValue = float(heightmap[index]);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
<!-- FRAGMENT SHADER -->
<script id="f_shader" type="x-shader/x-fragment">
varying float colorValue;
void main() {
// default color is something is not expected: RED
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
// IF WATER
if (colorValue == 0.0) {
// BLUE
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}
// IF GROUND
if (colorValue == 1.0) {
// GREEN
gl_FragColor = vec4(0.1, 0.6, 0.0, 1.0);
}
}
</script>
あなたはそれがほとんど働いているが、私は緑と青の領域を分割し、これらの赤い線を持っていると私はその理由を把握することはできません見ることができるように。 これらの赤い断片は、いずれのタイルにもマップされていないため、「失われたもの」と呼ばれています。理由は分かりません。
chunk.segments
(ジオメトリの高さと幅のセグメント数)の値が大きいほど、赤い線が細くなることがわかりました。
赤の代わりに緑と青のゾーンの間にグラデーションの塗りつぶしをする方法を知りたいと思います。
答えをありがとう。 "GPUが三角形に沿ってcolorValueを補間する"それで、私はさまざまなintを持つことができませんでした!しかし、私はあなたの "より良い解決策"の意味を理解していないのですが、いくつかのリソースを持っていますか? – Apolo