aq1229 2024-03-16 21:31 采纳率: 37.5%
浏览 26
已结题

JavaScript

如果想做出这种效果,该怎么修改我的代码?

img


var NumPoints = 50000;//总共使用5000个点绘制sierpinski镂垫
var points = [];   //存放顶点坐标的数组,初始为空

window.onload = function main(){
    var canvas = document.getElementById("webgl");
    if(!canvas){
        alert("获取canvas元素失败!");
        return;
    }
    var gl = WebGLUtils.setupWebGL(canvas);
    if (!gl){
        alert("获取WebGL上下文失败! ");
        return;
    }
    
    //
    var vertices = [
        vec2(-1.0,-1.0),vec2(0.0,1.0),vec2(1.0,-1.0)
    ];
    
    //在三角形内部随机选择一个初始点
    var a = Math.random();    //a为[0,1]直接随机值
    var b = (1-a) * Math.random();//b为[0,1-a)之间随机值
    var p = add(mult(a,vertices[0]),add(mult(b,vertices[1]),mult(1-a-b,vertices[2])));    //p为三角形三个顶点坐标的加权和,权值之和为1,这样p一定在三角形内部
    //在命令控制台输出p坐标
    console.log("初始点p:(%f,%f)",p[0],p[1]);
    
    
    var colors = [];
    /*计算并存储NumPoint个顶点坐标*/
    for (var i = 0; i<NumPoints;++i) {
        //随机选择一个三角形的顶点,j值为012
        var j = Math.floor(Math.random() * 3);
        //计算随机选择的顶点和p点之间的中点
        var p = mult(0.5,add(p,vertices[j]));
        points.push(p);    //将新顶点添加到数组points中
        //生成随机颜色
        colors.push(vec3(Math.random(), Math.random(), Math.random()));
        
        
    }
    
    
    
    
    
    
    
    
    
    /*设置webGL相关属性*/
    //设置视口(此处视口占满整个canvas)
    gl.viewport(0,//视口左边界举例canvas左边界距离
                0,//视口下边界距离canvas下边界距离
                canvas.width,//视口宽度
                canvas.height);//视口高度
    gl.clearColor(0.0,0.0,0.0,1.0);
    
    
    
    /*加载shader程序并为shader中attribute变量提供数据*/
    //加载id分别为"vertex-shader","fragment-shader"的shader程序,
    //并进行编译和链接,返回shader程序对象program
    var program = initShaders(gl,"vertex-shader","fragment-shader");
    gl.useProgram(program);    //启用该shader程序对象
    
    
    /*将顶点位置属性数据传输到GPU*/
    var verticesBufferId = gl.createBuffer();    //创建buffer
    gl.bindBuffer(gl.ARRAY_BUFFER,verticesBufferId);    //将id为verticesBufferId的buffer绑定为当前Array Buffer
    //为当前Array Buffer提供数据,传输到GPU
    gl.bufferData(gl.ARRAY_BUFFER,    //Buffer类型
        flatten(points),    //Buffer数据来源,flatten将points转换为GPU可接受的格式
        gl.STATIC_DRAW);   //表明将如何使用Buffer(STATIC_DRAW表明是一次提供数据,多遍绘制)
    
    
    /*为shader属性变量与buffer数据建立关联*/
    //获取名称为"a_Position"的shader attribute变量的位置
    var a_Position = gl.getAttribLocation(program,"a_Position");
    if(a_Position < 0){    //getAttribLocation获取失败则返回-1
        alert("获取attribute变量a_Position失!");
        return;
    }
    
    //指定利用当前Array Buffer为a_Position提供数据的具体方式
    gl.vertexAttribPointer(a_Position,    //shader attribu变量位置
        2,   //每个顶点属性有2个分量
        gl.FLOAT,    //数组数据类型(浮点型)
        false,    //不进行归一化处理
        0,    //相邻顶点属性地址相差0个字节
        0);    //第一个顶点属性在Buffer中偏移量为0字节
    gl.enableVertexAttribArray(a_Position);    //启用顶点属性数组
    
    
    
    
    
    
    var colorsBufferId = gl.createBuffer();//创建buffer
    gl.bindBuffer(gl.ARRAY_BUFFER,colorsBufferId);//将id为bufferId的buffer绑定为当前Array Buffer
    gl.bufferData(gl.ARRAY_BUFFER,   //Buffer类型
        flatten(colors),    //Buffer数据来源,flatten将vertices转换为GPU可接受的格式
        gl.STATIC_DRAW);    //表明将如何使用Buffer(STATIC_DRAW表明是一次提供数据,多遍绘制)
    
    /*为shader属性变量与buffer数据建立关联*/
    
    //获取名称为"a_Position"的shader attribute变量的位置
    var a_Color = gl.getAttribLocation(program,"a_Color");
    if(a_Color < 0){    //getAttribLocation获取失败则返回-1
        alert("获取attribute变量a_Color失!");
        return;
    }
    //指定利用当前Array Buffer为a_Position提供数据的具体方式
    gl.vertexAttribPointer(a_Color,    //shader attribute变量位置
        3,    //每个顶点属性有2个分量
        gl.FLOAT,    //数组数据类型(浮点型)
        false,    //不进行归一化处理
        0,    //相邻顶点属性地址相差0个字节
        0);    //第一个顶点属性在Buffer中偏移量为0字节
    gl.enableVertexAttribArray(a_Color);    //启用顶点属性数组
    
    
    
    
    
    
    
    render(gl);    //进行绘制
    

};

function render(gl) {
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.POINTS,
        0,
        points.length);
}
  • 写回答

27条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-03-16 21:32
    关注
    获得0.45元问题酬金

    引自免费微信小程序:皆我百晓生

    这段JavaScript代码的目的是在WebGL上下文中绘制Sierpinski垫片,它随机生成一定数量的点,并将这些点存储在缓冲区中,然后通过顶点着色器和片段着色器渲染为点。但是,你没有提到具体想要修改什么效果。假设你想增加点的绘制方式,例如改为线框模式或者三角形填充模式,你可以更改gl.drawArrays()函数中的参数。

    当前代码使用的是点绘制模式(POINTS):

    gl.drawArrays(gl.POINTS, 0, points.length);
    

    如果你想改成交叉线框模式来连接所有的点,可以使用LINES模式,并且需要确保每两个点组成一条线,所以点的数量应是偶数:

    if (points.length % 2 === 0) {
        gl.drawArrays(gl.LINES, 0, points.length / 2);
    } else {
        console.error("无法用线框模式渲染奇数个点");
    }
    

    如果要改成交错线框模式或三角形填充模式,你需要对数据进行重新组织,以便每个三角形由三个连续的顶点定义,然后使用TRIANGLES模式:

    // 假设已经重新组织了points数组以适应三角形模式
    const numTriangles = points.length / 3;
    
    gl.drawArrays(gl.TRIANGLES, 0, numTriangles * 3);
    

    请注意,在实际应用中,可能还需要调整着色器代码以适配新的绘制模式,同时检查并确保颜色缓冲区的设置正确无误。如果你的需求不同,请提供更具体的效果描述,以便我能给出更精确的解决方案。

    评论

报告相同问题?

问题事件

  • 系统已结题 3月24日
  • 创建了问题 3月16日