在 DirectX 中使用顶点着色器渲染圆
Rendering a circle with a Vertex shader in DirectX
我正在尝试通过在顶点着色器中操纵 texcoord 坐标来绘制一个简单的 2D 圆。这是代码:
float2 uv2 = 2.0 * (TextureCoordinate.xy - 0.5);
float tnm = 1.0 - length(uv2);
在像素着色器中,这会绘制一个圆。顶点着色器中的相同代码将绘制纯白色。如果我玩数字,但没有圆圈,我最多只能得到一些对角线渐变。
顶点着色器内部发生了什么?
PS。我应该澄清一下,我不想创建多边形、三角形或圆形 objects/meshes。我只是将 texcoord 传递给像素着色器并 return 它。在顶点中执行 1-texcoord 会按照像素输出中的预期翻转渐变。我的目标是在程序上生成一些球面法线。
PPS。假设顶点是 [-1,-1] 到 [1,1],我做了:
(uv + 1) * 0.5;
circle code above which expects [0,1]
(result * 2) - 1;
但是没有用。
首先,我建议你深入了解renderpipeline和vertex shaders和pixel shaders的含义。别生我的气,看来你需要对这个话题有更基本的了解。
我将尝试快速概述您的问题:您不会在顶点着色器中获得良好的圆,除非您会高度细分几何体。你需要像素着色器来让你的球体具有法线。
What is going on inside the vertex shader?
这是这里的主要问题:顶点着色器转换给定的几何体,因此可以对其进行光栅化以将像素渲染到屏幕上。光栅化器将获取生成的三角形,并为三角形在屏幕上包围的每个像素生成一个像素。该像素将由像素着色器处理并显示结果颜色。对于每个像素承载的数据,光栅化器对三个角的顶点数据进行插值,因此每个像素都有自己的位置相关数据。
这是你的问题。
如果你用圆数据填充你的顶点,这四个点会在那里映射到圆,并将对它们之间的其他点进行线性插值,但圆不能用这种方式描述为线性。一张小图来说明:
如您所见,四个角的纹理坐标映射到圆坐标。它们位于外面,因此它们的 y 高度将映射为零。现在这四个点被插入到像素着色器中,导致更多的零高度和没有真正的圆。 vertexshader 中的每个插值都以菱形结束,如果你将四边形分割一次,你会得到一个菱形,如果你将它分割得越来越多,它会近似于一个圆,但永远不会是完美的。
因此你需要像素着色器。因此每个像素都得到其插值位置以确定正确的球体法线而不是错误的插值法线。
由于这个问题,大多数现代照明计算都是在像素着色器中进行的。特别是对于镜面照明,获得精细和精确的高光是必不可少的。
我希望我的解释很容易理解:)
我正在尝试通过在顶点着色器中操纵 texcoord 坐标来绘制一个简单的 2D 圆。这是代码:
float2 uv2 = 2.0 * (TextureCoordinate.xy - 0.5);
float tnm = 1.0 - length(uv2);
在像素着色器中,这会绘制一个圆。顶点着色器中的相同代码将绘制纯白色。如果我玩数字,但没有圆圈,我最多只能得到一些对角线渐变。
顶点着色器内部发生了什么?
PS。我应该澄清一下,我不想创建多边形、三角形或圆形 objects/meshes。我只是将 texcoord 传递给像素着色器并 return 它。在顶点中执行 1-texcoord 会按照像素输出中的预期翻转渐变。我的目标是在程序上生成一些球面法线。
PPS。假设顶点是 [-1,-1] 到 [1,1],我做了:
(uv + 1) * 0.5;
circle code above which expects [0,1]
(result * 2) - 1;
但是没有用。
首先,我建议你深入了解renderpipeline和vertex shaders和pixel shaders的含义。别生我的气,看来你需要对这个话题有更基本的了解。
我将尝试快速概述您的问题:您不会在顶点着色器中获得良好的圆,除非您会高度细分几何体。你需要像素着色器来让你的球体具有法线。
What is going on inside the vertex shader?
这是这里的主要问题:顶点着色器转换给定的几何体,因此可以对其进行光栅化以将像素渲染到屏幕上。光栅化器将获取生成的三角形,并为三角形在屏幕上包围的每个像素生成一个像素。该像素将由像素着色器处理并显示结果颜色。对于每个像素承载的数据,光栅化器对三个角的顶点数据进行插值,因此每个像素都有自己的位置相关数据。 这是你的问题。
如果你用圆数据填充你的顶点,这四个点会在那里映射到圆,并将对它们之间的其他点进行线性插值,但圆不能用这种方式描述为线性。一张小图来说明:
如您所见,四个角的纹理坐标映射到圆坐标。它们位于外面,因此它们的 y 高度将映射为零。现在这四个点被插入到像素着色器中,导致更多的零高度和没有真正的圆。 vertexshader 中的每个插值都以菱形结束,如果你将四边形分割一次,你会得到一个菱形,如果你将它分割得越来越多,它会近似于一个圆,但永远不会是完美的。
因此你需要像素着色器。因此每个像素都得到其插值位置以确定正确的球体法线而不是错误的插值法线。
由于这个问题,大多数现代照明计算都是在像素着色器中进行的。特别是对于镜面照明,获得精细和精确的高光是必不可少的。
我希望我的解释很容易理解:)