我已经阅读了一些关于Cg的教程,但有一点我不太清楚.顶点和片段着色器之间究竟有什么区别?什么情况比另一种更适合?
我不完全清楚启用顶点属性数组的范围.我有几个不同的着色器程序,它们具有不同数量的顶点属性.是glEnableVertexAttribArray对着色器程序本地调用还是全局调用?
现在我在创建着色器程序时启用顶点属性数组,并且从不禁用它们,并且一切似乎都有效,但似乎我可能应该在绘制调用之前/之后启用/禁用它们.对此有影响吗?
(我正在使用WebGL,所以我们真的在谈论gl.enableVertexAttribArray和gl.disableVertexAttribArray.我还会注意到橙皮书,OpenGL着色语言,对这些调用没有任何信息.)
void main(void)
{
vec4 clipCoord = glModelViewProjectionmatrix * gl_Vertex;
gl_Position = clipCoord;
gl_FrontColor = gl_Color;
vec3 ndc = clipCoord.xyz / clipCoord.w;
Run Code Online (Sandbox Code Playgroud)
所以这clipCoord只是做标准的固定管道转换.为什么我会分开w,我从中得到什么?
我有一些简单的多边形(少于20个顶点)在一个简单的xy平面上渲染平面,使用GL_TRIANGLES和一个平面颜色,一个2d模拟.
我想为这些多边形添加可变厚度和不同颜色的边框.我有一些使用相同顶点和glLineWidth/GL_LINE_LOOP实现的东西,它起作用,但是是另一个渲染过程并重复所有顶点变换.
我想我应该能够使用gl_FragCoord和顶点数据和/或纹理坐标在片段着色器中完成此操作,但我不确定,我的天真尝试显然是不正确的.
我想象下面的东西.
uniform vec2 scale; // viewport h/w
uniform float line_width;
uniform vec4 fill_color;
uniform vec4 border_color;
varying vec4 vertex; // in world coords
void main()
{
if (distance_from_edge(gl_FragCoord, vertex, scale) < line_width)
{
// we're close to the edge the polygon, so we're the border.
gl_FragColor = border_color;
}
else
{
gl_FragColor = fill_color;
}
}
Run Code Online (Sandbox Code Playgroud)
我想弄清楚的部分是distance_from_edge函数 - 如何计算?使用gl_FragCoord是错误的方法 - 我应该使用某种纹理映射吗?
作为一个实验,我尝试用缩放将顶点转换为像素空间,然后以像素为单位计算它与gl_FragCoord之间的距离,但这会产生我并不真正理解的奇怪结果.另外我需要到边缘的距离,而不是顶点,但我不知道如何得到它.
有任何想法吗?
编辑:根据尼科尔的回应,我的问题变成:
假设我有一个三角形,其中3个角顶点标记为边缘顶点,并且中间的一个顶点标记为非边缘(因此总共渲染了3个三角形),那么如何在片段着色器中插值以绘制给定边框厚度?我假设我将边缘标志传递给片段着色器,以及所需的线条粗细,并进行一些插值计算以计算边缘与非边缘顶点之间的距离,并将颜色阈值设置为适当的边界/填充?
我有传递顶点和片段着色器.
顶点着色器
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Run Code Online (Sandbox Code Playgroud)
片段着色器
void main(void)
{
gl_FragColor = gl_Color;
}
Run Code Online (Sandbox Code Playgroud)
那些产生空渲染(黑色不是像glClearBuffer那样的背景颜色).
如果我修改顶点着色器以将gl_FrontColor设置为gl_Color,它会渲染未触及的OpenGl缓冲区...具有传递着色器的预期行为.
void main(void)
{
gl_FrontColor = gl_Color; //Added line
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Run Code Online (Sandbox Code Playgroud)
我很困惑,如何设置顶点着色器中的gl_FrontColor可以更改片段1中gl_Color的值?我错过了什么?
我的片段着色器中有两个不同坐标 和 大小的纹理:
varying highp vec2 v_currentTextureCoords;
varying highp vec2 v_backgroundTextureCoords;
uniform sampler2D u_currentTexture;
uniform sampler2D u_backgroundTexture;
void main()
{
vec4 currentColor = texture2D(u_currentTexture, v_currentTextureCoords);
vec4 backgroundColor = texture2D(u_backgroundTexture, v_backgroundTextureCoords);
gl_FragColor = backgroundColor;
}
Run Code Online (Sandbox Code Playgroud)
这是相应的顶点着色器:
attribute vec4 a_position;
attribute vec2 a_currentTextureCoords;
attribute vec2 a_backgroundTextureCoords;
varying vec2 v_currentTextureCoords;
varying vec2 v_backgroundTextureCoords;
void main()
{
gl_Position = a_position;
v_currentTextureCoords = a_currentTextureCoords;
v_backgroundTextureCoords = a_backgroundTextureCoords;
}
Run Code Online (Sandbox Code Playgroud)
那些着色器负责渲染u_currentTexture.
编辑:用我的真实应用程序(Android应用程序)更新帖子和问题.
如上所述,这两个纹理是:
u_backgroundTexture:这是一个视频流,全屏,大小为1080x1920u_currentTexture:它可以是任何图像,尺寸为469x833(较小但相同比例).为了简化,现在, …
我正在尝试学习如何编写顶点着色器.在Apple的示例项目中,他们有一条线来设置
glUniform1f(uniforms[UNIFORM_TRANSLATE], (Glfloat)transY);
Run Code Online (Sandbox Code Playgroud)
然后使用此值
// value passt in f
// glUniform1f(uniforms[UNIFORM_TRANSLATE](Glfloat)transY);
uniform float translate;
void main()
{
gl_Position.y+=sin( translate);
…
Run Code Online (Sandbox Code Playgroud)
我无法找到所有制服的所有制服的清单.
有没有人知道我在哪里可以找到所有制服的清单和一本关于学习如何编程顶点着色器的好书或教程.
我正在尝试将属性传递给我的顶点着色器但是由于某种原因它在第三个属性位置上给我一个-1我要求openGl通过glGetAttribLocation()来检索.目前它一直给我一个-1的texCoord属性,如果我切换texAttrib和colAttrib(切换代码中的行)它给我一个-1颜色属性而不是纹理,我不明白为什么?由于-1传递给glVertexAttribPointer,我得到1281 OpenGL错误:GL_INVALID_VALUE.
我的顶点着色器:
#version 150
in vec3 position;
in vec3 color;
in vec2 texcoord;
out vec3 Color;
out vec2 Texcoord;
void main()
{
Color = color;
Texcoord = texcoord;
gl_Position = vec4(position.x, position.y, position.z, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
OpenGL代码:
basicShader.Use();
// Buffers and shaders
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
// Make it active vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// Build basic triangle
float vertices[] = {
// position // color // textures
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, …Run Code Online (Sandbox Code Playgroud) 我想从网格红色,蓝色和绿色设置三角形的每个三个顶点.
如本教程的第一部分所示,该教程适用于另一种语言.这是他们用来为网格中每个三角形中的每个椎骨设置红色,绿色和蓝色的代码:
function set_wireframe_colors(m)
local cc = {}
for i = 1, m.size/3 do
table.insert(cc, color(255,0,0))
table.insert(cc, color(0,255,0))
table.insert(cc, color(0,0,255))
end
m.colors = cc
end
Run Code Online (Sandbox Code Playgroud)
这就是使用简单的顶点颜色着色器输出的样子:
我尝试在Unity中使用C#重新创建相同的东西,但我正在努力学习本教程的第一部分.
这是我的代码:
void Start()
{
Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] vertices = mesh.vertices;
//Create new colors array where the colors will be created.
Color32[] colors = new Color32[vertices.Length];
for (int i = 0; i < vertices.Length; i += 3)
{
colors[i] = new Color32(255, 0, 0, 255);
colors[i + 1] …Run Code Online (Sandbox Code Playgroud) 我一直在学习Metal for iOS/OSX,我开始遵循Ray Wenderlich教程(https://www.raywenderlich.com/146414/metal-tutorial-swift-3-part-1-getting-started).本教程工作正常,但没有提及MTLVertexAttributeDescriptors.
现在我正在开发自己的应用程序,我遇到了奇怪的故障,我想知道我不使用MTLVertexAttributeDescriptors的事实是否与问题有关.
他们有什么不同?我已经能够制作各种具有不同顶点结构的着色器,我甚至都不知道这些东西.
我知道你用它们来描述在着色器中使用的顶点组件的布局.例如,着色器可能将此结构用于顶点,并且它将在下面函数的顶点描述符中设置.
typedef struct
{
float3 position [[attribute(T_VertexAttributePosition)]];
float2 texCoord [[attribute(T_VertexAttributeTexcoord)]];
} Vertex;
class func buildMetalVertexDescriptor() -> MTLVertexDescriptor {
let mtlVertexDescriptor = MTLVertexDescriptor()
mtlVertexDescriptor.attributes[T_VertexAttribute.position.rawValue].format = MTLVertexFormat.float3
mtlVertexDescriptor.attributes[T_VertexAttribute.position.rawValue].offset = 0
mtlVertexDescriptor.attributes[T_VertexAttribute.position.rawValue].bufferIndex = T_BufferIndex.meshPositions.rawValue
mtlVertexDescriptor.attributes[T_VertexAttribute.texcoord.rawValue].format = MTLVertexFormat.float2
mtlVertexDescriptor.attributes[T_VertexAttribute.texcoord.rawValue].offset = 0
mtlVertexDescriptor.attributes[T_VertexAttribute.texcoord.rawValue].bufferIndex = T_BufferIndex.meshGenerics.rawValue
mtlVertexDescriptor.layouts[T_BufferIndex.meshPositions.rawValue].stride = 12
mtlVertexDescriptor.layouts[T_BufferIndex.meshPositions.rawValue].stepRate = 1
mtlVertexDescriptor.layouts[T_BufferIndex.meshPositions.rawValue].stepFunction = MTLVertexStepFunction.perVertex
mtlVertexDescriptor.layouts[T_BufferIndex.meshGenerics.rawValue].stride = 8
mtlVertexDescriptor.layouts[T_BufferIndex.meshGenerics.rawValue].stepRate = 1
mtlVertexDescriptor.layouts[T_BufferIndex.meshGenerics.rawValue].stepFunction = MTLVertexStepFunction.perVertex
return mtlVertexDescriptor
}
Run Code Online (Sandbox Code Playgroud)
但即使没有MTLVertexDescriptor设置,着色器也可以访问顶点缓冲区和数组中顶点的位置/ texCoord组件.只需设置顶点缓冲区,着色器就可以访问所有组件.这个描述符有什么好处呢?