Soft Lighting

As described by GD:

I was pretty annoyed with Lambert cosine law shading that everybody has been using for ages. It requires more lights to achieve not-rough shading. Since my game in development is outdoor, I wanted to make simple a pretty lighting shader for only one directional light. It looks something like this (this is a high poly mesh):

I wanted to share this with you, so if anyone wants “little softer” shading still being cheap for GPU, read my PDF paper.

It’s not anything new, nothing special, just some math creativity.

Shader Code

As written and released by JukkaKev├Ąt:

- This will take into account only one light and material color and alpha is given as parameters.

// ------------------
// Semantics
// ------------------

float4x4 matWorldIT : WORLDINVERSETRANSPOSE;
float4x4 matWorldViewProj : WORLDVIEWPROJECTION;
float3 lightDir : LIGHTDIR0_DIRECTION;
float3 lightCol : LIGHTDIR0_COLOR;
// float4 materialDiffuse : DIFFUSE;

// --------------------
// Parameters
// --------------------

float3 matDiffuseCol = {0.82, 0.8, 0.55};
float matAlpha = 1;
float interpolation = 0.6;

// -------------------------------------------------------------
// Input/Output channels
// -------------------------------------------------------------

struct VS_INPUT {
	float4 position : POSITION;   // Vertex position in object space
	float3 normal	: NORMAL;     // Vertex normal in object space
};

struct VS_OUTPUT {
	float4 position : POSITION;   // Pixel position in clip space	
	float3 normal : TEXCOORD0;    // Pixel normal vector
};

#define	PS_INPUT VS_OUTPUT            // What comes out of VS goes into PS!

// -------------------------------------------------------------
// Vertex Shader function
// -------------------------------------------------------------

VS_OUTPUT VS(VS_INPUT IN) {
	VS_OUTPUT OUT;

	// Calculate the world normal and position
	OUT.normal = mul(IN.normal, matWorldIT).xyz;
	OUT.position = mul(IN.position, matWorldViewProj);
 
	return OUT;
}

// -------------------------------------------------------------
// Pixel Shader function
// -------------------------------------------------------------

float4 PS(PS_INPUT IN) : COLOR {
	
	// Take the input vectors and normalize them
	float3 light = normalize(-lightDir); // Light is inverted cause reflection models needs the vector from surface to light
	float3 normal = normalize(IN.normal);

	// Josip Basic method
	float3 newvector = lerp(normal,light,interpolation);
	
	// Calculate the diffuse saturation
	float3 color = saturate(dot(newvector, light)) * matDiffuseCol;

	return float4(color, matAlpha);
}

// ----------------------------------------------------------------
// Compilation Techniques
// ----------------------------------------------------------------

technique TSM3 {
    pass P {
		VertexShader = compile vs_3_0 VS();
		PixelShader  = compile ps_3_0 PS();    
    }
}
technique TSM2a {
    pass P0 {  
		VertexShader = compile vs_2_0 VS();
		PixelShader  = compile ps_2_a PS();		
    }
}
technique TSM2b {
    pass P0 {  
		VertexShader = compile vs_2_0 VS();
		PixelShader  = compile ps_2_b PS();		
    }
}
technique TSM2 {
    pass P {
		VertexShader = compile vs_2_0 VS();
		PixelShader  = compile ps_2_0 PS();    
    }
}

Implementation Code

        TeaPot.SetLightingMode(CONST_TV_LIGHTINGMODE.TV_LIGHTING_MANAGED)
        TeaPotShader = Scene.CreateShader("Josip Basic's Lerp Lambertian Shader")
        TeaPotShader.CreateFromEffectFile(".\Shaders\SmoothLightShader.fx")
        TeaPot.SetShader(TeaPotShader)

In Action

 
sta_shader/soft_lighting_pixel_shader.txt · Last modified: 2013/11/22 13:31