雾化 透明度测试 以及 用户裁剪:Fog AlphaTest & ClipPlane - MartinRGB/GLES30_ProgrammingGuide_NDK GitHub Wiki
雾化
为了避免几何体突现的状况,可以考虑使用雾化:
1.雾化需要两个输入 像素到眼睛的距离(u_eyePos)
以及 雾化颜色(u_fogColor)
。除此之外,还要提供雾化覆盖的最小和最大范围
2.线性雾化因子公式 Factor = (MaxDist - EyeDist)/(MaxDist - MinDist),然后用 Factor 乘以雾化颜色,最后和总体颜色进行线性插值
例:
Vertex:
uniform mat4 u_matViewProjection;
uniform mat4 u_matView;
uniform vec4 u_eyePos;
in vec4 a_vertex;
in vec2 a_texCoord0;
out vec2 v_texCoord;
out float v_eyeDist;
void main( void )
{
// Transform vertex to view-space
vec4 vViewPos = u_matView * a_vertex;
// Compute the distance to eye
v_eyeDist = sqrt( (vViewPos.x - u_eyePos.x) *
(vViewPos.x - u_eyePos.x) +
(vViewPos.y - u_eyePos.y) *
(vViewPos.y - u_eyePos.y) +
(vViewPos.z - u_eyePos.z) *
(vViewPos.z - u_eyePos.z) );
gl_Position = u_matViewProjection * a_vertex;
v_texCoord = a_texCoord0.xy;
}
Fragment:
precision mediump float;
uniform vec4 u_fogColor;
uniform float u_fogMaxDist;
uniform float u_fogMinDist;
uniform sampler2D baseMap;
in vec2 v_texCoord;
in float v_eyeDist;
layout( location = 0 ) out vec4 outColor;
float computeLinearFogFactor()
{
float factor;
// Compute linear fog equation
factor = (u_fogMaxDist - v_eyeDist) /
(u_fogMaxDist - u_fogMinDist );
// Clamp in the [0,1] range
factor = clamp( factor, 0.0, 1.0 );
return factor;
}
void main( void )
{
float fogFactor = computeLinearFogFactor();
vec4 baseColor = texture( baseMap, v_texCoord );
// Compute final color as a lerp with fog factor
outColor = baseColor * fogFactor +
u_fogColor * (1.0 - fogFactor);
}
Alpha 测试
Fragment:
precision mediump float;
uniform sampler2D baseMap;
in vec2 v_texCoord;
layout( location = 0 ) out vec4 outColor;
void main( void )
{
vec4 baseColor = texture( baseMap, v_texCoord );
if( baseColor.a < 0.25 )
{
discard;
}
else
{
outColor = baseColor;
}
}
用户裁剪
Vertex:计算裁剪屏幕到顶点的距离
#version 300
uniform vec4 u_clipPlane;
uniform mat4 u_matViewProjection;
in vec4 a_vertex;
out float v_clipDist;
void main( void )
{
// Compute the distance between the vertex and
// the clip plane
v_clipDist = dot( a_vertex.xyz, u_clipPlane.xyz ) +
u_clipPlane.w;
gl_Position = u_matViewProjection * a_vertex;
}
Fragment: 决定是否要裁剪片段
#version 300
precision mediump float;
in float v_clipDist;
layout( location = 0 ) out vec4 outColor;
void main( void )
{
// Reject fragments behind the clip plane
if( v_clipDist < 0.0 )
discard;
outColor = vec4( 0.5, 0.5, 1.0, 0.0 );
}