Refactor Blinn-Phong shaders
This commit is contained in:
parent
e6b70fe6e2
commit
0e22dbfd47
6 changed files with 146 additions and 148 deletions
|
@ -38,6 +38,7 @@ namespace graphics {
|
|||
|
||||
extern char g_shaderBaseHeader[];
|
||||
extern char g_shaderBaseModel[];
|
||||
extern char g_shaderBaseBlinnPhong[];
|
||||
extern char g_shaderBasePBR[];
|
||||
extern char g_shaderBasePBRIBL[];
|
||||
extern char g_shaderVertexSimple[];
|
||||
|
@ -56,7 +57,7 @@ extern char g_shaderFragmentGrass[];
|
|||
extern char g_shaderFragmentBlur[];
|
||||
extern char g_shaderFragmentPresentWorld[];
|
||||
extern char g_shaderFragmentBlinnPhong[];
|
||||
extern char g_shaderFragmentBlinnPhongTextureless[];
|
||||
extern char g_shaderFragmentBlinnPhongDiffuseless[];
|
||||
extern char g_shaderFragmentIrradiance[];
|
||||
extern char g_shaderFragmentPrefilter[];
|
||||
extern char g_shaderFragmentBRDF[];
|
||||
|
@ -93,8 +94,8 @@ void Shaders::init() {
|
|||
initShader(ShaderName::FragmentGrass, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentGrass });
|
||||
initShader(ShaderName::FragmentBlur, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentBlur });
|
||||
initShader(ShaderName::FragmentPresentWorld, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentPresentWorld });
|
||||
initShader(ShaderName::FragmentBlinnPhong, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderBaseModel, g_shaderFragmentBlinnPhong });
|
||||
initShader(ShaderName::FragmentBlinnPhongTextureless, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderBaseModel, g_shaderFragmentBlinnPhongTextureless });
|
||||
initShader(ShaderName::FragmentBlinnPhong, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderBaseModel, g_shaderBaseBlinnPhong, g_shaderFragmentBlinnPhong });
|
||||
initShader(ShaderName::FragmentBlinnPhongDiffuseless, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderBaseModel, g_shaderBaseBlinnPhong, g_shaderFragmentBlinnPhongDiffuseless });
|
||||
initShader(ShaderName::FragmentIrradiance, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentIrradiance });
|
||||
initShader(ShaderName::FragmentPrefilter, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderBasePBR, g_shaderBasePBRIBL, g_shaderFragmentPrefilter });
|
||||
initShader(ShaderName::FragmentBRDF, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderBasePBR, g_shaderBasePBRIBL, g_shaderFragmentBRDF });
|
||||
|
@ -110,7 +111,7 @@ void Shaders::init() {
|
|||
initProgram(ShaderProgram::SimplePresentWorld, { ShaderName::VertexSimple, ShaderName::FragmentPresentWorld });
|
||||
initProgram(ShaderProgram::ModelColor, { ShaderName::VertexModel, ShaderName::FragmentColor });
|
||||
initProgram(ShaderProgram::ModelBlinnPhong, { ShaderName::VertexModel, ShaderName::FragmentBlinnPhong });
|
||||
initProgram(ShaderProgram::ModelBlinnPhongTextureless, { ShaderName::VertexModel, ShaderName::FragmentBlinnPhongTextureless });
|
||||
initProgram(ShaderProgram::ModelBlinnPhongDiffuseless, { ShaderName::VertexModel, ShaderName::FragmentBlinnPhongDiffuseless });
|
||||
initProgram(ShaderProgram::ModelPBR, { ShaderName::VertexModel, ShaderName::FragmentPBR });
|
||||
initProgram(ShaderProgram::ParticleParticle, { ShaderName::VertexParticle, ShaderName::FragmentParticle });
|
||||
initProgram(ShaderProgram::GrassGrass, { ShaderName::VertexGrass, ShaderName::FragmentGrass });
|
||||
|
|
|
@ -46,7 +46,7 @@ enum class ShaderProgram {
|
|||
SimplePresentWorld,
|
||||
ModelColor,
|
||||
ModelBlinnPhong,
|
||||
ModelBlinnPhongTextureless,
|
||||
ModelBlinnPhongDiffuseless,
|
||||
ModelPBR,
|
||||
ParticleParticle,
|
||||
GrassGrass,
|
||||
|
@ -244,7 +244,7 @@ private:
|
|||
|
||||
// Blinn-Phong
|
||||
FragmentBlinnPhong,
|
||||
FragmentBlinnPhongTextureless,
|
||||
FragmentBlinnPhongDiffuseless,
|
||||
|
||||
// PBR
|
||||
FragmentIrradiance,
|
||||
|
|
|
@ -202,6 +202,10 @@ in mat3 fragTanSpace;
|
|||
layout(location = 0) out vec4 fragColor;
|
||||
layout(location = 1) out vec4 fragColorBright;
|
||||
|
||||
vec2 getUV() {
|
||||
return fragTexCoords + uGeneral.uvOffset;
|
||||
}
|
||||
|
||||
vec2 packUV(vec2 uv, vec4 bounds) {
|
||||
return bounds.xy + bounds.zw * clamp(fract(uv), 0.001, 0.999);
|
||||
}
|
||||
|
@ -240,14 +244,26 @@ vec3 getNormalFromBumpmap(vec2 uv) {
|
|||
}
|
||||
|
||||
result = normalize(fragTanSpace * result);
|
||||
return result;
|
||||
}
|
||||
|
||||
vec3 getNormal(vec2 uv) {
|
||||
vec3 result;
|
||||
|
||||
if (isFeatureEnabled(FEATURE_BUMPMAPS)) {
|
||||
result = getNormalFromBumpmap(uv);
|
||||
} else {
|
||||
result = normalize(fragNormal);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float getShadow() {
|
||||
float shadow = 0.0;
|
||||
if (!isFeatureEnabled(FEATURE_SHADOWS) || !uShadows.lightPresent) return 0.0;
|
||||
|
||||
float result = 0.0;
|
||||
|
||||
if (uShadows.lightPresent) {
|
||||
if (uShadows.lightPosition.w == 0.0) {
|
||||
// Directional light
|
||||
|
||||
|
@ -260,13 +276,13 @@ float getShadow() {
|
|||
for (int x = -1; x <= 1; ++x) {
|
||||
for (int y = -1; y <= 1; ++y) {
|
||||
float pcfDepth = texture(uShadowMap, projCoords.xy + vec2(x, y) * texelSize).r;
|
||||
shadow += currentDepth > pcfDepth ? 1.0 : 0.0;
|
||||
result += currentDepth > pcfDepth ? 1.0 : 0.0;
|
||||
}
|
||||
}
|
||||
shadow /= 9.0;
|
||||
result /= 9.0;
|
||||
|
||||
if (projCoords.z > 1.0) {
|
||||
shadow = 0.0;
|
||||
result = 0.0;
|
||||
}
|
||||
} else {
|
||||
// Point light
|
||||
|
@ -285,17 +301,17 @@ float getShadow() {
|
|||
closestDepth *= SHADOW_FAR_PLANE;
|
||||
|
||||
if (currentDepth - bias > closestDepth) {
|
||||
shadow += 1.0;
|
||||
result += 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shadow /= samples * samples * samples;
|
||||
}
|
||||
result /= samples * samples * samples;
|
||||
}
|
||||
|
||||
return uShadows.strength * shadow;
|
||||
result *= uShadows.strength;
|
||||
return result;
|
||||
}
|
||||
|
||||
float getLightAttenuation(int light) {
|
||||
|
@ -308,9 +324,10 @@ float getLightAttenuation(int light) {
|
|||
return D / (D + r);
|
||||
}
|
||||
|
||||
vec3 applyFog(vec3 rgb, float distance) {
|
||||
vec3 applyFog(vec3 objectColor) {
|
||||
float distance = length(uGeneral.cameraPosition.xyz - fragPosition);
|
||||
float fogAmount = clamp(distance - uGeneral.fogNear, 0.0, uGeneral.fogFar - uGeneral.fogNear) / (uGeneral.fogFar - uGeneral.fogNear);
|
||||
return mix(rgb, uGeneral.fogColor.rgb, fogAmount);
|
||||
return mix(objectColor, uGeneral.fogColor.rgb, fogAmount);
|
||||
}
|
||||
)END";
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ uniform sampler2D uBRDFLookup;
|
|||
uniform samplerCube uIrradianceMap;
|
||||
uniform samplerCube uPrefilterMap;
|
||||
|
||||
void determineMetallicRoughness(vec4 diffuseSample, out float metallic, out float roughness) {
|
||||
void getMetallicRoughness(vec4 diffuseSample, out float metallic, out float roughness) {
|
||||
if (isFeatureEnabled(FEATURE_CUSTOMMAT) || !isFeatureEnabled(FEATURE_ENVMAP)) {
|
||||
metallic = uMaterial.metallic;
|
||||
roughness = uMaterial.roughness;
|
||||
|
@ -240,31 +240,19 @@ void determineMetallicRoughness(vec4 diffuseSample, out float metallic, out floa
|
|||
}
|
||||
|
||||
void main() {
|
||||
vec2 texCoords = fragTexCoords + uGeneral.uvOffset;
|
||||
|
||||
vec4 diffuseSample;
|
||||
if (isFeatureEnabled(FEATURE_DIFFUSE)) {
|
||||
diffuseSample = texture(uDiffuse, texCoords);
|
||||
} else {
|
||||
diffuseSample = vec4(vec3(0.5), 1.0);
|
||||
}
|
||||
|
||||
vec3 N;
|
||||
if (isFeatureEnabled(FEATURE_BUMPMAPS)) {
|
||||
N = getNormalFromBumpmap(texCoords);
|
||||
} else {
|
||||
N = normalize(fragNormal);
|
||||
}
|
||||
vec2 uv = getUV();
|
||||
vec4 diffuseSample = texture(uDiffuse, uv);
|
||||
|
||||
vec3 cameraToFragment = uGeneral.cameraPosition.xyz - fragPosition;
|
||||
vec3 V = normalize(cameraToFragment);
|
||||
vec3 N = getNormal(uv);
|
||||
vec3 R = reflect(-V, N);
|
||||
|
||||
vec3 albedo = isFeatureEnabled(FEATURE_HDR) ? pow(diffuseSample.rgb, vec3(GAMMA)) : diffuseSample.rgb;
|
||||
float ao = 1.0;
|
||||
|
||||
float metallic, roughness;
|
||||
determineMetallicRoughness(diffuseSample, metallic, roughness);
|
||||
getMetallicRoughness(diffuseSample, metallic, roughness);
|
||||
|
||||
vec3 objectColor;
|
||||
|
||||
|
@ -360,7 +348,7 @@ void main() {
|
|||
objectColor = pow(objectColor, vec3(1.0 / GAMMA));
|
||||
}
|
||||
if (isFeatureEnabled(FEATURE_FOG)) {
|
||||
objectColor = applyFog(objectColor, length(cameraToFragment));
|
||||
objectColor = applyFog(objectColor);
|
||||
}
|
||||
|
||||
vec3 brightColor = vec3(0.0);
|
||||
|
|
|
@ -25,93 +25,14 @@ namespace reone {
|
|||
|
||||
namespace graphics {
|
||||
|
||||
char g_shaderFragmentBlinnPhong[] = R"END(
|
||||
void main() {
|
||||
vec2 texCoords = fragTexCoords + uGeneral.uvOffset;
|
||||
vec4 diffuseSample = texture(uDiffuse, texCoords);
|
||||
vec3 cameraToFragment = uGeneral.cameraPosition.xyz - fragPosition;
|
||||
vec3 V = normalize(cameraToFragment);
|
||||
|
||||
vec3 N;
|
||||
if (isFeatureEnabled(FEATURE_BUMPMAPS)) {
|
||||
N = getNormalFromBumpmap(texCoords);
|
||||
} else {
|
||||
N = normalize(fragNormal);
|
||||
char g_shaderBaseBlinnPhong[] = R"END(
|
||||
vec3 getLightingIndirect(vec3 N) {
|
||||
return uGeneral.ambientColor.rgb * uMaterial.ambient.rgb;
|
||||
}
|
||||
|
||||
vec3 objectColor;
|
||||
|
||||
if (isFeatureEnabled(FEATURE_LIGHTING)) {
|
||||
objectColor = uGeneral.ambientColor.rgb * uMaterial.ambient.rgb * diffuseSample.rgb;
|
||||
|
||||
for (int i = 0; i < uLightCount; ++i) {
|
||||
vec3 L = normalize(uLights[i].position.xyz - fragPosition);
|
||||
vec3 H = normalize(V + L);
|
||||
|
||||
float diff = max(dot(L, N), 0.0);
|
||||
vec3 diffuse = uLights[i].multiplier * uLights[i].color.rgb * diff * uMaterial.diffuse.rgb * diffuseSample.rgb;
|
||||
|
||||
float spec = pow(max(dot(N, H), 0.0), uMaterial.shininess);
|
||||
vec3 specular = uLights[i].multiplier * uLights[i].color.rgb * spec * vec3(uMaterial.specular);
|
||||
|
||||
float attenuation = getLightAttenuation(i);
|
||||
diffuse *= attenuation;
|
||||
specular *= attenuation;
|
||||
|
||||
objectColor += diffuse + specular;
|
||||
}
|
||||
|
||||
objectColor = min(objectColor, diffuseSample.rgb);
|
||||
|
||||
} else {
|
||||
objectColor = diffuseSample.rgb;
|
||||
}
|
||||
|
||||
if (isFeatureEnabled(FEATURE_LIGHTMAP)) {
|
||||
vec4 lightmapSample = texture(uLightmap, fragLightmapCoords);
|
||||
objectColor = mix(objectColor, objectColor * lightmapSample.rgb, isFeatureEnabled(FEATURE_WATER) ? 0.2 : 1.0);
|
||||
}
|
||||
if (isFeatureEnabled(FEATURE_ENVMAP)) {
|
||||
vec3 R = reflect(-V, N);
|
||||
vec4 envmapSample = texture(uEnvmap, R);
|
||||
objectColor += (1.0 - diffuseSample.a) * envmapSample.rgb;
|
||||
}
|
||||
if (isFeatureEnabled(FEATURE_SHADOWS)) {
|
||||
vec3 S = vec3(1.0) - max(vec3(0.0), vec3(getShadow()) - uGeneral.ambientColor.rgb);
|
||||
objectColor *= S;
|
||||
}
|
||||
if (isFeatureEnabled(FEATURE_FOG)) {
|
||||
objectColor = applyFog(objectColor, length(cameraToFragment));
|
||||
}
|
||||
|
||||
float objectAlpha = uGeneral.alpha;
|
||||
if (!isFeatureEnabled(FEATURE_ENVMAP) && !isFeatureEnabled(FEATURE_BUMPMAPS)) {
|
||||
objectAlpha *= diffuseSample.a;
|
||||
}
|
||||
if (isFeatureEnabled(FEATURE_WATER)) {
|
||||
objectColor *= uGeneral.waterAlpha;
|
||||
objectAlpha *= uGeneral.waterAlpha;
|
||||
}
|
||||
|
||||
vec3 brightColor = vec3(0.0);
|
||||
if (isFeatureEnabled(FEATURE_SELFILLUM) && !isFeatureEnabled(FEATURE_WATER)) {
|
||||
objectColor *= uGeneral.selfIllumColor.rgb;
|
||||
brightColor = smoothstep(SELFILLUM_THRESHOLD, 1.0, uGeneral.selfIllumColor.rgb * diffuseSample.rgb * objectAlpha);
|
||||
}
|
||||
|
||||
fragColor = vec4(objectColor, objectAlpha);
|
||||
fragColorBright = vec4(brightColor, 1.0);
|
||||
}
|
||||
)END";
|
||||
|
||||
char g_shaderFragmentBlinnPhongTextureless[] = R"END(
|
||||
void main() {
|
||||
vec3 indirect = uGeneral.ambientColor.rgb * uMaterial.ambient.rgb;
|
||||
vec3 direct = vec3(0.0);
|
||||
|
||||
if (isFeatureEnabled(FEATURE_LIGHTING)) {
|
||||
vec3 getLightingDirect(vec3 N) {
|
||||
vec3 result = vec3(0.0);
|
||||
vec3 V = normalize(uGeneral.cameraPosition.xyz - fragPosition);
|
||||
vec3 N = normalize(fragNormal);
|
||||
|
||||
for (int i = 0; i < uLightCount; ++i) {
|
||||
vec3 L = normalize(uLights[i].position.xyz - fragPosition);
|
||||
|
@ -127,16 +48,87 @@ void main() {
|
|||
diffuse *= attenuation;
|
||||
specular *= attenuation;
|
||||
|
||||
direct += diffuse + specular;
|
||||
}
|
||||
} else if (isFeatureEnabled(FEATURE_LIGHTMAP)) {
|
||||
indirect *= texture(uLightmap, fragLightmapCoords).rgb;
|
||||
result += diffuse + specular;
|
||||
}
|
||||
|
||||
vec3 objectColor = indirect + direct;
|
||||
return result;
|
||||
}
|
||||
)END";
|
||||
|
||||
fragColor = vec4(objectColor, uGeneral.alpha);
|
||||
fragColorBright = vec4(0.0);
|
||||
char g_shaderFragmentBlinnPhong[] = R"END(
|
||||
void main() {
|
||||
vec2 uv = getUV();
|
||||
vec3 N = getNormal(uv);
|
||||
float shadow = getShadow();
|
||||
vec4 diffuseSample = texture(uDiffuse, uv);
|
||||
bool opaque = isFeatureEnabled(FEATURE_ENVMAP) || isFeatureEnabled(FEATURE_BUMPMAPS);
|
||||
|
||||
vec3 lighting;
|
||||
if (isFeatureEnabled(FEATURE_LIGHTMAP)) {
|
||||
vec4 lightmapSample = texture(uLightmap, fragLightmapCoords);
|
||||
lighting = (1.0 - 0.5 * shadow) * lightmapSample.rgb;
|
||||
if (isFeatureEnabled(FEATURE_WATER)) {
|
||||
lighting *= 0.2;
|
||||
}
|
||||
} else if (isFeatureEnabled(FEATURE_LIGHTING)) {
|
||||
vec3 indirect = getLightingIndirect(N);
|
||||
vec3 direct = getLightingDirect(N);
|
||||
lighting = min(vec3(1.0), indirect + (1.0 - shadow) * direct);
|
||||
} else {
|
||||
lighting = vec3(1.0);
|
||||
}
|
||||
|
||||
vec3 objectColor = lighting * uGeneral.color.rgb * diffuseSample.rgb;
|
||||
float objectAlpha = (opaque ? 1.0 : diffuseSample.a) * uGeneral.alpha;
|
||||
|
||||
if (isFeatureEnabled(FEATURE_ENVMAP)) {
|
||||
vec3 V = normalize(uGeneral.cameraPosition.xyz - fragPosition);
|
||||
vec3 R = reflect(-V, N);
|
||||
vec4 envmapSample = texture(uEnvmap, R);
|
||||
objectColor += (1.0 - diffuseSample.a) * envmapSample.rgb;
|
||||
}
|
||||
if (isFeatureEnabled(FEATURE_WATER)) {
|
||||
objectColor *= uGeneral.waterAlpha;
|
||||
objectAlpha *= uGeneral.waterAlpha;
|
||||
}
|
||||
if (isFeatureEnabled(FEATURE_FOG)) {
|
||||
objectColor = applyFog(objectColor);
|
||||
}
|
||||
|
||||
vec3 objectColorBright;
|
||||
if (isFeatureEnabled(FEATURE_SELFILLUM)) {
|
||||
objectColorBright = smoothstep(SELFILLUM_THRESHOLD, 1.0, uGeneral.selfIllumColor.rgb * diffuseSample.rgb * diffuseSample.a);
|
||||
} else {
|
||||
objectColorBright = vec3(0.0);
|
||||
}
|
||||
|
||||
fragColor = vec4(objectColor, objectAlpha);
|
||||
fragColorBright = vec4(objectColorBright, objectAlpha);
|
||||
}
|
||||
)END";
|
||||
|
||||
char g_shaderFragmentBlinnPhongDiffuseless[] = R"END(
|
||||
void main() {
|
||||
vec3 N = normalize(fragNormal);
|
||||
float shadow = getShadow();
|
||||
|
||||
vec3 lighting;
|
||||
if (isFeatureEnabled(FEATURE_LIGHTMAP)) {
|
||||
vec4 lightmapSample = texture(uLightmap, fragLightmapCoords);
|
||||
lighting = (1.0 - 0.5 * shadow) * lightmapSample.rgb;
|
||||
} else if (isFeatureEnabled(FEATURE_LIGHTING)) {
|
||||
vec3 indirect = getLightingIndirect(N);
|
||||
vec3 direct = getLightingDirect(N);
|
||||
lighting = min(vec3(1.0), indirect + (1.0 - shadow) * direct);
|
||||
} else {
|
||||
lighting = vec3(1.0);
|
||||
}
|
||||
|
||||
vec3 objectColor = lighting * uGeneral.color.rgb;
|
||||
float objectAlpha = uGeneral.alpha;
|
||||
|
||||
fragColor = vec4(objectColor, objectAlpha);
|
||||
fragColorBright = vec4(vec3(0.0), objectAlpha);
|
||||
}
|
||||
)END";
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ void ModelNodeSceneNode::drawSingle(bool shadowPass) {
|
|||
|
||||
} else {
|
||||
program = !_textures.diffuse ?
|
||||
ShaderProgram::ModelBlinnPhongTextureless :
|
||||
ShaderProgram::ModelBlinnPhongDiffuseless :
|
||||
(isFeatureEnabled(Feature::PBR) ? ShaderProgram::ModelPBR : ShaderProgram::ModelBlinnPhong);
|
||||
|
||||
if (_textures.diffuse) {
|
||||
|
|
Loading…
Reference in a new issue