将 GLSL 片段着色器降级到尽可能低的版本(至少 GLSL 3.3)
Downgrade GLSL Fragment Shader to lowest version possible (at least GLSL 3.3)
大家好。
我正在尝试制作基于节点的编辑器,用于特定目的。所以我借用了 Unreal Engine 4 Blueprint Editor 使用的正交网格样式作为开始。并为此编写简单的片段着色器。因为我真的不需要来自网格的任何顶点信息,它只是在中心点绘制,我通过鼠标右键移动并将其传递给着色器。出于兼容性原因,我如何将该着色器降级到最低版本,至少降级到 GLSL 3.3?为此,我使用 C# 和 OpenTK。
请帮忙。如果您能提供有关如何使此着色器更高效的任何建议,我将很高兴。
为网格绘制四边形并使用着色器:
GL.UseProgram(BasicProgramID);
GL.Uniform1(0, 16); //x cell size
GL.Uniform1(1, 16); //y cell size
// center point that controlled by mouse, invert y - axis, because shader draw from left bottom, idk why=(
GL.Uniform2(2, CenterPos.X , glControl1.Height - CenterPos.Y);
//prevent screen quad to move by other transformations
GL.MatrixMode(MatrixMode.Modelview);
GL.PushMatrix();
GL.LoadIdentity();
GL.Begin(PrimitiveType.Quads); //sorry for that deprecated method=) that's simplier to test app
GL.Color3(0, 0, 0);
GL.Vertex2(0.0f, 0.0f);
GL.Vertex2(glControl1.Width, 0.0f);
GL.Vertex2(glControl1.Width, glControl1.Height);
GL.Vertex2(0.0f, glControl1.Height);
GL.End();
GL.PopMatrix();
GL.UseProgram(0);
网格片段着色器:
#version 430
layout(location = 0) uniform int grid_dx;
layout(location = 1) uniform int grid_dy;
layout(location = 2) uniform vec2 grid_center;
out vec4 frag_color;
vec4 CenterAxisColor = vec4(0.0, 0.0, 0.0, 1.0);
vec4 BackgroundColor = vec4(0.15, 0.15, 0.15, 1.0);
vec4 InnerLinesColor = vec4(0.2, 0.2, 0.2, 1.0);
vec4 SectionBorderColor = vec4(0.09, 0.09, 0.09, 0.15);
void main() {
if ((int(gl_FragCoord.x) == int(grid_center.x))||(int(gl_FragCoord.y) == int(grid_center.y)))
frag_color = CenterAxisColor;
else if((int(gl_FragCoord.x - grid_center.x) % (grid_dx * 8) == 0)||(int(gl_FragCoord.y - grid_center.y) % (grid_dy * 8) == 0))
frag_color = SectionBorderColor;
else if ((int(gl_FragCoord.x - grid_center.x) % grid_dx == 0)||(int(gl_FragCoord.y - grid_center.y) % grid_dy == 0))
frag_color = InnerLinesColor;
else
frag_color = BackgroundColor;
}
更新
之前的shader版本,错误较多,无法使用zoom和customization。所以我决定把最终版本和评论放在这里。
#version 150
// Shader creates orthorgaphic grid like in Unreal Engine 4 Blueprint Editor.
// You can change parameters to create custom look and don't have problems with copyright.
// I dont provide lines thickness, because I would have to use a more cumbersome method for rendering.
// Even with one pixel size it works very accurate, because of straight lines and integer coordinates.
// You can do with that code what you want. I hope this helps someone.
// set top-left origin for window coordinates and moves the (x, y) value returned by gl_FragCoord of (0.5, 0.5) by default, to (0.0, 0.0)
layout (origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord;
// out pixel color. Set current pixel color for every shader call.
out vec4 frag_color;
// position of grid center. Used to pan grid. Just pass mouse position, when right mouse button pressed, for example.
uniform vec2 grid_center;
// smallest cell size. Used to set grid zoom. By default in UE4 16px, with zoom changes to 14, 12, 10 etc.
uniform ivec2 cell_size = ivec2(16, 16);
// you can also pass parameters in shader presented below just add "uniform"
// count of cells in section.
ivec2 cell_count = ivec2(8, 8);
// all colors. By default like in UE4 Blueprint Editor
vec4 BackgroundColor = vec4(0.15, 0.15, 0.15, 1.0);
vec4 CenterAxisColor = vec4(0.0, 0.0, 0.0, 1.0);
vec4 InnerLinesColor = vec4(0.2, 0.2, 0.2, 1.0);
vec4 SectionBorderColor = vec4(0.09, 0.09, 0.09, 0.15);
void main() {
frag_color = BackgroundColor; // set back color first and check other situations
// check if that grid center?
if ((gl_FragCoord.x == grid_center.x)||(gl_FragCoord.y == grid_center.y))
{
frag_color = CenterAxisColor;
}
else
{
//upper-right sections
if ((gl_FragCoord.x >= grid_center.x) && (gl_FragCoord.y <= grid_center.y)) // that pixel in correct part, relative to the center?
if(((int(gl_FragCoord.x - grid_center.x) % (cell_size.x * cell_count.x)) == 0)|| ((int(grid_center.y - gl_FragCoord.y) % (cell_size.y * cell_count.y)) == 0)) // that pixel lay on section border?
frag_color = SectionBorderColor;
else if(((int(gl_FragCoord.x - grid_center.x) % cell_size.x) == 0)|| ((int(grid_center.y - gl_FragCoord.y) % cell_size.y) == 0)) // that pixel lay on section divider-line?
frag_color = InnerLinesColor;
//bottom-right sections
if ((gl_FragCoord.x >= grid_center.x) && (gl_FragCoord.y >= grid_center.y)) // etc...
if(((int(gl_FragCoord.x - grid_center.x) % (cell_size.x * cell_count.x)) == 0)|| ((int(gl_FragCoord.y - grid_center.y) % (cell_size.y * cell_count.y)) == 0))
frag_color = SectionBorderColor;
else if(((int(gl_FragCoord.x - grid_center.x) % cell_size.x) == 0)|| ((int(gl_FragCoord.y - grid_center.y) % cell_size.y) == 0))
frag_color = InnerLinesColor;
//bottom-left sections
if ((gl_FragCoord.x <= grid_center.x) && (gl_FragCoord.y >= grid_center.y))
if(((int(grid_center.x - gl_FragCoord.x) % (cell_size.x * cell_count.x)) == 0)|| ((int(gl_FragCoord.y - grid_center.y) % (cell_size.y * cell_count.y)) == 0))
frag_color = SectionBorderColor;
else if(((int(grid_center.x - gl_FragCoord.x) % cell_size.x) == 0)|| ((int(gl_FragCoord.y - grid_center.y) % cell_size.y) == 0))
frag_color = InnerLinesColor;
//upper-left sections
if ((gl_FragCoord.x <= grid_center.x) && (gl_FragCoord.y <= grid_center.y))
if(((int(grid_center.x - gl_FragCoord.x) % (cell_size.x * cell_count.x)) == 0)|| ((int(grid_center.y - gl_FragCoord.y) % (cell_size.y * cell_count.y)) == 0))
frag_color = SectionBorderColor;
else if(((int(grid_center.x - gl_FragCoord.x) % cell_size.x) == 0)|| ((int(grid_center.y - gl_FragCoord.y) % cell_size.y) == 0))
frag_color = InnerLinesColor;
}
}
Shader work screenshot
如果你想使用GL.Begin
/Gl.End
序列,那么你必须使用GLSL 1.20 vertex shader and the built in Vertex Attributes gl_Vertex
, gl_Normal
, gl_Color
和 gl_MultiTexCoord0
.
无论如何OpenGL Shading Language 3.30 does not support location Layout Qualifier for uniform variables (except by enabling the extension GL_ARB_explicit_uniform_location
)。
您必须删除布局位置 (layout(location = 0)
)。程序链接后GL.GetUniformLocation
获取uniform变量的位置
#version 330
uniform int grid_dx;
uniform int grid_dy;
uniform vec2 grid_center;
out vec4 frag_color;
vec4 CenterAxisColor = vec4(0.0, 0.0, 0.0, 1.0);
vec4 BackgroundColor = vec4(0.15, 0.15, 0.15, 1.0);
vec4 InnerLinesColor = vec4(0.2, 0.2, 0.2, 1.0);
vec4 SectionBorderColor = vec4(0.09, 0.09, 0.09, 0.15);
void main() {
if ((int(gl_FragCoord.x) == int(grid_center.x))||(int(gl_FragCoord.y) == int(grid_center.y)))
frag_color = CenterAxisColor;
else if((int(gl_FragCoord.x - grid_center.x) % (grid_dx * 8) == 0)||(int(gl_FragCoord.y - grid_center.y) % (grid_dy * 8) == 0))
frag_color = SectionBorderColor;
else if ((int(gl_FragCoord.x - grid_center.x) % grid_dx == 0)||(int(gl_FragCoord.y - grid_center.y) % grid_dy == 0))
frag_color = InnerLinesColor;
else
frag_color = BackgroundColor;
}
大家好。
我正在尝试制作基于节点的编辑器,用于特定目的。所以我借用了 Unreal Engine 4 Blueprint Editor 使用的正交网格样式作为开始。并为此编写简单的片段着色器。因为我真的不需要来自网格的任何顶点信息,它只是在中心点绘制,我通过鼠标右键移动并将其传递给着色器。出于兼容性原因,我如何将该着色器降级到最低版本,至少降级到 GLSL 3.3?为此,我使用 C# 和 OpenTK。
请帮忙。如果您能提供有关如何使此着色器更高效的任何建议,我将很高兴。
为网格绘制四边形并使用着色器:
GL.UseProgram(BasicProgramID);
GL.Uniform1(0, 16); //x cell size
GL.Uniform1(1, 16); //y cell size
// center point that controlled by mouse, invert y - axis, because shader draw from left bottom, idk why=(
GL.Uniform2(2, CenterPos.X , glControl1.Height - CenterPos.Y);
//prevent screen quad to move by other transformations
GL.MatrixMode(MatrixMode.Modelview);
GL.PushMatrix();
GL.LoadIdentity();
GL.Begin(PrimitiveType.Quads); //sorry for that deprecated method=) that's simplier to test app
GL.Color3(0, 0, 0);
GL.Vertex2(0.0f, 0.0f);
GL.Vertex2(glControl1.Width, 0.0f);
GL.Vertex2(glControl1.Width, glControl1.Height);
GL.Vertex2(0.0f, glControl1.Height);
GL.End();
GL.PopMatrix();
GL.UseProgram(0);
网格片段着色器:
#version 430
layout(location = 0) uniform int grid_dx;
layout(location = 1) uniform int grid_dy;
layout(location = 2) uniform vec2 grid_center;
out vec4 frag_color;
vec4 CenterAxisColor = vec4(0.0, 0.0, 0.0, 1.0);
vec4 BackgroundColor = vec4(0.15, 0.15, 0.15, 1.0);
vec4 InnerLinesColor = vec4(0.2, 0.2, 0.2, 1.0);
vec4 SectionBorderColor = vec4(0.09, 0.09, 0.09, 0.15);
void main() {
if ((int(gl_FragCoord.x) == int(grid_center.x))||(int(gl_FragCoord.y) == int(grid_center.y)))
frag_color = CenterAxisColor;
else if((int(gl_FragCoord.x - grid_center.x) % (grid_dx * 8) == 0)||(int(gl_FragCoord.y - grid_center.y) % (grid_dy * 8) == 0))
frag_color = SectionBorderColor;
else if ((int(gl_FragCoord.x - grid_center.x) % grid_dx == 0)||(int(gl_FragCoord.y - grid_center.y) % grid_dy == 0))
frag_color = InnerLinesColor;
else
frag_color = BackgroundColor;
}
更新
之前的shader版本,错误较多,无法使用zoom和customization。所以我决定把最终版本和评论放在这里。
#version 150
// Shader creates orthorgaphic grid like in Unreal Engine 4 Blueprint Editor.
// You can change parameters to create custom look and don't have problems with copyright.
// I dont provide lines thickness, because I would have to use a more cumbersome method for rendering.
// Even with one pixel size it works very accurate, because of straight lines and integer coordinates.
// You can do with that code what you want. I hope this helps someone.
// set top-left origin for window coordinates and moves the (x, y) value returned by gl_FragCoord of (0.5, 0.5) by default, to (0.0, 0.0)
layout (origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord;
// out pixel color. Set current pixel color for every shader call.
out vec4 frag_color;
// position of grid center. Used to pan grid. Just pass mouse position, when right mouse button pressed, for example.
uniform vec2 grid_center;
// smallest cell size. Used to set grid zoom. By default in UE4 16px, with zoom changes to 14, 12, 10 etc.
uniform ivec2 cell_size = ivec2(16, 16);
// you can also pass parameters in shader presented below just add "uniform"
// count of cells in section.
ivec2 cell_count = ivec2(8, 8);
// all colors. By default like in UE4 Blueprint Editor
vec4 BackgroundColor = vec4(0.15, 0.15, 0.15, 1.0);
vec4 CenterAxisColor = vec4(0.0, 0.0, 0.0, 1.0);
vec4 InnerLinesColor = vec4(0.2, 0.2, 0.2, 1.0);
vec4 SectionBorderColor = vec4(0.09, 0.09, 0.09, 0.15);
void main() {
frag_color = BackgroundColor; // set back color first and check other situations
// check if that grid center?
if ((gl_FragCoord.x == grid_center.x)||(gl_FragCoord.y == grid_center.y))
{
frag_color = CenterAxisColor;
}
else
{
//upper-right sections
if ((gl_FragCoord.x >= grid_center.x) && (gl_FragCoord.y <= grid_center.y)) // that pixel in correct part, relative to the center?
if(((int(gl_FragCoord.x - grid_center.x) % (cell_size.x * cell_count.x)) == 0)|| ((int(grid_center.y - gl_FragCoord.y) % (cell_size.y * cell_count.y)) == 0)) // that pixel lay on section border?
frag_color = SectionBorderColor;
else if(((int(gl_FragCoord.x - grid_center.x) % cell_size.x) == 0)|| ((int(grid_center.y - gl_FragCoord.y) % cell_size.y) == 0)) // that pixel lay on section divider-line?
frag_color = InnerLinesColor;
//bottom-right sections
if ((gl_FragCoord.x >= grid_center.x) && (gl_FragCoord.y >= grid_center.y)) // etc...
if(((int(gl_FragCoord.x - grid_center.x) % (cell_size.x * cell_count.x)) == 0)|| ((int(gl_FragCoord.y - grid_center.y) % (cell_size.y * cell_count.y)) == 0))
frag_color = SectionBorderColor;
else if(((int(gl_FragCoord.x - grid_center.x) % cell_size.x) == 0)|| ((int(gl_FragCoord.y - grid_center.y) % cell_size.y) == 0))
frag_color = InnerLinesColor;
//bottom-left sections
if ((gl_FragCoord.x <= grid_center.x) && (gl_FragCoord.y >= grid_center.y))
if(((int(grid_center.x - gl_FragCoord.x) % (cell_size.x * cell_count.x)) == 0)|| ((int(gl_FragCoord.y - grid_center.y) % (cell_size.y * cell_count.y)) == 0))
frag_color = SectionBorderColor;
else if(((int(grid_center.x - gl_FragCoord.x) % cell_size.x) == 0)|| ((int(gl_FragCoord.y - grid_center.y) % cell_size.y) == 0))
frag_color = InnerLinesColor;
//upper-left sections
if ((gl_FragCoord.x <= grid_center.x) && (gl_FragCoord.y <= grid_center.y))
if(((int(grid_center.x - gl_FragCoord.x) % (cell_size.x * cell_count.x)) == 0)|| ((int(grid_center.y - gl_FragCoord.y) % (cell_size.y * cell_count.y)) == 0))
frag_color = SectionBorderColor;
else if(((int(grid_center.x - gl_FragCoord.x) % cell_size.x) == 0)|| ((int(grid_center.y - gl_FragCoord.y) % cell_size.y) == 0))
frag_color = InnerLinesColor;
}
}
Shader work screenshot
如果你想使用GL.Begin
/Gl.End
序列,那么你必须使用GLSL 1.20 vertex shader and the built in Vertex Attributes gl_Vertex
, gl_Normal
, gl_Color
和 gl_MultiTexCoord0
.
无论如何OpenGL Shading Language 3.30 does not support location Layout Qualifier for uniform variables (except by enabling the extension GL_ARB_explicit_uniform_location
)。
您必须删除布局位置 ()。程序链接后layout(location = 0)
GL.GetUniformLocation
获取uniform变量的位置
#version 330
uniform int grid_dx;
uniform int grid_dy;
uniform vec2 grid_center;
out vec4 frag_color;
vec4 CenterAxisColor = vec4(0.0, 0.0, 0.0, 1.0);
vec4 BackgroundColor = vec4(0.15, 0.15, 0.15, 1.0);
vec4 InnerLinesColor = vec4(0.2, 0.2, 0.2, 1.0);
vec4 SectionBorderColor = vec4(0.09, 0.09, 0.09, 0.15);
void main() {
if ((int(gl_FragCoord.x) == int(grid_center.x))||(int(gl_FragCoord.y) == int(grid_center.y)))
frag_color = CenterAxisColor;
else if((int(gl_FragCoord.x - grid_center.x) % (grid_dx * 8) == 0)||(int(gl_FragCoord.y - grid_center.y) % (grid_dy * 8) == 0))
frag_color = SectionBorderColor;
else if ((int(gl_FragCoord.x - grid_center.x) % grid_dx == 0)||(int(gl_FragCoord.y - grid_center.y) % grid_dy == 0))
frag_color = InnerLinesColor;
else
frag_color = BackgroundColor;
}