Barabas' Parallax Mapping

From Mount&Blade Modding Wiki
Revision as of 17:48, 26 February 2012 by Swyter (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Barabas implemented Parallax Mapping in Mount&Blade, for this to work you need to specify the height in the red channel of your normal map. Everything is configurable. Please note that every GPU instruction counts and it's always better a good performance than amazing visuals.

Use it wisely.

Pixel Shader:

PS_OUTPUT ps_main_bump( VS_OUTPUT_BUMP In, uniform const int PcfMode ,uniform const bool use_parallax = false, uniform const bool use_self_shading = false)
{ 
	PS_OUTPUT Output;
 
 
	float3 normal;
 
	Output.RGBColor.rgb =1.0f;
	float shade;
 
	if(use_parallax)
	{
		float height = (tex2D(NormalTextureSampler, In.Tex0).r);
		float fHeightMapScale = 0.015;
 
		float heightmap =  .5f-height;
 
		In.Tex0 -= fHeightMapScale *heightmap * In.ViewDir.xy*In.WorldNormal.w;
 
		normal.xy = (2.0f * tex2D(NormalTextureSampler, In.Tex0).ag - 1.0f);
 
		normal.z = sqrt(1.0f - dot(normal.xy, normal.xy));
		shade = saturate(dot(In.SunLightDir.xyz, normal.xyz));
 
		if (In.SunLightDir.z > 0.0 && use_self_shading)
		{
			float height2 = tex2D(NormalTextureSampler, In.Tex0 + (fHeightMapScale *heightmap * In.SunLightDir.xy)/max(0.2,In.SunLightDir.z) ).r;
			Output.RGBColor.rgb -= 0.7*saturate(height2-height);
		}
 
	}
	else
	{
	normal.xy = (2.0f * tex2D(NormalTextureSampler, In.Tex0).ag - 1.0f);
 
	normal.z = sqrt(1.0f - dot(normal.xy, normal.xy));
	shade = saturate(dot(In.SunLightDir.xyz, normal.xyz));
	}
 
	float4 total_light = vAmbientColor;//In.LightAmbient;
	if (PcfMode != PCF_NONE)
	{
		float sun_amount = 0.03f + GetSunAmount(PcfMode, In.ShadowTexCoord, In.ShadowTexelPos);
		total_light += shade * sun_amount * vSunColor;
	}
	else
	{
		total_light += shade  * vSunColor;
	}
	total_light += saturate(dot(In.SkyLightDir.xyz, normal.xyz)) * vSkyLightColor;
 
	#ifndef USE_LIGHTING_PASS
		total_light += saturate(dot(In.PointLightDir.xyz, normal.xyz)) * vPointLightColor;
	#endif
 
	Output.RGBColor.rgb *= total_light.rgb;
	Output.RGBColor.a = 1.0f;
	Output.RGBColor *= vMaterialColor;
 
	float4 tex_col = tex2D(MeshTextureSampler, In.Tex0);
	INPUT_TEX_GAMMA(tex_col.rgb);
 
	Output.RGBColor *= tex_col; //turned off texture map for testing shadow
	Output.RGBColor *= In.VertexColor;
 
 
	OUTPUT_GAMMA(Output.RGBColor.rgb);
 
	return Output;
}

[edit] Source

Latest (optimized) version: http://forums.taleworlds.com/index.php/topic,208694.msg5072033.html#msg5072033

Massive loop (slow) version: http://forums.taleworlds.com/index.php/topic,208694.msg5071585.html#msg5071585 and

Original implementation: http://forums.taleworlds.com/index.php/topic,208694.msg5069190.html#msg5069190

[edit] Preview

A good bunch of screenshots can be found here: http://forums.taleworlds.com/index.php/topic,208694.msg5126320.html#msg5126320

mb108.jpg mb110.jpg mb111.jpg

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox