Improve shadow on postshader and add a gamma sRGB color space convertion

This commit is contained in:
Mario Luzeiro 2016-09-30 21:25:39 +01:00 committed by Wayne Stambaugh
parent 49dce5d191
commit 89bb47ede6
5 changed files with 109 additions and 51 deletions

View File

@ -71,7 +71,7 @@ void C3D_RENDER_RAYTRACING::setupMaterials()
glm::clamp( ((SFVEC3F)(1.0f) - glm::clamp( ((SFVEC3F)(1.0f) -
(SFVEC3F)m_settings.m_CopperColor), (SFVEC3F)m_settings.m_CopperColor),
SFVEC3F( 0.0f ), SFVEC3F( 0.0f ),
SFVEC3F( 0.40f ) ), // specular SFVEC3F( 0.45f ) ), // specular
shininessfactor * 128.0f, // shiness shininessfactor * 128.0f, // shiness
0.0f, // transparency 0.0f, // transparency
0.0f ); 0.0f );
@ -92,7 +92,7 @@ void C3D_RENDER_RAYTRACING::setupMaterials()
glm::clamp( ((SFVEC3F)(1.0f) - glm::clamp( ((SFVEC3F)(1.0f) -
(SFVEC3F)m_settings.m_SilkScreenColor), (SFVEC3F)m_settings.m_SilkScreenColor),
SFVEC3F( 0.0f ), SFVEC3F( 0.0f ),
SFVEC3F( 0.1f ) ), // specular SFVEC3F( 0.10f ) ), // specular
0.078125f * 128.0f, // shiness 0.078125f * 128.0f, // shiness
0.0f, // transparency 0.0f, // transparency
0.0f ); 0.0f );
@ -244,10 +244,10 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
m_lights.Clear(); m_lights.Clear();
// This will work as the front camera light. // This will work as the front camera light.
const float light_camera_intensity = 0.17f; const float light_camera_intensity = 0.15;
const float light_directional_intensity_top = 0.15f; const float light_directional_intensity_top = 0.2;
const float light_directional_intensity = ( 1.0f - ( light_camera_intensity + const float light_directional_intensity = ( 1.0f - ( light_camera_intensity +
light_directional_intensity_top ) ) / 4.0f; light_directional_intensity_top ) ) / 2.0f;
m_camera_light = new CDIRECTIONALLIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ), m_camera_light = new CDIRECTIONALLIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ),
SFVEC3F( light_camera_intensity ) ); SFVEC3F( light_camera_intensity ) );

View File

@ -37,6 +37,10 @@
#include "3d_math.h" #include "3d_math.h"
#include "../common_ogl/ogl_utils.h" #include "../common_ogl/ogl_utils.h"
// This should be used in future for the function
// convertLinearToSRGB
//#include <glm/gtc/color_space.hpp>
#ifdef _OPENMP #ifdef _OPENMP
#include <omp.h> #include <omp.h>
#endif #endif
@ -418,6 +422,49 @@ void C3D_RENDER_RAYTRACING::rt_render_tracing( GLubyte *ptrPBO ,
} }
} }
#define USE_SRGB_SPACE
#ifdef USE_SRGB_SPACE
// This should be removed in future when the KiCad support a greater version of
// glm lib.
// This function implements the conversion from linear RGB to sRGB
// https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L12
static SFVEC3F convertLinearToSRGB( const SFVEC3F &aRGBcolor )
{
const float gammaCorrection = 1.0f / 1.3f;
const SFVEC3F clampedColor = glm::clamp( aRGBcolor, SFVEC3F(0.0f), SFVEC3F(1.0f) );
return glm::mix(
glm::pow( clampedColor, SFVEC3F(gammaCorrection) ) * 1.055f - 0.055f,
clampedColor * 12.92f,
glm::lessThan( clampedColor, SFVEC3F(0.0031308f) ) );
}
#endif
void C3D_RENDER_RAYTRACING::rt_final_color( GLubyte *ptrPBO,
const SFVEC3F &rgbColor,
bool applyColorSpaceConversion )
{
SFVEC3F color = rgbColor;
#ifdef USE_SRGB_SPACE
// This should be used in future when the KiCad support a greater version of
// glm lib.
// if( applyColorSpaceConversion )
// rgbColor = glm::convertLinearToSRGB( rgbColor );
if( applyColorSpaceConversion )
color = convertLinearToSRGB( rgbColor );
#endif
ptrPBO[0] = (unsigned int)glm::clamp( (int)(color.r * 255), 0, 255 );
ptrPBO[1] = (unsigned int)glm::clamp( (int)(color.g * 255), 0, 255 );
ptrPBO[2] = (unsigned int)glm::clamp( (int)(color.b * 255), 0, 255 );
ptrPBO[3] = 255;
}
void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO , void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
signed int iBlock ) signed int iBlock )
@ -485,6 +532,9 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
// If post processing is enabled, it will not reflect the final result // If post processing is enabled, it will not reflect the final result
// (as the final color will be computed on post processing) // (as the final color will be computed on post processing)
// but it is used for report progress // but it is used for report progress
const bool isFinalColor = !m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING );
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
{ {
const SFVEC3F &outColor = bgColor[y]; const SFVEC3F &outColor = bgColor[y];
@ -496,10 +546,7 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
{ {
GLubyte *ptr = &ptrPBO[ (yConst + x) * 4 ]; GLubyte *ptr = &ptrPBO[ (yConst + x) * 4 ];
ptr[0] = (unsigned int)glm::clamp( (int)(outColor.r * 255), 0, 255 ); rt_final_color( ptr, outColor, isFinalColor );
ptr[1] = (unsigned int)glm::clamp( (int)(outColor.g * 255), 0, 255 );
ptr[2] = (unsigned int)glm::clamp( (int)(outColor.b * 255), 0, 255 );
ptr[3] = 255;
} }
} }
@ -1081,6 +1128,13 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
hColor = hColor * 0.60f + aaColor * 0.40f; hColor = hColor * 0.60f + aaColor * 0.40f;
} }
// This will set the output color to be displayed
// If post processing is enabled, it will not reflect the final result
// (as the final color will be computed on post processing)
// but it is used for report progress
GLubyte *ptr = &ptrPBO[ ( blockPos.x + x +
((y + blockPos.y) * m_realBufferSize.x) ) * 4 ];
if( m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) ) if( m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
{ {
if( hitPacket[i].m_hitresult == true ) if( hitPacket[i].m_hitresult == true )
@ -1099,19 +1153,12 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
0, 0,
1.0f ); 1.0f );
rt_final_color( ptr, hColor, false );
}
else
{
rt_final_color( ptr, hColor, true );
} }
// This will set the output color to be displayed
// If post processing is enabled, it will not reflect the final result
// (as the final color will be computed on post processing)
// but it is used for report progress
GLubyte *ptr = &ptrPBO[ ( blockPos.x + x +
((y + blockPos.y) * m_realBufferSize.x) ) * 4 ];
ptr[0] = (unsigned int)glm::clamp( (int)(hColor.r * 255), 0, 255 );
ptr[1] = (unsigned int)glm::clamp( (int)(hColor.g * 255), 0, 255 );
ptr[2] = (unsigned int)glm::clamp( (int)(hColor.b * 255), 0, 255 );
ptr[3] = 255;
} }
} }
} }
@ -1260,27 +1307,37 @@ void C3D_RENDER_RAYTRACING::rt_render_post_process_blur_finish( GLubyte *ptrPBO,
bluredShadeColor.g + bluredShadeColor.g +
bluredShadeColor.b ) / 3.0f; bluredShadeColor.b ) / 3.0f;
const SFVEC3F shadedColor = m_postshader_ssao.GetColorAtNotProtected( const SFVEC3F &originalColor = m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x, y ) );
SFVEC2I( x, y ) ) * ( SFVEC3F(1.0f) -
bluredShadeColor ) - float luminanceColor = (originalColor.r * 0.2126f +
( bluredShadeColor - grayBluredColor * 0.5f ); originalColor.g * 0.7152f +
originalColor.b * 0.0722f);
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoeCoxLjMtMC4xNSkqKC14KjEuMysyLjE1KSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjQ5MjM4OTg5MzY5NjAyNCIsIjIuMTY2Nzg0ODAzNTQyNDk4IiwiLTAuNjYzNzYwNzIzNzUyMjA5NSIsIjEuNTg4MDM5MDg5OTMzMDM0NiJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
// luminanceColor = (+luminanceColor * 1.3f - 0.15f) *
// (-luminanceColor * 1.3f + 2.15f);
// http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoeC0wLjEpKjkiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC45OTI5NjA0NzE5OTg5Njk1IiwiMS45MzQzNzkyODU3OTE4NDYzIiwiLTAuNDE1MTAzMzMwNzkyMzc5NyIsIjEuMzg2MzM2NTIwMTU1ODE0MiJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
luminanceColor = (luminanceColor - 0.10f) * 9.0f;
luminanceColor = glm::clamp( luminanceColor, 0.0f, 1.0f );
const SFVEC3F shadedColor = ( originalColor *
( SFVEC3F(1.0f) - 2.0f * bluredShadeColor * luminanceColor ) ) -
( bluredShadeColor - (grayBluredColor * 0.65f) );
// Debug code // Debug code
//const SFVEC3F shadedColor = ( bluredShadeColor - grayBluredColor * 0.5f); //const SFVEC3F shadedColor = bluredShadeColor;
//const SFVEC3F shadedColor = - glm::min( bluredShadeColor, SFVEC3F(0.0f) ); //const SFVEC3F shadedColor = SFVEC3F(grayOriginalColorFactor);
//const SFVEC3F shadedColor = 0.5f * (SFVEC3F(1.0f) - bluredShadeColor) -
// glm::min( bluredShadeColor, SFVEC3F(0.0f) );
//const SFVEC3F shadedColor = bluredShadeColor;
#else #else
// Debug code // Debug code
//const SFVEC3F shadedColor = SFVEC3F( 1.0f ) - //const SFVEC3F shadedColor = SFVEC3F( 1.0f ) -
// m_shaderBuffer[ y * m_realBufferSize.x + x]; // m_shaderBuffer[ y * m_realBufferSize.x + x];
const SFVEC3F shadedColor = m_shaderBuffer[ y * m_realBufferSize.x + x ]; const SFVEC3F shadedColor = m_shaderBuffer[ y * m_realBufferSize.x + x ];
#endif #endif
ptr[0] = (unsigned int)glm::clamp( (int)(shadedColor.r * 255), 0, 255 );
ptr[1] = (unsigned int)glm::clamp( (int)(shadedColor.g * 255), 0, 255 ); rt_final_color( ptr, shadedColor, true );
ptr[2] = (unsigned int)glm::clamp( (int)(shadedColor.b * 255), 0, 255 );
ptr[3] = 255;
ptr += 4; ptr += 4;
} }
} }
@ -1289,7 +1346,7 @@ void C3D_RENDER_RAYTRACING::rt_render_post_process_blur_finish( GLubyte *ptrPBO,
#pragma omp barrier #pragma omp barrier
// Debug code // Debug code
//m_postshader_ssao.DebugBuffersOutputAsImages(); m_postshader_ssao.DebugBuffersOutputAsImages();
} }
// End rendering // End rendering
@ -2074,6 +2131,7 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
} }
} }
// Improvement: this is not taking in account the lightcolor
if( nr_lights_that_can_cast_shadows > 0 ) if( nr_lights_that_can_cast_shadows > 0 )
{ {
aHitInfo.m_ShadowFactor = shadow_att_factor_sum / aHitInfo.m_ShadowFactor = shadow_att_factor_sum /

View File

@ -81,6 +81,7 @@ private:
void rt_render_post_process_shade( GLubyte *ptrPBO , REPORTER *aStatusTextReporter ); void rt_render_post_process_shade( GLubyte *ptrPBO , REPORTER *aStatusTextReporter );
void rt_render_post_process_blur_finish( GLubyte *ptrPBO , REPORTER *aStatusTextReporter ); void rt_render_post_process_blur_finish( GLubyte *ptrPBO , REPORTER *aStatusTextReporter );
void rt_render_trace_block( GLubyte *ptrPBO , signed int iBlock ); void rt_render_trace_block( GLubyte *ptrPBO , signed int iBlock );
void rt_final_color( GLubyte *ptrPBO, const SFVEC3F &rgbColor, bool applyColorSpaceConversion );
// Materials // Materials
void setupMaterials(); void setupMaterials();

View File

@ -71,8 +71,8 @@ CMATERIAL::CMATERIAL( const SFVEC3F &aAmbient,
// This may be a good value if based on nr of lights // This may be a good value if based on nr of lights
// that contribute to the illumination of that point // that contribute to the illumination of that point
#define AMBIENT_FACTOR (1.0f/6.0f) #define AMBIENT_FACTOR (1.0f / 6.0f)
#define SPECULAR_FACTOR 1.000f #define SPECULAR_FACTOR 1.0f
// https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model // https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model
SFVEC3F CBLINN_PHONG_MATERIAL::Shade( const RAY &aRay, SFVEC3F CBLINN_PHONG_MATERIAL::Shade( const RAY &aRay,
@ -85,13 +85,13 @@ SFVEC3F CBLINN_PHONG_MATERIAL::Shade( const RAY &aRay,
{ {
wxASSERT( NdotL >= FLT_EPSILON ); wxASSERT( NdotL >= FLT_EPSILON );
//const float ambientFactor = AMBIENT_FACTOR; const float ambientFactor = AMBIENT_FACTOR;
// This is a hack to get some kind of fake ambient illumination // This is a hack to get some kind of fake ambient illumination
// There is no logic behind this, just pure artistic experimentation // There is no logic behind this, just pure artistic experimentation
const float ambientFactor = glm::max( ( (1.0f - NdotL) /** (1.0f - NdotL)*/ ) * //const float ambientFactor = glm::max( ( (1.0f - NdotL) /** (1.0f - NdotL)*/ ) *
( AMBIENT_FACTOR + AMBIENT_FACTOR ), // ( AMBIENT_FACTOR + AMBIENT_FACTOR ),
AMBIENT_FACTOR ); // AMBIENT_FACTOR );
if( aShadowAttenuationFactor > FLT_EPSILON ) if( aShadowAttenuationFactor > FLT_EPSILON )
{ {

View File

@ -84,9 +84,11 @@ float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos,
//shadow_factor = (1.0f / ( shadow_factor * 1.7f + 1.9f ))- 0.28f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoMS4wLyh4KjEuNysxLjkpKS0wLjI4IiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuNTk5NTUxMjY3NTY5ODI1IiwiMS4yNzM5NDYxNzc0MTYyOTg4IiwiLTAuMTE0MzIxNTY5MjEzMDEwMDgiLCIxLjAzODU5OTkzNTM5MzgzNTMiXX1d //shadow_factor = (1.0f / ( shadow_factor * 1.7f + 1.9f ))- 0.28f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoMS4wLyh4KjEuNysxLjkpKS0wLjI4IiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuNTk5NTUxMjY3NTY5ODI1IiwiMS4yNzM5NDYxNzc0MTYyOTg4IiwiLTAuMTE0MzIxNTY5MjEzMDEwMDgiLCIxLjAzODU5OTkzNTM5MzgzNTMiXX1d
//shadow_factor = (shadow_factor - 0.1); //shadow_factor = (shadow_factor - 0.1);
//shadow_factor = (1.0f / ( shadow_factor * shadow_factor * 1.7f + 1.1f ))- 0.58f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoMS4wLygoeC0wLjEpKih4LTAuMSkqMS43KzEuMSkpLTAuNTgiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC41OTk1NTEyNjc1Njk4MjUiLCIxLjI3Mzk0NjE3NzQxNjI5ODgiLCItMC4xMTQzMjE1NjkyMTMwMTAwOCIsIjEuMDM4NTk5OTM1MzkzODM1MyJdLCJzaXplIjpbNjQ5LDM5OV19XQ-- //shadow_factor = (1.0f / ( shadow_factor * shadow_factor * 1.7f + 1.1f ))- 0.58f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoMS4wLygoeC0wLjEpKih4LTAuMSkqMS43KzEuMSkpLTAuNTgiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC41OTk1NTEyNjc1Njk4MjUiLCIxLjI3Mzk0NjE3NzQxNjI5ODgiLCItMC4xMTQzMjE1NjkyMTMwMTAwOCIsIjEuMDM4NTk5OTM1MzkzODM1MyJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
//shadow_factor = -shadow_factor * shadow_factor * 0.2f + 0.15f; //http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoLXgqMC4yKzAuMTUpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuNTk5NTUxMjY3NTY5ODI1IiwiMS4yNzM5NDYxNzc0MTYyOTg4IiwiLTAuMTE0MzIxNTY5MjEzMDEwMDgiLCIxLjAzODU5OTkzNTM5MzgzNTMiXSwic2l6ZSI6WzY0OSwzOTldfV0- //shadow_factor = -shadow_factor * shadow_factor * 0.1f + 0.10f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoLXgqMC4xMCswLjEwKSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjU5OTU1MTI2NzU2OTgyNSIsIjEuMjczOTQ2MTc3NDE2Mjk4OCIsIi0wLjExNDMyMTU2OTIxMzAxMDA4IiwiMS4wMzg1OTk5MzUzOTM4MzUzIl0sInNpemUiOls2NDksMzk5XX1d
shadow_factor = -shadow_factor * shadow_factor * 0.3f + 0.25f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoLXgqMC4zKzAuMjUpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuNTk5NTUxMjY3NTY5ODI1IiwiMS4yNzM5NDYxNzc0MTYyOTg4IiwiLTAuMTE0MzIxNTY5MjEzMDEwMDgiLCIxLjAzODU5OTkzNTM5MzgzNTMiXSwic2l6ZSI6WzY0OSwzOTldfV0- shadow_factor = -shadow_factor * shadow_factor * 0.2f + 0.15f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoLXgqMC4yKzAuMTUpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuNTk5NTUxMjY3NTY5ODI1IiwiMS4yNzM5NDYxNzc0MTYyOTg4IiwiLTAuMTE0MzIxNTY5MjEzMDEwMDgiLCIxLjAzODU5OTkzNTM5MzgzNTMiXSwic2l6ZSI6WzY0OSwzOTldfV0-
shadow_factor = glm::max( shadow_factor, -0.06f ); // add some bias //shadow_factor = -shadow_factor * shadow_factor * 0.3f + 0.25f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoLXgqMC4zKzAuMjUpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuNTk5NTUxMjY3NTY5ODI1IiwiMS4yNzM5NDYxNzc0MTYyOTg4IiwiLTAuMTE0MzIxNTY5MjEzMDEwMDgiLCIxLjAzODU5OTkzNTM5MzgzNTMiXSwic2l6ZSI6WzY0OSwzOTldfV0-
//shadow_factor = -shadow_factor * shadow_factor * 0.4f + 0.40f; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoLXgqMC40MCswLjM1KSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjU5OTU1MTI2NzU2OTgyNSIsIjEuMjczOTQ2MTc3NDE2Mjk4OCIsIi0wLjExNDMyMTU2OTIxMzAxMDA4IiwiMS4wMzg1OTk5MzUzOTM4MzUzIl0sInNpemUiOls2NDksMzk5XX1d
shadow_factor = glm::max( shadow_factor, 0.00f );
// Calculate the edges ambient oclusion // Calculate the edges ambient oclusion
// ///////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
@ -137,6 +139,7 @@ float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos,
// Test / Debug code // Test / Debug code
//return_value = glm::max( aaFactor, shadow_factor ); //return_value = glm::max( aaFactor, shadow_factor );
//return_value = aaFactor; //return_value = aaFactor;
//return_value = shadow_factor;
} }
else else
{ {
@ -146,10 +149,7 @@ float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos,
//return_value = 0.0f; //return_value = 0.0f;
} }
// Test / Debug code return glm::clamp( return_value, 0.0f, 1.0f );
//return glm::clamp( return_value, 0.0f, 1.000f );
//return 0.0f;
return return_value;
} }
@ -266,11 +266,10 @@ SFVEC3F CPOSTSHADER_SSAO::Shade( const SFVEC2I &aShaderPos ) const
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw, 0) ) ); giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw, 0) ) );
} }
ao = (ao / 24.0f) + 0.0f; // Apply a bias for the ambient oclusion ao = (ao / 24.0f) + 0.0f; // Apply a bias for the ambient oclusion
//ao = 1.0f - ( 1.0f / (ao * 1.0f + 1.0f) );
gi = (gi * 5.0f / 24.0f); // Apply a bias for the global illumination gi = (gi * 5.0f / 24.0f); // Apply a bias for the global illumination
return SFVEC3F( SFVEC3F(ao) - gi ); //return SFVEC3F(ao);
return SFVEC3F( SFVEC3F(ao) - gi);
// Test source code // Test source code
//return SFVEC3F( col ); //return SFVEC3F( col );