Use a separate (simplified) shader for diffuseless models

This commit is contained in:
Vsevolod Kremianskii 2021-05-07 19:39:40 +07:00
parent e8ff1d9ece
commit e6b70fe6e2
4 changed files with 62 additions and 21 deletions

View file

@ -51,15 +51,16 @@ extern char g_shaderFragmentColor[];
extern char g_shaderFragmentDepth[]; extern char g_shaderFragmentDepth[];
extern char g_shaderFragmentGUI[]; extern char g_shaderFragmentGUI[];
extern char g_shaderFragmentText[]; extern char g_shaderFragmentText[];
extern char g_shaderFragmentBlinnPhong[];
extern char g_shaderFragmentPBR[];
extern char g_shaderFragmentParticle[]; extern char g_shaderFragmentParticle[];
extern char g_shaderFragmentGrass[]; extern char g_shaderFragmentGrass[];
extern char g_shaderFragmentBlur[];
extern char g_shaderFragmentPresentWorld[];
extern char g_shaderFragmentBlinnPhong[];
extern char g_shaderFragmentBlinnPhongTextureless[];
extern char g_shaderFragmentIrradiance[]; extern char g_shaderFragmentIrradiance[];
extern char g_shaderFragmentPrefilter[]; extern char g_shaderFragmentPrefilter[];
extern char g_shaderFragmentBRDF[]; extern char g_shaderFragmentBRDF[];
extern char g_shaderFragmentBlur[]; extern char g_shaderFragmentPBR[];
extern char g_shaderFragmentPresentWorld[];
static constexpr int kBindingPointIndexCombined = 1; static constexpr int kBindingPointIndexCombined = 1;
static constexpr int kBindingPointIndexText = 2; static constexpr int kBindingPointIndexText = 2;
@ -88,15 +89,16 @@ void Shaders::init() {
initShader(ShaderName::FragmentDepth, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentDepth }); initShader(ShaderName::FragmentDepth, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentDepth });
initShader(ShaderName::FragmentGUI, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentGUI }); initShader(ShaderName::FragmentGUI, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentGUI });
initShader(ShaderName::FragmentText, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentText }); initShader(ShaderName::FragmentText, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentText });
initShader(ShaderName::FragmentBlinnPhong, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderBaseModel, g_shaderFragmentBlinnPhong });
initShader(ShaderName::FragmentPBR, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderBasePBR, g_shaderBasePBRIBL, g_shaderBaseModel, g_shaderFragmentPBR });
initShader(ShaderName::FragmentParticle, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentParticle }); initShader(ShaderName::FragmentParticle, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentParticle });
initShader(ShaderName::FragmentGrass, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentGrass }); 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::FragmentIrradiance, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentIrradiance }); 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::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 }); initShader(ShaderName::FragmentBRDF, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderBasePBR, g_shaderBasePBRIBL, g_shaderFragmentBRDF });
initShader(ShaderName::FragmentBlur, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentBlur }); initShader(ShaderName::FragmentPBR, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderBasePBR, g_shaderBasePBRIBL, g_shaderBaseModel, g_shaderFragmentPBR });
initShader(ShaderName::FragmentPresentWorld, GL_FRAGMENT_SHADER, { g_shaderBaseHeader, g_shaderFragmentPresentWorld });
initProgram(ShaderProgram::SimpleColor, { ShaderName::VertexSimple, ShaderName::FragmentColor }); initProgram(ShaderProgram::SimpleColor, { ShaderName::VertexSimple, ShaderName::FragmentColor });
initProgram(ShaderProgram::SimpleDepth, { ShaderName::VertexSimple, ShaderName::GeometryDepth, ShaderName::FragmentDepth }); initProgram(ShaderProgram::SimpleDepth, { ShaderName::VertexSimple, ShaderName::GeometryDepth, ShaderName::FragmentDepth });
@ -108,6 +110,7 @@ void Shaders::init() {
initProgram(ShaderProgram::SimplePresentWorld, { ShaderName::VertexSimple, ShaderName::FragmentPresentWorld }); initProgram(ShaderProgram::SimplePresentWorld, { ShaderName::VertexSimple, ShaderName::FragmentPresentWorld });
initProgram(ShaderProgram::ModelColor, { ShaderName::VertexModel, ShaderName::FragmentColor }); initProgram(ShaderProgram::ModelColor, { ShaderName::VertexModel, ShaderName::FragmentColor });
initProgram(ShaderProgram::ModelBlinnPhong, { ShaderName::VertexModel, ShaderName::FragmentBlinnPhong }); initProgram(ShaderProgram::ModelBlinnPhong, { ShaderName::VertexModel, ShaderName::FragmentBlinnPhong });
initProgram(ShaderProgram::ModelBlinnPhongTextureless, { ShaderName::VertexModel, ShaderName::FragmentBlinnPhongTextureless });
initProgram(ShaderProgram::ModelPBR, { ShaderName::VertexModel, ShaderName::FragmentPBR }); initProgram(ShaderProgram::ModelPBR, { ShaderName::VertexModel, ShaderName::FragmentPBR });
initProgram(ShaderProgram::ParticleParticle, { ShaderName::VertexParticle, ShaderName::FragmentParticle }); initProgram(ShaderProgram::ParticleParticle, { ShaderName::VertexParticle, ShaderName::FragmentParticle });
initProgram(ShaderProgram::GrassGrass, { ShaderName::VertexGrass, ShaderName::FragmentGrass }); initProgram(ShaderProgram::GrassGrass, { ShaderName::VertexGrass, ShaderName::FragmentGrass });

View file

@ -46,6 +46,7 @@ enum class ShaderProgram {
SimplePresentWorld, SimplePresentWorld,
ModelColor, ModelColor,
ModelBlinnPhong, ModelBlinnPhong,
ModelBlinnPhongTextureless,
ModelPBR, ModelPBR,
ParticleParticle, ParticleParticle,
GrassGrass, GrassGrass,
@ -224,6 +225,7 @@ public:
private: private:
enum class ShaderName { enum class ShaderName {
// Common
VertexSimple, VertexSimple,
VertexModel, VertexModel,
VertexParticle, VertexParticle,
@ -235,15 +237,20 @@ private:
FragmentDepth, FragmentDepth,
FragmentGUI, FragmentGUI,
FragmentText, FragmentText,
FragmentBlinnPhong,
FragmentPBR,
FragmentParticle, FragmentParticle,
FragmentGrass, FragmentGrass,
FragmentBlur,
FragmentPresentWorld,
// Blinn-Phong
FragmentBlinnPhong,
FragmentBlinnPhongTextureless,
// PBR
FragmentIrradiance, FragmentIrradiance,
FragmentPrefilter, FragmentPrefilter,
FragmentBRDF, FragmentBRDF,
FragmentBlur, FragmentPBR
FragmentPresentWorld
}; };
bool _inited { false }; bool _inited { false };

View file

@ -28,14 +28,7 @@ namespace graphics {
char g_shaderFragmentBlinnPhong[] = R"END( char g_shaderFragmentBlinnPhong[] = R"END(
void main() { void main() {
vec2 texCoords = fragTexCoords + uGeneral.uvOffset; vec2 texCoords = fragTexCoords + uGeneral.uvOffset;
vec4 diffuseSample = texture(uDiffuse, texCoords);
vec4 diffuseSample;
if (isFeatureEnabled(FEATURE_DIFFUSE)) {
diffuseSample = texture(uDiffuse, texCoords);
} else {
diffuseSample = vec4(vec3(0.5), 1.0);
}
vec3 cameraToFragment = uGeneral.cameraPosition.xyz - fragPosition; vec3 cameraToFragment = uGeneral.cameraPosition.xyz - fragPosition;
vec3 V = normalize(cameraToFragment); vec3 V = normalize(cameraToFragment);
@ -111,6 +104,42 @@ void main() {
} }
)END"; )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 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);
vec3 H = normalize(V + L);
vec3 diff = uMaterial.diffuse.rgb * max(dot(L, N), 0.0);
vec3 diffuse = uLights[i].multiplier * uLights[i].color.rgb * diff;
float spec = uMaterial.specular * pow(max(dot(N, H), 0.0), uMaterial.shininess);
vec3 specular = uLights[i].multiplier * uLights[i].color.rgb * spec;
float attenuation = getLightAttenuation(i);
diffuse *= attenuation;
specular *= attenuation;
direct += diffuse + specular;
}
} else if (isFeatureEnabled(FEATURE_LIGHTMAP)) {
indirect *= texture(uLightmap, fragLightmapCoords).rgb;
}
vec3 objectColor = indirect + direct;
fragColor = vec4(objectColor, uGeneral.alpha);
fragColorBright = vec4(0.0);
}
)END";
} // namespace graphics } // namespace graphics
} // namespace reone } // namespace reone

View file

@ -241,7 +241,9 @@ void ModelNodeSceneNode::drawSingle(bool shadowPass) {
program = ShaderProgram::SimpleDepth; program = ShaderProgram::SimpleDepth;
} else { } else {
program = isFeatureEnabled(Feature::PBR) ? ShaderProgram::ModelPBR : ShaderProgram::ModelBlinnPhong; program = !_textures.diffuse ?
ShaderProgram::ModelBlinnPhongTextureless :
(isFeatureEnabled(Feature::PBR) ? ShaderProgram::ModelPBR : ShaderProgram::ModelBlinnPhong);
if (_textures.diffuse) { if (_textures.diffuse) {
uniforms.combined.featureMask |= UniformFeatureFlags::diffuse; uniforms.combined.featureMask |= UniformFeatureFlags::diffuse;