Glsl 只给相机前面的脸涂上红色?

Glsl 只给相机前面的脸涂上红色?,glsl,shader,Glsl,Shader,我是GLSL的新手,我一直在努力寻找将旋转立方体的表面涂成红色的方法。我已经在其中一个面上画出了红色,得到了法线x,但我的目标是让立方体在面对摄影机的任何面上画出一个红色的面 片段着色器 #版本330 vec3正常; out vec4 fragColor; vec4色; 在vec4中,顶点颜色; void main(){ vec3 nor=正常化(正常); fragColor=vec4(nor.x,0.0,0.0,1.0); } 顶点着色器 #版本330 均匀mat4矩阵; 一致mat4u_-

我是GLSL的新手,我一直在努力寻找将旋转立方体的表面涂成红色的方法。我已经在其中一个面上画出了红色,得到了法线x,但我的目标是让立方体在面对摄影机的任何面上画出一个红色的面

片段着色器

#版本330
vec3正常;
out vec4 fragColor;
vec4色;
在vec4中,顶点颜色;
void main(){
vec3 nor=正常化(正常);
fragColor=vec4(nor.x,0.0,0.0,1.0);
}
顶点着色器

#版本330
均匀mat4矩阵;
一致mat4u_-vp_矩阵;
vec3 a_位置的布局(位置=0);
vec3 a_normal中的布局(位置=1);
vec3正常;
out vec4 fragColor;
输出vec4顶点颜色;
输出vec4颜色;
void main()
{
正常=正常;
gl_位置=u_vp_矩阵*u_m_矩阵*vec4(a_位置,1.0);
}
我试着用法线和相机的观察方向(0,0,1)来处理点积,但我还没有取得任何成果

这将是理想的效果:


事实上,我确实认为这涉及到一些数学(点积),可能会得到cosTetha并查看向量是否完全垂直,取决于绘制的面是红色还是黑色?

在视图空间中,z轴指向视图端口。当立方体的一侧朝向摄影机时,视图空间中的法向量为(0,0,1)。红色可以从法向量的z分量得到

但是法向量必须从模型空间转换到视图空间(在顶点着色器中)。为此,您必须了解视图矩阵:

mat3 normalMat=逆(转置(mat3(u_v_矩阵*u_m_矩阵));
normal=normalMat*a_normal;
在片段着色器中,红色通道可以从z组件获得:

vec3 nor=normalize(正常);
fragColor=vec4(nor.z,0.0,0.0,1.0);

通过使用
mat3(u\u vp\u矩阵*u\u m\u矩阵)
进行变换,可以在规范化设备空间中近似法向量。这是不准确的,但它也会根据其方向为面着色。在规格化设备空间中,z轴指向视口。e、 g:

顶点着色器:

#版本330
均匀mat4矩阵;
一致mat4u_-vp_矩阵;
vec3 a_位置的布局(位置=0);
vec3 a_normal中的布局(位置=1);
vec3正常;
void main()
{
法线=mat3(u_vp_矩阵*u_m_矩阵)*a_法线;
gl_位置=u_vp_矩阵*u_m_矩阵*vec4(a_位置,1.0);
}
片段着色器:

#版本330
vec3正常;
out vec4 fragColor;
void main(){
vec3 nor=正常化(正常);
fragColor=vec4(-nor.z,0.0,0.0,1.0);
}


如果您只想为面向摄影机的面上色,则必须将面法向量与视图空间z轴之间的角度的余弦与45°的余弦进行比较。将值与边进行比较,并根据结果返回0.0或1.0:

顶点着色器:

mat3 normalMat=逆(转置(mat3(u_v_矩阵*u_m_矩阵));
normal=normalMat*a_normal;
片段着色器:

vec3 nor=normalize(正常);
//浮动红=阶跃(0.707,绝对值(nor,vec3(0.0,0.0,1.0));
浮动红=阶跃(0.707,点(nor,vec3(0.0,0.0,1.0));
fragColor=vec4(红色,0.0,0.0,1.0);

使用step实际上似乎对我不起作用(立方体中没有显示颜色),但在fragColor的第一个分量中使用(-nor.z*-nor.x)几乎达到了我想要的效果。@Ivan如果使用NDC法向量,那么它必须是
step(0.707,点(nor,vec3(0.0,0.0,-1.0))。无论如何,您可以执行
步骤(0.707,abs(dot(nor,vec3(0.0,0.0,1.0))在这两种情况下。都很有魅力,谢谢你,拉比,我从这个答案中学到了很多!:)