Monster-source        

Monster.source
//TWEAK HERE
    //
    //	#define PER_VERTEX 1				-> TODO /?/
    //	#define SPOT_LIGHTS 1				-> TODO
    //	#define DETAIL_BUMP_TEXTURE 1		-> TODO (bump means normal map, height in alpha optional)
    //	#define DETAIL_DIFFUSE_TEXTURE 1	-> TODO
    //	#define SPECULAR_POWER_TEXTURE 1	-> TODO (stored in diffuse texture's alpha)
    //	#define ENVIRONMENT_MAPPING 1		-> TODO
    //	#define AMBIENT_OCCLUSION 1			-> TODO (modulates envir. lighting aka. ambient)
    //	#define OPACITY_TEXTURE 1			-> TODO (offset-mapped decals, for.ex)
    //
    //	Other suggestions?


    #define FADING 0
	//fading is buggy, experimental guarantees :)

    #define ATTENUATION 0
 
    #define LIGHT0_IS_DIRECTIONAL 0
 	//if u have directional light (suppose a healthy 1 only), it is always light0
 	//(regarding that you turn off lights in RECOMMENDED ORDER of 2,1,0)
 	//so do not attenuate it, but then we have power to attenuate light1, and light2
        //even with offset mapping on !
 
    #define ANY_TEXTURE 1
    #define DIFFUSE_TEXTURE 1
 
    #define AT_LEAST_PERPIXEL 1
    #define AT_LEAST_NORMAL_MAPPING 1
    #define OFFSET_MAPPING 1
 
    #define AMBIENT 1
    #define DIFFUSE 1
    #define SPECULAR 1
 
    #define LIGHT0 1
    #define LIGHT1 1
    #define LIGHT2 1
 
    
 
 
    /////////////////////////////////////////////////////////////////////////////////////////////////
    //									VERT COMES
    /////////////////////////////////////////////////////////////////////////////////////////////////
 
 
    //quite chaotic form, maybe more logical arrangement possible
    void monster_vs
    (
             float4 position	: POSITION,
             float3 normal		: NORMAL,
             out float4 oPosition	: POSITION,
 
        #if ANY_TEXTURE
             float2 uv		: TEXCOORD0,
             out float2 oUv		: TEXCOORD0,
             uniform float scale,
        #endif
 
        #if AT_LEAST_NORMAL_MAPPING
             float3 tangent     	: TEXCOORD1,
        #elif AT_LEAST_PERPIXEL  //just normal perpixel, use texcoord7 to transmit to frag (holds eyedir in offset case)
             out float3 oNorm	: TEXCOORD7,
        #endif
             
 
    // Still in frag shader!	
    //	#if AMBIENT
    //		uniform float4 ambient,
    //		out float4 oColor	: COLOR,
    //	#endif
 
 
        #if LIGHT0
             uniform float4 lightPosition0, // object space
          #if DIFFUSE
             out float3 oLightDir0  : TEXCOORD1,
          #endif
          #if SPECULAR
             out float3 oHalfAngle0	: TEXCOORD4,
          #endif
        #endif
 
        #if LIGHT1
             uniform float4 lightPosition1, // object space
          #if DIFFUSE
             out float3 oLightDir1  : TEXCOORD2,
          #endif
          #if SPECULAR
             out float3 oHalfAngle1	: TEXCOORD5,
          #endif
        #endif
 
        #if LIGHT2
             uniform float4 lightPosition2, // object space
          #if DIFFUSE
             out float3 oLightDir2	: TEXCOORD3,
          #endif
        #endif
 
        #if ATTENUATION
          out float4 dist	: TEXCOORD6, // .x, .y, and .z is used for light distances
        #elif SPECULAR
          out float3 oHalfAngle2	: TEXCOORD6,
        #endif 
 
        #if OFFSET_MAPPING  //needs eye no matter specular
             uniform float3 eyePosition,   // object space
             out float3 oEyeDir     : TEXCOORD7,
        #elif SPECULAR	//no need to output eye, even if normal-mapping is on
             uniform float3 eyePosition,   // object space
	#elif FADING
	     uniform float3 eyePosition,   // object space
		//Fading will modify alpha, and will be passed to frag in COLOR,
		//though I could do it with dist.w, which is unmodified even with atten
		//but I do not use dist without atten, anyway. Dunno which is faster.
        #endif

	#if FADING
	  out float4 oFadeColor	: COLOR,
	  uniform float4 fadefirst,
	  uniform float4 fadesecond,
	#endif
             
             uniform float4x4 worldviewproj 
    )
    {
        oPosition = mul(worldviewproj , position);
 
    #if ANY_TEXTURE
        oUv = uv * scale;
    #endif
 
 
    #if AT_LEAST_NORMAL_MAPPING	
        float3 binormal = cross(tangent, normal);
        float3x3 rotation = float3x3(tangent, binormal, normal);
    #elif AT_LEAST_PERPIXEL
        oNorm = normal;
    #endif
 
 
    #if OFFSET_MAPPING	//no matter specular, I need eye for offsetting
        float3 eyeDir = eyePosition - position.xyz;
        eyeDir = normalize(mul(rotation, eyeDir));
        oEyeDir = eyeDir;
    #elif SPECULAR	//I need eye only if specular other than offset, plus no eye output now
        float3 eyeDir = normalize(eyePosition - position.xyz);
      #if AT_LEAST_NORMAL_MAPPING  //eye needs adjustment if normal-mapping
        eyeDir = normalize(mul(rotation, eyeDir));
      #endif
    #endif
 
    //if DIFFUSE is commented out, we only need temp_lightDirX for oHalfAngle
    //and if both DIFFUSE and SPECULAR is out, we shall not calculate any lighting
    #if LIGHT0
      #if ATTENUATION
        #if LIGHT0_IS_DIRECTIONAL
	  // light0 is directional, atten is on, but we do not atten light0
	  float3 temp_lightDir0 = normalize(lightPosition0.xyz -  (position * lightPosition0.w));          
	  dist.x = 0; 
	    //I need dist.x even I do not use it now. Compiler blah-blah about continous oTex6.
	#else
	  float3 temp_lightDir0 = lightPosition0.xyz -  (position * lightPosition0.w);
          dist.x = length(temp_lightDir0);
          temp_lightDir0 = temp_lightDir0 / dist.x; //normalize it this way
 
     //	oatten.x = 1/(atten.y + dist0*atten.z + dist0*dist0*atten.w);
    //  Attenuation calc, could be even much faster if it could be done in vertex shader.
    //  Think about leaving kl component only, and calculating atten value here,
    //  instead doing only distance here, and calculating atten in frag shader.

        #endif
      #else
        float3 temp_lightDir0 = normalize(lightPosition0.xyz -  (position * lightPosition0.w));
      #endif
      #if AT_LEAST_NORMAL_MAPPING
        temp_lightDir0 = normalize(mul(rotation, temp_lightDir0));
        #if DIFFUSE
          oLightDir0 = temp_lightDir0;
        #endif
      #elif DIFFUSE //just normal perpixel
        oLightDir0 = temp_lightDir0;
      #endif
 
      #if SPECULAR
        oHalfAngle0 = normalize(eyeDir + temp_lightDir0);
      #endif
 
    #endif
 
    #if LIGHT1
      #if ATTENUATION
        float3 temp_lightDir1 = lightPosition1.xyz -  (position * lightPosition1.w);
        dist.y = length(temp_lightDir1);
        temp_lightDir1 = temp_lightDir1 / dist.y; //normalize it this way
      #else
        float3 temp_lightDir1 = normalize(lightPosition1.xyz -  (position * lightPosition1.w));
      #endif
      #if AT_LEAST_NORMAL_MAPPING
        temp_lightDir1 = normalize(mul(rotation, temp_lightDir1));
        #if DIFFUSE
          oLightDir1 = temp_lightDir1;
        #endif
      #elif DIFFUSE //just normal perpixel
        oLightDir1 = temp_lightDir1;
      #endif
 
      #if SPECULAR
        oHalfAngle1 = normalize(eyeDir + temp_lightDir1);
      #endif
 
    #endif
 
    #if LIGHT2
      #if ATTENUATION
        float3 temp_lightDir2 = lightPosition2.xyz -  (position * lightPosition2.w);
        dist.z = length(temp_lightDir2);
        temp_lightDir2 = temp_lightDir2 / dist.z; //normalize it this way
      #else
        float3 temp_lightDir2 = normalize(lightPosition2.xyz -  (position * lightPosition2.w));
        #if SPECULAR
          oHalfAngle2 = normalize(eyeDir + temp_lightDir2);
        #endif
      #endif
      #if AT_LEAST_NORMAL_MAPPING
        temp_lightDir2 = normalize(mul(rotation, temp_lightDir2));
        #if DIFFUSE
          oLightDir2 = temp_lightDir2;
        #endif
      #elif DIFFUSE //just normal perpixel
        oLightDir2 = temp_lightDir2;
      #endif
    #endif


    #if FADING
      float ratio = saturate(1-(distance(eyePosition, position.xyz)-fadefirst) / fadesecond); 
      oFadeColor = float4(0,0,0,ratio);
    #endif
 
    }



// Helper: Expand a range-compressed vector
    float3 expand(float3 v)
    {
        return (v - 0.5) * 2;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////
    //									FRAG COMES
    /////////////////////////////////////////////////////////////////////////////////////////////////
 
 
 
    void monster_ps(
 
        #if DIFFUSE_TEXTURE
              uniform sampler2D diffuseMap : register(s1),
              float2 uv		: TEXCOORD0,
        #elif ANY_TEXTURE
             float2 uv		: TEXCOORD0,
        #endif
 
        #if LIGHT0
          #if DIFFUSE
             float3 LightDir0  	: TEXCOORD1,
             uniform float4 lightDiffuse0,
          #endif
          #if SPECULAR
             float3 HalfAngle0	: TEXCOORD4,
             uniform float4 lightSpecular0,
          #endif
        #endif
 
        #if LIGHT1
          #if DIFFUSE
             float3 LightDir1  	: TEXCOORD2,
             uniform float4 lightDiffuse1,
          #endif
          #if SPECULAR
             float3 HalfAngle1	: TEXCOORD5,
             uniform float4 lightSpecular1,
          #endif
        #endif
 
        #if LIGHT2
          #if DIFFUSE
             float3 LightDir2	: TEXCOORD3,
             uniform float4 lightDiffuse2,
          #endif
        #endif
             
        #if OFFSET_MAPPING
             float3 EyeDir     	: TEXCOORD7,
             uniform float4 scaleBias,
             uniform sampler2D   normalHeightMap : register(s0),
        #elif AT_LEAST_NORMAL_MAPPING
              uniform sampler2D   normalHeightMap : register(s0),
        #elif AT_LEAST_PERPIXEL	//no normal-mapping, use standard normal, in eyedir's place
             float3 normalvec		: TEXCOORD7,
        #endif
 
        #if SPECULAR
            uniform float exponent0,
    //		uniform float exponent1,
    //		uniform float exponent2,
        #endif
 
        #if AMBIENT
            uniform float4 ambient,
        #endif
 
        #if ATTENUATION	//if on, supposed to have light0 on as well, OR light0_directional!
            float4 dist		: TEXCOORD6,
	  #if !LIGHT0_IS_DIRECTIONAL
            uniform float4 atten0,
          #endif
          #if LIGHT1
            uniform float4 atten1,
          #endif
          #if LIGHT2
            uniform float4 atten2,
          #endif
        #elif SPECULAR
          #if LIGHT2
             float3 HalfAngle2	: TEXCOORD6,
             uniform float4 lightSpecular2,
          #endif
        #endif
 

	#if FADING
	  float4 inFadeColor : COLOR,
	#endif
	
            out float4 oColor	: COLOR
        )
    {
    #if OFFSET_MAPPING
        float height = tex2D(normalHeightMap, uv).a;
        float scale = scaleBias.x;
        float bias = scaleBias.y;
        float displacement = (height * scale) + bias;
        float3 uv2 = float3(uv, 1); 
        float2 newTexCoord = ((EyeDir * displacement) + uv2).xy;
        float3 bumpVec = expand(tex2D(normalHeightMap, newTexCoord ).xyz);
//	float3 bumpVec = tex2D(normalHeightMap, newTexCoord ).xyz;
        float3 N = normalize(bumpVec);
      #if DIFFUSE_TEXTURE
        float3 diffusetex = tex2D(diffuseMap, newTexCoord).xyz; 
      #endif
    #elif AT_LEAST_NORMAL_MAPPING
        float3 bumpVec = expand(tex2D(normalHeightMap, uv).xyz);
//	float3 N = tex2D(normalHeightMap, uv).xyz;
        float3 N = normalize(bumpVec);
      #if DIFFUSE_TEXTURE
        float3 diffusetex = tex2D(diffuseMap, uv).xyz;
      #endif
    #elif AT_LEAST_PERPIXEL
        float3 N = normalize(normalvec);
      #if DIFFUSE_TEXTURE
        float3 diffusetex = tex2D(diffuseMap, uv).xyz;
      #endif
    #elif DIFFUSE_TEXTURE
        float3 diffusetex = tex2D(diffuseMap, uv).xyz;
    #endif	
 
 
    //If different exponents for different specular-lights, change 3 places here!
 
    #if LIGHT0
      #if DIFFUSE
        float NdotL0 = dot(normalize(LightDir0), N);
        #if SPECULAR //both
          float NdotH0 = dot(normalize(HalfAngle0), N);
          float4 Lit0 = lit(NdotL0,NdotH0,exponent0);
        #else //just diffuse
          float4 Lit0;
          Lit0.y = saturate(NdotL0);
        #endif
      #elif SPECULAR //just specular
        float NdotH0 = dot(normalize(HalfAngle0), N);
        float4 Lit0;
        Lit0.z = pow(saturate(NdotH0),exponent0);
      #endif
    #endif
 
    #if LIGHT1
      #if DIFFUSE
        float NdotL1 = dot(normalize(LightDir1), N);
        #if SPECULAR //both
          float NdotH1 = dot(normalize(HalfAngle1), N);
          float4 Lit1 = lit(NdotL1,NdotH1,exponent0);
        #else //just diffuse
          float4 Lit1;
          Lit1.y = saturate(NdotL1);
        #endif
      #elif SPECULAR //just specular
        float NdotH1 = dot(normalize(HalfAngle1), N);
        float4 Lit1;
        Lit1.z = pow(saturate(NdotH1),exponent0);
      #endif
    #endif
 
    #if LIGHT2
      #if DIFFUSE
        float NdotL2 = dot(normalize(LightDir2), N);
        #if SPECULAR //both
          #if !ATTENUATION
            float NdotH2 = dot(normalize(HalfAngle2), N);
            float4 Lit2 = lit(NdotL2,NdotH2,exponent0);
          #else
            float4 Lit2;
            Lit2.y = saturate(NdotL2);
          #endif
        #else //just diffuse
          float4 Lit2;
          Lit2.y = saturate(NdotL2);
        #endif
      #elif SPECULAR //just specular
        #if !ATTENUATION
          float NdotH2 = dot(normalize(HalfAngle2), N);
          float4 Lit2;
          Lit2.z = pow(saturate(NdotH2),exponent0);
        #else
          float4 Lit2;
          Lit2 = float4(1,0,0,1);
        #endif
      #endif
    #endif
 
        oColor = 
 
    #if ATTENUATION //since usage rules specify it, we have at least light0 on with at least either
                    //diffuse or specular also on !
                    // - if you want no lighting, just textures, turn attenuation off!
                    //But yes, you can have diffusetex with just specular :)
                    //Note that you can't have specular of light2 with attenuation on. See docs.
 
    // Final color formula with atten
    // oColor = atten0 * (diffusetex * lightDiffuse0 * Lit0.y + lightSpecular0 * Lit0.z)
    //		    atten1 * (diffusetex * lightDiffuse1 * Lit1.y + lightSpecular1 * Lit1.z)
    //		    atten2 * (diffusetex * lightDiffuse2 * Lit2.y + lightSpecular2 * Lit2.z)
    //		    + ambient;
 
      #if !DIFFUSE	//we start with the no diffuse just diffusetex case, here only spec is attenuated
        #if DIFFUSE_TEXTURE
          float4(diffusetex,1) +
        #endif
      #endif
 
//      1/(atten0.y + atten0.z*dist.x + atten0.w*dist.x*dist.x)* (
// use simpler formular instead: counts much in FPS!
      #if !LIGHT0_IS_DIRECTIONAL
        1/(1 + atten0.z*dist.x)* (
      #else
        (	//for syntax
      #endif
        //we always have light0 on here, and spec0 or diffuse0 with it
      #if SPECULAR
        lightSpecular0 * Lit0.z
        #if DIFFUSE
          +
        #else //light0 has only spec, light0 done
          )
        #endif
      #endif
      #if DIFFUSE
        lightDiffuse0 * Lit0.y	//without + sign, we are good at no specular case as well
        #if DIFFUSE_TEXTURE
          * float4(diffusetex,1)) //light0 done
        #else
          ) //light0 done
        #endif
      #endif
 
      #if LIGHT1	//optional, but if we have it, we have either diff1 or spec1, difftex can be 0/1
//        + 1/(atten1.y + atten1.z*dist.y + atten1.w*dist.y*dist.y) * (
// use simpler formula instead
	  + 1/(1 + atten1.z*dist.y) * (
        #if SPECULAR
          lightSpecular1 * Lit1.z
          #if DIFFUSE
            +
          #else //light1 has only spec, light1 done
            )
          #endif
        #endif
 
        #if DIFFUSE
          lightDiffuse1 * Lit1.y	//without + sign here, we are good at no specular case as well
          #if DIFFUSE_TEXTURE
            * float4(diffusetex,1)) //light1 done
          #else
            ) //light1 done
          #endif
        #endif
      #endif
 
      #if LIGHT2	//ditto goes for diff2, and difftex (no specular here)
//        + 1/(atten2.y + atten2.z*dist.z + atten2.w*dist.z*dist.z) * (
// use simpler formula instead
	  + 1/(1 + atten2.z*dist.z) * (
        #if DIFFUSE
          lightDiffuse2 * Lit2.y	//without + sign here, we are good at no specular case as well
          #if DIFFUSE_TEXTURE
            * float4(diffusetex,1)) //light2 done
          #else
            ) //light2 done
          #endif
        #endif
      #endif
 
    #else
 
    // And wo. atten
    // oColor = diffusetex 
    //		    * (lightDiffuse0 * Lit0.y + lightDiffuse1 * Lit1.y + lightDiffuse2 * Lit2.y)
    //		    + lightSpecular0 * Lit0.z + lightSpecular1 * Lit1.z + lightSpecular2 * Lit2.z
    //		    + ambient;
 
      float4(0,0,0,0)	//this is needed to simplify preprocessor stuff, no FPS cost :)
 
      #if DIFFUSE_TEXTURE //at least diffuse texture, no lighting yet
          + float4(diffusetex,1)
        #if DIFFUSE //modulate texture with lighting
          *(
          #if LIGHT0
            lightDiffuse0 * Lit0.y
          #endif
          #if LIGHT1
            + lightDiffuse1 * Lit1.y
          #endif
          #if LIGHT2
            + lightDiffuse2 * Lit2.y
          #endif
          )
        #endif
      #elif DIFFUSE //just diffuse lighting, no modulation
          #if LIGHT0
            + lightDiffuse0 * Lit0.y
          #endif
          #if LIGHT1
            + lightDiffuse1 * Lit1.y
          #endif
          #if LIGHT2
            + lightDiffuse2 * Lit2.y
          #endif
      #endif
        
      #if SPECULAR
        #if LIGHT0
          + lightSpecular0 * Lit0.z
        #endif
        #if LIGHT1
          + lightSpecular1 * Lit1.z
        #endif
        #if LIGHT2  
          + lightSpecular2 * Lit2.z
        #endif
      #endif
    #endif
 
    #if AMBIENT
        + ambient
    #endif
        ;
 
 
    #if FADING
	//WARNING: this will eat up all original/computed alpha!
	oColor = float4(oColor.x, oColor.y, oColor.z, inFadeColor.w);
    #endif
    }