How do I make a painting application with WebGL?


يرجى شرح بإيجاز لمإذا تشعر أنك ينبغي الإبلاغ عن هذا السؤال.


The goal is pretty straight forward. I want to make a drawing application that is purely based on WebGL. I already have a canvas and I managed to get a shader working and to display colors.

The idea was, I render whatever is on the canvas to a texture and then “reuse” that texture in the next frame in the shader again, so that I could draw on top of that.

I am new to WebGL but already I have some experience with GLSL. However I am struggling setting up the with all textures and framebuffers and such, especially in what order. I couldn’t find a solution to my specific problem without overcomplicating things that I don’t need. I mean I don’t want to draw a cube with a texture on it. I don’t need a projection matrix. Everything in theory will be in 2D.

Can anyone give me a guide how to set up things to achieve my goal?
Any help would be highly appreciated!

Here’s what I have so far. I am using VueJS btw

import vertexShader from “raw-loader!../shader/vertex.glsl”;
import fragmentShader from “raw-loader!../shader/fragment.glsl”;

export default defineComponent({
name: ‘HomePage’,
setup() {
let canvas = ref<HTMLCanvasElement>();

const canvasSize = ref({ width: 1920, height: 1080 });

let gl: WebGL2RenderingContext | null;
let location: WebGLUniformLocation | null;
let texture: WebGLTexture | null;
let textureLocation: WebGLUniformLocation | null;

onMounted(() => {
if (canvas.value) {
gl = canvas.value.getContext(‘webgl2’);
if (gl) {
// Set the view port
gl.viewport(0, 0, canvas.value.width, canvas.value.height);

//Create a vertex shader object
const vertShader = gl.createShader(gl.VERTEX_SHADER);

if (vertShader) {
gl.shaderSource(vertShader, vertexShader);

if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) console.error(gl.getShaderInfoLog(vertShader));

// Create fragment shader object
const fragShader = gl.createShader(gl.FRAGMENT_SHADER);

if (fragShader) {
gl.shaderSource(fragShader, fragmentShader);

if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) console.error(gl.getShaderInfoLog(fragShader));

// Create a shader program object to store combined shader program
const shaderProgram = gl.createProgram();

if (shaderProgram) {
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);


location = gl.getUniformLocation(shaderProgram, “mouse”);
gl.uniform2f(location, 0, 0);

texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);

textureLocation = gl.getUniformLocation(shaderProgram, “u_texture”);

gl.uniform1i(textureLocation, 0);


gl.drawArrays(gl.TRIANGLE_FAN, 0, 3);

const pointermove = (e:any) => {
if (gl && canvas.value) {
gl.uniform2f(location, e.clientX, canvas.value.height – e.clientY);

gl.drawArrays(gl.TRIANGLE_FAN, 0, 3);

return {

Fragment shader:

#version 300 es

precision highp float;

in vec2 texcoord;
out vec4 fragmentColor;

uniform sampler2D u_texture;
uniform vec2 mouse;

void main(void) {
//fragmentColor = vec4(0.0, 0.0, 0.0, 1.0);
fragmentColor = vec4(texture(u_texture, texcoord).rgb, 1.0);
float x = gl_FragCoord.x – mouse.x;
float y = gl_FragCoord.y – mouse.y;
fragmentColor.rgb += mix(1.0, 0.0, (x*x + y*y) * 0.001);

Vertex Shader:

#version 300 es

precision highp float;

out vec2 texcoord;

void main(void) {
float x = float((gl_VertexID & 1) << 2);
float y = float((gl_VertexID & 2) << 1);
texcoord.x = x * 0.5;
texcoord.y = y * 0.5;
gl_Position = vec4(x – 1.0, y – 1.0, 0, 1);

X 5 أشهر 2022-07-10T12:01:26+03:00 0 إجابة 4 مشاهدات مبتدئ 0

‫أضف إجابة


مجهول يجيب