use texture for rendering planets

This commit is contained in:
Ilion Beyst 2022-07-18 07:40:01 +02:00
parent e5cb04208f
commit 270476e038
6 changed files with 113 additions and 79 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -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);
} }

View 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);
}

View file

@ -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";

View file

@ -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,
const layout = new VertexBufferLayout(); 1, -1
layout.push(GL.FLOAT, 3, 4, "a_position"); ]);
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 vao = new VertexArray(); const vao = new VertexArray();
vao.addBuffer(positionBuffer, layout); vao.addBuffer(vb_pos, layout_pos);
vao.addBuffer(vb_tex, layout_tex);
this.renderer.addToDraw(
indexBuffer, const uniforms = {
vao, u_trans: transform,
this.shader, u_trans_next: transform,
{ };
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);
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([

View file

@ -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);