GLSL着色器的问题
Trouble with GLSL Shader
我正在尝试制作一个基本的 Rim Lighting 着色器,但我认为我做错了什么。
它应该是这样的:
但我得到这个:
这是我的代码:
顶点:
attribute vec3 AE_POSITION;
attribute vec2 AE_TEXCOORD;
attribute vec3 AE_NORMAL;
attribute vec3 AE_TANGENT;
uniform mat4 AE_MVP;
uniform mat4 AE_Model;
varying vec3 AE_WorldPosition;
varying vec3 AE_WorldNormal;
void main() {
AE_WorldPosition = (AE_Model * vec4(AE_POSITION, 1.0)).xyz;
AE_WorldNormal = normalize((AE_Model * vec4(AE_NORMAL, 1.0)).xyz);
gl_Position = AE_MVP * AE_Model * vec4(AE_POSITION, 1.0);
}
片段:
varying vec3 AE_WorldPosition;
varying vec3 AE_WorldNormal;
uniform vec3 AE_EyePos;
void main() {
vec3 v = normalize(AE_EyePos - AE_WorldPosition);
float rim = 1.0 - max(dot(v, AE_WorldNormal), 0.0);
rim = smoothstep(0.6, 1.0, rim);
vec3 finalRim = vec3(1.0, 0.0, 0.0) * vec3(rim);
gl_FragColor = vec4(finalRim, 1.0);
}
如果我做对了,如果 q=dot(camera_direction,surface_normal)
在 0.0
附近,你应该添加红色
不知道为什么当你的例子有白色边缘时不是白色而不是你在整个表面上调制红色
如果这是第二次渲染过程
那么你的图像已经渲染好了,所以要么扔掉边缘碎片,要么添加源图像纹理并合并为碎片,要么使用透明度并合并。
如果这不是多通道渲染
那么:colors,textures,texcoords
,... 表面在哪里?我会尝试像这样的片段:
float q,m=0.3f;
vec4 col; // let this be surface computed color (does not matter for which of above approaches)
vec3 v;
// here compute the col if not multi pass
v=normalize(AE_EyePos - AE_WorldPosition);
q=dot(v, AE_WorldNormal);
q*=q; // enhance rim gradient and also abs can use any even higher power...
if (q<m) // rim size limit
{
q=1.0-(q/m);
col.xyz+=vec3(1.0,0.0,0.0)*q; // use = for multi pass
}
// else discard; // if multi pass
gl_FragColor=col;
我正在尝试制作一个基本的 Rim Lighting 着色器,但我认为我做错了什么。
它应该是这样的:
但我得到这个:
这是我的代码:
顶点:
attribute vec3 AE_POSITION;
attribute vec2 AE_TEXCOORD;
attribute vec3 AE_NORMAL;
attribute vec3 AE_TANGENT;
uniform mat4 AE_MVP;
uniform mat4 AE_Model;
varying vec3 AE_WorldPosition;
varying vec3 AE_WorldNormal;
void main() {
AE_WorldPosition = (AE_Model * vec4(AE_POSITION, 1.0)).xyz;
AE_WorldNormal = normalize((AE_Model * vec4(AE_NORMAL, 1.0)).xyz);
gl_Position = AE_MVP * AE_Model * vec4(AE_POSITION, 1.0);
}
片段:
varying vec3 AE_WorldPosition;
varying vec3 AE_WorldNormal;
uniform vec3 AE_EyePos;
void main() {
vec3 v = normalize(AE_EyePos - AE_WorldPosition);
float rim = 1.0 - max(dot(v, AE_WorldNormal), 0.0);
rim = smoothstep(0.6, 1.0, rim);
vec3 finalRim = vec3(1.0, 0.0, 0.0) * vec3(rim);
gl_FragColor = vec4(finalRim, 1.0);
}
如果我做对了,如果
附近,你应该添加红色q=dot(camera_direction,surface_normal)
在0.0
不知道为什么当你的例子有白色边缘时不是白色而不是你在整个表面上调制红色
如果这是第二次渲染过程
那么你的图像已经渲染好了,所以要么扔掉边缘碎片,要么添加源图像纹理并合并为碎片,要么使用透明度并合并。
如果这不是多通道渲染
那么:
colors,textures,texcoords
,... 表面在哪里?我会尝试像这样的片段:float q,m=0.3f; vec4 col; // let this be surface computed color (does not matter for which of above approaches) vec3 v; // here compute the col if not multi pass v=normalize(AE_EyePos - AE_WorldPosition); q=dot(v, AE_WorldNormal); q*=q; // enhance rim gradient and also abs can use any even higher power... if (q<m) // rim size limit { q=1.0-(q/m); col.xyz+=vec3(1.0,0.0,0.0)*q; // use = for multi pass } // else discard; // if multi pass gl_FragColor=col;