Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /******************************************************************************
- HLSL Normal Map Specular Shader - 3 Lights
- by Ben Cloward
- bsmji@hotmail.com
- http://www.monitorstudios.com/bcloward/
- This shader is based on several shaders written by Kevin Bjorke of Nvidia and
- included with the Cg plugin for 3DS Max 5.1.
- This shader uses a normal map for per-pixel lighting - to give the illusion that
- the model surface contains more detail than is really there. It also adds a specular
- component for making models look shiny.
- It accepts the following inputs:
- Ambient Color
- Diffuse Color
- Diffuse Texture
- Specular Texture (a colored specular mask)
- Specular Color
- Shininess
- Normal Map Texture
- DXT5 Compressed Normal Map
- Flip Normal Map Green Channel
- Point Light1 Position
- Point Light1 Color
- Point Light2 Position
- Point Light2 Color
- Point Light3 Position
- Point Light3 Color
- It requires hardware support for DirectX 9.
- Normal Map compression is an option that you can use with this shader.
- Copy the red channel of your normal map to the alpha channel. Then delete the
- red and blue channels and save your normal map in DXT5 DDS format. Put your
- compressed normal map in the DXT5 Normal Map slot for the shader. Then choose
- "Compressed" as the technique instead of "complete."
- This shader is intended to be used by the DirectX 9 shader of 3DS Max
- but it could also be used in other applications that support the FX format.
- ******************************************************************************/
- /************* TWEAKABLES **************/
- half4 ambient : Ambient
- <
- string UIName = "Ambient Color";
- > = {0.25f, 0.25f, 0.25f, 1.0f};
- half4 surfColor : Diffuse
- <
- string UIName = "Diffuse Color";
- > = {1.0f, 1.0f, 1.0f, 1.0f};
- texture colorTexture : DiffuseMap
- <
- string name = "default_color.dds";
- string UIName = "Diffuse Texture";
- string TextureType = "2D";
- >;
- texture specTexture : SpecularMap
- <
- string name = "default_color.dds";
- string UIName = "Specular Texture";
- string TextureType = "2D";
- >;
- half4 specularColor : Specular
- <
- string UIName = "Specular Color";
- > = { 0.2f, 0.2f, 0.2f, 1.0f };
- half shininess <
- string UIWidget = "slider";
- float UIMin = 1;
- float UIMax = 128;
- string UIName = "Shininess";
- > = 40;
- texture normalMap : NormalMap
- <
- string name = "default_bump_normal.dds";
- string UIName = "Normal Map";
- string TextureType = "2D";
- >;
- texture CnormalMap : CNormalMap
- <
- string name = "default_bump_normal.dds";
- string UIName = "DXT5 Normal Map";
- string TextureType = "2D";
- >;
- bool direction
- <
- string gui = "slider";
- string UIName = "Flip Normal Map Green Channel";
- > = false;
- /************** light info **************/
- half4 light1Pos : POSITION
- <
- string UIName = "Light 1 Position";
- string Object = "PointLight";
- string Space = "World";
- int refID = 0;
- > = {100.0f, 100.0f, 100.0f, 0.0f};
- half4 light1Color : LIGHTCOLOR
- <
- int LightRef = 0;
- > = { 1.0f, 1.0f, 1.0f, 0.0f };
- //----------------------------------
- half4 light2Pos : POSITION
- <
- string UIName = "Light 2 Position";
- string Object = "PointLight";
- string Space = "World";
- int refID = 1;
- > = {-100.0f, 100.0f, 100.0f, 0.0f};
- half4 light2Color : LIGHTCOLOR
- <
- int LightRef = 1;
- > = { 1.0f, 1.0f, 1.0f, 0.0f };
- //----------------------------------
- half4 light3Pos : POSITION
- <
- string UIName = "Light 3 Position";
- string Object = "PointLight";
- string Space = "World";
- int refID = 2;
- > = {100.0f, -100.0f, 100.0f, 0.0f};
- half4 light3Color : LIGHTCOLOR
- <
- int LightRef = 2;
- > = { 1.0f, 1.0f, 1.0f, 0.0f };
- /****************************************************/
- /********** SAMPLERS ********************************/
- /****************************************************/
- sampler2D colorTextureSampler = sampler_state
- {
- Texture = <colorTexture>;
- MinFilter = Linear;
- MagFilter = Linear;
- MipFilter = Anisotropic;
- };
- sampler2D specTextureSampler = sampler_state
- {
- Texture = <specTexture>;
- MinFilter = Linear;
- MagFilter = Linear;
- MipFilter = Anisotropic;
- };
- sampler2D normalMapSampler = sampler_state
- {
- Texture = <normalMap>;
- MinFilter = Linear;
- MagFilter = Linear;
- MipFilter = Anisotropic;
- };
- sampler2D CnormalMapSampler = sampler_state
- {
- Texture = <CnormalMap>;
- MinFilter = Linear;
- MagFilter = Linear;
- MipFilter = Anisotropic;
- };
- /***********************************************/
- /*** automatically-tracked "tweakables" ********/
- /***********************************************/
- half4x4 wvp : WorldViewProjection < string UIWidget = "None"; >;
- half4x4 worldIT : WorldInverseTranspose < string UIWidget = "None"; >;
- half4x4 viewInv : ViewInverse < string UIWidget = "None"; >;
- half4x4 world : World < string UIWidget = "None"; >;
- /****************************************************/
- /********** CG SHADER FUNCTIONS *********************/
- /****************************************************/
- // input from application
- struct a2v {
- half4 position : POSITION;
- half2 texCoord : TEXCOORD0;
- half3 tangent : TANGENT;
- half3 binormal : BINORMAL;
- half3 normal : NORMAL;
- };
- // output to fragment program
- struct v2f {
- half4 position : POSITION;
- half2 texCoord : TEXCOORD0;
- half3 eyeVec : TEXCOORD1;
- half3 lightVec : TEXCOORD2;
- half3 worldNormal : TEXCOORD3;
- half3 worldTangent : TEXCOORD4;
- half3 worldBinormal : TEXCOORD5;
- };
- // blinn lighting with lit function
- half4 blinn2(half3 N,
- half3 L,
- half3 V,
- uniform half4 specularColor,
- uniform half shininess
- )
- {
- half3 H = normalize(V+L);
- half4 lighting = lit(dot(L,N), dot(H,N), shininess);
- return lighting.y + specularColor*lighting.z;
- }
- /**************************************/
- /***** VERTEX SHADER ******************/
- /**************************************/
- v2f v(a2v In, uniform half4 lightPosition)
- {
- v2f Out;
- Out.worldNormal = mul(In.normal, worldIT).xyz;
- Out.worldTangent = mul(In.tangent, worldIT).xyz;
- Out.worldBinormal = mul(In.binormal, worldIT).xyz;
- //can use either positive or negative y format normal maps
- //comment out this if statement to save 6 instructions!
- if (direction == true) Out.worldTangent = -Out.worldTangent;
- half3 worldSpacePos = mul(In.position, world);
- Out.lightVec = lightPosition - worldSpacePos;
- Out.texCoord.xy = In.texCoord;
- Out.eyeVec = viewInv[3].xyz - worldSpacePos;
- Out.position = mul(In.position, wvp);
- return Out;
- }
- /**************************************/
- /***** FRAGMENT PROGRAM ***************/
- /**************************************/
- float4 f(v2f In,uniform half4 lightColor) : COLOR
- {
- //fetch the diffuse and normal and spec maps
- half4 colorMap = tex2D(colorTextureSampler, In.texCoord.xy);
- half4 specMap = tex2D(specTextureSampler, In.texCoord.xy);
- half3 normal = tex2D(normalMapSampler, In.texCoord).xyz * 2.0 - 1.0;
- //create tangent space vectors
- half3 Nn = In.worldNormal;
- half3 Tn = In.worldTangent;
- half3 Bn = In.worldBinormal;
- //these vectors could be normalized, but it costs 4 more instructions
- //and makes almost no difference to image quality
- //half3 Nn = normalize(In.worldNormal);
- //half3 Tn = normalize(In.worldTangent);
- //half3 Bn = normalize(In.worldBinormal);
- //offset world space normal with normal map values
- half3 N = (Nn * normal.z) + (normal.x * Bn + normal.y * -Tn);
- N = normalize(N);
- //create lighting vectors - view vector and light vector
- half3 V = normalize(In.eyeVec);
- half3 L = normalize(In.lightVec.xyz);
- //lighting
- //lighting
- //ambient light
- half4 C = ambient*colorMap * 0.33;
- //specular color
- half4 specCol = specularColor*specMap;
- //diffuse and specular
- C += lightColor * blinn2(N, L, V, specCol, shininess);
- C *= colorMap*surfColor;
- return C;
- }
- float4 f2(v2f In,uniform half4 lightColor) : COLOR
- {
- //fetch the diffuse, specular and normal maps
- half4 colorMap = tex2D(colorTextureSampler, In.texCoord.xy);
- half4 specMap = tex2D(specTextureSampler, In.texCoord.xy);
- //swizzle the compressed dxt5 format
- half3 normal = tex2D(CnormalMapSampler, In.texCoord).wyz * 2.0 - 1.0;
- //generate the z component of the vector
- normal.z = sqrt(1 - normal.x * normal.x - normal.y * normal.y);
- //create tangent space vectors
- half3 Nn = In.worldNormal;
- half3 Tn = In.worldTangent;
- half3 Bn = In.worldBinormal;
- //these vectors could be normalized, but it costs 4 more instructions
- //and makes almost no difference to image quality
- //half3 Nn = normalize(In.worldNormal);
- //half3 Tn = normalize(In.worldTangent);
- //half3 Bn = normalize(In.worldBinormal);
- //offset world space normal with normal map values
- half3 N = (Nn * normal.z) + (normal.x * Bn + normal.y * -Tn);
- N = normalize(N);
- //create lighting vectors - view vector and light vector
- half3 V = normalize(In.eyeVec);
- half3 L = normalize(In.lightVec.xyz);
- //lighting
- //ambient light
- half4 C = ambient*colorMap * 0.33;
- //specular color
- half4 specCol = specularColor*specMap;
- //diffuse and specular
- C += lightColor * blinn2(N, L, V, specCol, shininess);
- C *= colorMap*surfColor;
- return C;
- }
- /****************************************************/
- /********** TECHNIQUES ******************************/
- /****************************************************/
- technique Complete
- {
- pass light1
- {
- VertexShader = compile vs_1_1 v(light1Pos);
- ZEnable = true;
- ZWriteEnable = true;
- CullMode = cw;
- AlphaBlendEnable = false;
- PixelShader = compile ps_2_0 f(light1Color);
- }
- pass light2
- {
- VertexShader = compile vs_1_1 v(light2Pos);
- ZEnable = true;
- ZWriteEnable = false;
- ZFunc = LessEqual;
- CullMode = None;
- AlphaBlendEnable = true;
- SrcBlend = One;
- DestBlend = One;
- PixelShader = compile ps_2_0 f(light2Color);
- }
- pass light3
- {
- VertexShader = compile vs_1_1 v(light3Pos);
- ZEnable = true;
- ZWriteEnable = false;
- ZFunc = LessEqual;
- CullMode = None;
- AlphaBlendEnable = true;
- SrcBlend = One;
- DestBlend = One;
- PixelShader = compile ps_2_0 f(light3Color);
- }
- }
- technique Compressed
- {
- pass light1
- {
- VertexShader = compile vs_1_1 v(light1Pos);
- ZEnable = true;
- ZWriteEnable = true;
- CullMode = cw;
- AlphaBlendEnable = false;
- PixelShader = compile ps_2_0 f2(light1Color);
- }
- pass light2
- {
- VertexShader = compile vs_1_1 v(light2Pos);
- ZEnable = true;
- ZWriteEnable = false;
- ZFunc = LessEqual;
- CullMode = None;
- AlphaBlendEnable = true;
- SrcBlend = One;
- DestBlend = One;
- PixelShader = compile ps_2_0 f2(light2Color);
- }
- pass light3
- {
- VertexShader = compile vs_1_1 v(light3Pos);
- ZEnable = true;
- ZWriteEnable = false;
- ZFunc = LessEqual;
- CullMode = None;
- AlphaBlendEnable = true;
- SrcBlend = One;
- DestBlend = One;
- PixelShader = compile ps_2_0 f2(light3Color);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement