/////////////////////////// // New General Purpose Shader! // ver 0.01 // core part - begin /////////////////////////// // back compatibility: set this to 1 if you are using version 0.80x #define MAB_080X 0 struct VS_MTARINI_OUT { float4 Pos : POSITION; float3 Normal : TEXCOORD7; float4 Color : COLOR0; float2 Tex0 : TEXCOORD0; float3 SunLightDir : TEXCOORD1; float4 ShadowTexCoord : TEXCOORD2; float2 TexelPos : TEXCOORD3; float3 worldPos : TEXCOORD4; float ModelX : TEXCOORD5; float3 HalfwayDir : TEXCOORD6; float Fog : FOG; }; struct PS_MTARINI_IN { float4 Color : COLOR0; float3 Normal : TEXCOORD7; float2 Tex0 : TEXCOORD0; float3 SunLightDir : TEXCOORD1; float4 ShadowTexCoord : TEXCOORD2; float2 TexelPos : TEXCOORD3; float3 worldPos : TEXCOORD4; float ModelX : TEXCOORD5; float3 HalfwayDir : TEXCOORD6; }; // shader parameters... // ... for cast-shadows (VS and FS) #define SHADOW_NO 0 // no sininess #define SHADOW_YES 1 // constant shininess // ... for normal (VS and FS) #define NORMAL_VN 2 // get normal from vertex normal (for shininess) #define NORMAL_T2RGB 1 // get normal from texture 2 (bumpmap) // ... for shininess (VS and FS) #define SHINE_NO 0 // no sininess #define SHINE_YES 1 // constant shininess #define SHINE_T1A 2 // shininess from texture 1 alpha #define SHINE_T2A 3 // shininess from texture 2 alpha #define SHINE_T2RGB 4 // shininess from texture 1 color #define SHINE_VCA 5 // shininess from vertex color alpha // ... for transperency (FS only) #define TRANSP_NO 0 // don't use alpha (alpha=1 always) #define TRANSP_VCA 1 // use alpha from vertex color alpha #define TRANSP_T1A 2 // use alpha from texture 1 alpha #define TRANSP_T1AxVCA 3 // use alpha as the previous 2 // ... for emission (FS only) #define EMISS_NO 0 // don't use emission #define EMISS_VCA 1 // use emi from vertex color alpha #define EMISS_T1A 2 // use emi from texture color alpha #define EMISS_T2A 3 // use emi from bump texture alpha #define EMISS_T2RGB 4 // use emi from bump texture alpha // ...for rigging (VS only) #define RIG_NO 0 #define RIG_YES 1 VS_MTARINI_OUT vs_mtarini_main ( uniform const int PcfMode, uniform const int Shadow, uniform const int Normal, uniform const int Shine, uniform const int DoRig, float4 vPosition : POSITION, float3 vNormal : NORMAL, float2 tc : TEXCOORD0, float4 vColor : COLOR0, float4 vBlendWeights : BLENDWEIGHT, float4 vBlendIndices : BLENDINDICES) { VS_MTARINI_OUT Out = (VS_MTARINI_OUT)0; float4 vObjectPos; float3 vObjectN; if (DoRig) { float4x4 mat0 = matWorldArray[vBlendIndices.x]; float4x4 mat1 = matWorldArray[vBlendIndices.y]; float4x4 mat2 = matWorldArray[vBlendIndices.z]; float4x4 mat3 = matWorldArray[vBlendIndices.w]; vObjectPos= mul(mat0, vPosition - matBoneOriginArray[vBlendIndices.x]) * vBlendWeights.x + mul(mat1, vPosition - matBoneOriginArray[vBlendIndices.y]) * vBlendWeights.y + mul(mat2, vPosition - matBoneOriginArray[vBlendIndices.z]) * vBlendWeights.z + mul(mat3, vPosition - matBoneOriginArray[vBlendIndices.w]) * vBlendWeights.w ; vObjectN = normalize( mul((float3x3)mat0, vNormal) * vBlendWeights.x + mul((float3x3)mat1, vNormal) * vBlendWeights.y + mul((float3x3)mat2, vNormal) * vBlendWeights.z + mul((float3x3)mat3, vNormal) * vBlendWeights.w ); } else { vObjectPos = vPosition; vObjectN = vNormal; } Out.ModelX = vNormal.x; //vPosition.x; if ( Normal==NORMAL_T2RGB) // must send light dir (in model space) Out.SunLightDir = mul( -vSkyLightDir , (float3x3)matWorld); // compute light dir in model space if (Shine!=SHINE_NO) { // must send half-way vector in model space (shininess always computed per fragment) float3 hwd = -vSkyLightDir -float3(matView[2][0],matView[2][1],matView[2][2]); // vied dir Out.HalfwayDir = normalize( mul( hwd , (float3x3)matWorld) ); if (Normal==NORMAL_VN) { // must send normal in model space-- even if color will be preshaded Out.Normal = vObjectN; } } float4 vWorldPos = mul(matWorld,vObjectPos); Out.Pos = mul(matViewProj, vWorldPos); float3 vWorldN = mul((float3x3)matWorld, vObjectN); //normal in world space float3 P = mul(matView, vWorldPos); //position in view space Out.worldPos = vWorldPos; Out.Tex0 = tc; float4 diffuse_light; if (Normal==NORMAL_T2RGB) { // approximation: put togheter all color, ambient, likght and sky, then half all lgiht when is shadow diffuse_light= (vAmbientColor+vSkyLightColor+vSunColor); } else { // preshade color //directional lights, compute diffuse color diffuse_light = vAmbientColor + max(0, dot(vWorldN, -vSkyLightDir)) * vSkyLightColor; //point lights for(int j = 0; j < iLightPointCount; j++) { int i = iLightIndices[j]; float3 point_to_light = vLightPosDir[i]-vWorldPos; float LD = length(point_to_light); float3 L = normalize(point_to_light); float wNdotL = dot(vWorldN, L); float fAtten = 0.1f/LD + 0.9f / (LD * LD); //compute diffuse color diffuse_light += max(0, wNdotL) * vLightDiffuse[i] * fAtten; } } //apply material color Out.Color = vMaterialColor * vColor * diffuse_light; if (PcfMode != PCF_NONE && Shadow) { //shadow mapping variables // float wNdotSun = max(-0.0001f,dot(vWorldN, -vSunDir)); // Out.SunLight = (wNdotSun) * vSunColor * vMaterialColor * vColor; float4 ShadowPos = mul(matSunViewProj, vWorldPos); Out.ShadowTexCoord = ShadowPos; Out.ShadowTexCoord.z /= ShadowPos.w; Out.ShadowTexCoord.w = 1.0f; Out.TexelPos = Out.ShadowTexCoord * fShadowMapSize; //shadow mapping variables end } //apply fog float d = length(P); Out.Fog = saturate((fFogEnd - d) / (fFogEnd - fFogStart)); return Out; } PS_OUTPUT ps_mtarini_main( PS_MTARINI_IN In, uniform const int Shadow, uniform const int PcfMode, uniform const int Normal, uniform const int Shine, uniform const int Transp, uniform const int Emiss ) { PS_OUTPUT Output; if ((PcfMode != PCF_NONE)) { // first texture access float4 texelColor = tex2D(MeshTextureSampler, In.Tex0); #if (!MAB_080X) texelColor.rgb = pow(texelColor.rgb, input_gamma); #endif float4 outColor = texelColor; float4 texelBump; // do a second texture access? if (Shine==SHINE_T2RGB || Normal==NORMAL_T2RGB || Shine==SHINE_T2A || Emiss==EMISS_T2A || Emiss==EMISS_T2RGB) texelBump=tex2D(NormalTextureSampler, In.Tex0); // compute lighitng here? if (Normal==NORMAL_T2RGB || Shine!=SHINE_NO) { // compute lighitng here float3 normal; if (Normal==NORMAL_T2RGB) { // get normal from bumpmap normal = normalize(2.0f * texelBump.xyz - 1.0f); // flip normals on other face (two modes): // normal.x = (In.ModelX<0)?-normal.x:normal.x; // (mode 1: hard) normal.x *= max( min(In.ModelX*5,+1), -1); // (mode 2: smooth) float lambert = dot(normalize(normal), normalize(In.SunLightDir) ) ; lambert = ((lambert<0)?-lambert*0.21:lambert)*0.8 + 0.2; outColor *= lambert ; } else { normal = In.Normal; // will use preshaded color, but need per vertex normal for phong } if (Shine!=SHINE_NO) { float phong = max(dot(normalize(normal), normalize(In.HalfwayDir) ),0) ; phong = pow (phong, fMaterialPower); if (Shine==SHINE_T1A) phong*=texelColor.a; if (Shine==SHINE_T2A) phong*=texelBump.a; if (Shine==SHINE_VCA) phong*=In.Color.a; if (Shine==SHINE_T2RGB) outColor += phong * texelBump ; // *vSpecularColor ; else outColor += phong * vSpecularColor ; } } else { // do nothing, will use preshaded color } //outColor.x = (In.ModelX<0)?0:1; // just a test Output.RGBColor = outColor * In.Color ; // put in shadow if (Shadow) Output.RGBColor *= 0.5+0.5*GetSunAmount(PcfMode, In.ShadowTexCoord, In.TexelPos); // emission? if (Emiss==EMISS_VCA) Output.RGBColor.rgb += vSpecularColor.rgb * In.Color.a; if (Emiss==EMISS_T1A) Output.RGBColor.rgb += vSpecularColor.rgb * texelColor.a; if (Emiss==EMISS_T2A) Output.RGBColor.rgb += vSpecularColor.rgb * texelBump.a; if (Emiss==EMISS_T2RGB) Output.RGBColor.rgb += texelBump.rgb; // transparency? if (Transp==TRANSP_NO ) Output.RGBColor.a=1; if (Transp==TRANSP_VCA) Output.RGBColor.a=In.Color.w; if (Transp==TRANSP_T1A) Output.RGBColor.a=texelColor.w; if (Transp==TRANSP_T1AxVCA) Output.RGBColor.a=texelColor.w * In.Color.w; } else { Output.RGBColor = tex2D(MeshTextureSampler, In.Tex0) * In.Color; Output.RGBColor.a = 1.0f; } #if (!MAB_080X) Output.RGBColor.rgb = pow(Output.RGBColor.rgb, output_gamma_inv); #endif return Output; } /////////////////////////// // New General Purpose Shader! // ver 0.01 // core part - end ///////////////////////////