赞
踩
std::uniform_real_distribution<GLfloat> randomFloats(0.0, 1.0); // 均匀的获取0.0到1.0之间的随机数
std::default_random_engine generator;
std::vector<glm::vec3> ssaoKernel;
for (GLuint i = 0; i < N; ++i)
{
glm::vec3 sample( randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) );
sample = glm::normalize(sample);
GLfloat scale = GLfloat(i) / N;
scale = lerp(0.1f, 1.0f, scale * scale);
sample *= scale;//往圆心偏移
ssaoKernel.push_back(sample);
}
GLfloat lerp(GLfloat a, GLfloat b, GLfloat f)
{
return a + f * (b - a);
}
//创建一个4x4朝向切线空间平面法线的随机旋转向量数组
std::vector<glm::vec3> ssaoNoise;
for (GLuint i = 0; i < 16; i++)
{
glm::vec3 noise( random(), random(), 0.0f); //采样核心是沿着正z方向在切线空间内旋转,所以设定z分量为0.0,random()的取值是-1.0到1.0
ssaoNoise.push_back(noise);
}
//ssaoNoise数组创建noiseTexture...
vec3 normal = texture(gNormal, TexCoords).rgb;
vec3 randomVec = texture(texNoise, TexCoords * noiseScale).xyz;
vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));//施密特正交化,由randowVec和normal,求一个与normal垂直的向量
vec3 bitangent = cross(normal, tangent);
mat3 TBN = mat3(tangent, bitangent, normal);
//将采样点转换到摄像机空间,统计遮蔽因子...
float occlusion = 0.0;
for(int i = 0; i < kernelSize; ++i)
{
vec3 samplePos = TBN * samples[i]; //将采样点转换到摄像机空间
samplePos = fragPos + samplePos * radius;
vec4 offset = vec4(samplePos, 1.0);
offset = projection * offset;
offset.xyz /= offset.w;
offset.xyz = offset.xyz * 0.5 + 0.5;
float sampleDepth = texture(gPosition, offset.xy).z;
occlusion += sampleDepth >= samplePos.z ? 1.0 : 0.0;
}
occlusion = 1.0 - (occlusion / kernelSize);
FragColor = occlusion;
uniform sampler2D ssao;
void main()
{
vec2 texelSize = 1.0 / vec2(textureSize(ssaoInput, 0));
float result = 0.0;
for (int x = -2; x < 2; ++x)
{
for (int y = -2; y < 2; ++y)
{
vec2 offset = vec2(float(x), float(y)) * texelSize;
result += texture(ssao, TexCoords + offset).r;
}
}
FragColor = result / (4.0 * 4.0);
}
ssao纹理,他是一个灰度图,灰度图不是说一定得是灰色,而是说他的三个颜色通道的值相同,因此在创建这种纹理时,纹理内部格式设置为只有一个颜色通道,这里设置为GL_RED,所以就得到了下面红色的结果
上面红色的看着不习惯,下面白色的也许会更容易体会啥是AO;白色是因为纹理的内部格式设置为了GL_RGB,在实际应用时不建议这么做
vec3 Diffuse = texture(gAlbedo, TexCoords).rgb;
float AmbientOcclusion = texture(ssao, TexCoords).r;
vec3 ambient = vec3(0.3 * Diffuse * AmbientOcclusion);
vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Diffuse * light.Color;
//...
vec3 specular = light.Color * spec;
//...
float attenuation = 1.0 / (1.0 + light.Linear * distance + light.Quadratic * distance *
distance);//light.Linear线形衰减因子,light.Quadratic二次衰减因子
diffuse *= attenuation;
specular *= attenuation;
lighting += diffuse + specular;
FragColor = vec4(lighting, 1.0);
使用ssao
没有使用ssao
ssao的效果本身就不是很明显,再加上背包的颜色又比较重,在背包上很难看处差别;
在图的右上角,三个面两两相交处,可以看到少许差异
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。