iPad GLSL.如何从片段着色器中获取表面-不是顶点-法线 [英] iPad GLSL. From within a fragment shader how do I get the surface - not vertex - normal

查看:69
本文介绍了iPad GLSL.如何从片段着色器中获取表面-不是顶点-法线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以从片段着色器中访问表面法线-与片段平面相关的法线?还是可以在顶点着色器中完成?

Is it possible to access the surface normal - the normal associated with the plane of a fragment - from within a fragment shader? Or perhaps this can be done in the vertex shader?

当我们沿着着色器管道进行操作时,是否会丢失所有与关联几何相关的知识,或者是否有一些聪明的方法可以在片段着色器的顶点中恢复该信息?

Is all knowledge of the associated geometry lost when we go down the shader pipeline or is there some clever way of recovering that information in either the vertex of fragment shader?

谢谢.

干杯,
道格
推特:@dugla

Cheers,
Doug
twitter: @dugla

推荐答案

表面法线矢量可以近似地通过碎片着色器中视图空间位置的偏导数来计算.偏导数可以通过以下函数获得: dFdxdFdy .为此,需要OpenGL es 3.0或 OES_standard_derivatives 扩展名:

The surface normal vector can be calculated approximately by the partial derivative of the view space position in the frgament shader. The partial derivative can be get by the functions dFdx and dFdy. For this is required OpenGL es 3.0 or the OES_standard_derivatives extension:

in vec3 view_position;

void main()
{
    vec3 normalvector = cross(dFdx(view_position), dFdy(view_position));
    nv = normalize(normalvector * sign(normalvector.z));

    .....
}


通常,可以在几何着色器中计算曲面的法线向量(自OpenGL ES 3.2起). 例如,如果绘制三角形,则将在几何着色器中获得所有三个点. 三个点定义了一个可以从其计算法线向量的平面. 您只需注意点是顺时针还是逆时针排列.


In general it is possible to calculate the normal vector of a surface in a geometry shader (since OpenGL ES 3.2). For example if you draw triangles you get all three points in the geometry shader. Three points define a plane from which the normal vector can be calculated. You just have to be careful if the points are arranged clockwise or counterclockwise.

三角形的法向向量是2个定义的向量的归一化叉积 三角形的角点. 请参阅以下示例,其中包含逆时针三角形:

The normal vector of a triangle is the normalized cross product of 2 vectors defined by the corner points of the triangle. See the folowing example which for counterclockwise triangles:

#version 400

layout (location = 0) in vec3 inPos;

out vec3 vertPos;

uniform mat4 u_projectionMat44;
uniform mat4 u_modelViewMat44;

void main()
{
    vec4 viewPos = u_modelViewMat44 * vec4( inPos, 1.0 );
    vertPos = viewPos.xyz;
    gl_Position = u_projectionMat44 * viewPos;
}

几何着色器

#version 400

layout( triangles ) in;
layout( triangle_strip, max_vertices = 3 ) out;

in vec3 vertPos[];

out vec3 geoPos;
out vec3 geoNV;

void main()
{
    vec3 leg1 = vertPos[1] - vertPos[0];
    vec3 leg2 = vertPos[2] - vertPos[0];
    geoNV = normalize( cross( leg1, leg2 ) ); 

    geoPos = vertPos[0];
    EmitVertex();
    geoPos = vertPos[1];
    EmitVertex();
    geoPos = vertPos[2];
    EmitVertex();
    EndPrimitive();
}

片段着色器

#version 400

in vec3 geoPos;
in vec3 geoNV;

void main()
{
    // ...
}

当然,您也可以在tesselation着色器中计算法线向量(自OpenGL ES 3.2起). 但这仅在您出于其他原因已经需要曲面细分着色器并另外计算时才有意义 面部的法线向量:

Of course you can calculate the normalvector also in the tesselation shaders (since OpenGL ES 3.2). But this makes sense only if you already required tessellation shader for other reasons and additionally calculate the normal vector of the face:

顶点着色器与上面的相同.

The vertex shader is the same as above.

#version 400

layout( vertices=3 ) out;

in  vec3 vertPos[];
out vec3 tctrlPos[];

void main()
{
    tctrlPos[gl_InvocationID] = vertPos[gl_InvocationID];

    if ( gl_InvocationID == 0 )
    {
        gl_TessLevelOuter[0] =  ;
        gl_TessLevelOuter[1] =  ;
        gl_TessLevelOuter[2] =  ;
        gl_TessLevelInner[0] =  ;
    }
}

镶嵌评估着色器

#version 400

layout(triangles, ccw) in;

in vec3 tctrlPos[];

out vec3 tevalPos;
out vec3 tevalNV;

void main()
{
  vec3 leg1 = tctrlPos[1] - tctrlPos[0];
  vec3 leg2 = tctrlPos[2] - tctrlPos[0];
  tevalNV = normalize( cross( leg1, leg2 ) ); 

  tevalPos = tctrlPos[0] * gl_TessCoord.x + tctrlPos[1] * gl_TessCoord.y + tctrlPos[2] * gl_TessCoord.z;
}

Fragmant着色器

#version 400

in vec3 tevalPos;
in vec3 tevalNV;

void main()
{
    // ...
}

这篇关于iPad GLSL.如何从片段着色器中获取表面-不是顶点-法线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆