use texture for rendering planets
This commit is contained in:
parent
e5cb04208f
commit
270476e038
6 changed files with 113 additions and 79 deletions
BIN
web/pw-visualizer/assets/res/earth.png
Normal file
BIN
web/pw-visualizer/assets/res/earth.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -10,5 +10,4 @@ uniform sampler2D u_texture;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_FragColor = texture2D(u_texture, v_texCoord);
|
gl_FragColor = texture2D(u_texture, v_texCoord);
|
||||||
// gl_FragColor = vec4(0.7, 0.7, 0.0, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
21
web/pw-visualizer/assets/shaders/frag/masked_image.glsl
Normal file
21
web/pw-visualizer/assets/shaders/frag/masked_image.glsl
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Passed in from the vertex shader.
|
||||||
|
varying vec2 v_texCoord;
|
||||||
|
|
||||||
|
uniform float u_step_interval;
|
||||||
|
uniform float u_time;
|
||||||
|
uniform vec3 u_color;
|
||||||
|
uniform vec3 u_color_next;
|
||||||
|
|
||||||
|
|
||||||
|
// The texture.
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float alpha = texture2D(u_texture, v_texCoord).a;
|
||||||
|
vec3 color = mix(u_color, u_color_next, u_time);
|
||||||
|
gl_FragColor = vec4(color, alpha);
|
||||||
|
}
|
|
@ -4,9 +4,13 @@ export {default as earthSvg} from "../assets/res/earth.svg";
|
||||||
export {default as marsSvg} from "../assets/res/mars.svg";
|
export {default as marsSvg} from "../assets/res/mars.svg";
|
||||||
export {default as venusSvg} from "../assets/res/venus.svg";
|
export {default as venusSvg} from "../assets/res/venus.svg";
|
||||||
|
|
||||||
|
export {default as earthPng} from "../assets/res/earth.png";
|
||||||
|
|
||||||
export {default as fontPng} from "../assets/res/font.png";
|
export {default as fontPng} from "../assets/res/font.png";
|
||||||
|
|
||||||
export {default as imageFragmentShader} from "../assets/shaders/frag/image.glsl?url";
|
export {default as imageFragmentShader} from "../assets/shaders/frag/image.glsl?url";
|
||||||
|
export {default as maskedImageFragmentShader} from "../assets/shaders/frag/masked_image.glsl?url";
|
||||||
|
|
||||||
export {default as simpleFragmentShader} from "../assets/shaders/frag/simple.glsl?url";
|
export {default as simpleFragmentShader} from "../assets/shaders/frag/simple.glsl?url";
|
||||||
export {default as vorFragmentShader} from "../assets/shaders/frag/vor.glsl?url";
|
export {default as vorFragmentShader} from "../assets/shaders/frag/vor.glsl?url";
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,13 @@ import {
|
||||||
UniformMatrix3fv,
|
UniformMatrix3fv,
|
||||||
UniformBool,
|
UniformBool,
|
||||||
} from "./webgl/shader";
|
} from "./webgl/shader";
|
||||||
import { Renderer } from "./webgl/renderer";
|
import { DefaultRenderable, Renderer } from "./webgl/renderer";
|
||||||
import { VertexBuffer, IndexBuffer } from "./webgl/buffer";
|
import { VertexBuffer, IndexBuffer } from "./webgl/buffer";
|
||||||
import { VertexBufferLayout, VertexArray } from "./webgl/vertexBufferLayout";
|
import { VertexBufferLayout, VertexArray } from "./webgl/vertexBufferLayout";
|
||||||
import { defaultLabelFactory, LabelFactory, Align, Label } from "./webgl/text";
|
import { defaultLabelFactory, LabelFactory, Align, Label } from "./webgl/text";
|
||||||
import { VoronoiBuilder } from "./voronoi/voronoi";
|
import { VoronoiBuilder } from "./voronoi/voronoi";
|
||||||
import * as assets from "./assets";
|
import * as assets from "./assets";
|
||||||
|
import { Texture } from "./webgl/texture";
|
||||||
|
|
||||||
|
|
||||||
function to_bbox(box: number[]): BBox {
|
function to_bbox(box: number[]): BBox {
|
||||||
|
@ -133,6 +134,7 @@ export class GameInstance {
|
||||||
shader: Shader;
|
shader: Shader;
|
||||||
vor_shader: Shader;
|
vor_shader: Shader;
|
||||||
image_shader: Shader;
|
image_shader: Shader;
|
||||||
|
masked_image_shader: Shader;
|
||||||
|
|
||||||
text_factory: LabelFactory;
|
text_factory: LabelFactory;
|
||||||
planet_labels: Label[];
|
planet_labels: Label[];
|
||||||
|
@ -174,6 +176,7 @@ export class GameInstance {
|
||||||
this.vor_shader = shaders["vor"].create_shader(GL, {
|
this.vor_shader = shaders["vor"].create_shader(GL, {
|
||||||
PLANETS: "" + planets.length,
|
PLANETS: "" + planets.length,
|
||||||
});
|
});
|
||||||
|
this.masked_image_shader = shaders["masked_image"].create_shader(GL);
|
||||||
|
|
||||||
this.text_factory = defaultLabelFactory(GL, this.image_shader);
|
this.text_factory = defaultLabelFactory(GL, this.image_shader);
|
||||||
this.planet_labels = [];
|
this.planet_labels = [];
|
||||||
|
@ -234,45 +237,53 @@ export class GameInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
_create_planets(planets: Float32Array, meshes: Mesh[]) {
|
_create_planets(planets: Float32Array, meshes: Mesh[]) {
|
||||||
|
const earth = Texture.fromImage(GL, assets.earthPng, 'earth');
|
||||||
|
|
||||||
for (let i = 0; i < this.planet_count; i++) {
|
for (let i = 0; i < this.planet_count; i++) {
|
||||||
{
|
{
|
||||||
const transform = new UniformMatrix3fv([
|
const transform = new UniformMatrix3fv([
|
||||||
1,
|
1, 0, 0,
|
||||||
0,
|
0, 1, 0,
|
||||||
0,
|
-planets[i * 3], -planets[i * 3 + 1], 1, // TODO: why are negations needed?
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
-planets[i * 3],
|
|
||||||
-planets[i * 3 + 1],
|
|
||||||
1,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const indexBuffer = new IndexBuffer(
|
const gl = GL;
|
||||||
GL,
|
const ib = new IndexBuffer(gl, [
|
||||||
meshes[i % meshes.length].cells
|
0, 1, 2,
|
||||||
);
|
1, 2, 3
|
||||||
const positionBuffer = new VertexBuffer(
|
]);
|
||||||
GL,
|
const vb_pos = new VertexBuffer(gl, [
|
||||||
meshes[i % meshes.length].positions
|
-1, 1,
|
||||||
);
|
1, 1,
|
||||||
|
-1, -1,
|
||||||
|
1, -1
|
||||||
|
]);
|
||||||
|
const vb_tex = new VertexBuffer(gl, [
|
||||||
|
0, 0,
|
||||||
|
1, 0,
|
||||||
|
0, 1,
|
||||||
|
1, 1]);
|
||||||
|
|
||||||
|
const layout_pos = new VertexBufferLayout();
|
||||||
|
// 2?
|
||||||
|
layout_pos.push(gl.FLOAT, 2, 4, "a_position");
|
||||||
|
|
||||||
|
const layout_tex = new VertexBufferLayout();
|
||||||
|
layout_tex.push(gl.FLOAT, 2, 4, "a_texCoord");
|
||||||
|
|
||||||
const layout = new VertexBufferLayout();
|
|
||||||
layout.push(GL.FLOAT, 3, 4, "a_position");
|
|
||||||
const vao = new VertexArray();
|
const vao = new VertexArray();
|
||||||
vao.addBuffer(positionBuffer, layout);
|
vao.addBuffer(vb_pos, layout_pos);
|
||||||
|
vao.addBuffer(vb_tex, layout_tex);
|
||||||
|
|
||||||
|
const uniforms = {
|
||||||
|
u_trans: transform,
|
||||||
|
u_trans_next: transform,
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderable = new DefaultRenderable(ib, vao, this.masked_image_shader, [earth], uniforms);
|
||||||
|
|
||||||
|
this.renderer.addRenderable(renderable, LAYERS.planet);
|
||||||
|
|
||||||
this.renderer.addToDraw(
|
|
||||||
indexBuffer,
|
|
||||||
vao,
|
|
||||||
this.shader,
|
|
||||||
{
|
|
||||||
u_trans: transform,
|
|
||||||
u_trans_next: transform,
|
|
||||||
},
|
|
||||||
[],
|
|
||||||
LAYERS.planet
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -430,25 +441,30 @@ export class GameInstance {
|
||||||
this.use_vor = false;
|
this.use_vor = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const shaders_to_update = [
|
||||||
|
this.shader,
|
||||||
|
this.image_shader,
|
||||||
|
this.masked_image_shader,
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
// If not playing, still reder with different viewbox, so people can still pan etc.
|
// If not playing, still reder with different viewbox, so people can still pan etc.
|
||||||
if (!this.playing) {
|
if (!this.playing) {
|
||||||
this.last_time = time;
|
this.last_time = time;
|
||||||
|
|
||||||
this.shader.uniform(
|
shaders_to_update.forEach((shader) => {
|
||||||
GL,
|
shader.uniform(
|
||||||
"u_viewbox",
|
GL,
|
||||||
new Uniform4f(this.resizer.get_viewbox())
|
"u_viewbox",
|
||||||
);
|
new Uniform4f(this.resizer.get_viewbox())
|
||||||
|
);
|
||||||
|
})
|
||||||
|
|
||||||
this.vor_shader.uniform(
|
this.vor_shader.uniform(
|
||||||
GL,
|
GL,
|
||||||
"u_viewbox",
|
"u_viewbox",
|
||||||
new Uniform4f(this.resizer.get_viewbox())
|
new Uniform4f(this.resizer.get_viewbox())
|
||||||
);
|
);
|
||||||
this.image_shader.uniform(
|
|
||||||
GL,
|
|
||||||
"u_viewbox",
|
|
||||||
new Uniform4f(this.resizer.get_viewbox())
|
|
||||||
);
|
|
||||||
|
|
||||||
this.renderer.render(GL);
|
this.renderer.render(GL);
|
||||||
return;
|
return;
|
||||||
|
@ -481,39 +497,24 @@ export class GameInstance {
|
||||||
this.vor_shader.uniform(GL, "u_resolution", new Uniform2f(RESOLUTION));
|
this.vor_shader.uniform(GL, "u_resolution", new Uniform2f(RESOLUTION));
|
||||||
this.vor_shader.uniform(GL, "u_vor", new UniformBool(this.use_vor));
|
this.vor_shader.uniform(GL, "u_vor", new UniformBool(this.use_vor));
|
||||||
|
|
||||||
this.shader.uniform(
|
shaders_to_update.forEach((shader) => {
|
||||||
GL,
|
shader.uniform(
|
||||||
"u_time",
|
GL,
|
||||||
new Uniform1f((time - this.last_time) / ms_per_frame)
|
"u_time",
|
||||||
);
|
new Uniform1f((time - this.last_time) / ms_per_frame)
|
||||||
this.shader.uniform(
|
);
|
||||||
GL,
|
shader.uniform(
|
||||||
"u_mouse",
|
GL,
|
||||||
new Uniform2f(this.resizer.get_mouse_pos())
|
"u_mouse",
|
||||||
);
|
new Uniform2f(this.resizer.get_mouse_pos())
|
||||||
this.shader.uniform(
|
);
|
||||||
GL,
|
shader.uniform(
|
||||||
"u_viewbox",
|
GL,
|
||||||
new Uniform4f(this.resizer.get_viewbox())
|
"u_viewbox",
|
||||||
);
|
new Uniform4f(this.resizer.get_viewbox())
|
||||||
this.shader.uniform(GL, "u_resolution", new Uniform2f(RESOLUTION));
|
);
|
||||||
|
shader.uniform(GL, "u_resolution", new Uniform2f(RESOLUTION));
|
||||||
this.image_shader.uniform(
|
});
|
||||||
GL,
|
|
||||||
"u_time",
|
|
||||||
new Uniform1f((time - this.last_time) / ms_per_frame)
|
|
||||||
);
|
|
||||||
this.image_shader.uniform(
|
|
||||||
GL,
|
|
||||||
"u_mouse",
|
|
||||||
new Uniform2f(this.resizer.get_mouse_pos())
|
|
||||||
);
|
|
||||||
this.image_shader.uniform(
|
|
||||||
GL,
|
|
||||||
"u_viewbox",
|
|
||||||
new Uniform4f(this.resizer.get_viewbox())
|
|
||||||
);
|
|
||||||
this.image_shader.uniform(GL, "u_resolution", new Uniform2f(RESOLUTION));
|
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
this.renderer.render(GL);
|
this.renderer.render(GL);
|
||||||
|
@ -616,6 +617,15 @@ export async function set_instance(source: string): Promise<GameInstance> {
|
||||||
assets.simpleVertexShader,
|
assets.simpleVertexShader,
|
||||||
),
|
),
|
||||||
])(),
|
])(),
|
||||||
|
(async () =>
|
||||||
|
<[string, ShaderFactory]>[
|
||||||
|
"masked_image",
|
||||||
|
await ShaderFactory.create_factory(
|
||||||
|
assets.maskedImageFragmentShader,
|
||||||
|
assets.simpleVertexShader,
|
||||||
|
),
|
||||||
|
])(),
|
||||||
|
|
||||||
];
|
];
|
||||||
let shaders_array: [string, ShaderFactory][];
|
let shaders_array: [string, ShaderFactory][];
|
||||||
[meshes, shaders_array] = await Promise.all([
|
[meshes, shaders_array] = await Promise.all([
|
||||||
|
|
|
@ -57,8 +57,8 @@ async function main() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: do we still need this?
|
||||||
const mesh = await url_to_mesh("static/res/images/earth.svg");
|
const mesh = await url_to_mesh("static/res/images/earth.svg");
|
||||||
console.log(Math.max(...mesh.positions), Math.min(...mesh.positions));
|
|
||||||
const renderer = new Renderer();
|
const renderer = new Renderer();
|
||||||
|
|
||||||
const factory = await ShaderFactory.create_factory(assets.simpleFragmentShader, assets.simpleVertexShader);
|
const factory = await ShaderFactory.create_factory(assets.simpleFragmentShader, assets.simpleVertexShader);
|
||||||
|
|
Loading…
Reference in a new issue