now using deferred rendering instead of forward rendering; some little problem: grid not render, shadow not impl
This commit is contained in:
@ -1164,7 +1164,7 @@ namespace Prism
|
||||
UpdateWindowTitle("Untitled Scene");
|
||||
m_SceneFilePath = std::string();
|
||||
|
||||
m_EditorCamera = EditorCamera(glm::perspectiveFov(glm::radians(45.0f), 1280.0f, 720.0f, 0.1f, 1000.0f));
|
||||
m_EditorCamera = EditorCamera(glm::perspectiveFov(glm::radians(45.0f), 1280.0f, 720.0f, 0.1f, 100.0f));
|
||||
m_SelectionContext.clear();
|
||||
}
|
||||
|
||||
|
||||
@ -24,16 +24,16 @@ uniform sampler2D u_Texture;
|
||||
uniform bool u_Horizontal; // 未使用,可保留或移除
|
||||
uniform bool u_FirstPass; // 是否进行阈值处理
|
||||
uniform float u_Threshold; // 亮度阈值
|
||||
uniform int u_Quality;
|
||||
uniform float u_Directions; // 模糊方向数
|
||||
uniform float u_Size; // 模糊半径
|
||||
|
||||
void main()
|
||||
{
|
||||
float Pi = 6.28318530718; // 2*PI
|
||||
|
||||
float Directions = 32.0; // 模糊方向数
|
||||
float Quality = 6.0; // 每个方向上的采样质量(采样次数)
|
||||
float Size = 16.0; // 模糊半径
|
||||
|
||||
vec2 Radius = Size / textureSize(u_Texture, 0);
|
||||
vec2 Radius = u_Size / textureSize(u_Texture, 0);
|
||||
|
||||
// 中心像素采样
|
||||
vec3 centerColor = texture(u_Texture, v_TexCoord).rgb;
|
||||
@ -50,9 +50,9 @@ void main()
|
||||
float totalSamples = 1.0; // 有效采样计数(中心像素已计入)
|
||||
|
||||
// 周围像素采样
|
||||
for (float d = 0.0; d < Pi; d += Pi / Directions)
|
||||
for (float d = 0.0; d < Pi; d += Pi / u_Directions)
|
||||
{
|
||||
for (float i = 1.0 / Quality; i <= 1.0; i += 1.0 / Quality)
|
||||
for (float i = 1.0 / u_Quality; i <= 1.0; i += 1.0 / u_Quality)
|
||||
{
|
||||
vec2 offset = vec2(cos(d), sin(d)) * Radius * i;
|
||||
vec3 sampleColor = texture(u_Texture, v_TexCoord + offset).rgb;
|
||||
|
||||
348
Editor/assets/shaders/Lighting.glsl
Normal file
348
Editor/assets/shaders/Lighting.glsl
Normal file
@ -0,0 +1,348 @@
|
||||
#type vertex
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 a_Position;
|
||||
layout(location = 1) in vec2 a_TexCoord;
|
||||
|
||||
out vec2 v_TexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
v_TexCoord = a_TexCoord;
|
||||
gl_Position = vec4(a_Position.xy, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
||||
#type fragment
|
||||
#version 430 core
|
||||
|
||||
// ==================== 输入 ====================
|
||||
in vec2 v_TexCoord;
|
||||
|
||||
// G-buffer 纹理
|
||||
uniform sampler2D u_AlbedoMetallic; // RGB: albedo, A: metallic
|
||||
uniform sampler2D u_NormalRoughness; // RGB: normal (encoded), A: roughness
|
||||
uniform sampler2D u_EmissiveAO; // RGB: emissive, A: AO
|
||||
uniform sampler2D u_Depth; // depth
|
||||
|
||||
// 相机参数
|
||||
uniform mat4 u_InvViewProj; // 逆视图投影矩阵,用于重建世界坐标
|
||||
uniform vec3 u_CameraPosition;
|
||||
|
||||
// 光源结构体(与你的PBR着色器一致)
|
||||
struct DirectionalLight {
|
||||
vec3 Direction;
|
||||
vec3 Radiance;
|
||||
float Intensity;
|
||||
bool CastShadows;
|
||||
};
|
||||
struct PointLight {
|
||||
vec3 Position;
|
||||
vec3 Radiance;
|
||||
float Intensity;
|
||||
float Range;
|
||||
bool CastShadows;
|
||||
};
|
||||
struct SpotLight {
|
||||
vec3 Position;
|
||||
vec3 Direction;
|
||||
vec3 Radiance;
|
||||
float Intensity;
|
||||
float Range;
|
||||
float InnerConeCos;
|
||||
float OuterConeCos;
|
||||
bool CastShadows;
|
||||
};
|
||||
|
||||
uniform DirectionalLight u_DirectionalLights; // 仅一个方向光
|
||||
uniform int u_PointLightCount;
|
||||
uniform PointLight u_PointLights[16]; // 假设最多16个点光源
|
||||
uniform int u_SpotLightCount;
|
||||
uniform SpotLight u_SpotLights[16]; // 最多16个聚光源
|
||||
|
||||
// IBL 相关
|
||||
uniform samplerCube u_EnvRadianceTex;
|
||||
uniform samplerCube u_EnvIrradianceTex;
|
||||
uniform sampler2D u_BRDFLUTTexture;
|
||||
uniform float u_IBLContribution;
|
||||
uniform float u_EnvMapRotation;
|
||||
|
||||
// 阴影相关
|
||||
uniform sampler2D u_ShadowMap;
|
||||
uniform float u_ShadowBias;
|
||||
uniform float u_ShadowSoftness;
|
||||
uniform int u_ShadowEnabled;
|
||||
uniform float u_ShadowIntensity; // 阴影强度(0-1)
|
||||
uniform mat4 u_LightSpaceMatrix; // 方向光光源空间矩阵
|
||||
|
||||
// 天空盒(可选)
|
||||
uniform samplerCube u_Skybox; // 如果深度为1.0则采样天空盒
|
||||
uniform float u_SkyIntensity;
|
||||
uniform float u_SkyTextureLod;
|
||||
|
||||
// 输出
|
||||
layout(location = 0) out vec4 o_Color;
|
||||
|
||||
// ==================== 常量 ====================
|
||||
const float PI = 3.14159265359;
|
||||
const float Epsilon = 0.00001;
|
||||
const vec3 Fdielectric = vec3(0.04);
|
||||
|
||||
|
||||
// ==================== 工具函数 ====================
|
||||
// 从深度重建世界坐标
|
||||
vec3 worldPosFromDepth(vec2 uv, float depth) {
|
||||
vec4 clipPos = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
|
||||
vec4 worldPos = u_InvViewProj * clipPos;
|
||||
return worldPos.xyz / worldPos.w;
|
||||
}
|
||||
|
||||
// 从深度重建世界空间方向(用于天空盒采样)
|
||||
vec3 worldDirFromUV(vec2 uv) {
|
||||
// 假设深度为1.0时,得到远平面方向
|
||||
vec4 clipPos = vec4(uv * 2.0 - 1.0, 1.0, 1.0);
|
||||
vec4 worldPos = u_InvViewProj * clipPos;
|
||||
return normalize(worldPos.xyz / worldPos.w);
|
||||
}
|
||||
|
||||
// 旋转向量(绕Y轴)
|
||||
vec3 RotateVectorAboutY(float angle, vec3 vec) {
|
||||
angle = radians(angle);
|
||||
mat3 rotationMatrix = mat3(
|
||||
vec3(cos(angle), 0.0, sin(angle)),
|
||||
vec3(0.0, 1.0, 0.0),
|
||||
vec3(-sin(angle), 0.0, cos(angle))
|
||||
);
|
||||
return rotationMatrix * vec;
|
||||
}
|
||||
|
||||
// ==================== PBR 函数(复用你的代码) ====================
|
||||
float ndfGGX(float cosLh, float roughness) {
|
||||
float alpha = roughness * roughness;
|
||||
float alphaSq = alpha * alpha;
|
||||
float denom = (cosLh * cosLh) * (alphaSq - 1.0) + 1.0;
|
||||
return alphaSq / (PI * denom * denom);
|
||||
}
|
||||
|
||||
float GeometrySchlickGGX(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;
|
||||
}
|
||||
|
||||
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(vec3 F0, float cosTheta) {
|
||||
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
|
||||
}
|
||||
|
||||
vec3 fresnelSchlickRoughness(vec3 F0, float cosTheta, float roughness) {
|
||||
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
|
||||
}
|
||||
|
||||
// ---------- 方向光 ----------
|
||||
vec3 ComputeDirectionalLight(DirectionalLight light, vec3 F0, vec3 N, vec3 V, float NdotV, vec3 albedo, float roughness, float metallic) {
|
||||
vec3 L = normalize(-light.Direction);
|
||||
vec3 Lradiance = light.Radiance * light.Intensity;
|
||||
|
||||
vec3 Lh = normalize(L + V);
|
||||
float cosLi = max(dot(N, L), 0.0);
|
||||
float cosLh = max(dot(N, Lh), 0.0);
|
||||
|
||||
vec3 F = fresnelSchlick(F0, max(dot(Lh, V), 0.0));
|
||||
float D = ndfGGX(cosLh, roughness);
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
|
||||
vec3 kd = (1.0 - F) * (1.0 - metallic);
|
||||
vec3 diffuseBRDF = kd * albedo;
|
||||
vec3 specularBRDF = (F * D * G) / max(Epsilon, 4.0 * cosLi * NdotV);
|
||||
|
||||
return (diffuseBRDF + specularBRDF) * Lradiance * cosLi;
|
||||
}
|
||||
|
||||
// ---------- 点光源 ----------
|
||||
vec3 ComputePointLight(PointLight light, vec3 F0, vec3 N, vec3 V, float NdotV, vec3 albedo, float roughness, float metallic, vec3 worldPos) {
|
||||
vec3 lightVec = light.Position - worldPos;
|
||||
float dist = length(lightVec);
|
||||
if (dist > light.Range) return vec3(0.0);
|
||||
|
||||
vec3 L = lightVec / dist;
|
||||
vec3 Lradiance = light.Radiance * light.Intensity;
|
||||
|
||||
float attenuation = 1.0 / (dist * dist + 0.0001);
|
||||
float rangeFactor = clamp(1.0 - (dist / light.Range), 0.0, 1.0);
|
||||
rangeFactor = rangeFactor * rangeFactor;
|
||||
attenuation *= rangeFactor;
|
||||
|
||||
vec3 Lh = normalize(L + V);
|
||||
float cosLi = max(dot(N, L), 0.0);
|
||||
float cosLh = max(dot(N, Lh), 0.0);
|
||||
|
||||
vec3 F = fresnelSchlick(F0, max(dot(Lh, V), 0.0));
|
||||
float D = ndfGGX(cosLh, roughness);
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
|
||||
vec3 kd = (1.0 - F) * (1.0 - metallic);
|
||||
vec3 diffuseBRDF = kd * albedo;
|
||||
vec3 specularBRDF = (F * D * G) / max(Epsilon, 4.0 * cosLi * NdotV);
|
||||
|
||||
return (diffuseBRDF + specularBRDF) * Lradiance * cosLi * attenuation;
|
||||
}
|
||||
|
||||
// ---------- 聚光源 ----------
|
||||
vec3 ComputeSpotLight(SpotLight light, vec3 F0, vec3 N, vec3 V, float NdotV, vec3 albedo, float roughness, float metallic, vec3 worldPos) {
|
||||
vec3 lightVec = light.Position - worldPos;
|
||||
float dist = length(lightVec);
|
||||
if (dist > light.Range) return vec3(0.0);
|
||||
|
||||
vec3 L = lightVec / dist;
|
||||
vec3 Lradiance = light.Radiance * light.Intensity;
|
||||
|
||||
float attenuation = 1.0 / (dist * dist + 0.0001);
|
||||
float rangeFactor = clamp(1.0 - (dist / light.Range), 0.0, 1.0);
|
||||
rangeFactor = rangeFactor * rangeFactor;
|
||||
attenuation *= rangeFactor;
|
||||
|
||||
float cosAngle = dot(-L, normalize(light.Direction));
|
||||
if (cosAngle < light.OuterConeCos) return vec3(0.0);
|
||||
float angleFalloff = (cosAngle - light.OuterConeCos) / (light.InnerConeCos - light.OuterConeCos);
|
||||
angleFalloff = clamp(angleFalloff, 0.0, 1.0);
|
||||
attenuation *= angleFalloff;
|
||||
|
||||
vec3 Lh = normalize(L + V);
|
||||
float cosLi = max(dot(N, L), 0.0);
|
||||
float cosLh = max(dot(N, Lh), 0.0);
|
||||
|
||||
vec3 F = fresnelSchlick(F0, max(dot(Lh, V), 0.0));
|
||||
float D = ndfGGX(cosLh, roughness);
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
|
||||
vec3 kd = (1.0 - F) * (1.0 - metallic);
|
||||
vec3 diffuseBRDF = kd * albedo;
|
||||
vec3 specularBRDF = (F * D * G) / max(Epsilon, 4.0 * cosLi * NdotV);
|
||||
|
||||
return (diffuseBRDF + specularBRDF) * Lradiance * cosLi * attenuation;
|
||||
}
|
||||
|
||||
// ---------- IBL ----------
|
||||
vec3 IBL(vec3 F0, vec3 N, vec3 V, float NdotV, float roughness, float metallic, vec3 albedo) {
|
||||
vec3 irradiance = texture(u_EnvIrradianceTex, N).rgb;
|
||||
vec3 F = fresnelSchlickRoughness(F0, NdotV, roughness);
|
||||
vec3 kd = (1.0 - F) * (1.0 - metallic);
|
||||
vec3 diffuseIBL = albedo * irradiance;
|
||||
|
||||
vec3 R = 2.0 * NdotV * N - V; // 反射向量
|
||||
int u_EnvRadianceTexLevels = textureQueryLevels(u_EnvRadianceTex);
|
||||
vec3 specularIrradiance = textureLod(
|
||||
u_EnvRadianceTex,
|
||||
RotateVectorAboutY(u_EnvMapRotation, R),
|
||||
roughness * u_EnvRadianceTexLevels
|
||||
).rgb;
|
||||
|
||||
vec2 specularBRDF = texture(u_BRDFLUTTexture, vec2(NdotV, 1.0 - roughness)).rg;
|
||||
vec3 specularIBL = specularIrradiance * (F * specularBRDF.x + specularBRDF.y);
|
||||
|
||||
return kd * diffuseIBL + specularIBL;
|
||||
}
|
||||
|
||||
// ---------- 阴影 ----------
|
||||
float calculateShadow(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir) {
|
||||
if (u_ShadowEnabled == 0) return 0.0;
|
||||
|
||||
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
||||
projCoords = projCoords * 0.5 + 0.5;
|
||||
|
||||
if (projCoords.z > 1.0 || projCoords.x < 0.0 || projCoords.x > 1.0 || projCoords.y < 0.0 || projCoords.y > 1.0)
|
||||
return 0.0;
|
||||
|
||||
float closestDepth = texture(u_ShadowMap, projCoords.xy).r;
|
||||
float currentDepth = projCoords.z;
|
||||
|
||||
float bias = max(u_ShadowBias * (1.0 - dot(normal, lightDir)), u_ShadowBias * 0.1);
|
||||
|
||||
float shadow = 0.0;
|
||||
vec2 texelSize = 1.0 / textureSize(u_ShadowMap, 0);
|
||||
int pcfRange = int(u_ShadowSoftness);
|
||||
int sampleCount = 0;
|
||||
|
||||
for (int x = -pcfRange; x <= pcfRange; ++x) {
|
||||
for (int y = -pcfRange; y <= pcfRange; ++y) {
|
||||
float pcfDepth = texture(u_ShadowMap, projCoords.xy + vec2(x, y) * texelSize).r;
|
||||
shadow += (currentDepth - bias > pcfDepth) ? 1.0 : 0.0;
|
||||
sampleCount++;
|
||||
}
|
||||
}
|
||||
shadow /= float(sampleCount);
|
||||
|
||||
return shadow * u_ShadowIntensity; // 应用阴影强度
|
||||
}
|
||||
|
||||
// ==================== 主函数 ====================
|
||||
void main() {
|
||||
vec2 uv = v_TexCoord;
|
||||
float depth = texture(u_Depth, uv).r;
|
||||
|
||||
if (depth >= 1.0) {
|
||||
vec3 dir = worldDirFromUV(uv);
|
||||
vec3 skyColor = textureLod(u_Skybox, dir, u_SkyTextureLod).rgb * u_SkyIntensity;
|
||||
o_Color = vec4(skyColor, 1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 albedoMetal = texture(u_AlbedoMetallic, uv);
|
||||
vec4 normalRough = texture(u_NormalRoughness, uv);
|
||||
vec4 emissiveAO = texture(u_EmissiveAO, uv);
|
||||
|
||||
vec3 albedo = albedoMetal.rgb;
|
||||
float metallic = albedoMetal.a;
|
||||
vec3 normal = normalRough.rgb * 2.0 - 1.0;
|
||||
float roughness = normalRough.a;
|
||||
vec3 emissive = emissiveAO.rgb;
|
||||
float ao = emissiveAO.a;
|
||||
|
||||
vec3 worldPos = worldPosFromDepth(uv, depth);
|
||||
vec3 V = normalize(u_CameraPosition - worldPos);
|
||||
float NdotV = clamp(dot(normal, V), 0.0, 1.0);
|
||||
|
||||
vec3 F0 = mix(Fdielectric, albedo, metallic);
|
||||
|
||||
vec3 Lo = vec3(0.0);
|
||||
|
||||
// Direction Light
|
||||
if (u_DirectionalLights.Intensity > 0.0) {
|
||||
Lo += ComputeDirectionalLight(u_DirectionalLights, F0, normal, V, NdotV, albedo, roughness, metallic);
|
||||
}
|
||||
|
||||
// Point Light
|
||||
for (int i = 0; i < u_PointLightCount; ++i) {
|
||||
Lo += ComputePointLight(u_PointLights[i], F0, normal, V, NdotV, albedo, roughness, metallic, worldPos);
|
||||
}
|
||||
|
||||
// Spot light
|
||||
for (int i = 0; i < u_SpotLightCount; ++i) {
|
||||
Lo += ComputeSpotLight(u_SpotLights[i], F0, normal, V, NdotV, albedo, roughness, metallic, worldPos);
|
||||
}
|
||||
|
||||
float shadowFactor = 1.0;
|
||||
if (u_ShadowEnabled > 0 && u_DirectionalLights.CastShadows && u_DirectionalLights.Intensity > 0.0) {
|
||||
vec4 fragPosLightSpace = u_LightSpaceMatrix * vec4(worldPos, 1.0);
|
||||
float shadow = calculateShadow(fragPosLightSpace, normal, u_DirectionalLights.Direction);
|
||||
shadowFactor = 1.0 - shadow;
|
||||
}
|
||||
Lo *= shadowFactor;
|
||||
|
||||
// 计算 IBL
|
||||
vec3 ibl = IBL(F0, normal, V, NdotV, roughness, metallic, albedo) * u_IBLContribution;
|
||||
|
||||
vec3 finalColor = Lo + ibl + emissive;
|
||||
|
||||
o_Color = vec4(finalColor, 1.0);
|
||||
}
|
||||
@ -161,6 +161,13 @@ uniform float u_ShadowSoftness;
|
||||
uniform float u_ShadowIntensity;
|
||||
uniform int u_ShadowEnabled;
|
||||
|
||||
// Emissive
|
||||
uniform sampler2D u_EmissiveTexture;
|
||||
uniform float u_EmissiveTexToggle;
|
||||
uniform vec3 u_EmissiveColor;
|
||||
uniform float u_EmissiveIntensity;
|
||||
|
||||
|
||||
struct PBRParameters
|
||||
{
|
||||
vec3 Albedo;
|
||||
@ -425,7 +432,16 @@ float ComputeShadow(vec4 fragPosLightSpace, float NdotL)
|
||||
|
||||
void main()
|
||||
{
|
||||
m_Params.Albedo = u_AlbedoTexToggle > 0.5 ? texture(u_AlbedoTexture, vs_Input.TexCoord).rgb : u_AlbedoColor;
|
||||
float alpha = 1.0;
|
||||
if (u_AlbedoTexToggle > 0.5) {
|
||||
vec4 albedoWithAlpha = texture(u_AlbedoTexture, vs_Input.TexCoord);
|
||||
m_Params.Albedo = albedoWithAlpha.rgb;
|
||||
alpha = albedoWithAlpha.a;
|
||||
} else {
|
||||
m_Params.Albedo = u_AlbedoColor;
|
||||
alpha = 1.0;
|
||||
}
|
||||
|
||||
m_Params.Metalness = u_MetalnessTexToggle > 0.5 ? texture(u_MetalnessTexture, vs_Input.TexCoord).r : u_Metalness;
|
||||
m_Params.Roughness = u_RoughnessTexToggle > 0.5 ? texture(u_RoughnessTexture, vs_Input.TexCoord).r : u_Roughness;
|
||||
m_Params.Roughness = max(m_Params.Roughness, 0.05);
|
||||
@ -463,7 +479,16 @@ void main()
|
||||
|
||||
vec3 iblContribution = IBL(F0, Lr) * u_IBLContribution;
|
||||
|
||||
color = vec4(lightContribution + iblContribution, 1.0);
|
||||
vec3 emissive = u_EmissiveColor;
|
||||
if (u_EmissiveTexToggle > 0.5) {
|
||||
emissive = texture(u_EmissiveTexture, vs_Input.TexCoord).rgb;
|
||||
}
|
||||
emissive *= u_EmissiveIntensity;
|
||||
|
||||
vec3 finalRGB = lightContribution + iblContribution + emissive;
|
||||
vec4 finalColor = vec4(finalRGB, alpha);
|
||||
|
||||
color = finalColor;
|
||||
|
||||
// Bloom
|
||||
float brightness = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
|
||||
@ -55,6 +55,12 @@ void main()
|
||||
#type fragment
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) out vec4 outAlbedoMetal;
|
||||
layout(location = 1) out vec4 outNormalRoughness;
|
||||
layout(location = 2) out vec4 outEmissiveAO;
|
||||
layout(location = 3) out vec4 outColor;
|
||||
layout(location = 4) out vec4 outBloomColor;
|
||||
|
||||
const float PI = 3.141592;
|
||||
const float Epsilon = 0.00001;
|
||||
|
||||
@ -100,8 +106,8 @@ in VertexOutput
|
||||
vec4 FragPosLightSpace;
|
||||
} vs_Input;
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
layout(location = 1) out vec4 o_BloomColor;
|
||||
|
||||
uniform bool u_GBufferMode;
|
||||
|
||||
uniform DirectionalLight u_DirectionalLights;
|
||||
|
||||
@ -149,6 +155,12 @@ uniform float u_ShadowSoftness;
|
||||
uniform float u_ShadowIntensity;
|
||||
uniform int u_ShadowEnabled;
|
||||
|
||||
// Emissive
|
||||
uniform sampler2D u_EmissiveTexture;
|
||||
uniform float u_EmissiveTexToggle;
|
||||
uniform vec3 u_EmissiveColor;
|
||||
uniform float u_EmissiveIntensity;
|
||||
|
||||
struct PBRParameters
|
||||
{
|
||||
vec3 Albedo;
|
||||
@ -411,19 +423,44 @@ float ComputeShadow(vec4 fragPosLightSpace, float NdotL)
|
||||
|
||||
void main()
|
||||
{
|
||||
m_Params.Albedo = u_AlbedoTexToggle > 0.5 ? texture(u_AlbedoTexture, vs_Input.TexCoord).rgb : u_AlbedoColor;
|
||||
m_Params.Metalness = u_MetalnessTexToggle > 0.5 ? texture(u_MetalnessTexture, vs_Input.TexCoord).r : u_Metalness;
|
||||
m_Params.Roughness = u_RoughnessTexToggle > 0.5 ? texture(u_RoughnessTexture, vs_Input.TexCoord).r : u_Roughness;
|
||||
m_Params.Roughness = max(m_Params.Roughness, 0.05);
|
||||
// === 1. 采样基础属性(所有模式都需要) ===
|
||||
vec4 albedoWithAlpha = texture(u_AlbedoTexture, vs_Input.TexCoord);
|
||||
vec3 albedo = u_AlbedoTexToggle > 0.5 ? albedoWithAlpha.rgb : u_AlbedoColor;
|
||||
float alpha = u_AlbedoTexToggle > 0.5 ? albedoWithAlpha.a : 1.0;
|
||||
|
||||
// normal
|
||||
m_Params.Normal = normalize(vs_Input.Normal);
|
||||
float metallic = u_MetalnessTexToggle > 0.5 ? texture(u_MetalnessTexture, vs_Input.TexCoord).r : u_Metalness;
|
||||
float roughness = u_RoughnessTexToggle > 0.5 ? texture(u_RoughnessTexture, vs_Input.TexCoord).r : u_Roughness;
|
||||
roughness = max(roughness, 0.05);
|
||||
|
||||
// === 2. 法线计算(世界空间) ===
|
||||
vec3 normal = normalize(vs_Input.Normal);
|
||||
if (u_NormalTexToggle > 0.5)
|
||||
{
|
||||
m_Params.Normal = normalize(2.0 * texture(u_NormalTexture, vs_Input.TexCoord).rgb - 1.0);
|
||||
m_Params.Normal = normalize(vs_Input.WorldNormals * m_Params.Normal);
|
||||
vec3 tangentNormal = texture(u_NormalTexture, vs_Input.TexCoord).rgb * 2.0 - 1.0;
|
||||
normal = normalize(vs_Input.WorldNormals * tangentNormal);
|
||||
}
|
||||
|
||||
// === 3. 自发光计算 ===
|
||||
vec3 emissive = u_EmissiveColor;
|
||||
if (u_EmissiveTexToggle > 0.5)
|
||||
emissive = texture(u_EmissiveTexture, vs_Input.TexCoord).rgb;
|
||||
emissive *= u_EmissiveIntensity;
|
||||
|
||||
// === 4. GBuffer 模式:直接输出到多个目标 ===
|
||||
if (u_GBufferMode)
|
||||
{
|
||||
outAlbedoMetal = vec4(albedo, metallic);
|
||||
outNormalRoughness = vec4(normal * 0.5 + 0.5, roughness);
|
||||
outEmissiveAO = vec4(emissive, 1.0); // AO 暂设为 1.0
|
||||
return; // 提前结束
|
||||
}
|
||||
|
||||
// === 5. 非 GBuffer 模式:继续 PBR 光照计算 ===
|
||||
// 填充 PBRParameters
|
||||
m_Params.Albedo = albedo;
|
||||
m_Params.Metalness = metallic;
|
||||
m_Params.Roughness = roughness;
|
||||
m_Params.Normal = normal;
|
||||
m_Params.View = normalize(u_CameraPosition - vs_Input.WorldPosition);
|
||||
m_Params.NdotV = max(dot(m_Params.Normal, m_Params.View), 0.0);
|
||||
|
||||
@ -449,9 +486,12 @@ void main()
|
||||
|
||||
vec3 iblContribution = IBL(F0, Lr) * u_IBLContribution;
|
||||
|
||||
color = vec4(lightContribution + iblContribution, 1.0);
|
||||
vec3 finalRGB = lightContribution + iblContribution + emissive;
|
||||
vec4 finalColor = vec4(finalRGB, alpha);
|
||||
|
||||
outColor = finalColor;
|
||||
|
||||
// Bloom
|
||||
float brightness = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
o_BloomColor = brightness > u_BloomThreshold ? color : vec4(0.0, 0.0, 0.0, 1.0);
|
||||
float brightness = dot(finalColor.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
outBloomColor = brightness > u_BloomThreshold ? finalColor : vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
@ -17,13 +17,11 @@ void main()
|
||||
#version 430
|
||||
|
||||
layout(location = 0) out vec4 o_Color;
|
||||
layout(location = 1) out vec4 o_BloomTexture;
|
||||
|
||||
in vec2 v_TexCoord;
|
||||
|
||||
uniform sampler2DMS u_Texture;
|
||||
uniform sampler2D u_BloomTexture;
|
||||
|
||||
uniform sampler2D u_HDRTexture; // 来自 LightingPass 的 HDR 颜色
|
||||
uniform sampler2D u_BloomTexture; // 来自 BloomBlendPass 的 Bloom 纹理
|
||||
|
||||
uniform bool u_EnableAutoExposure;
|
||||
uniform float u_ManualExposure;
|
||||
@ -32,73 +30,36 @@ layout(std430, binding = 2) buffer Exposure
|
||||
float u_Exposure;
|
||||
};
|
||||
|
||||
uniform int u_TextureSamples;
|
||||
|
||||
uniform bool u_EnableBloom;
|
||||
uniform float u_BloomThreshold;
|
||||
|
||||
const float uFar = 1.0;
|
||||
|
||||
vec4 SampleTexture(sampler2D tex, vec2 texCoord)
|
||||
{
|
||||
return texture(tex, texCoord);
|
||||
}
|
||||
|
||||
vec4 MultiSampleTexture(sampler2DMS tex, vec2 tc)
|
||||
{
|
||||
ivec2 texSize = textureSize(tex);
|
||||
ivec2 texCoord = ivec2(tc * texSize);
|
||||
vec4 result = vec4(0.0);
|
||||
for (int i = 0; i < u_TextureSamples; i++)
|
||||
result += texelFetch(tex, texCoord, i);
|
||||
|
||||
result /= float(u_TextureSamples);
|
||||
return result;
|
||||
}
|
||||
|
||||
float MultiSampleDepth(sampler2DMS tex, vec2 tc)
|
||||
{
|
||||
ivec2 texSize = textureSize(tex);
|
||||
ivec2 texCoord = ivec2(tc * texSize);
|
||||
float result = 0.0;
|
||||
for (int i = 0; i < u_TextureSamples; i++)
|
||||
result += texelFetch(tex, texCoord, i).r;
|
||||
result /= float(u_TextureSamples);
|
||||
return result;
|
||||
}
|
||||
const float gamma = 2.2;
|
||||
const float pureWhite = 1.0;
|
||||
|
||||
void main()
|
||||
{
|
||||
const float gamma = 2.2;
|
||||
const float pureWhite = 1.0;
|
||||
|
||||
// Tonemapping
|
||||
vec4 msColor = MultiSampleTexture(u_Texture, v_TexCoord);
|
||||
vec3 color = msColor.rgb;
|
||||
// 采样 HDR 颜色(单样本)
|
||||
vec3 color = texture(u_HDRTexture, v_TexCoord).rgb;
|
||||
|
||||
// 混合 Bloom(如果启用)
|
||||
if (u_EnableBloom)
|
||||
{
|
||||
vec3 bloomColor = texture(u_BloomTexture, v_TexCoord).rgb;
|
||||
color += bloomColor;
|
||||
color += bloomColor; // 在 HDR 空间混合
|
||||
}
|
||||
|
||||
if(u_EnableAutoExposure)
|
||||
color *= u_Exposure;
|
||||
// 应用曝光
|
||||
if (u_EnableAutoExposure)
|
||||
color *= u_Exposure;
|
||||
else
|
||||
color *= u_ManualExposure;
|
||||
color *= u_ManualExposure;
|
||||
|
||||
// Reinhard tonemapping operator.
|
||||
// see: "Photographic Tone Reproduction for Digital Images", eq. 4
|
||||
// Reinhard 色调映射
|
||||
float luminance = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||
float mappedLuminance = (luminance * (1.0 + luminance / (pureWhite * pureWhite))) / (1.0 + luminance);
|
||||
|
||||
// Scale color by ratio of average luminances.
|
||||
// 按亮度比例缩放颜色
|
||||
vec3 mappedColor = (mappedLuminance / luminance) * color;
|
||||
|
||||
// Gamma correction.
|
||||
// Gamma 校正
|
||||
o_Color = vec4(pow(mappedColor, vec3(1.0 / gamma)), 1.0);
|
||||
|
||||
// Show over-exposed areas
|
||||
// if (o_Color.r > 1.0 || o_Color.g > 1.0 || o_Color.b > 1.0)
|
||||
// o_Color.rgb *= vec3(1.0, 0.25, 0.25);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user