Glsl 着色器学校,顶点着色器:可变变量

Glsl 着色器学校,顶点着色器:可变变量,glsl,webgl,fragment-shader,vertex-shader,Glsl,Webgl,Fragment Shader,Vertex Shader,我目前正在学习一点图形编程/glsl使用,效果非常好。但是,我仍停留在关于顶点着色器的第二节课上 要求解决方案的三角形似乎显示了一个充满YUV颜色空间不同颜色的三角形: 我知道可以计算RGB和YUV之间的转换,但是我不太确定顶点或片段着色器中的坐标空间是如何工作的 我的顶点着色器如下所示: precision highp float; attribute vec4 position; attribute vec3 color; varying vec4 fragPosition; void

我目前正在学习一点图形编程/glsl使用,效果非常好。但是,我仍停留在关于顶点着色器的第二节课上

要求解决方案的三角形似乎显示了一个充满YUV颜色空间不同颜色的三角形:

我知道可以计算RGB和YUV之间的转换,但是我不太确定顶点或片段着色器中的坐标空间是如何工作的

我的顶点着色器如下所示:

precision highp float;

attribute vec4 position;
attribute vec3 color;

varying vec4 fragPosition;
void main() {
  gl_Position = position;
  fragPosition = position; // send the position to the fragment shader
}
precision highp float;

varying vec4 fragPosition; // is set by vertex shader

void main() {
  gl_FragColor = fragPosition.rgba;
}
而我的片段着色器如下所示:

precision highp float;

attribute vec4 position;
attribute vec3 color;

varying vec4 fragPosition;
void main() {
  gl_Position = position;
  fragPosition = position; // send the position to the fragment shader
}
precision highp float;

varying vec4 fragPosition; // is set by vertex shader

void main() {
  gl_FragColor = fragPosition.rgba;
}
渲染的三角形如下所示(左侧部分是要解决的问题,右侧部分是到目前为止我的解决方案):


fragPosition.a
连续
1.0
;为什么褪色看起来这么奇怪?三角形内部的坐标空间是如何精确计算的?如果没有断点或打印语句,我就无法理解它,这并不是一件容易的事情。为什么左下角完全是黑色的,为什么没有蓝点?

opengl的默认空间是NDC空间。它是[-1,1]范围内的单位立方体。其中x=-1位于屏幕左侧,x=1位于屏幕右侧,y=-1位于底部,y=+1位于顶部,z=-1位于近平面,z=+1位于远平面

现在在着色器中基本上要做的是将片段坐标显示为颜色

三角形的顶部是绿色的,因为坐标类似于[0,1,0,1],当被解释为颜色时,它会变成绿色。三角形的右边有一个坐标[1,-1,0,1],该坐标为红色。底部可能类似于[0,-1,0,1],为黑色

顺便说一句,我不确定
fragment.a
是否实际为1.0,您可以通过执行
gl\u FragColor=fragPosition.aaaa。如果
.a
为1.0,则只能看到白色,如果
.a
为~0.5,则应为灰色,依此类推


我在这里猜测,我认为您在本课中应该做的是使用颜色输入(
attribute vec3 color;
)并在着色器中实现rgba到yuv的转换。

opengl的默认空间是NDC空间。它是[-1,1]范围内的单位立方体。其中x=-1位于屏幕左侧,x=1位于屏幕右侧,y=-1位于底部,y=+1位于顶部,z=-1位于近平面,z=+1位于远平面

现在在着色器中基本上要做的是将片段坐标显示为颜色

三角形的顶部是绿色的,因为坐标类似于[0,1,0,1],当被解释为颜色时,它会变成绿色。三角形的右边有一个坐标[1,-1,0,1],该坐标为红色。底部可能类似于[0,-1,0,1],为黑色

顺便说一句,我不确定
fragment.a
是否实际为1.0,您可以通过执行
gl\u FragColor=fragPosition.aaaa。如果
.a
为1.0,则只能看到白色,如果
.a
为~0.5,则应为灰色,依此类推


我在这里猜测,我认为您在本课中应该做的是使用颜色输入(
attribute vec3 color;
),并在着色器中实现rgba到yuv的转换。

我在这里看到3种不同的解决方案

首先是在FS(片段着色器)中执行整个计算。例如,这种解决方案适用于后处理,但对性能有很大影响

设计理念: 只通过VS(顶点着色器)传递白色三角形,需要一个属性,并根据位置在FS中执行所有颜色

第二种解决方案是在VS中使用颜色,并使用插值在FS中实现结果。总的来说,这种解决方案是最快的,但并非所有类型的问题都包含简单的插值

设计理念: 需要一个属性和一个变量。将一个三角形的数据从js传递到VS,在VS中建立角点的颜色,并从插值的颜色值中获得FS结果

第三种解决方案是在JS中初始化颜色,将其传递给VS,其中每个角点都有一种颜色,使用插值并从FS获得结果。最后一个解决方案提供了高模块性,并可能允许交互。成本是更长的代码,可能会更慢

设计理念:使用两个属性和一个变量,将positions和colorsYUV传递给VS,然后仅对颜色进行插值,其余结果以FS形式显示

我对上一个解决方案进行了简化编码,因为您可以从中学到最多

//堆栈溢出目的
//初始化画布和webgl
var canvas=document.getElementById(“c”);
var gl=canvas.getContext(“webgl”);
gl.viewportWidth=canvas.width;
gl.viewportHeight=canvas.height;
//创建着色器
var vsSource=`
精密中泵浮子;
属性向量2 a_位置;
属性vec3 a_color_yuv;
可变的vec3颜色;
void main(){
v_color_yuv=a_color_yuv;
gl_位置=vec4(a_位置,0,1.);
}
`;
变量fsSource=`
精密中泵浮子;
不同的vec3颜色是由顶点着色器设置的
void main(){
浮点r=v_color_yuv.x+1.4075*(v_color_yuv.z);
浮点数g=v_color_yuv.x-0.3455*(v_color_yuv.y)-(0.7169*(v_color_yuv.z));
浮动b=v_color_yuv.x+1.7790*(v_color_yuv.y);
gl_FragColor=vec4(r,g,b,1.);
}
`;
var vs=gl.createShader(gl.VERTEX\u着色器);
var fs=gl.createShader(gl.FRAGMENT\u着色器);
//“替换”将从着色器源中删除非SCII角色,因为我使用创建它们http://es6-features.org/#StringInterpolation
gl.shaderSource(vs,vsSource.replace(/[^\x00-\x7F]/g,”);
gl.shaderSource(fs,fsSource.replace(/[^\x00-\x7F]/g,”);
总帐编译主管(vs);
总帐编辑主任(fs);
//创建webgl程序
var shaderProgram=gl.createProgram();
德国劳埃德船级社