#include "CalcBlendBone.fxh" #include "CalcFog.fxh" #include "CalcLight.fxh" #include "CalcShadow.fxh" ////////////////////////////////////////////////////////////////////////////////////////////// // World Mat Param ////////////////////////////////////////////////////////////////////////////////////////////// float4x4 g_WorldViewMat : WORLDVIEW; float4x4 g_InvViewMat : INVVIEW; #ifdef BAKE_VELOCITY float4x4 g_PrevWorldViewProjMat : PREVWORLDVIEWPROJ; float4x4 g_InvWorldViewPrevWVPMat : INVWORLDVIEWPREVWORLDVIEWPROJ; #endif ////////////////////////////////////////////////////////////////////////////////////////////// // Shared Param ////////////////////////////////////////////////////////////////////////////////////////////// shared float4x4 g_ProjMat : PROJECTION; shared float g_fElapsedTime : TIME; ////////////////////////////////////////////////////////////////////////////////////////////// // Global Param ////////////////////////////////////////////////////////////////////////////////////////////// #ifdef _3DSMAX_ float4x4 g_WorldViewProjMat : WORLDVIEWPROJ; float4 g_LightDir : DIRECTION < string UIName = "Light Direction"; string Object = "TargetLight"; int RefID = 0; > = { 0.577f, -0.577f, 0.577f, 0.0f }; float4 g_LightDiffuse : LIGHTCOLOR < int LightRef = 0; > = { 1.0f, 1.0f, 1.0f, 1.0f }; #endif ////////////////////////////////////////////////////////////////////////////////////////////// // Custom Param ////////////////////////////////////////////////////////////////////////////////////////////// #define _USE_DIFFUSE_ #include "MaterialColor.fxh" texture2D g_EnvTex : ENVTEXTURE < string UIName = "Environment Texture"; >; sampler2D g_EnvSampler = sampler_state { texture = < g_EnvTex >; MinFilter = Linear; MagFilter = Linear; MipFilter = None; }; texture2D g_MaskTex : MASKTEXTURE < string UIName = "Mask Texture"; >; sampler2D g_MaskSampler = sampler_state { texture = < g_MaskTex >; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; }; float4 g_EmissiveColor[ 5 ] : EMMISIVECOLOR < string UIName = "EmissiveColor"; >; float g_EmissivePower : EMISSIVEPOWER < string UIName = "Emissive Power"; > = 1.0f; float g_EmissivePowerRange : EMISSIVEPOWERRANGE < string UIName = "Emissive Power Range"; > = 0.0f; float g_EmissiveAniSpeed : EMISSIVEANISPEED < string UIName = "Emissive Ani Speed"; > = 1.0f; float4 g_SkinColor : SKINCOLOR < string UIName = "Skin Color"; > = { 0.5 , 0.5, 0.5, 1.0 }; float4 g_EyeColor : EYECOLOR < string UIName = "Eye Color"; > = { 1.0, 1.0, 1.0, 1.0 }; float4 g_SkinCoeffA = float4( 1414.7135, 1414.7135, 1414.7135, 1); float4 g_SkinCoeffB = float4( 1.0, 1.0, 1.0, 1); float4 g_SkinCoeffC = float4( 4000000, 4000000, 4000000, 1); float4 g_SkinCoeffD = float4( -1413.7135, -1413.7135, -1413.7135, 1); ////////////////////////////////////////////////////////////////////////////////////////////// // Vertex Buffer Declaration ////////////////////////////////////////////////////////////////////////////////////////////// struct VertexInput { float3 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord0 : TEXCOORD0; }; struct VertexInputAni { float3 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord0 : TEXCOORD0; int4 nBoneIndex : BLENDINDICES; float4 fWeight : BLENDWEIGHT; }; struct VertexOutput { float4 Position : POSITION; float3 Reflect : TEXCOORD0; float3 TexCoord0 : TEXCOORD1; float4 Color : TEXCOORD2; float4 Fog : TEXCOORD3; #ifdef BAKE_DEPTHMAP float DepthValue : TEXCOORD4; #endif #ifdef BAKE_VELOCITY float2 Velocity : TEXCOORD5; #endif }; struct VertexOutputShadow { float4 Position : POSITION; float3 Reflect : TEXCOORD0; float3 TexCoord0 : TEXCOORD1; float4 Color : TEXCOORD2; float4 Fog : TEXCOORD3; #if defined( SIMPLE_SHADOWMAP ) || defined( DEPTH_SHADOWMAP ) float4 LightSpacePos : TEXCOORD4; #endif #ifdef BAKE_DEPTHMAP float DepthValue : TEXCOORD5; #endif #ifdef BAKE_VELOCITY float2 Velocity : TEXCOORD6; #endif }; struct PixelOutput { float4 Color : COLOR0; #ifdef BAKE_DEPTHMAP float4 Depth : COLOR1; #endif #ifdef BAKE_VELOCITY float4 Velocity : COLOR2; #endif }; ////////////////////////////////////////////////////////////////////////////////////////////// // Start Vertex Shader ////////////////////////////////////////////////////////////////////////////////////////////// #ifdef ETERNITY_ENGINE #define CalcDiffuse \ \ float3 WorldViewPos = mul( float4( Input.Position.xyz, 1.0f ), g_WorldViewMat ); \ Output.Position = mul( float4( WorldViewPos, 1.0f ), g_ProjMat ); \ float3 WorldViewNormal = normalize( mul( Input.Normal, g_WorldViewMat ) ); \ \ float4 DiffuseLight = float4( 0.0f, 0.0f, 0.0f, 1.0f ); \ DiffuseLight = CalcDiffuseAll( DiffuseLight, WorldViewNormal, WorldViewPos ); \ \ float4 Ambient = g_MaterialAmbient * g_LightAmbient; \ float4 Diffuse = g_MaterialDiffuse * DiffuseLight; \ Output.Color = Diffuse + Ambient; \ Output.Color.w = g_MaterialAmbient.w; \ Output.TexCoord0.xy = Input.TexCoord0; \ Output.TexCoord0.x = frac(Input.TexCoord0.x); \ Output.TexCoord0.z = floor(Input.TexCoord0.x); \ float3 WorldViewReflect = reflect( normalize( WorldViewPos ), WorldViewNormal ); \ Output.Reflect = normalize( mul( WorldViewReflect, g_InvViewMat ) ); \ Output.Reflect.y = 0.5f - Output.Reflect.y * 0.5f; \ float2 ScreenCoord = Output.Position.xy / Output.Position.w; \ Output.Fog.xy = ( ScreenCoord + 1.0f ) * 0.5f; \ Output.Fog.y = 1.0f - Output.Fog.y; \ VertexOutput DiffuseVS( VertexInput Input ) { VertexOutput Output; CalcDiffuse; Output.Fog.zw = CalcFogValue( Output.Position.z ); #ifdef BAKE_DEPTHMAP Output.DepthValue = Output.Position.z; #endif #ifdef BAKE_VELOCITY Output.Velocity = Output.Position.xy / Output.Position.w; float4 PrevWorldViewProjPos = mul( float4( Input.Position.xyz, 1.0f ), g_PrevWorldViewProjMat ); Output.Velocity -= PrevWorldViewProjPos.xy / PrevWorldViewProjPos.w; #endif return Output; } VertexOutputShadow DiffuseShadowVS( VertexInput Input ) { VertexOutputShadow Output; CalcDiffuse; Output.Fog.zw = CalcFogValue( Output.Position.z ); #if defined( SIMPLE_SHADOWMAP ) || defined( DEPTH_SHADOWMAP ) Output.LightSpacePos = mul( float4( Input.Position.xyz, 1.0f ) , g_WorldLightViewProjMat ); Output.LightSpacePos.z = dot( float4( Input.Position.xyz, 1.0f ) , g_WorldLightViewProjDepth ) * Output.LightSpacePos.w; #endif #ifdef BAKE_DEPTHMAP Output.DepthValue = Output.Position.z; #endif #ifdef BAKE_VELOCITY Output.Velocity = Output.Position.xy / Output.Position.w; float4 PrevWorldViewProjPos = mul( float4( Input.Position.xyz, 1.0f ), g_PrevWorldViewProjMat ); Output.Velocity -= PrevWorldViewProjPos.xy / PrevWorldViewProjPos.w; #endif return Output; } #define CalcDiffuseAni \ float3 WorldViewPos = CalcBlendPosition( Input.Position, Input.nBoneIndex, Input.fWeight ); \ Output.Position = mul( float4( WorldViewPos, 1.f ) , g_ProjMat ); \ \ float3 WorldViewNormal = CalcBlendNormal( Input.Normal, Input.nBoneIndex, Input.fWeight ); \ \ float4 DiffuseLight = float4( 0.0f, 0.0f, 0.0f, 1.0f ); \ DiffuseLight = CalcDiffuseAll( DiffuseLight, WorldViewNormal, WorldViewPos ); \ \ float4 Ambient = g_MaterialAmbient * g_LightAmbient; \ float4 Diffuse = g_MaterialDiffuse * DiffuseLight; \ Output.Color = Diffuse + Ambient; \ Output.Color.w = g_MaterialAmbient.w; \ Output.TexCoord0.xy = Input.TexCoord0; \ Output.TexCoord0.x = frac(Input.TexCoord0.x); \ Output.TexCoord0.z = floor(Input.TexCoord0.x); \ \ float3 WorldViewReflect = reflect( normalize( WorldViewPos ), WorldViewNormal ); \ Output.Reflect = normalize( mul( WorldViewReflect, g_InvViewMat ) ); \ Output.Reflect.y = 0.5f - Output.Reflect.y * 0.5f; \ float2 ScreenCoord = Output.Position.xy / Output.Position.w; \ Output.Fog.xy = ( ScreenCoord + 1.0f ) * 0.5f; \ Output.Fog.y = 1.0f - Output.Fog.y; \ VertexOutput DiffuseAniVS( VertexInputAni Input ) { VertexOutput Output; CalcDiffuseAni; Output.Fog.zw = CalcFogValue( Output.Position.z ); #ifdef BAKE_DEPTHMAP Output.DepthValue = Output.Position.z; #endif #ifdef BAKE_VELOCITY Output.Velocity = Output.Position.xy / Output.Position.w; float4 PrevWorldViewProjPos = mul( float4( WorldViewPos.xyz, 1.0f ), g_InvWorldViewPrevWVPMat ); Output.Velocity -= PrevWorldViewProjPos.xy / PrevWorldViewProjPos.w; #endif return Output; } VertexOutputShadow DiffuseAniShadowVS( VertexInputAni Input ) { VertexOutputShadow Output; CalcDiffuseAni; Output.Fog.zw = CalcFogValue( Output.Position.z ); #if defined( SIMPLE_SHADOWMAP ) || defined( DEPTH_SHADOWMAP ) Output.LightSpacePos = mul( float4( WorldViewPos.xyz, 1.0f ) , g_InvViewLightViewProjMat ); Output.LightSpacePos.z = dot( float4( WorldViewPos.xyz, 1.0f ) , g_InvViewLightViewProjDepth ) * Output.LightSpacePos.w; #endif #ifdef BAKE_DEPTHMAP Output.DepthValue = Output.Position.z; #endif #ifdef BAKE_VELOCITY Output.Velocity = Output.Position.xy / Output.Position.w; float4 PrevWorldViewProjPos = mul( float4( WorldViewPos.xyz, 1.0f ), g_InvWorldViewPrevWVPMat ); Output.Velocity -= PrevWorldViewProjPos.xy / PrevWorldViewProjPos.w; #endif return Output; } #else float4x4 g_ViewMat : VIEW; VertexOutput DiffuseVS( VertexInput Input ) { VertexOutput Output; Output.Position = mul( float4( Input.Position.xyz , 1.0 ) , g_WorldViewProjMat ); float3 TransformNormal = normalize( mul( Input.Normal, g_WorldViewMat ) ); float3 LightVec = normalize( mul( g_LightDir, g_ViewMat ) ); float DiffuseLight = saturate( dot( TransformNormal, LightVec ) ); float4 Ambient = g_MaterialAmbient * g_LightAmbient; float4 Diffuse = g_MaterialDiffuse * g_LightDiffuse * DiffuseLight; Output.Color = Diffuse + Ambient; Output.Color.w = g_MaterialAmbient.w; Output.Fog = 0.0f; float3 WorldViewPos = mul( float4( Input.Position.xyz , 1.0 ) , g_ViewMat ); Output.TexCoord0.xy = Input.TexCoord0; Output.TexCoord0.z = 0; float3 WorldViewReflect = reflect( normalize( WorldViewPos ), TransformNormal ); Output.Reflect = normalize( mul( WorldViewReflect, g_InvViewMat ) ); Output.Reflect.y = 0.5f - Output.Reflect.y * 0.5f; return Output; } #endif ////////////////////////////////////////////////////////////////////////////////////////////// // Start Pixel Shader ////////////////////////////////////////////////////////////////////////////////////////////// #ifdef _3DSMAX_ float4 CalcDiffuseColor( VertexOutput Input ) { float4 DiffuseTex = tex2D( g_DiffuseSampler, Input.TexCoord0 ); float4 MaskTex = tex2D( g_MaskSampler, Input.TexCoord0 ); float fEmissive = g_EmissivePower + g_EmissivePowerRange * cos( g_fElapsedTime * g_EmissiveAniSpeed ); float4 EmissiveColor = g_EmissiveColor[ Input.TexCoord0.z ] * g_EmissivePower; float4 Result = Input.Color * DiffuseTex; Result.xyz = lerp( Result.xyz, EmissiveColor.xyz, MaskTex.r ); float2 TexCoord; TexCoord.x = frac( atan2( Input.Reflect.x, Input.Reflect.z ) / ( 6.283185308 ) + 1.0f ); TexCoord.y = Input.Reflect.y; float4 EnvTex = tex2D( g_EnvSampler, TexCoord ); Result = Result + float4( MaskTex.yyy, 0.0f ) * EnvTex; return Result; } #else float4 CalcDiffuseColor( VertexOutput Input ) { float4 DiffuseTex = tex2D( g_DiffuseSampler, Input.TexCoord0.xy ); float4 MaskTex = tex2D( g_MaskSampler, Input.TexCoord0.xy ); float3 SkinColor = DiffuseTex.xyz * g_SkinCoeffA.w - g_SkinCoeffD.xyz; SkinColor = g_SkinCoeffA.xyz - g_SkinCoeffB.xyz * sqrt( g_SkinCoeffC.xyz - SkinColor * SkinColor ); DiffuseTex.xyz = lerp( DiffuseTex.xyz, SkinColor, MaskTex.b); DiffuseTex.xyz = lerp( DiffuseTex.xyz, DiffuseTex.xyz*g_EyeColor.xyz, MaskTex.a); float4 EmissiveColor = g_EmissiveColor[ Input.TexCoord0.z ]; float4 Result = Input.Color * DiffuseTex; Result.xyz = lerp( Result.xyz, EmissiveColor.xyz, EmissiveColor.a*MaskTex.r ); float2 TexCoord; TexCoord.x = frac( atan2( Input.Reflect.x, Input.Reflect.z ) / ( 6.283185308 ) + 1.0f ); TexCoord.y = Input.Reflect.y; float4 EnvTex = tex2D( g_EnvSampler, TexCoord ); Result = Result + float4( MaskTex.yyy, 0.0f ) * EnvTex; return Result; } #endif PixelOutput DiffusePS( VertexOutput Input ) : COLOR { PixelOutput Output; Output.Color = CalcDiffuseColor( Input ); Output.Color.xyz = CalcFogColor( Output.Color.xyz, Input.Fog ); #ifdef BAKE_DEPTHMAP Output.Depth = float4( Input.DepthValue.x, 0.0f, 0.0f, 1.0f ); #endif #ifdef BAKE_VELOCITY Output.Velocity = float4( Input.Velocity, 0.0f, 1.0f ); #endif return Output; } PixelOutput DiffuseShadowPS( VertexOutputShadow Input ) : COLOR { PixelOutput Output; Output.Color = CalcDiffuseColor( ( VertexOutput )Input ); #if defined( SIMPLE_SHADOWMAP ) || defined( DEPTH_SHADOWMAP ) Output.Color.xyz *= CalcShadow( Input.LightSpacePos ); #endif Output.Color.xyz = CalcFogColor( Output.Color.xyz, Input.Fog ); #ifdef BAKE_DEPTHMAP Output.Depth = float4( Input.DepthValue.x, 0.0f, 0.0f, 1.0f ); #endif #ifdef BAKE_VELOCITY Output.Velocity = float4( Input.Velocity, 0.0f, 1.0f ); #endif return Output; } ////////////////////////////////////////////////////////////////////////////////////////////// // Start Technique ////////////////////////////////////////////////////////////////////////////////////////////// #ifdef ETERNITY_ENGINE technique DiffuseTech { pass p0 { VertexShader = compile vs_2_0 DiffuseVS(); PixelShader = compile ps_2_0 DiffusePS(); } } technique DiffuseAniTech { pass p0 { VertexShader = compile vs_2_0 DiffuseAniVS(); PixelShader = compile ps_2_0 DiffusePS(); } } technique DiffuseShadowTech { pass p0 { VertexShader = compile vs_2_0 DiffuseShadowVS(); PixelShader = compile ps_2_0 DiffusePS();//DiffuseShadowPS(); // ¼¿ÇÁ ½¦µµ¿ì ¾ø´Ù. } } technique DiffuseAniShadowTech { pass p0 { VertexShader = compile vs_2_0 DiffuseAniShadowVS(); PixelShader = compile ps_2_0 DiffusePS();//DiffuseShadowPS(); // ¼¿ÇÁ ½¦µµ¿ì ¾ø´Ù. } } #else technique DiffuseTech { pass p0 { VertexShader = compile vs_2_0 DiffuseVS(); PixelShader = compile ps_2_0 DiffusePS(); } } #endif