Skip to content
Snippets Groups Projects
Commit 87015efa authored by Min-Jae, Lee's avatar Min-Jae, Lee
Browse files

Impl. Defered rendering by MRT

parent b791ed70
No related branches found
No related tags found
No related merge requests found
const glsl_1st_vert = `#version 300 es
layout(location = 0) in vec4 iPosition;
layout(location = 1) in vec4 iNormal;
uniform vec2 resolution;
out vec4 vPosition;
out vec4 vNormal;
// Refer from gl-matrix
mat4 persp(in float fovy, in float aspect, in float near, in float far) {
float f = 1. / tan(fovy / 2.), nf = 1. / (near - far);
return mat4(
f / aspect, 0, 0, 0,
0, f, 0, 0,
0, 0, (far + near) * nf, -1,
0, 0, (far * near) * nf * 2., 0);
}
mat4 lookAt(in vec3 eye, in vec3 center, in vec3 up) {
vec3 z = eye - center;
z /= length(z);
vec3 x = cross(up, z);
x /= length(x);
vec3 y = cross(z, x);
y /= length(y);
return transpose(mat4(
x, -dot(x, eye),
y, -dot(y, eye),
z, -dot(z, eye),
0,0,0,1
));
}
void main() {
mat4 projection = persp(radians(30.0), resolution.x / resolution.y, .1, 1e3);
mat4 view = lookAt(
vec3(1, 1, 1) * 5.,
vec3(0, 0, 0),
vec3(0, 1, 0)
);
mat4 model = mat4(
1,0,0,0
,0,1,0,0
,0,0,1,0
,0,0,0,1
);
gl_Position = vPosition = projection * view * model * iPosition;
vNormal= transpose(inverse(view * model)) * iNormal;
}
`;
const glsl_1st_frag = `#version 300 es
precision mediump float;
layout(location = 0) out vec4 fPosition;
layout(location = 1) out vec4 fNormal;
in highp vec4 vPosition;
in highp vec4 vNormal;
void main() {
fPosition = vec4((vPosition.xyz / vPosition.w + 1.) / 2., 1);
fNormal = vec4(vNormal.xyz, 1);
}
`;
const glsl_2nd_vert = `#version 300 es
out highp vec2 vUV;
void main() {
vUV = vec2((gl_VertexID / 2) ^ (gl_VertexID % 2), gl_VertexID / 2);
gl_Position = vec4(vec2(-1, -1) + 2. * vUV, 0, 1);
}
`;
const glsl_2nd_frag = `#version 300 es
precision mediump float;
precision highp sampler2DArray;
layout(location = 0) out vec4 fColor;
uniform vec2 resolution;
uniform sampler2DArray gBuffers;
in highp vec2 vUV;
// Kernel refer from https://en.wikipedia.org/wiki/Sobel_operator#Formulation
float sobel(mat3 r) {
mat3 t = transpose(r);
vec3 v = (r[2] - r[0] + t[2] - t[0]) * vec3(1,2,1);
return v.x+v.y+v.z;
}
void main() {
vec2 texel = 1. / resolution;
mat3 normalx = mat3(
texture(gBuffers, vec3(vUV + texel * vec2(-1,-1), 1)).x
,texture(gBuffers, vec3(vUV + texel * vec2( 0,-1), 1)).x
,texture(gBuffers, vec3(vUV + texel * vec2( 1,-1), 1)).x
,texture(gBuffers, vec3(vUV + texel * vec2(-1, 0), 1)).x
,texture(gBuffers, vec3(vUV + texel * vec2( 0, 0), 1)).x
,texture(gBuffers, vec3(vUV + texel * vec2( 1, 0), 1)).x
,texture(gBuffers, vec3(vUV + texel * vec2(-1, 1), 1)).x
,texture(gBuffers, vec3(vUV + texel * vec2( 0, 1), 1)).x
,texture(gBuffers, vec3(vUV + texel * vec2( 1, 1), 1)).x
), normaly = mat3(
texture(gBuffers, vec3(vUV + texel * vec2(-1,-1), 1)).y
,texture(gBuffers, vec3(vUV + texel * vec2( 0,-1), 1)).y
,texture(gBuffers, vec3(vUV + texel * vec2( 1,-1), 1)).y
,texture(gBuffers, vec3(vUV + texel * vec2(-1, 0), 1)).y
,texture(gBuffers, vec3(vUV + texel * vec2( 0, 0), 1)).y
,texture(gBuffers, vec3(vUV + texel * vec2( 1, 0), 1)).y
,texture(gBuffers, vec3(vUV + texel * vec2(-1, 1), 1)).y
,texture(gBuffers, vec3(vUV + texel * vec2( 0, 1), 1)).y
,texture(gBuffers, vec3(vUV + texel * vec2( 1, 1), 1)).y
), normalz = mat3(
texture(gBuffers, vec3(vUV + texel * vec2(-1,-1), 1)).z
,texture(gBuffers, vec3(vUV + texel * vec2( 0,-1), 1)).z
,texture(gBuffers, vec3(vUV + texel * vec2( 1,-1), 1)).z
,texture(gBuffers, vec3(vUV + texel * vec2(-1, 0), 1)).z
,texture(gBuffers, vec3(vUV + texel * vec2( 0, 0), 1)).z
,texture(gBuffers, vec3(vUV + texel * vec2( 1, 0), 1)).z
,texture(gBuffers, vec3(vUV + texel * vec2(-1, 1), 1)).z
,texture(gBuffers, vec3(vUV + texel * vec2( 0, 1), 1)).z
,texture(gBuffers, vec3(vUV + texel * vec2( 1, 1), 1)).z
);
float G = sobel(normalx) + sobel(normaly) + sobel(normalz);
fColor = G>5e-2 ? vec4(0,0,0,1) : texture(gBuffers, vec3(vUV, 0));
}
`;
const vertices = [
/* x,y,z, */
-1.,-1.,-1.,-1, 0, 0,
-1.,-1., 1.,-1, 0, 0,
-1., 1., 1.,-1, 0, 0,
-1.,-1.,-1.,-1, 0, 0,
-1., 1., 1.,-1, 0, 0,
-1., 1.,-1.,-1, 0, 0,
1.,-1., 1., 0,-1, 0,
-1.,-1.,-1., 0,-1, 0,
1.,-1.,-1., 0,-1, 0,
1.,-1., 1., 0,-1, 0,
-1.,-1., 1., 0,-1, 0,
-1.,-1.,-1., 0,-1, 0,
1., 1.,-1., 0, 0,-1,
-1.,-1.,-1., 0, 0,-1,
-1., 1.,-1., 0, 0,-1,
1., 1.,-1., 0, 0,-1,
1.,-1.,-1., 0, 0,-1,
-1.,-1.,-1., 0, 0,-1,
1., 1., 1., 1, 0, 0,
1.,-1.,-1., 1, 0, 0,
1., 1.,-1., 1, 0, 0,
1.,-1.,-1., 1, 0, 0,
1., 1., 1., 1, 0, 0,
1.,-1., 1., 1, 0, 0,
1., 1., 1., 0, 1, 0,
1., 1.,-1., 0, 1, 0,
-1., 1.,-1., 0, 1, 0,
1., 1., 1., 0, 1, 0,
-1., 1.,-1., 0, 1, 0,
-1., 1., 1., 0, 1, 0,
-1., 1., 1., 0, 0, 1,
-1.,-1., 1., 0, 0, 1,
1.,-1., 1., 0, 0, 1,
1., 1., 1., 0, 0, 1,
-1., 1., 1., 0, 0, 1,
1.,-1., 1., 0, 0, 1,
];
const shaderFromCode = (gl, type, source) => {
const s = gl.createShader(type);
gl.shaderSource(s, source);
gl.compileShader(s);
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS))
throw new Error("Failed: compile shader.\n" + gl.getShaderInfoLog(s));
return s;
}
const shaderProgramLoader = (gl, vert, frag) => {
const p = gl.createProgram();
gl.attachShader(p, shaderFromCode(gl, gl.VERTEX_SHADER, vert));
gl.attachShader(p, shaderFromCode(gl, gl.FRAGMENT_SHADER, frag));
gl.linkProgram(p);
if (!gl.getProgramParameter(p, gl.LINK_STATUS)) {
throw new Error("Failed: link program.\n" + gl.getProgramInfoLog(p));
}
return p;
};
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
if ('undefined' === typeof WebGL2RenderingContext) { if ('undefined' === typeof WebGL2RenderingContext)
throw new Error('This tutorial required WebGL version 2.'); throw new Error('This tutorial required WebGL version 2.');
const dom = document.querySelector('canvas#view');
const gl = dom.getContext('webgl2');
if (!gl)
throw new Error('Failed WebGL Initialization.');
const program1st = shaderProgramLoader(gl, glsl_1st_vert, glsl_1st_frag);
const program2nd = shaderProgramLoader(gl, glsl_2nd_vert, glsl_2nd_frag);
const GFramebuffer = gl.createFramebuffer();
let GBuffers = null;
window.addEventListener('resize', () => {
dom.width = dom.clientWidth;
dom.height = dom.clientHeight;
gl.viewport(0, 0, dom.width, dom.height);
if (null !== GBuffers) {
gl.deleteTexture(GBuffers);
GBuffers = null;
} }
const glCtx = document.querySelector('canvas#view').getContext('webgl2'); gl.activeTexture(gl.TEXTURE0);
if (!glCtx) { GBuffers = gl.createTexture();
throw new Error('Failed WebGL Initialization.') gl.bindTexture(gl.TEXTURE_2D_ARRAY, GBuffers);
} gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texImage3D(
gl.TEXTURE_2D_ARRAY,
0,
gl.RGBA,
dom.clientWidth, dom.clientHeight,
2,
0,
gl.RGBA,
gl.UNSIGNED_BYTE,
null
);
gl.useProgram(program1st);
gl.bindFramebuffer(gl.FRAMEBUFFER, GFramebuffer);
var drawBuffers = [
gl.COLOR_ATTACHMENT0,
gl.COLOR_ATTACHMENT1,
];
for (let i = 0; i < 2; ++i)
gl.framebufferTextureLayer(gl.DRAW_FRAMEBUFFER, drawBuffers[i], GBuffers, 0, i);
gl.drawBuffers(drawBuffers);
});
window.dispatchEvent(new Event('resize'));
((program) => {
const vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 24, 0);
gl.vertexAttribPointer(1, 3, gl.FLOAT, gl.FALSE, 24, 12);
})(program1st);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.BACK);
const loop = () => {
requestAnimationFrame(loop);
((gl) => {
gl.bindFramebuffer(gl.FRAMEBUFFER, GFramebuffer);
gl.useProgram(program1st);
gl.uniform2f(gl.getUniformLocation(program1st, "resolution"), dom.clientWidth, dom.clientHeight);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.enable(gl.DEPTH_TEST);
gl.enableVertexAttribArray(0);
gl.enableVertexAttribArray(1);
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 3);
gl.disableVertexAttribArray(0);
gl.disableVertexAttribArray(1);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.useProgram(program2nd);
gl.uniform2f(gl.getUniformLocation(program2nd, "resolution"), dom.clientWidth, dom.clientHeight);
gl.disable(gl.DEPTH_TEST);
gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
})(gl);
};
loop();
}); });
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment