diff --git a/KREngine/KREngine/Classes/KRCamera.cpp b/KREngine/KREngine/Classes/KRCamera.cpp index bb87151..ac77228 100644 --- a/KREngine/KREngine/Classes/KRCamera.cpp +++ b/KREngine/KREngine/Classes/KRCamera.cpp @@ -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(), 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(), 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(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { + if(getContext().getShaderManager()->selectShader(*this, pVisShader, m_viewport, matModel, std::vector(), 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(), 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(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + getContext().getShaderManager()->selectShader(*this, postShader, m_viewport, KRMat4(), std::vector(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT); m_pContext->getTextureManager()->selectTexture(0, NULL); GLDEBUG(glActiveTexture(GL_TEXTURE0)); diff --git a/KREngine/KREngine/Classes/KRCamera.h b/KREngine/KREngine/Classes/KRCamera.h index bccbeb1..13752a2 100644 --- a/KREngine/KREngine/Classes/KRCamera.h +++ b/KREngine/KREngine/Classes/KRCamera.h @@ -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; diff --git a/KREngine/KREngine/Classes/KRDirectionalLight.cpp b/KREngine/KREngine/Classes/KRDirectionalLight.cpp index f5afa0b..1ae676f 100644 --- a/KREngine/KREngine/Classes/KRDirectionalLight.cpp +++ b/KREngine/KREngine/Classes/KRDirectionalLight.cpp @@ -97,7 +97,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector &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]); diff --git a/KREngine/KREngine/Classes/KREngine.mm b/KREngine/KREngine/Classes/KREngine.mm index 4d1325c..131e1bb 100644 --- a/KREngine/KREngine/Classes/KREngine.mm +++ b/KREngine/KREngine/Classes/KREngine.mm @@ -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]; diff --git a/KREngine/KREngine/Classes/KRLight.cpp b/KREngine/KREngine/Classes/KRLight.cpp index b09d811..bcbaab3 100644 --- a/KREngine/KREngine/Classes/KRLight.cpp +++ b/KREngine/KREngine/Classes/KRLight.cpp @@ -156,7 +156,7 @@ void KRLight::render(KRCamera *pCamera, std::vector &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 &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(), 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(), KRNode::RENDER_PASS_SHADOWMAP); + getContext().getShaderManager()->selectShader(*pCamera, shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector(), KRNode::RENDER_PASS_SHADOWMAP); getScene().render(pCamera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP, true); diff --git a/KREngine/KREngine/Classes/KRMaterial.cpp b/KREngine/KREngine/Classes/KRMaterial.cpp index f297624..ed92c46 100644 --- a/KREngine/KREngine/Classes/KRMaterial.cpp +++ b/KREngine/KREngine/Classes/KRMaterial.cpp @@ -201,7 +201,7 @@ bool KRMaterial::isTransparent() { } #if TARGET_OS_IPHONE -bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, std::vector &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) { +bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector &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; } diff --git a/KREngine/KREngine/Classes/KRMaterial.h b/KREngine/KREngine/Classes/KRMaterial.h index e4812bf..a3ee627 100644 --- a/KREngine/KREngine/Classes/KRMaterial.h +++ b/KREngine/KREngine/Classes/KRMaterial.h @@ -89,7 +89,7 @@ public: char *getName(); #if TARGET_OS_IPHONE - bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, std::vector &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass); + bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass); #endif diff --git a/KREngine/KREngine/Classes/KRParticleSystemBrownian.cpp b/KREngine/KREngine/Classes/KRParticleSystemBrownian.cpp index 9c674c0..024a6f0 100644 --- a/KREngine/KREngine/Classes/KRParticleSystemBrownian.cpp +++ b/KREngine/KREngine/Classes/KRParticleSystemBrownian.cpp @@ -73,7 +73,7 @@ void KRParticleSystemBrownian::render(KRCamera *pCamera, std::vector 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 diff --git a/KREngine/KREngine/Classes/KRPointLight.cpp b/KREngine/KREngine/Classes/KRPointLight.cpp index f602633..ee87e7b 100644 --- a/KREngine/KREngine/Classes/KRPointLight.cpp +++ b/KREngine/KREngine/Classes/KRPointLight.cpp @@ -73,7 +73,7 @@ void KRPointLight::render(KRCamera *pCamera, std::vector &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)) { diff --git a/KREngine/KREngine/Classes/KRScene.cpp b/KREngine/KREngine/Classes/KRScene.cpp index e74d842..1c0bd64 100644 --- a/KREngine/KREngine/Classes/KRScene.cpp +++ b/KREngine/KREngine/Classes/KRScene.cpp @@ -239,7 +239,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::map &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)); } diff --git a/KREngine/KREngine/Classes/KRShader.cpp b/KREngine/KREngine/Classes/KRShader.cpp index 66ac368..f39dbfd 100644 --- a/KREngine/KREngine/Classes/KRShader.cpp +++ b/KREngine/KREngine/Classes/KRShader.cpp @@ -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 &lights, const KRNode::RenderPass &renderPass) const { +bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &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::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)); diff --git a/KREngine/KREngine/Classes/KRShader.h b/KREngine/KREngine/Classes/KRShader.h index d0ef2ab..0b287b6 100644 --- a/KREngine/KREngine/Classes/KRShader.h +++ b/KREngine/KREngine/Classes/KRShader.h @@ -56,7 +56,7 @@ public: #if TARGET_OS_IPHONE - bool bind(const KRViewport &viewport, const KRMat4 &matModel, const std::vector &lights, const KRNode::RenderPass &renderPass) const; + bool bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &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 diff --git a/KREngine/KREngine/Classes/KRShaderManager.cpp b/KREngine/KREngine/Classes/KRShaderManager.cpp index 32ed025..04c991a 100644 --- a/KREngine/KREngine/Classes/KRShaderManager.cpp +++ b/KREngine/KREngine/Classes/KRShaderManager.cpp @@ -50,7 +50,7 @@ KRShaderManager::~KRShaderManager() { } -KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCamera *pCamera, const std::vector &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 &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 &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 &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 &lights, const KRNode::RenderPass &renderPass) +bool KRShaderManager::selectShader(KRCamera &camera, const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &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; } diff --git a/KREngine/KREngine/Classes/KRShaderManager.h b/KREngine/KREngine/Classes/KRShaderManager.h index 712d659..3cbc826 100644 --- a/KREngine/KREngine/Classes/KRShaderManager.h +++ b/KREngine/KREngine/Classes/KRShaderManager.h @@ -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 &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 &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 &lights, const KRNode::RenderPass &renderPass); + bool selectShader(KRCamera &camera, const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &lights, const KRNode::RenderPass &renderPass); - bool selectShader(const std::string &shader_name, const KRCamera *pCamera, const std::vector &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 &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(); diff --git a/KREngine/KREngine/Shaders/ObjectShader.fsh b/KREngine/KREngine/Shaders/ObjectShader.fsh index 84107d1..b6cdef4 100644 --- a/KREngine/KREngine/Shaders/ObjectShader.fsh +++ b/KREngine/KREngine/Shaders/ObjectShader.fsh @@ -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 }