#version430 corelayout(location =0) in vec3 aPos;layout(location =1) in vec3 aNormal;layout(location =2) in vec2 aTexCoords;layout(location =3) in vec3 Tangent;layout(location =4) in vec3 Bitangent;layout(location =5) in ivec4 BoneIDs;layout(location =6) in vec4 Weights;
out vec2 TexCoords;
out vec3 WorldPos;
out vec3 Normal;layout(std140 , binding =0) uniform PV
{
mat4 projection;
mat4 view;};
uniform mat4 model;constint MAX_BONES =100;// Max number of bones
uniform mat4 gBones[MAX_BONES];// Bone transformations voidmain(){
mat4 BoneTransform = gBones[ BoneIDs[0]]* Weights[0];
BoneTransform += gBones[ BoneIDs[1]]* Weights[1];
BoneTransform += gBones[ BoneIDs[2]]* Weights[2];
BoneTransform += gBones[ BoneIDs[3]]* Weights[3];// Transformed vertex position
vec4 tPos = BoneTransform *vec4(aPos,1.0);
TexCoords = aTexCoords;
WorldPos =vec3(model * tPos);
Normal =mat3(model)* aNormal;//gl_Position = projection * view * vec4(WorldPos, 1.0);
gl_Position = projection * view * model * tPos;}-----------------------#version430 corelayout(location =0) out vec3 gPosition;layout(location =1) out vec4 gAlbedoMap;layout(location =2) out vec3 gSpecularMap;layout(location =3) out vec3 gNormalMap;layout(location =4) out vec4 gHeightAoMetallicRoughnessMap;
in vec2 TexCoords;
in vec3 WorldPos;
in vec3 Normal;// material parameters
uniform sampler2D albedoMap;
uniform sampler2D specularMap;
uniform sampler2D normalMap;
uniform sampler2D heightMap;
uniform sampler2D aoMap;
uniform sampler2D metallicMap;
uniform sampler2D roughnessMap;
uniform float use_albedoMap;
uniform float use_specularMap;
uniform float use_normalMap;
uniform float use_heightMap;
uniform float use_aoMap;
uniform float use_metallicMap;
uniform float use_roughnessMap;voidmain(){
gPosition = WorldPos;
gAlbedoMap =vec4(texture(albedoMap, TexCoords).rgb ,1.0f);
gNormalMap =(1.0- use_normalMap)* Normal + use_normalMap *(texture(normalMap, TexCoords).rgb);
gSpecularMap =(1.0- use_specularMap)*vec3(0.8f,0.8f,0.8f)+ use_specularMap *(texture(specularMap, TexCoords).rgb);float height =(1.0- use_heightMap)*0.5f+ use_heightMap *texture(heightMap, TexCoords).r;float metallic =(1.0- use_metallicMap)*0.3f+ use_metallicMap *texture(metallicMap, TexCoords).r;float roughness =(1.0- use_roughnessMap)*0.2f+ use_roughnessMap *texture(roughnessMap, TexCoords).r;float ao =(1.0- use_albedoMap)*0.2f+ use_albedoMap *texture(aoMap, TexCoords).r;
gHeightAoMetallicRoughnessMap =vec4(height ,ao ,metallic ,roughness);}
最后是G缓冲的shader
#version430 corelayout(location =0) in vec3 aPos;layout(location =1) in vec2 aTexCoords;
out vec2 TexCoords;voidmain(){
TexCoords = aTexCoords;
gl_Position =vec4(aPos,1.0);}--------------------------#version 430 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D gPosition;
uniform sampler2D gAlbedoMap;
uniform sampler2D gSpecularMap;
uniform sampler2D gNormalMap;
uniform sampler2D gHeightAoMetallicRoughnessMap;layout(std140 , binding =1) uniform BaseLight
{
vec4 lightDir;
vec4 color;
vec4 ambient;};layout(std140 , binding =2) uniform BaseView
{
vec3 viewPos;};// lightsconstfloat PI =3.14159265359;// ----------------------------------------------------------------------------// Easy trick to get tangent-normals to world-space to keep PBR code simplified.// Don't worry if you don't get what's going on; you generally want to do normal // mapping the usual way for performance anways; I do plan make a note of this // technique somewhere later in the normal mapping tutorial.
vec3 getNormalFromMap(){
vec3 tangentNormal =texture(gNormalMap, TexCoords).xyz *2.0-1.0;
vec3 Q1 =dFdx(texture(gPosition, TexCoords).rgb);
vec3 Q2 =dFdy(texture(gPosition, TexCoords).rgb);
vec2 st1 =dFdx(TexCoords);
vec2 st2 =dFdy(TexCoords);
vec3 N =normalize(texture(gNormalMap, TexCoords).rgb);
vec3 T =normalize(Q1*st2.t - Q2*st1.t);
vec3 B =-normalize(cross(N, T));
mat3 TBN =mat3(T, B, N);returnnormalize(TBN * tangentNormal);}// ----------------------------------------------------------------------------floatDistributionGGX(vec3 N, vec3 H,float roughness){float a = roughness*roughness;float a2 = a*a;float NdotH =max(dot(N, H),0.0);float NdotH2 = NdotH*NdotH;float nom = a2;float denom =(NdotH2 *(a2 -1.0)+1.0);
denom = PI * denom * denom;return nom / denom;}// ----------------------------------------------------------------------------floatGeometrySchlickGGX(float NdotV,float roughness){float r =(roughness +1.0);float k =(r*r)/8.0;float nom = NdotV;float denom = NdotV *(1.0- k)+ k;return nom / denom;}// ----------------------------------------------------------------------------floatGeometrySmith(vec3 N, vec3 V, vec3 L,float roughness){float NdotV =max(dot(N, V),0.0);float NdotL =max(dot(N, L),0.0);float ggx2 =GeometrySchlickGGX(NdotV, roughness);float ggx1 =GeometrySchlickGGX(NdotL, roughness);return ggx1 * ggx2;}// ----------------------------------------------------------------------------
vec3 fresnelSchlick(float cosTheta, vec3 F0){return F0 +(1.0- F0)*pow(clamp(1.0- cosTheta,0.0,1.0),5.0);}// ----------------------------------------------------------------------------voidmain(){
vec3 albedo =pow(texture(gAlbedoMap, TexCoords).rgb,vec3(2.2));float metallic =texture(gHeightAoMetallicRoughnessMap, TexCoords).b;float roughness =texture(gHeightAoMetallicRoughnessMap, TexCoords).a;float ao =texture(gHeightAoMetallicRoughnessMap, TexCoords).g;
vec3 WorldPos =texture(gPosition, TexCoords).rgb;
vec3 N =getNormalFromMap();
vec3 V =normalize(viewPos - WorldPos);// calculate reflectance at normal incidence; if dia-electric (like plastic) use F0 // of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
vec3 F0 =vec3(0.04);
F0 =mix(F0, albedo, metallic);// reflectance equation
vec3 Lo =vec3(0.0);
vec3 L =normalize(-lightDir.xyz);
vec3 H =normalize(V + L);//float distance = length(lightPositions[i] - WorldPos);//float attenuation = 1.0 / (distance * distance);float attenuation =1.0;
vec3 radiance = color.xyz * attenuation;// Cook-Torrance BRDFfloat NDF =DistributionGGX(N, H, roughness);float G =GeometrySmith(N, V, L, roughness);
vec3 F =fresnelSchlick(max(dot(H, V),0.0), F0);
vec3 numerator = NDF * G * F;float denominator =4*max(dot(N, V),0.0)*max(dot(N, L),0.0)+0.0001;// + 0.0001 to prevent divide by zero
vec3 specular = numerator / denominator;// kS is equal to Fresnel
vec3 kS = F;// for energy conservation, the diffuse and specular light can't// be above 1.0 (unless the surface emits light); to preserve this// relationship the diffuse component (kD) should equal 1.0 - kS.
vec3 kD =vec3(1.0)- kS;// multiply kD by the inverse metalness such that only non-metals // have diffuse lighting, or a linear blend if partly metal (pure metals// have no diffuse light).
kD *=1.0- metallic;// scale light by NdotLfloat NdotL =max(dot(N, L),0.0);// add to outgoing radiance Lo
Lo +=(kD * albedo / PI + specular)* radiance * NdotL;// note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again // ambient lighting (note that the next IBL tutorial will replace // this ambient lighting with environment lighting).
vec3 ambient2 = ambient.xyz * albedo * ao;
vec3 color2 = ambient2 + Lo;// HDR tonemapping
color2 = color2 /(color2 +vec3(1.0));// gamma correct
color2 =pow(color2,vec3(1.0/2.2));
FragColor =vec4(color2,1.0);}--