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 142 143 144 145 146 147 148 149 150 151 152 153 154 155
| // G-Buffer Pass (几何阶段) CCProgram gbuffer-vs %{ precision highp float; in vec3 a_position; in vec3 a_normal; in vec2 a_texCoord; in vec4 a_tangent; out vec3 v_worldPos; out vec3 v_normal; out vec2 v_uv; out vec3 v_tangent; out vec3 v_bitangent; uniform CCGlobal { mat4 cc_matViewProj; }; uniform CCLocal { mat4 cc_matWorld; mat4 cc_matWorldIT; }; void vert() { vec4 worldPos = cc_matWorld * vec4(a_position, 1.0); v_worldPos = worldPos.xyz; v_normal = normalize((cc_matWorldIT * vec4(a_normal, 0.0)).xyz); v_tangent = normalize((cc_matWorld * vec4(a_tangent.xyz, 0.0)).xyz); v_bitangent = cross(v_normal, v_tangent) * a_tangent.w; v_uv = a_texCoord; gl_Position = cc_matViewProj * worldPos; } }%
CCProgram gbuffer-fs %{ precision highp float; in vec3 v_worldPos; in vec3 v_normal; in vec2 v_uv; in vec3 v_tangent; in vec3 v_bitangent; // 多个渲染目标 (MRT) layout(location = 0) out vec4 gBuffer0; // rgb: albedo, a: metallic layout(location = 1) out vec4 gBuffer1; // rgb: normal, a: roughness layout(location = 2) out vec4 gBuffer2; // rgb: emission, a: ao layout(location = 3) out vec4 gBuffer3; // rgba: velocity/motion vector uniform sampler2D albedoTexture; uniform sampler2D normalTexture; uniform sampler2D pbrTexture; // r: metallic, g: roughness, b: ao uniform sampler2D emissionTexture; void frag() { // 采样纹理 vec4 albedo = texture(albedoTexture, v_uv); vec3 normalMap = texture(normalTexture, v_uv).xyz * 2.0 - 1.0; vec3 pbrData = texture(pbrTexture, v_uv).rgb; vec3 emission = texture(emissionTexture, v_uv).rgb; // 计算世界空间法线 mat3 TBN = mat3(v_tangent, v_bitangent, v_normal); vec3 worldNormal = normalize(TBN * normalMap); // 编码法线到[0,1]范围 vec3 encodedNormal = worldNormal * 0.5 + 0.5; // 填充G-Buffer gBuffer0 = vec4(albedo.rgb, pbrData.r); // albedo + metallic gBuffer1 = vec4(encodedNormal, pbrData.g); // normal + roughness gBuffer2 = vec4(emission, pbrData.b); // emission + ao gBuffer3 = vec4(0, 0, 0, 1); // motion vector (这里暂时�?) } }%
// 光照Pass (着色阶�? CCProgram lighting-vs %{ precision highp float; in vec2 a_position; // 全屏四边�? out vec2 v_uv; void vert() { v_uv = a_position * 0.5 + 0.5; gl_Position = vec4(a_position, 0.0, 1.0); } }%
CCProgram lighting-fs %{ precision highp float; in vec2 v_uv; layout(location = 0) out vec4 fragColor; // G-Buffer纹理 uniform sampler2D gBuffer0; uniform sampler2D gBuffer1; uniform sampler2D gBuffer2; uniform sampler2D depthTexture; // 光照数据 uniform CCForwardLight { vec4 cc_mainLitDir; vec4 cc_mainLitColor; vec4 cc_ambientSky; }; uniform CCGlobal { mat4 cc_matViewInv; mat4 cc_matProjInv; vec4 cc_cameraPos; }; // 从深度重构世界位�? vec3 reconstructWorldPos(vec2 uv, float depth) { vec4 clipPos = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0); vec4 viewPos = cc_matProjInv * clipPos; viewPos /= viewPos.w; vec4 worldPos = cc_matViewInv * viewPos; return worldPos.xyz; } void frag() { // 采样G-Buffer vec4 gb0 = texture(gBuffer0, v_uv); vec4 gb1 = texture(gBuffer1, v_uv); vec4 gb2 = texture(gBuffer2, v_uv); float depth = texture(depthTexture, v_uv).r; // 解析材质数据 vec3 albedo = gb0.rgb; float metallic = gb0.a; vec3 normal = gb1.rgb * 2.0 - 1.0; float roughness = gb1.a; vec3 emission = gb2.rgb; float ao = gb2.a; // 重构世界位置 vec3 worldPos = reconstructWorldPos(v_uv, depth); vec3 viewDir = normalize(cc_cameraPos.xyz - worldPos); // 执行PBR光照计算 vec3 lightDir = normalize(-cc_mainLitDir.xyz); vec3 lighting = calculatePBRLighting(albedo, normal, viewDir, lightDir, metallic, roughness); // 添加环境光和自发�? vec3 finalColor = lighting + cc_ambientSky.rgb * albedo * ao + emission; fragColor = vec4(finalColor, 1.0); } }%
|