1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| CCEffect %{ techniques: - name: opaque passes: - vert: pbr-vs:vert frag: pbr-fs:frag properties: &props albedoMap: { value: white } normalMap: { value: normal } metallicMap: { value: white } roughnessMap: { value: white } aoMap: { value: white } emissiveMap: { value: black } albedoFactor: { value: [1, 1, 1, 1], editor: { type: color } } metallicFactor: { value: 1.0, range: [0, 1] } roughnessFactor: { value: 1.0, range: [0, 1] } normalScale: { value: 1.0, range: [0, 2] } aoStrength: { value: 1.0, range: [0, 1] } emissiveFactor: { value: [0, 0, 0, 1], editor: { type: color } } }%
CCProgram pbr-vs %{ #include <surface-vertex> }%
CCProgram pbr-fs %{ #include <surface-fragment> uniform PBRProperties { vec4 albedoFactor; float metallicFactor; float roughnessFactor; float normalScale; float aoStrength; vec4 emissiveFactor; }; uniform sampler2D albedoMap; uniform sampler2D normalMap; uniform sampler2D metallicMap; uniform sampler2D roughnessMap; uniform sampler2D aoMap; uniform sampler2D emissiveMap; float DistributionGGX(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 num = a2; float denom = (NdotH2 * (a2 - 1.0) + 1.0); denom = 3.14159265 * denom * denom; return num / denom; } float GeometrySchlickGGX(float NdotV, float roughness) { float r = (roughness + 1.0); float k = (r * r) / 8.0; float num = NdotV; float denom = NdotV * (1.0 - k) + k; return num / denom; } float GeometrySmith(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); } void surf (in SurfaceIn In, inout SurfaceOut Out) { vec4 albedo = texture(albedoMap, In.uv) * albedoFactor; vec3 normal = normalize(In.worldNormal); float metallic = texture(metallicMap, In.uv).r * metallicFactor; float roughness = texture(roughnessMap, In.uv).r * roughnessFactor; float ao = mix(1.0, texture(aoMap, In.uv).r, aoStrength); vec3 emissive = texture(emissiveMap, In.uv).rgb * emissiveFactor.rgb; #if HAS_NORMAL_MAP vec3 normalMap = texture(normalMap, In.uv).rgb * 2.0 - 1.0; normalMap.xy *= normalScale; normal = normalize(In.worldTangent.xyz * normalMap.x + In.worldBinormal.xyz * normalMap.y + In.worldNormal.xyz * normalMap.z); #endif vec3 viewDir = normalize(cc_cameraPos.xyz - In.worldPos); vec3 lightDir = normalize(-cc_mainLitDir.xyz); vec3 lightColor = cc_mainLitColor.rgb * cc_mainLitColor.a; vec3 H = normalize(viewDir + lightDir); float NdotV = max(dot(normal, viewDir), 0.0); float NdotL = max(dot(normal, lightDir), 0.0); float HdotV = max(dot(H, viewDir), 0.0); float D = DistributionGGX(normal, H, roughness); float G = GeometrySmith(normal, viewDir, lightDir, roughness); vec3 F = fresnelSchlick(HdotV, F0); vec3 kS = F; vec3 kD = vec3(1.0) - kS; kD *= 1.0 - metallic; vec3 numerator = D * G * F; float denominator = 4.0 * NdotV * NdotL + 0.0001; vec3 specular = numerator / denominator; vec3 diffuse = kD * albedo.rgb / PI; vec3 directLighting = (diffuse + specular) * lightColor * NdotL; vec3 ambient = cc_ambientSky.rgb * albedo.rgb * ao * 0.03; Out.albedo = vec4(color, albedo.a); Out.normal = normal; Out.metallic = metallic; Out.roughness = roughness; Out.ao = ao; Out.emissive = emissive; } }%
|