Delay Coloring for WebGL – Jeff Zhong – Cnblogs.com
MRT
- FBO
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const fbo = {
framebuffer: fb,
textures: []};// Create a color texture
for(let i = 0; i < 3; i++){
const tex = initTexture(gl, { informat: gl.RGBA16F, type: gl.FLOAT }, width, height);
framebufferInfo.textures.push(tex);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, tex, 0);
}
// Create deep render buffer
const depthBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);
Copy the code
- draw buffer
gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);
Copy the code
- Gbuffer shader
#version 300 es
in vec4 aPosition;
in vec4 aNormal;
uniform mat4 modelMatrix;
uniform mat4 vpMatrix;
out vec3 vPosition;
out vec3 vNormal;
void main() {
gl_Position = vpMatrix * modelMatrix * aPosition;
vNormal = vec3(transpose(inverse(modelMatrix)) * aNormal);
vPosition = vec3(modelMatrix * aPosition);
}
Copy the code
#version 300 es
precision highp float;
layout (location = 0) out vec3 gPosition;// The location of each slice
layout (location = 1) out vec3 gNormal; // The normal vector of each slice
layout (location = 2) out vec4 gColor; // The color of each slice
uniform vec4 color;
in vec3 vPosition;
in vec3 vNormal;
void main() {
gPosition = vPosition;
gNormal = normalize(vNormal);
gColor = color;
}
Copy the code
Light processing
- Light processing shader
#version 300 es
#define GLSLIFY 1
in vec3 aPosition;
in vec2 aTexcoord;
out vec2 texcoord;
void main() {
texcoord = aTexcoord;
gl_Position = vec4(aPosition, 1.0);
}
Copy the code
#version 300 es
precision highp float;
#define GLSLIFY 1
uniform vec3 viewPosition;
uniform vec3 lightDirection;
uniform vec3 lightColor;
uniform vec3 ambientColor;
uniform float shininess;
uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gColor;
struct PointLight {
vec3 position;
vec3 color;
float shininess;
float line;
float quad;
};
uniform PointLight pointLights[10];
struct SpotLight {
vec3 position;
vec3 direction;
vec3 color;
float outerRad;
float innerRad;
float shininess;
};
uniform SpotLight spotLights[3];
in vec2 texcoord;
out vec4 FragColor;
/* * point light source */
vec3 getPointLights(vec3 fragPos, vec3 normal, vec3 color, vec3 viewDir) {
vec3 ret = vec3(0.0);
for(int i = 0; i < 10; i++) {
vec3 lightPos = pointLights[i].position;
vec3 lightColor = pointLights[i].color;
float lightShininess = pointLights[i].shininess;
vec3 lightDir = normalize(lightPos - fragPos);
float cosTheta = max(dot(lightDir, normal), 0.0);
vec3 diffuse = lightColor * color * cosTheta;
/ / highlights
vec3 halfwayDir = normalize(lightDir + viewDir);
float specularIntensity = pow(max(dot(normal, halfwayDir), 0.0), lightShininess);
vec3 specular = lightColor * specularIntensity;
// Light intensity attenuation
float dis = distance(lightPos, fragPos);
float att = 1.0 / (1.0 + pointLights[i].line * dis + pointLights[i].quad * (dis * dis));
ret += (diffuse + specular) * att;
}
return ret;
}
/* * spotlight */
vec3 getSpotLights(vec3 fragPos, vec3 normal, vec3 color, vec3 viewDir) {
vec3 ret = vec3(0.0);
for(int i = 0; i < 3; i++) {
vec3 lightPos = spotLights[i].position;
vec3 lightColor = spotLights[i].color;
float lightShininess = spotLights[i].shininess;
vec3 lightDir = normalize(spotLights[i].direction);
float outerLimit = cos(spotLights[i].outerRad); / / irradiation Angle | fuzzy diameter range Angle
float innerLimit = cos(spotLights[i].innerRad); // Blur the inner diameter Angle
vec3 surToLightDir = normalize(lightPos - fragPos); // Point light position - vertex position
float dotFromDirection = dot(surToLightDir, lightDir); // The Angle between the light direction and the surface light direction
float inlightBloom = smoothstep(outerLimit, innerLimit, dotFromDirection); // Spotlight range + edge blur
float cosTheta = max(dot(surToLightDir, normal), 0.0); // The dot product of the ray direction and the normal vector can be used to calculate the cosine of the Angle (range 0-90 degrees)
vec3 diffuse = lightColor * color * cosTheta * inlightBloom;
/ / highlights
vec3 halfwayDir = normalize(surToLightDir + viewDir);
float specularIntensity = pow(max(dot(normal, halfwayDir), 0.0), lightShininess);
vec3 specular = lightColor * specularIntensity * inlightBloom;
ret += (diffuse + specular);
}
return ret;
}
void main() {
vec3 fragPos = texture(gPosition, texcoord).rgb; // The location of each slice
vec3 normal = texture(gNormal, texcoord).rgb; // The normal direction of each slice
vec3 color = texture(gColor, texcoord).rgb; // The color of each slice
vec3 viewDir = normalize(viewPosition - fragPos); // View direction
vec3 lightDir = normalize(lightDirection); // Parallel light direction
float cosTheta = max(dot(lightDir, normal), 0.0); // Angle between ray direction and normal vector
/ / the ambient light
vec3 ambient = ambientColor * color;
/ / diffuse
vec3 diffuse = lightColor * color * cosTheta;
FragColor = vec4(ambient + diffuse + getPointLights(fragPos, normal, color, viewDir) + getSpotLights(fragPos, normal, color, viewDir), 1.0);
}
Copy the code