使用点精灵的正常定向椭圆形状(表面)

时间:2013-12-14 18:48:42

标签: opengl graphics glsl

我试图用点精灵重现这种效果(给定顶点有位置和法线)。

http://imageshack.com/a/img36/7057/5t7b.jpg

基本上丢弃点精灵的碎片,取决于该点的法线,以产生与点法线相切的椭圆形状(基本上近似于3D圆的正投影到2D椭圆)。

从等式中我发现d = - (nx / nz)* x-(ny / nz)* y,其中如果从点中心到点(x,y,d)的世界空间距离,则丢弃片段)大于磁盘半径(如图像上方的文字所示)。

我正在尝试使用点精灵在我的GLSL顶点和片段着色器中找到正确的方法。

在我的着色器中我正在做这样的事情,这是行不通的:

//vertex shader
#version 400


layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;

out vec3 Color;
flat out vec3 PtPosition;
flat out vec3 PtNormal;
out vec3 FragPosition;

uniform mat4 MVP;
uniform float heightMin;
uniform float heightMax;
uniform bool invertGrad = false;


uniform mat4 MV;
uniform float pointSize;
uniform float viewportDim;


float perspPtSize(vec3 ptPos, mat4 mv, float ptWorldSize, float viewportDim)
{
  vec3 posEye = vec3(mv * vec4(ptPos, 1.0));
  return ptWorldSize * (viewportDim / length(posEye));
}

void main()
{
  Color = vec3(1.0,1.0,1.0);
  PtPosition = vec3(MV * vec4(VertexPosition,1.0));
  FragPosition = PtPosition; 
  PtNormal = vec3(MV * vec4(VertexNormal,1.0));
  gl_Position = MVP * vec4(VertexPosition,1.0);


  gl_PointSize = perspPtSize(VertexPosition.xyz,MV,pointSize,viewportDim);
}


//fragment shader
#version 400

layout( location = 0 ) out vec4 FragColor;

in vec3 Color;
flat in vec3 PtPosition;
flat in vec3 PtNormal;

void main() 
{
  vec2 ptC = gl_PointCoord- vec2(0.5);
  float depth = -PtNormal.x/PtNormal.z*ptC.x - 
                 PtNormal.y/PtNormal.z*ptC.y; 
  float sqrMag = ptC.x*ptC.x + ptC.y*ptC.y + depth*depth; 

  if(sqrMag > 0.25) 
  { discard; } 
  else 
  { fragColor = vec4(color, 1.0); }
}

有没有人成功实现过这样的效果?我尝试在世界空间中这样做但最终得到的结果不正确,我想如果我把它全部留在点精灵表示的空间中它可能会更容易。

我认为我遗漏了一些基本概念,这有什么建议吗?

2 个答案:

答案 0 :(得分:0)

顺便说一下,gl_PointCoord在屏幕空间中,你的法线在视图空间中是(某种)(所以并非所有内容都在“gl_PointCoord表示的空间”中完成。) / p>

我建议您使用普通矩阵(MV的左上角3x3子矩阵的转置反转)来转换法线而不是ModelView矩阵,否则它们将无法正确旋转。如果MV矩阵中存在任何缩放,您还需要在执行此操作后重新规范化法线。

在这方面,如果您打算将法线乘以4x4矩阵,无论出于何种原因,请不要将W坐标设置为 1.0 W = 1.0 用于空间向量(例如 平移 实际上有意义的向量),而法线是定向的;请改用 0.0

答案 1 :(得分:0)

尝试将一个减号更改为加号,如:

float depth = -PtNormal.x/PtNormal.z*ptC.x + PtNormal.y/PtNormal.z*ptC.y;

似乎有一个( - )太多了。希望有所帮助

(我正在读这本书并遇到同样的问题......迟到总比我想的要好;-))