Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
W
WebGL Tutorial
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
MinJae Lee
WebGL Tutorial
Commits
87015efa
Commit
87015efa
authored
4 years ago
by
Min-Jae, Lee
Browse files
Options
Downloads
Patches
Plain Diff
Impl. Defered rendering by MRT
parent
b791ed70
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
script.js
+277
-6
277 additions, 6 deletions
script.js
with
277 additions
and
6 deletions
script.js
+
277
−
6
View file @
87015efa
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
();
});
});
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment