Implemented linear, exponential, and exponential squared per-pixel fog.

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40162
This commit is contained in:
kearwood
2012-11-21 22:47:33 +00:00
parent 5728b5b000
commit 002ad4bda6
15 changed files with 183 additions and 42 deletions

View File

@@ -120,6 +120,13 @@ KRCamera::KRCamera(KRContext &context) : KRContextObject(context) {
volumetric_environment_max_distance = 1000.0f;
volumetric_environment_quality = (50 - 5.0) / 495.0f;
volumetric_environment_intensity = 1.0f;
fog_near = 500.0f;
fog_far = 1000.0f;
fog_density = 0.01f;
fog_color = KRVector3(0.5, 0.5, 0.5);
fog_type = 0;
}
KRCamera::~KRCamera() {
@@ -336,7 +343,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
}
if(m_pSkyBoxTexture) {
getContext().getShaderManager()->selectShader("sky_box", this, std::vector<KRLight *>(), m_viewport, KRMat4(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE);
getContext().getShaderManager()->selectShader("sky_box", *this, std::vector<KRLight *>(), m_viewport, KRMat4(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE);
getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture);
@@ -462,7 +469,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
matModel.scale((*itr).first.size() / 2.0f);
matModel.translate((*itr).first.center());
if(getContext().getShaderManager()->selectShader(pVisShader, m_viewport, matModel, std::vector<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
if(getContext().getShaderManager()->selectShader(*this, pVisShader, m_viewport, matModel, std::vector<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
}
}
@@ -657,7 +664,7 @@ void KRCamera::renderPost()
GLDEBUG(glDisable(GL_DEPTH_TEST));
KRShader *postShader = m_pContext->getShaderManager()->getShader("PostShader", this, std::vector<KRLight *>(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
getContext().getShaderManager()->selectShader(postShader, m_viewport, KRMat4(), std::vector<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
getContext().getShaderManager()->selectShader(*this, postShader, m_viewport, KRMat4(), std::vector<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
m_pContext->getTextureManager()->selectTexture(0, NULL);
GLDEBUG(glActiveTexture(GL_TEXTURE0));

View File

@@ -123,6 +123,12 @@ public:
float volumetric_environment_quality;
float volumetric_environment_intensity;
float fog_near;
float fog_far;
float fog_density;
KRVector3 fog_color;
int fog_type; // 0 = no fog, 1 = linear, 2 = exponential, 3 = exponential squared
private:
KRVector3 m_position;

View File

@@ -97,7 +97,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector<KRLight *> &light
light_direction_view_space.normalize();
KRShader *pShader = getContext().getShaderManager()->getShader("light_directional", pCamera, this_light, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(getContext().getShaderManager()->selectShader(pShader, viewport, getModelMatrix(), this_light, renderPass)) {
if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), this_light, renderPass)) {
light_direction_view_space.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE]);
m_color.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]);

View File

@@ -137,7 +137,14 @@ float const PI = 3.141592653589793f;
@"volumetric_environment_downsample" : @35,
@"volumetric_environment_max_distance" : @36,
@"volumetric_environment_slices" : @37,
@"volumetric_environment_intensity" : @38
@"volumetric_environment_intensity" : @38,
@"fog_type": @39,
@"fog_near": @40,
@"fog_far": @41,
@"fog_density": @42,
@"fog_color_r": @43,
@"fog_color_g": @44,
@"fog_color_b": @45
} copy];
[self loadShaders];
@@ -200,7 +207,7 @@ float const PI = 3.141592653589793f;
-(int)getParameterCount
{
return 39;
return 46;
}
-(NSString *)getParameterNameWithIndex: (int)i
@@ -210,7 +217,7 @@ float const PI = 3.141592653589793f;
-(NSString *)getParameterLabelWithIndex: (int)i
{
NSString *parameter_labels[39] = {
NSString *parameter_labels[46] = {
@"Camera FOV",
@"Shadow Quality (0 - 2)",
@"Enable per-pixel lighting",
@@ -249,13 +256,20 @@ float const PI = 3.141592653589793f;
@"Volumetric Env. - Resolution",
@"Volumetric Env. - Maximum Distance",
@"Volumetric Env. - Quality",
@"Volumetric Env. - Intensity"
@"Volumetric Env. - Intensity",
@"Fog - Type",
@"Fog - Near",
@"Fog - Far",
@"Fog - Density",
@"Fog - Color R",
@"Fog - Color G",
@"fog - Color B"
};
return parameter_labels[i];
}
-(KREngineParameterType)getParameterTypeWithIndex: (int)i
{
KREngineParameterType types[39] = {
KREngineParameterType types[46] = {
KRENGINE_PARAMETER_FLOAT,
KRENGINE_PARAMETER_INT,
@@ -295,13 +309,20 @@ float const PI = 3.141592653589793f;
KRENGINE_PARAMETER_INT,
KRENGINE_PARAMETER_FLOAT,
KRENGINE_PARAMETER_FLOAT,
KRENGINE_PARAMETER_FLOAT,
KRENGINE_PARAMETER_INT,
KRENGINE_PARAMETER_FLOAT,
KRENGINE_PARAMETER_FLOAT,
KRENGINE_PARAMETER_FLOAT,
KRENGINE_PARAMETER_FLOAT,
KRENGINE_PARAMETER_FLOAT,
KRENGINE_PARAMETER_FLOAT
};
return types[i];
}
-(float)getParameterValueWithIndex: (int)i
{
float values[39] = {
float values[46] = {
_camera->perspective_fov,
(float)_camera->m_cShadowBuffers,
_camera->bEnablePerPixel ? 1.0f : 0.0f,
@@ -340,7 +361,14 @@ float const PI = 3.141592653589793f;
5 - _camera->volumetric_environment_downsample,
_camera->volumetric_environment_max_distance,
_camera->volumetric_environment_quality,
_camera->volumetric_environment_intensity
_camera->volumetric_environment_intensity,
_camera->fog_type,
_camera->fog_near,
_camera->fog_far,
_camera->fog_density,
_camera->fog_color.x,
_camera->fog_color.y,
_camera->fog_color.z
};
return values[i];
}
@@ -506,16 +534,38 @@ float const PI = 3.141592653589793f;
case 38:
_camera->volumetric_environment_intensity = v;
break;
case 39:
_camera->fog_type = v;
break;
case 40:
_camera->fog_near = v;
break;
case 41:
_camera->fog_far = v;
break;
case 42:
_camera->fog_density = v;
break;
case 43:
_camera->fog_color.x = v;
break;
case 44:
_camera->fog_color.y = v;
break;
case 45:
_camera->fog_color.z = v;
break;
}
}
-(float)getParameterMinWithIndex: (int)i
{
float minValues[39] = {
float minValues[46] = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 50.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 50.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
};
return minValues[i];
@@ -523,12 +573,13 @@ float const PI = 3.141592653589793f;
-(float)getParameterMaxWithIndex: (int)i
{
float maxValues[39] = {
float maxValues[46] = {
PI, 3.0f, 1.0f, 1.0, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 10.0f,
1.0f, 10.0f, 2.0f, 1.0f, 1.0f, 1.0f, 5.0f, 1.0f,
0.5f, 1.0f, 2.0f, 2.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1000.0f, 50000.0f,
1.0f, 5.0f, 50000.0f, 1.0f, 10.0f
1.0f, 1.0f, 1.0f, 1.0f, 1000.0f, 10000.0f,
1.0f, 5.0f, 10000.0f, 1.0f, 10.0f,
3.0f, 10000.0f, 10000.0f, 0.10f, 1.0f, 1.0f, 1.0f
};
return maxValues[i];

View File

@@ -156,7 +156,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
KRShader *pFogShader = m_pContext->getShaderManager()->getShader(shader_name, pCamera, this_light, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_ADDITIVE_PARTICLES);
if(getContext().getShaderManager()->selectShader(pFogShader, viewport, KRMat4(), this_light, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE)) {
if(getContext().getShaderManager()->selectShader(*pCamera, pFogShader, viewport, KRMat4(), this_light, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE)) {
int slice_count = (int)(pCamera->volumetric_environment_quality * 495.0) + 5;
float slice_near = -pCamera->getPerspectiveNearZ();
@@ -185,7 +185,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
// Render light flare on transparency pass
KRShader *pShader = getContext().getShaderManager()->getShader("flare", pCamera, lights, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(getContext().getShaderManager()->selectShader(pShader, viewport, getModelMatrix(), lights, renderPass)) {
if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), lights, renderPass)) {
GLDEBUG(glUniform1f(
pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE],
m_flareSize
@@ -297,7 +297,7 @@ void KRLight::renderShadowBuffers(KRCamera *pCamera)
// Use shader program
KRShader *shadowShader = m_pContext->getShaderManager()->getShader("ShadowShader", pCamera, std::vector<KRLight *>(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
getContext().getShaderManager()->selectShader(shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector<KRLight *>(), KRNode::RENDER_PASS_SHADOWMAP);
getContext().getShaderManager()->selectShader(*pCamera, shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector<KRLight *>(), KRNode::RENDER_PASS_SHADOWMAP);
getScene().render(pCamera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP, true);

View File

@@ -201,7 +201,7 @@ bool KRMaterial::isTransparent() {
}
#if TARGET_OS_IPHONE
bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
bool bSameMaterial = *prevBoundMaterial == this;
bool bLightMap = pLightMap && pCamera->bEnableLightMap;
@@ -242,7 +242,7 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, con
bool bSameShader = strcmp(pShader->getKey(), szPrevShaderKey) == 0;
if(!bSameShader) {
if(!getContext().getShaderManager()->selectShader(pShader, viewport, matModel, lights, renderPass)) {
if(!getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, matModel, lights, renderPass)) {
return false;
}

View File

@@ -89,7 +89,7 @@ public:
char *getName();
#if TARGET_OS_IPHONE
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass);
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass);
#endif

View File

@@ -73,7 +73,7 @@ void KRParticleSystemBrownian::render(KRCamera *pCamera, std::vector<KRLight *>
KRShader *pParticleShader = m_pContext->getShaderManager()->getShader("particle", pCamera, lights, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(getContext().getShaderManager()->selectShader(pParticleShader, viewport, getModelMatrix(), lights, renderPass)) {
if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), lights, renderPass)) {
GLDEBUG(glUniform1f(
pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE],
1.0f

View File

@@ -73,7 +73,7 @@ void KRPointLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, con
KRShader *pShader = getContext().getShaderManager()->getShader(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point"), pCamera, this_light, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(getContext().getShaderManager()->selectShader(pShader, viewport, sphereModelMatrix, this_light, renderPass)) {
if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, this_light, renderPass)) {

View File

@@ -239,7 +239,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBo
GLDEBUG(glDepthMask(GL_FALSE));
}
if(getContext().getShaderManager()->selectShader("occlusion_test", pCamera, lights, viewport, matModel, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
if(getContext().getShaderManager()->selectShader("occlusion_test", *pCamera, lights, viewport, matModel, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
}

View File

@@ -183,6 +183,17 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_SLICE_DEPTH_SCALE] = glGetUniformLocation(m_iProgram, "slice_depth_scale"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_VOLUMETRIC_ENVIRONMENT_FRAME] = glGetUniformLocation(m_iProgram, "volumetricEnvironmentFrame"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_FOG_NEAR] = glGetUniformLocation(m_iProgram, "fog_near"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_FOG_FAR] = glGetUniformLocation(m_iProgram, "fog_far"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_FOG_DENSITY] = glGetUniformLocation(m_iProgram, "fog_density"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_FOG_COLOR] = glGetUniformLocation(m_iProgram, "fog_color"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_FOG_SCALE] = glGetUniformLocation(m_iProgram, "fog_scale"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL] = glGetUniformLocation(m_iProgram, "fog_density_premultiplied_exponential"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED] = glGetUniformLocation(m_iProgram, "fog_density_premultiplied_squared"));
}
} catch(...) {
@@ -217,17 +228,17 @@ KRShader::~KRShader() {
#if TARGET_OS_IPHONE
bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass) const {
bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass) const {
if(m_iProgram == 0) {
return false;
}
// FINDME - HACK - Temporary placeholder code
GLDEBUG(glUseProgram(m_iProgram));
int light_directional_count = 0;
int light_point_count = 0;
int light_spot_count = 0;
// TODO - Need to support multiple lights and more light types in forward rendering
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_DEFERRED_GBUFFER && renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE) {
for(std::vector<KRLight *>::const_iterator light_itr=lights.begin(); light_itr != lights.end(); light_itr++) {
KRLight *light = (*light_itr);
@@ -378,6 +389,22 @@ bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const st
));
}
// Fog parameters
GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_FOG_NEAR], camera.fog_near));
GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_FOG_FAR], camera.fog_far));
GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_FOG_DENSITY], camera.fog_density));
camera.fog_color.setUniform(m_uniforms[KRENGINE_UNIFORM_FOG_COLOR]);
if(m_uniforms[KRENGINE_UNIFORM_FOG_SCALE] != -1) {
GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_FOG_SCALE], 1.0f / (camera.fog_far - camera.fog_near)));
}
if(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL] != -1) {
GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL], -camera.fog_density * 1.442695f)); // -fog_density / log(2)
}
if(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED] != -1) {
GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED], -camera.fog_density * camera.fog_density * 1.442695)); // -fog_density * fog_density / log(2)
}
// Sets the diffuseTexture variable to the first texture unit
GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_DIFFUSETEXTURE], 0));

View File

@@ -56,7 +56,7 @@ public:
#if TARGET_OS_IPHONE
bool bind(const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass) const;
bool bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass) const;
#endif
@@ -129,6 +129,15 @@ public:
KRENGINE_UNIFORM_VOLUMETRIC_ENVIRONMENT_FRAME,
KRENGINE_UNIFORM_RENDER_FRAME,
KRENGINE_UNIFORM_FOG_NEAR,
KRENGINE_UNIFORM_FOG_FAR,
KRENGINE_UNIFORM_FOG_DENSITY,
KRENGINE_UNIFORM_FOG_COLOR,
KRENGINE_UNIFORM_FOG_SCALE,
KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL,
KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED,
KRENGINE_UNIFORM_SLICE_DEPTH_SCALE,
KRENGINE_NUM_UNIFORMS

View File

@@ -50,7 +50,7 @@ KRShaderManager::~KRShaderManager() {
}
KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCamera *pCamera, const std::vector<KRLight *> &lights, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) {
KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector<KRLight *> &lights, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) {
int iShadowQuality = 0; // FINDME - HACK - Placeholder code, need to iterate through lights and dynamically build shader
@@ -75,7 +75,7 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCam
char szKey[256];
sprintf(szKey, "%i_%i_%i_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s_%i_%d_%d_%f_%f_%f_%f_%f_%f_%f", light_directional_count, light_point_count, light_spot_count, pCamera->bEnablePerPixel, bAlphaTest, bAlphaBlend, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, pCamera->bDebugPSSM, iShadowQuality, pCamera->bEnableAmbient, pCamera->bEnableDiffuse, pCamera->bEnableSpecular, bLightMap, bDiffuseMapScale, bSpecMapScale, bReflectionMapScale, bNormalMapScale, bDiffuseMapOffset, bSpecMapOffset, bReflectionMapOffset, bNormalMapOffset,pCamera->volumetric_environment_enable && pCamera->volumetric_environment_downsample != 0, renderPass, shader_name.c_str(),pCamera->dof_quality,pCamera->bEnableFlash,pCamera->bEnableVignette,pCamera->dof_depth,pCamera->dof_falloff,pCamera->flash_depth,pCamera->flash_falloff,pCamera->flash_intensity,pCamera->vignette_radius,pCamera->vignette_falloff);
sprintf(szKey, "%i_%i_%i_%i_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s_%i_%d_%d_%f_%f_%f_%f_%f_%f_%f", light_directional_count, light_point_count, light_spot_count, pCamera->fog_type, pCamera->bEnablePerPixel,bAlphaTest, bAlphaBlend, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, pCamera->bDebugPSSM, iShadowQuality, pCamera->bEnableAmbient, pCamera->bEnableDiffuse, pCamera->bEnableSpecular, bLightMap, bDiffuseMapScale, bSpecMapScale, bReflectionMapScale, bNormalMapScale, bDiffuseMapOffset, bSpecMapOffset, bReflectionMapOffset, bNormalMapOffset,pCamera->volumetric_environment_enable && pCamera->volumetric_environment_downsample != 0, renderPass, shader_name.c_str(),pCamera->dof_quality,pCamera->bEnableFlash,pCamera->bEnableVignette,pCamera->dof_depth,pCamera->dof_falloff,pCamera->flash_depth,pCamera->flash_falloff,pCamera->flash_intensity,pCamera->vignette_radius,pCamera->vignette_falloff);
KRShader *pShader = m_shaders[szKey];
@@ -122,6 +122,7 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCam
stream << "\n#define ENABLE_AMBIENT " << (pCamera->bEnableAmbient ? "1" : "0");
stream << "\n#define ENABLE_DIFFUSE " << (pCamera->bEnableDiffuse ? "1" : "0");
stream << "\n#define ENABLE_SPECULAR " << (pCamera->bEnableSpecular ? "1" : "0");
stream << "\n#define FOG_TYPE " << pCamera->fog_type;
switch(renderPass) {
case KRNode::RENDER_PASS_DEFERRED_GBUFFER:
stream << "\n#define GBUFFER_PASS " << 1;
@@ -137,7 +138,6 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCam
break;
}
stream << "\n#define DOF_QUALITY " << pCamera->dof_quality;
stream << "\n#define ENABLE_FLASH " << (pCamera->bEnableFlash ? "1" : "0");
stream << "\n#define ENABLE_VIGNETTE " << (pCamera->bEnableVignette ? "1" : "0");
@@ -167,19 +167,19 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCam
return pShader;
}
bool KRShaderManager::selectShader(const std::string &shader_name, const KRCamera *pCamera, const std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass)
bool KRShaderManager::selectShader(const std::string &shader_name, KRCamera &camera, const std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass)
{
KRShader *pShader = getShader(shader_name, pCamera, lights, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, bDiffuseMapScale, bSpecMapScale, bNormalMapScale, bReflectionMapScale, bDiffuseMapOffset, bSpecMapOffset, bNormalMapOffset, bReflectionMapOffset, bAlphaTest, bAlphaBlend, renderPass);
return selectShader(pShader, viewport, matModel, lights, renderPass);
KRShader *pShader = getShader(shader_name, &camera, lights, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, bDiffuseMapScale, bSpecMapScale, bNormalMapScale, bReflectionMapScale, bDiffuseMapOffset, bSpecMapOffset, bNormalMapOffset, bReflectionMapOffset, bAlphaTest, bAlphaBlend, renderPass);
return selectShader(camera, pShader, viewport, matModel, lights, renderPass);
}
bool KRShaderManager::selectShader(const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass)
bool KRShaderManager::selectShader(KRCamera &camera, const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass)
{
if(pShader) {
bool bSameShader = strcmp(pShader->getKey(), m_szCurrentShaderKey) == 0;
if(!bSameShader) {
strcpy(m_szCurrentShaderKey, pShader->getKey());
return pShader->bind(viewport, matModel, lights, renderPass);
return pShader->bind(camera, viewport, matModel, lights, renderPass);
} else {
return true;
}

View File

@@ -59,11 +59,11 @@ public:
const std::string &getVertShaderSource(const std::string &name);
KRShader *getShader(const std::string &shader_name, const KRCamera *pCamera, const std::vector<KRLight *> &lights, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass);
KRShader *getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector<KRLight *> &lights, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass);
bool selectShader(const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass);
bool selectShader(KRCamera &camera, const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass);
bool selectShader(const std::string &shader_name, const KRCamera *pCamera, const std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass);
bool selectShader(const std::string &shader_name, KRCamera &camera, const std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass);
long getShaderHandlesUsed();

View File

@@ -27,6 +27,30 @@
#extension GL_EXT_shadow_samplers : require
#if FOG_TYPE > 0
// FOG_TYPE 1 - Linear
// FOG_TYPE 2 - Exponential
// FOG_TYPE 3 - Exponential squared
uniform lowp vec3 fog_color;
uniform mediump float fog_near;
#if FOG_TYPE == 1
uniform mediump float fog_far;
uniform mediump float fog_scale;
#endif
#if FOG_TYPE > 1
uniform mediump float fog_density;
#endif
#if FOG_TYPE == 2
uniform mediump float fog_density_premultiplied_exponential;
#endif
#if FOG_TYPE == 3
uniform mediump float fog_density_premultiplied_squared;
#endif
#endif
#if ENABLE_PER_PIXEL == 1 || GBUFFER_PASS == 1
uniform mediump float material_shininess;
#if HAS_NORMAL_MAP == 1
@@ -314,9 +338,8 @@ void main()
#endif
#endif
// -------------------- Add specular light --------------------
#if ENABLE_SPECULAR == 1
// -------------------- Add specular light --------------------
#if HAS_SPEC_MAP == 1 && ENABLE_PER_PIXEL == 1
gl_FragColor += vec4(material_specular * vec3(texture2D(specularTexture, spec_uv)) * specularFactor, 0.0);
#else
@@ -329,11 +352,29 @@ void main()
gl_FragColor.a = gl_FragColor.a * material_alpha;
#endif
// -------------------- Multiply light map --------------------
// -------------------- Multiply light map --------------------
#if HAS_LIGHT_MAP == 1
mediump vec3 lightMapColor = vec3(texture2D(lightmapTexture, lightmap_uv));
gl_FragColor = vec4(gl_FragColor.r * lightMapColor.r, gl_FragColor.g * lightMapColor.g, gl_FragColor.b * lightMapColor.b, gl_FragColor.a);
#endif
// -------------------- Apply Fog --------------------
#if FOG_TYPE == 1
// Linear fog
gl_FragColor.rgb = mix(fog_color.rgb, gl_FragColor.rgb, clamp((fog_far - gl_FragCoord.z / gl_FragCoord.w) * fog_scale, 0.0, 1.0));
#endif
#if FOG_TYPE == 2
// Exponential fog
mediump float fog_z = gl_FragCoord.z / gl_FragCoord.w - fog_near;
gl_FragColor.rgb = mix(fog_color.rgb, gl_FragColor.rgb, clamp(exp2(fog_density_premultiplied_exponential * fog_z), 0.0, 1.0));
#endif
#if FOG_TYPE == 3
// Exponential squared fog
mediump float fog_z = max(gl_FragCoord.z / gl_FragCoord.w - fog_near, 0.0);
gl_FragColor.rgb = mix(fog_color.rgb, gl_FragColor.rgb, clamp(exp2(fog_density_premultiplied_squared * fog_z * fog_z), 0.0, 1.0));
#endif
#endif
}