0

我的顶点着色器具有以下属性:

属性float a_color;

我有一个数组缓冲区(WebAssembly的内存),它只包含0和1,我通过创建一个Uint8阵列。然而,我的顶点着色器忽略了它(没有错误,但似乎将所有内容都视为0)。我正在使用twgl公司。这是我的代码:

顶点着色器:

属性vec2 a_position;属性float a_color;均匀vec2u_resolution;均匀浮点u_point_width;可变vec4 v颜色;vec2 normalize_coords(vec2位置){浮子x=位置[0];浮子y=位置[1];float resx=u_resolution[0];float resy=u_resolution[1];返回vec2(2.0*x/resx-1.0,2.0*y/resy-1.0);}空main(){gl_PointSize=u_point_width;vec2坐标=normalize_coords(a_position);gl_Position=vec4(坐标*vec2(1,-1),0,1);v颜色=vec4(0,a颜色,0,1);}

碎片着色器:

高精度浮点;可变vec4 v颜色;空main(){gl_FragColor=v_color;}

Java脚本:

const canvas=文档.getElementById(“c”);常量单元格大小=10;const gl=canvas.getContext(“webgl”);const programInfo=twgl.createProgramInfo(gl[“顶点着色器”,“碎片阴影”]);twgl.setDefaults({attribPrefix:“a_”});twgl.resizeCanvasToDisplaySize(gl.canvas,window.devicePixelRatio);gl.视口(0,0,gl.canvas.width,gl.cavas.height);const universe=universe.new(数学细胞(gl.canvas.width/CELL_SIZE/2),数学细胞(gl.canvas.height/CELL_SIZE/2));const width=universe.width();const height=universe.height();设点=[];for(设i=0;i<宽度;i++){for(设j=0;j<高度;j++){点push([i*CELL_SIZE*2,j*CELLS_SIZE*2]);}}const cellsPtr=universe.cells();//Web程序集内存(仅0和1)const cells=新Uint8Array(memory.buffer,cellsPtr,width*height);常量数组={位置:{数据:新的Float32Array(points.flat()),大小:2},颜色:{数据:单元格,尺寸:1,类型:gl.UNSIGNED_BYTE}};const bufferInfo=twgl.createBufferInfoFromArrays(gl,数组);const制服={u_resolution:[gl.canvas.width,gl.cavas.height],u_point_width:单元格大小};gl.清除颜色(0,0,0,1);全局清除(全局COLOR_BUFFER_BIT);gl.useProgram(programInfo.program);twgl.setUniforms(programInfo,制服);twgl.setBuffersAndAttributes(gl,programInfo,bufferInfo);twgl.drawBufferInfo(gl,缓冲信息,gl.POINTS);函数renderLoop(时间){twgl.resizeCanvasToDisplaySize(gl.canvas,window.devicePixelRatio);gl.视口(0,0,gl.canvas.width,gl.cavas.height);universe.tick();const cellsPtr=universe.cells();const cells=新Uint8Array(内存缓冲区,单元格Ptr,宽度*高度);const制服={u_resolution:[gl.canvas.width,gl.cavas.height],u_point_width:单元格大小};gl.清除颜色(0,0,0,1);全局清除(全局COLOR_BUFFER_BIT);gl.useProgram(programInfo.program);twgl.setUniforms(programInfo,制服);twgl.setAttribInfoBufferFromArray(gl,缓冲区信息.attribs.a_color{数据:单元格,尺寸:1,类型:gl.UNSIGNED_BYTE}); // 使用新颜色动态更新缓冲区twgl.setBuffersAndAttributes(gl,programInfo,bufferInfo);twgl.drawBufferInfo(gl,缓冲信息,gl.POINTS);请求动画帧(renderLoop);}requestAnimationFrame(renderLoop);};

如果手动转换,我没有问题细胞Float32数组.我做错什么了吗?

下面是上述代码的实时简化版本(屏幕上应该有绿色点,但没有):

https://codesandbox.io/ssilly-jackson-ut3wm

4
  • 尝试gl.vertexAttribPointer(a_color_location,1,gl.UNSIGNED_BYTE,true,0,0);将normalized设置为true,以便对类型进行规范化
    – 盲人67
    评论 2020年3月13日13:40
  • 1
    你需要发布更多代码问题本身.@Blindman67的评论无关紧要,因为你指出你在数组中输入0和1。例子:jsfiddle.net/greggman/sd6pkvqx 评论 2020年3月13日15:52
  • @gman是的,我应该这么做。我修改了我的问题。下面是Codesandbox上的一个简化示例:代码沙盒.io-s/silly-jackson-ut3wm
    – 杰基里
    评论 2020年3月13日16:05
  • 我要补充的是,我尝试将Uint8Array更改为Uint8ClampedArray,它似乎如我所期望的那样工作,但仅在Chrome中,而不是Firefox中
    – 杰基里
    评论 2020年3月13日16:09

2个答案2

重置为默认值
1

如果您实际使用的是twgl,那么它猜测size=3表示位置,4表示颜色,2表示texcoords的方法与twgl猜测使用的问题相同规格化:true你需要告诉它规格化:false

发件人文档

使正常化布尔值---规范化顶点属性指针。默认值为真的如果类型为Int8阵列Uint8阵列否则.

所以,

常量数组={位置:{数据:新的Float32Array(points.flat()),大小:2},颜色:{数据:单元格,尺寸:1,类型:gl.UNSIGNED_BYTE,normalize:false,//已添加<------------------------}};

BTW:如果细胞是一个Uint8阵列那么你不需要类型:gl.UNSIGNED_BYTE.twgl将类型设置为gl.UNSIGNED_BYTE(通用集成电路)基于数据Uint8阵列.

0
0

您正在使用的库不是始终默认的未定义属性。设置归一化的真的沿着某条路Uint8阵列Int8阵列数组类型。

规范化属性缓冲区数据

normalize参数,如果真的在里面WebGLRendering上下文.vertexAttribPointer将在单位范围内规范化整数。对于有符号-1到1,对于无符号0到1。

这将导致颜色属性设置为1/255使用类型数组时Uint8阵列还有dont定义的值归一化的`

可以在顶点着色器中将该值重新缩放为1。

顶点着色器示例

属性浮动颜色;//... 代码可变vec4 colorOut;空main(){// ... 代码colorOut=vec4(0,颜色*255.0,0,1);//将颜色缩放255}

例子

展示如何归一化的更改属性数据。红色表示未规范化,绿色表示。请注意,这不使用任何库。

const GL_OPTIONS={alpha:false,深度:false,预乘alpha:fase,preserveDrawingBufer:true};const CELL_SIZE=10,GRID_SIZE=32,GRID_PX_WIDTH=GRID_SITE*CELL_SIZE,CELLS=GRID_SIZE**2;常量GL_SETUP={get-context(){return canvas.getContext(“webgl”,GL_OPTIONS)},获取位置(){return[“A_pos”,“A_green”,“A _ red”,“U _ res”]},get-vertex(){return`属性vec2 pos;属性浮动绿色;属性浮动红色;均匀vec2 res;可变vec4颜色V;空main(){gl_PointSize=${(CELL_SIZE-2).toFixed(1)};gl_Position=vec4(位置/分辨率,0,1);颜色V=vec4(红色、绿色*255.0、0、1);}`;},get-fragment(){return`高精度浮点;可变vec4颜色V;空main(){gl_FragColor=颜色V;}`;},获取缓冲区(){返回{pos:{buffer:GL_SETUP.grid},红色:{size:1,类型:gl.UNSIGNED_BYTE,规格化:false,缓冲区:gl_SETUP.colorsRed},绿色:{size:1,类型:gl.UNSIGNED_BYTE,规格化:true,缓冲区:gl_SETUP.colorsGreen}};},获取网格(){var i=单元格,buf=新的Float32Array(i*2),idx;同时(i--){idx=i<<1;buf[idx++]=(i%GRID_SIZE)*单元格大小-GRID_PX_WIDTH/2;buf[idx]=(i/GRID_SIZE|0)*CELL_SIZE-GRID_PX_WIDTH/2;}返回buf;},获取colorsRed(){var i=单元格,buf=新Uint8Array(i);while(i--){buf[i]=数学随机数()<0.5&&i<单元格/2?1:0}返回buf;},获取颜色绿色(){var i=单元格,buf=新Uint8Array(i);while(i--){buf[i]=数学随机数()<0.5&&i>=单元格/2?1:0}返回buf;},    };const gl=gl_SETUP.context;const着色器=initShader(gl,gl_SETUP);const W=canvas.width=innerWidth,H=canvas.height=innerHeight;全局视口(0、0、W、H);gl.uniform2fv(shader.locations.res,新的Float32Array([W/2,-H/2]));gl.drawArrays(gl.点,0,单元格);函数compileAndAttach(gl,program,src,type=gl.VERTEX_SHADER){const shader=gl.createShader(类型);gl.shaderSource(着色器,src);gl.compileShader(着色器);gl.attachShader(程序、着色器);}函数createShader(gl,设置){常量位置={},程序=gl.createProgram();compileAndAttach(gl,program,settings.vertex);compileAndAttach(gl,程序,settings.fragment,gl.fragment_SHADER);gl.linkProgram(程序);gl.useProgram(程序);for(设置位置的常量描述){const[类型,名称]=desc.split(“_”);locations[name]=gl[`get${type===“A”?“Attrib”:“Uniform”}位置`](程序,名称);}返回{程序,位置,gl};}函数initShader(gl,settings){const shader=createShader(gl,设置);for(Object.entries(settings.buffers)的const[name,data]){const{use=gl.STATIC_DRAW,type=gl.FLOAT,buffer,size=2,normalize=false}=数据;gl.绑定缓冲区(gl.ARRAY_BUFFER,gl.createBuffer());gl.bufferData(gl.ARRAY_BUFFER,缓冲区,使用);gl.enableVertexAttribArray(shader.locations[name]);gl.vertexAttribPointer(shader.locations[name],大小,类型,规格化,0,0);}返回着色器;}
正文{填充:0px}帆布{位置:绝对;顶部:0px;左:0px;}
<canvas id=“canvas”></canvas>

1
  • 1
    我仍然不确定这个答案与所提问题有什么关系。提问者不想要标准化值。至于图书馆。它做的最常见的事情是对无符号字节数据进行规范化。你称之为反复无常,我称之为方便,这正是图书馆的设计宗旨。 评论 2020年3月14日16:44

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.