您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
优化 WebGl 着色器性能(动态调整复杂度、纹理优化、视锥裁剪等)
当前为
// ==UserScript== // @name WebGL (Shaders优化工具) // @namespace http://tampermonkey.net/ // @version 1.0 // @description 优化 WebGl 着色器性能(动态调整复杂度、纹理优化、视锥裁剪等) // @author KiwiFruit // @match *://*/* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; // 1. 动态调整着色器复杂度(根据设备 DPI) function getShaderPrecision() { const dpi = window.devicePixelRatio; return dpi >= 2 ? 'highp' : 'mediump'; // 高 DPI 使用高精度 [[3]] } // 2. 创建顶点着色器 function createVertexShader(gl) { const precision = getShaderPrecision(); const vertexShaderSource = ` attribute vec4 a_Position; attribute vec3 a_Normal; uniform mat4 u_ModelViewMatrix; uniform mat4 u_ProjectionMatrix; varying vec3 v_Normal; void main() { v_Normal = normalize((u_ModelViewMatrix * vec4(a_Normal, 0.0)).xyz); gl_Position = u_ProjectionMatrix * u_ModelViewMatrix * a_Position; } `; return compileShader(gl, gl.VERTEX_SHADER, vertexShaderSource); } // 3. 创建片元着色器(动态精度) function createFragmentShader(gl) { const precision = getShaderPrecision(); const fragmentShaderSource = ` precision ${precision} float; // 动态精度 [[3]] varying vec3 v_Normal; uniform vec3 u_LightColor; uniform vec3 u_LightDirection; void main() { float light = max(dot(v_Normal, u_LightDirection), 0.0); gl_FragColor = vec4(u_LightColor * light, 1.0); } `; return compileShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource); } // 4. 编译着色器通用函数 function compileShader(gl, type, source) { const shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { console.error('Shader compile failed:', gl.getShaderInfoLog(shader)); gl.deleteShader(shader); return null; } return shader; } // 5. 预编译并缓存着色器程序 let shaderProgramCache = null; async function preloadShaders(gl) { if (shaderProgramCache) return shaderProgramCache; const vs = createVertexShader(gl); const fs = createFragmentShader(gl); const program = gl.createProgram(); gl.attachShader(program, vs); gl.attachShader(program, fs); gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { console.error('Program link failed:', gl.getProgramInfoLog(program)); return null; } shaderProgramCache = program; return program; } // 6. 创建带 Mipmap 的纹理 [[10]] function createMipmapTexture(gl, image) { const texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); gl.generateMipmap(gl.TEXTURE_2D); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); return texture; } // 7. 视锥裁剪逻辑 [[5]] function isObjectVisible(object, camera) { const distance = Math.sqrt( (object.position.x - camera.position.x) ** 2 + (object.position.y - camera.position.y) ** 2 + (object.position.z - camera.position.z) ** 2 ); return distance < camera.far; // 根据摄像机远裁剪面剔除 [[5]] } // 8. 静态分辨率适配(根据设备 DPI)[[2]] function adjustResolutionByDPI(canvas) { const dpi = window.devicePixelRatio; const targetDpi = 1.0; // 固定目标 DPI const scale = dpi > targetDpi ? targetDpi / dpi : 1.0; canvas.width = Math.floor(canvas.clientWidth * scale); canvas.height = Math.floor(canvas.clientHeight * scale); canvas.getContext('webgl').viewport(0, 0, canvas.width, canvas.height); } // 9. 主函数:初始化 WebGL 并应用优化 function initWebGL() { const canvas = document.createElement('canvas'); adjustResolutionByDPI(canvas); // 静态分辨率适配 [[2]] document.body.appendChild(canvas); const gl = canvas.getContext('webgl'); if (!gl) { console.error('WebGL not supported'); return; } // 预编译着色器 [[3]] preloadShaders(gl).then(program => { if (!program) return; // 示例:绘制一个简单立方体 const vertices = new Float32Array([ // 顶点坐标 -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ]); const normals = new Float32Array([ // 法线向量 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ]); // 创建缓冲区 const vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); const normalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer); gl.bufferData(gl.ARRAY_BUFFER, normals, gl.STATIC_DRAW); // 绑定属性 gl.useProgram(program); const aPosition = gl.getAttribLocation(program, 'a_Position'); const aNormal = gl.getAttribLocation(program, 'a_Normal'); gl.enableVertexAttribArray(aPosition); gl.enableVertexAttribArray(aNormal); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer); gl.vertexAttribPointer(aNormal, 3, gl.FLOAT, false, 0, 0); // 设置统一变量 const uModelViewMatrix = gl.getUniformLocation(program, 'u_ModelViewMatrix'); const uProjectionMatrix = gl.getUniformLocation(program, 'u_ProjectionMatrix'); const uLightColor = gl.getUniformLocation(program, 'u_LightColor'); const uLightDirection = gl.getUniformLocation(program, 'u_LightDirection'); gl.uniform3f(uLightColor, 1.0, 1.0, 1.0); gl.uniform3f(uLightDirection, 0.5, 0.5, 1.0); // 渲染循环 function render() { gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); // 绘制立方体面 requestAnimationFrame(render); } render(); }); } // 10. 监听页面加载完成 window.addEventListener('load', () => { try { initWebGL(); // 初始化 WebGL 渲染 [[3]] } catch (error) { console.error('WebGL 初始化失败:', error); } }); })();