index.vert
#version 300 es
layout (location = 0) in vec3 aVertexPosition;
layout (location = 1) in vec3 aVertexNormal;
uniform mat4 uMatModel;
uniform mat4 uMatView;
uniform mat4 uMatProj;
uniform mat4 uMatNormal;
uniform vec3 uLightDir;
uniform vec4 uAmbient;
uniform vec3 uMaterialColor;
out vec4 vVertexColor;
void main() {
vec3 N = aVertexNormal;
vec3 invL = normalize(uMatNormal * vec4(uLightDir, 0.0)).xyz;
float diffuse = clamp(dot(N, invL), 0.1, 1.0);
vVertexColor = vec4(uMaterialColor, 1.0) * vec4(vec3(diffuse), 1.0) + uAmbient;
gl_Position = uMatProj * uMatView * uMatModel * vec4(aVertexPosition, 1.0);
}
render.ts
import { SketchGl, SketchFn, SketchConfig } from "sketchgl"
import { Matrix4, RawVector3 } from "sketchgl/math"
import { Program, Uniforms } from "sketchgl/program"
import { Geometry } from "sketchgl/geometry"
import { AngleCamera, AngleCameraController } from "sketchgl/camera"
import vert from "./index.vert?raw"
import frag from "./index.frag?raw"
import rabbitModel from "@/model/json/Bunny-LowPoly.json" assert { type: "json" }
const sketch: SketchFn = (skCanvas) => {
const { gl, canvas } = skCanvas
const uMaterialColor: RawVector3 = [0.855, 0.792, 0.969]
const uniforms = new Uniforms(gl, [
"uMatView",
"uMatModel",
"uMatProj",
"uMatNormal",
"uLightDir",
"uAmbient",
"uMaterialColor"
])
const program = new Program(gl)
program.attach(vert, frag)
program.activate()
const rabbit = new Geometry(gl)
rabbit.registAttrib("vertice", {
location: 0,
components: 3,
buffer: new Float32Array(rabbitModel.vertices.map(Number))
})
rabbit.registAttrib("normal", {
location: 1,
components: 3,
buffer: new Float32Array(rabbitModel.normals.map(Number))
})
rabbit.registIndices(new Uint16Array(rabbitModel.indices))
rabbit.setup()
const camera = new AngleCamera("ORBIT")
camera.goHome([30, 30, 300])
camera.azimuth = 0
camera.elevation = 60
camera.focus = [0, 0, 0]
camera.update()
const matP = Matrix4.perspective(camera.fov, canvas.width / canvas.height, camera.near, camera.far)
const matM = Matrix4.identity()
AngleCameraController.init(canvas, camera)
uniforms.init(program.glProgram)
uniforms.fmatrix4("uMatModel", matM.values)
uniforms.fmatrix4("uMatProj", matP.values)
uniforms.fmatrix4("uMatNormal", matM.inverse().values)
uniforms.fvector3("uLightDir", [-0.5, 0.5, 200])
uniforms.fvector3("uMaterialColor", uMaterialColor)
uniforms.fvector4("uAmbient", [0.2, 0.1, 0.2, 1.0])
gl.clearColor(1.0, 1.0, 1.0, 1.0)
gl.clearDepth(1.0)
gl.enable(gl.DEPTH_TEST)
gl.depthFunc(gl.LEQUAL)
gl.enable(gl.CULL_FACE)
return {
drawOnFrame() {
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height)
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
const matV = camera.View
uniforms.fmatrix4("uMatView", matV.values)
rabbit.bind()
rabbit.draw()
},
control(ui) {
ui.rgb("Color", uMaterialColor, (c) => {
uniforms.fvector3("uMaterialColor", c)
})
}
}
}
export const onload = () => {
const config: SketchConfig = {
canvas: {
el: "gl-canvas",
fit: "square",
autoResize: true
}
}
SketchGl.init(config, sketch)
}