I have created a 3D world in WebGL with a modular camera that moves around the world using the keyboard. I would like to add a minimap to my world, and I plan to do this by creating a quad and rendering the texture from the camera in a TopDown View on my quad.
I am already able to render a texture to a quad, but my problem is fixing the quad to the top right of the camera. Does anyone have an idea how I can achieve this?
I tried to create a second canvas and render it to the second canvas but this approach would not work because it either does not render the correct scenegraph or does not render to the canvas.
For reference, this is my script for rendering to a texture:
function initRenderToTexture() {
//general setup
gl.activeTexture(gl.TEXTURE0);
//create framebuffer
renderTargetFramebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, renderTargetFramebuffer);
//TASK 5: Setup color and depth texture and bind them to the framebuffer
//create color texture
renderTargetColorTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, renderTargetColorTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.texImage2D(gl.TEXTURE_2D, //texture unit target == texture type
0, //level of detail level (default 0)
gl.RGBA, //internal format of the data in memory
framebufferWidth, //texture width (required if no image given)
framebufferHeight, //texture height (required if no image given)
0, //border (enable or disable setting a border color for clamping, required if no image given)
gl.RGBA, //image format (should match internal format)
gl.UNSIGNED_BYTE, //image data type
null); //actual image data
//create depth texture
renderTargetDepthTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, renderTargetDepthTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT32F, framebufferWidth, framebufferHeight, 0, gl.DEPTH_COMPONENT, gl.FLOAT, null);
//attach textures to framebuffer
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, renderTargetColorTexture, 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, renderTargetDepthTexture, 0);
//check if framebuffer was created successfully
if(gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
alert('Framebuffer incomplete!');
}
//clean up
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
function renderToTexture() {
//TASK 5: Render C3PO to framebuffer/texture
//bind framebuffer to draw scene into texture
gl.bindFramebuffer(gl.FRAMEBUFFER, renderTargetFramebuffer);
//setup viewport
gl.viewport(0, 0, framebufferWidth, framebufferHeight);
gl.clearColor(0.9, 0.9, 0.9, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
//setup context and camera matrices
const context = createSGContext(gl);
context.projectionMatrix = mat4.perspective(mat4.create(), glm.deg2rad(30), framebufferWidth / framebufferHeight, 0.01, 100);
context.viewMatrix = mat4.lookAt(mat4.create(), [0,10,0], [0,0,0], [1,1,0]);
//render scenegraph
root.render(context);
//disable framebuffer (to render to screen again)
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
The shaders are just standard phong shaders except those lines:
//texture related variables
uniform bool u_enableObjectTexture;
//TASK 1: define texture sampler and texture coordinates
varying vec2 v_texCoord;
uniform sampler2D u_tex;
void main (void) {
vec4 textureColor = vec4(0,0,0,1);
if(u_enableObjectTexture)
{
//TASK 2: integrate texture color into phong shader
textureColor = texture2D(u_tex,v_texCoord);
//gl_FragColor = vec4(0,0,0,1);
//TASK 1: simple texturing: replace vec4(0,0,0,1) with texture lookup
gl_FragColor = texture2D(u_tex,v_texCoord);
return;
}
}