Is there a way to export a ShaderFX shader created in Maya to Unity? I know that this is possible in other game engines but since Unity uses ShaderLab does it work with Unity?
Waw that'd be really cool, Ultimately I would like to have the shader in that Amplify Shader form so that I can make adjustments to it for my game, so if you can build it in Amplify Shader it's even better for me, but a hlsl form would be a big help already. Here's the hlsl code, it's the dota 2 shader: Code (CSharp): // ----------------------------------------- Header ------------------------------------------ #ifndef SFX_HLSL_5 #define SFX_HLSL_5 #endif #ifndef _MAYA_ #define _MAYA_ #endif #ifndef half #define half float #define half2 float2 #define half3 float3 #define half4 float4 #endif // ----------------------------------- Per Frame -------------------------------------- cbuffer UpdatePerFrame : register(b0) { float4x4 viewI : ViewInverse < string UIWidget = "None"; >; bool MayaHwFogEnabled : HardwareFogEnabled < string UIWidget = "None"; > = false; int MayaHwFogMode : HardwareFogMode < string UIWidget = "None"; > = 0; float MayaHwFogStart : HardwareFogStart < string UIWidget = "None"; > = 0.0; float MayaHwFogEnd : HardwareFogEnd < string UIWidget = "None"; > = 100.0; float MayaHwFogDensity : HardwareFogDensity < string UIWidget = "None"; > = 0.1; float4 MayaHwFogColor : HardwareFogColor < string UIWidget = "None"; > = { 0.5, 0.5, 0.5, 1.0 }; float4x4 viewPrj : ViewProjection < string UIWidget = "None"; >; float4x4 view : View < string UIWidget = "None"; >; }; // --------------------------------------- Per Object ----------------------------------------- cbuffer UpdatePerObject : register(b1) { int ClampDynamicLights < float UIMin = 0; float UISoftMin = 0; float UIMax = 99; float UISoftMax = 99; float UIStep = 1; string UIName = "ClampDynamicLights"; string UIWidget = "Slider"; > = 99; float4x4 world : World < string UIWidget = "None"; >; float4x4 wvp : WorldViewProjection < string UIWidget = "None"; >; }; // --------------------------------------- Attributes ----------------------------------------- cbuffer UpdateAttributes : register(b2) { float3 specularColor < string UIName = "specularColor"; string UIWidget = "ColorPicker"; > = {0.854306,0.954687,1.000000}; float specularExponent < float UIMin = 0.000000; float UISoftMin = 0.000000; float UIMax = 99.000000; float UISoftMax = 99.000000; float UIStep = 0.010000; string UIName = "specularExponent"; string UIWidget = "Slider"; > = 23.000000; float specularScale < float UIMin = 0.000000; float UISoftMin = 0.000000; float UIMax = 99.000000; float UISoftMax = 99.000000; float UIStep = 0.010000; string UIName = "specularScale"; string UIWidget = "Slider"; > = 42.000000; float3 rimLightColor < string UIName = "rimLightColor"; string UIWidget = "ColorPicker"; > = {0.735357,0.906332,0.954687}; float rimLightScale < float UIMin = 0.000000; float UISoftMin = 0.000000; float UIMax = 99.000000; float UISoftMax = 99.000000; float UIStep = 0.010000; string UIName = "rimLightScale"; string UIWidget = "Slider"; > = 10.000000; float cubeMapScalar < float UIMin = 0.000000; float UISoftMin = 0.000000; float UIMax = 99.000000; float UISoftMax = 99.000000; float UIStep = 0.010000; string UIName = "cubeMapScalar"; string UIWidget = "Slider"; > = 0.000000; }; // ---------------------------------------- Textures ----------------------------------------- Texture2D fresnelWarpColor < string ResourceName = "__death_prophet_base_fresnelWarpColor.tga"; string UIName = "fresnelWarpColor"; string ResourceType = "2D"; string UIWidget = "FilePicker"; >; Texture2D fresnelWarpRim < string ResourceName = "__death_prophet_base_fresnelWarpRim.tga"; string UIName = "fresnelWarpRim"; string ResourceType = "2D"; string UIWidget = "FilePicker"; >; Texture2D fresnelWarpSpec < string ResourceName = "__death_prophet_base_fresnelWarpSpec.tga"; string UIName = "fresnelWarpSpec"; string ResourceType = "2D"; string UIWidget = "FilePicker"; >; Texture2D cubeMap < string ResourceName = "__death_prophet_base_cubeMap.tga"; string UIName = "cubeMap"; string ResourceType = "2D"; string UIWidget = "FilePicker"; >; SamplerState MMMLCCCSampler { Filter = MIN_MAG_MIP_LINEAR; AddressU = CLAMP; AddressV = CLAMP; AddressW = CLAMP; }; Texture2D color < string ResourceName = "__death_prophet_base_color.tga"; string UIName = "color"; string ResourceType = "2D"; string UIWidget = "FilePicker"; >; SamplerState MMMLWWWSampler { Filter = MIN_MAG_MIP_LINEAR; AddressU = WRAP; AddressV = WRAP; AddressW = WRAP; }; Texture2D normal < string ResourceName = "__death_prophet_base_normal.tga"; string UIName = "normal"; string ResourceType = "2D"; string UIWidget = "FilePicker"; >; Texture2D specularMask < string ResourceName = "__death_prophet_base_specularMask.tga"; string UIName = "specularMask"; string ResourceType = "2D"; string UIWidget = "FilePicker"; >; Texture2D rimMask < string ResourceName = "__death_prophet_base_rimMask.tga"; string UIName = "rimMask"; string ResourceType = "2D"; string UIWidget = "FilePicker"; >; Texture2D selfIllumMask < string ResourceName = "__death_prophet_base_selfIllumMask.tga"; string UIName = "selfIllumMask"; string ResourceType = "2D"; string UIWidget = "FilePicker"; >; Texture2D translucency < string ResourceName = "__death_prophet_base_translucency.tga"; string UIName = "translucency"; string ResourceType = "2D"; string UIWidget = "FilePicker"; >; Texture2D metalnessMask < string ResourceName = "__death_prophet_base_metalnessMask.tga"; string UIName = "metalnessMask"; string ResourceType = "2D"; string UIWidget = "FilePicker"; >; Texture2D TransDepthTexture : transpdepthtexture < string ResourceName = ""; string UIName = "TransDepthTexture"; string ResourceType = "2D"; string UIWidget = "None"; >; Texture2D OpaqueDepthTexture : opaquedepthtexture < string ResourceName = ""; string UIName = "OpaqueDepthTexture"; string ResourceType = "2D"; string UIWidget = "None"; >; SamplerState MMMPBBW_255_255_255_255_Sampler { Filter = MIN_MAG_MIP_POINT; AddressU = BORDER; AddressV = BORDER; AddressW = WRAP; BorderColor = float4(1.000000,1.000000,1.000000,1.000000); }; // ---------------------------------------- Functions ----------------------------------------- // You may add new struct outputs, function inputs and adjust code in the function. // Function name and output struct should match 'Function Name' attribute on node. // Available preprocessor definitions: SFX_HLSL_3, SFX_HLSL_5, SFX_GLSL_1_2, SFX_GLSL_4, SFX_CGFX_3, SFX_OSGFX, _MAYA_, _3DSMAX_, SFX_SWATCH // You can use SFX_TEXTURE[n] or SFX_SAMPLER[n] to refer to texture inputs so you do not have to hardcode their names float3 my_lerp( float3 a, float3 b, float w ) { return a + w * ( b - a ) ; }; float my_saturate( float x ) { return (x < 0.0) ? 0.0 : (1.0 < x) ? 1.0 : x; }; float3 calcReflectionVectorUnnormalized( float3 N, float3 L ){ return ( 2.0 * ( dot ( N, L ) ) * N ) - ( dot( N, N ) * L ); }; float2 calcCubeMapUV( float3 N ) { float nx_abs = abs( N.r ); float ny_abs = abs( N.g ); float nz_abs = abs( N.b ); float cubeU = 0; float cubeV = 0; if ( nx_abs > ny_abs && nx_abs > nz_abs ) { if ( N.r > 0.0 ) { cubeU = ( ( ( -1.0 * N.b ) / nx_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( -1.0 * N.g ) / nx_abs ) + 1.0 ) / 2.0; } else { cubeU = ( ( ( 1.0 * N.b ) / nx_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( -1.0 * N.g ) / nx_abs ) + 1.0 ) / 2.0; } } else if ( ny_abs > nx_abs && ny_abs > nz_abs ) { if ( N.g > 0.0 ) { cubeU = ( ( ( 1.0 * N.r ) / ny_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( 1.0 * N.b ) / ny_abs ) + 1.0 ) / 2.0; } else { cubeU = ( ( ( 1.0 * N.r ) / ny_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( -1.0 * N.b ) / ny_abs ) + 1.0 ) / 2.0; } } else { if ( N.b > 0.0 ) { cubeU = ( ( ( 1.0 * N.r ) / nz_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( -1.0 * N.g ) / nz_abs ) + 1.0 ) / 2.0; } else { cubeU = ( ( ( -1.0 * N.r ) / nz_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( -1.0 * N.g ) / nz_abs ) + 1.0 ) / 2.0; } } return float2( cubeU, cubeV ); }; struct Dota2HeroOutput { float4 color; }; Dota2HeroOutput Dota2HeroFunc( float3 color, float3 normal, float3 specularMask, float3 specularColor, float specularExponent, float specularScale, float3 rimMask, float3 rimLightColor, float rimLightScale, float3 selfIllumMask, float cubeMapScale, float3 translucency, float3 metalnessMask, float3 Nn, float3 Tn, float3 Bn, float3 L ) { Dota2HeroOutput OUT; // // compute the diffuse element // normal.g = 1.0 - normal.g; normal = normal * 2 - 1.0; float3 N = normalize( (normal.x * Tn) + (normal.y * Bn) + (normal.z * Nn) ); float N_dot_L = 0; #ifdef SFX_HLSL_5 N_dot_L = saturate( dot( N, L ) ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) N_dot_L = my_saturate( dot( N, L ) ); #endif float halfLambert = ( N_dot_L * 0.5 ) + 0.5; float3 diffuse = float3( halfLambert, halfLambert, halfLambert ); // // compute the fresnel terms // float L_dot_N = 0; #ifdef SFX_HLSL_5 L_dot_N = saturate( dot( L, Nn ) ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) L_dot_N = my_saturate( dot( L, Nn ) ); #endif float fwRim = 0; float fwColor = 0; float fwSpec = 0; #ifdef SFX_HLSL_5 fwColor = fresnelWarpColor.Sample( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).r; fwRim = fresnelWarpRim.Sample( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).g; fwSpec = fresnelWarpSpec.Sample( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).b; #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) fwColor = tex2D( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).x; fwRim = tex2D( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).y; fwSpec = tex2D( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).z; #endif /** * TODO: NON-HLSL FUNCTIONS GO HERE */ // // compute the specular element // float3 R = reflect( L, N ); float R_dot_L = 0; #ifdef SFX_HLSL_5 R_dot_L = saturate( dot( L, -R.rgb ) ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) R_dot_L = my_saturate( dot( L, -R.rgb ) ); #endif float specularIntensity = 0; #ifdef SFX_HLSL_5 specularIntensity = saturate( N_dot_L ) * pow( max( 0.001, R_dot_L ), specularExponent ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) specularIntensity = my_saturate( N_dot_L ) * pow( max( 0.001, R_dot_L ), specularExponent ); #endif float3 spec = float3( specularIntensity, specularIntensity, specularIntensity ); spec *= specularScale; // // cubemap // float3 RU = calcReflectionVectorUnnormalized( L, N ); float2 cubeUV = calcCubeMapUV( RU ); float3 vCubemap = float3( 0, 0, 0 ); #ifdef SFX_HLSL_5 vCubemap = cubeMap.Sample( MMMLCCCSampler, cubeUV ).r ; #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) vCubemap = tex2D( MMMLCCCSampler, cubeUV ).r ; #endif spec += ( vCubemap.rgb * ( 1.0 - metalnessMask.r ) ); spec *= specularMask; float3 specTint = float3( 1, 1, 1 ); #ifdef SFX_HLSL_5 specTint = lerp( color, specularColor, specularMask ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) specTint = my_lerp( color, specularColor, specularMask ); #endif spec *= specTint; spec *= fwSpec; // // accumulate the final color // float3 accum = ( color * diffuse ) + spec; // // metalness // float3 metalness = spec; #ifdef SFX_HLSL_5 accum = lerp( accum, metalness, metalnessMask.r ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) accum = my_lerp( accum, metalness, metalnessMask.r ); #endif // // add rim light // float3 rimLight = rimLightColor * rimLightScale * rimMask; rimLight *= max(0, dot( Nn, float3( 0, 1, 0 ) ) ); rimLight *= fwRim; accum += rimLight; #ifdef SFX_HLSL_5 accum = lerp( accum, color, selfIllumMask.r ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) accum = my_lerp( accum, color, selfIllumMask.r ); #endif OUT.color = float4( accum.r, accum.g, accum.b, translucency.r ); return OUT; }; float4 sampleTransDepthTex(float2 UV) { float4 col = float4(0,0,0,0); #if defined(SFX_CGFX_3) || defined(SFX_HLSL_3) col = tex2D( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #ifdef SFX_HLSL_5 #if defined(SFX_SWATCH) || defined(_3DSMAX_) col = TransDepthTexture.Sample( MMMPBBW_255_255_255_255_Sampler, UV ); #else col = TransDepthTexture.Sample( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #endif #ifdef SFX_GLSL_4 col = texture( TransDepthTexture, UV ); #endif #ifdef SFX_OGSFX col = texture( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #ifdef SFX_GLSL_1_2 col = texture2D( TransDepthTexture, UV ); #endif return col; } float4 sampleOpaqueDepthTex(float2 UV) { float4 col = float4(0,0,0,0); #if defined(SFX_CGFX_3) || defined(SFX_HLSL_3) col = tex2D( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #ifdef SFX_HLSL_5 #if defined(SFX_SWATCH) || defined(_3DSMAX_) col = OpaqueDepthTexture.Sample( MMMPBBW_255_255_255_255_Sampler, UV ); #else col = OpaqueDepthTexture.Sample( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #endif #ifdef SFX_GLSL_4 col = texture( OpaqueDepthTexture, UV ); #endif #ifdef SFX_OGSFX col = texture( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #ifdef SFX_GLSL_1_2 col = texture2D( OpaqueDepthTexture, UV ); #endif return col; } struct DepthPeelOutput { float4 LinearDepth; float Peel; }; DepthPeelOutput DepthPeelFunc( float3 worldPos, float4x4 view, float4x4 viewPrj ) { DepthPeelOutput OUT; #ifdef SFX_CGFX_3 float currZ = abs( mul( view, float4(worldPos, 1.0f) ).z ); float4 Pndc = mul( viewPrj, float4(worldPos, 1.0f) ); float2 UV = Pndc.xy / Pndc.w * float2(0.5f, 0.5f) + 0.5f; float prevZ = sampleTransDepthTex(UV).r; float opaqZ = sampleOpaqueDepthTex(UV).r; float bias = 0.00002f; if (currZ < prevZ * (1.0f + bias) || currZ > opaqZ * (1.0f - bias)) { discard; } float ld = abs( mul( view, float4(worldPos, 1.0f) ).z ); OUT.LinearDepth = float4(ld, ld, ld, ld); #else #if defined(SFX_GLSL_1_2) || defined(SFX_GLSL_4) || defined(SFX_OGSFX) float currZ = abs( ( view * float4(worldPos, 1.0f) ).z ); float4 Pndc = viewPrj * float4(worldPos, 1.0f); float2 UV = Pndc.xy / Pndc.w * float2(0.5f, 0.5f) + 0.5f; float prevZ = sampleTransDepthTex(UV).r; float opaqZ = sampleOpaqueDepthTex(UV).r; float bias = 0.00002f; if (currZ < prevZ * (1.0f + bias) || currZ > opaqZ * (1.0f - bias)) { discard; } float ld = abs( ( view * float4(worldPos, 1.0f) ).z ); OUT.LinearDepth = float4(ld, ld, ld, ld); #else float currZ = abs( mul( float4(worldPos, 1.0f), view ).z ); float4 Pndc = mul( float4(worldPos, 1.0f), viewPrj ); float2 UV = Pndc.xy / Pndc.w * float2(0.5f, -0.5f) + 0.5f; float prevZ = sampleTransDepthTex(UV).r; float opaqZ = sampleOpaqueDepthTex(UV).r; float bias = 0.00002f; if (currZ < prevZ * (1.0f + bias) || currZ > opaqZ * (1.0f - bias)) { discard; } float ld = abs( mul( float4(worldPos, 1.0f), view ).z ); OUT.LinearDepth = float4(ld, ld, ld, ld); #endif #endif OUT.Peel = 1.0f; return OUT; } // -------------------------------------- ShaderVertex -------------------------------------- struct APPDATA { float3 Position : POSITION; float2 map1 : TEXCOORD0; float3 Normal : NORMAL; float3 Tangent : TANGENT; float3 BiNormal : BINORMAL; }; struct SHADERDATA { float4 Position : SV_Position; float4 map1 : TEXCOORD0; float4 Normal : NORMAL; float4 Tangent : TANGENT; float4 BiNormal : BINORMAL; float4 WorldPosition : TEXCOORD1; half3 FogFactor : TEXCOORD2; }; SHADERDATA ShaderVertex(APPDATA IN) { SHADERDATA OUT; OUT.Position = float4(IN.Position, 1); float4 OutUVs = float4(IN.map1.x, IN.map1.y, 0.000000, 0.000000); OUT.map1 = OutUVs; float3 MulOp = mul(IN.Normal, ((float3x3)world)); float3 NormalN = normalize(MulOp); float4 WorldNormal = float4(NormalN.x, NormalN.y, NormalN.z, 1.000000); OUT.Normal = WorldNormal; float3 MulOp431 = mul(IN.Tangent, ((float3x3)world)); float3 TangentNorm = normalize(MulOp431); float4 WorldTangent = float4(TangentNorm.x, TangentNorm.y, TangentNorm.z, 1.000000); OUT.Tangent = WorldTangent; float3 MulOp407 = mul(IN.BiNormal, ((float3x3)world)); float3 BiNormalNorm = normalize(MulOp407); float4 WorldBiNormal = float4(BiNormalNorm.x, BiNormalNorm.y, BiNormalNorm.z, 1.000000); OUT.BiNormal = WorldBiNormal; float4 WorldPos = mul(OUT.Position, world); OUT.WorldPosition = WorldPos; OUT.WorldPosition = (mul(float4(IN.Position,1), world)); float4 _HPosition = mul( float4(OUT.WorldPosition.xyz, 1), viewPrj ); float fogFactor = 0.0; if (MayaHwFogMode == 0) { fogFactor = saturate((MayaHwFogEnd - _HPosition.z) / (MayaHwFogEnd - MayaHwFogStart)); } else if (MayaHwFogMode == 1) { fogFactor = 1.0 / (exp(_HPosition.z * MayaHwFogDensity)); } else if (MayaHwFogMode == 2) { fogFactor = 1.0 / (exp(pow(_HPosition.z * MayaHwFogDensity, 2))); } OUT.FogFactor = float3(fogFactor, fogFactor, fogFactor); float4 WVSpace = mul(OUT.Position, wvp); OUT.Position = WVSpace; return OUT; } // -------------------------------------- ShaderPixel -------------------------------------- struct PIXELDATA { float4 Color : SV_Target; }; PIXELDATA ShaderPixel(SHADERDATA IN) { PIXELDATA OUT; float4 LightLoopTotal11 = float4(0,0,0,0); for (int ActiveLightIndex = 0; ActiveLightIndex < 3; ++ActiveLightIndex) { if (ActiveLightIndex >= ClampDynamicLights) {continue;} LightLoopTotal11 += float4(0, 0, 0, 0); } float4 Sampler = color.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float4 Sampler378 = normal.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float4 Sampler463 = specularMask.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float3 PowOp = pow(Sampler463.xyz, float3(2.200000,2.200000,2.200000)); float4 Sampler491 = rimMask.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float3 PowOp506 = pow(Sampler491.xyz, float3(2.200000,2.200000,2.200000)); float4 Sampler520 = selfIllumMask.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float3 PowOp535 = pow(Sampler520.xyz, float3(2.200000,2.200000,2.200000)); float4 Sampler580 = translucency.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float3 PowOp595 = pow(Sampler580.xyz, float3(2.200000,2.200000,2.200000)); float4 Sampler607 = metalnessMask.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float3 PowOp622 = pow(Sampler607.xyz, float3(2.200000,2.200000,2.200000)); float3 NormOp = normalize(IN.Normal.xyz); float3 NormOp439 = normalize(IN.Tangent.xyz); float3 NormOp415 = normalize(IN.BiNormal.xyz); float3 CameraPosition = viewI[3].xyz; float3 CamVec = (CameraPosition - IN.WorldPosition.xyz); float3 CamVecNorm = normalize(CamVec); Dota2HeroOutput CustomCode = Dota2HeroFunc(Sampler.xyz, Sampler378.xyz, PowOp, specularColor.xyz, specularExponent, specularScale, PowOp506, rimLightColor.xyz, rimLightScale, PowOp535, cubeMapScalar, PowOp595, PowOp622, NormOp, NormOp439, NormOp415, CamVecNorm); float4 LightLoopAndAfterLoop = (LightLoopTotal11 + CustomCode.color); float SatOp = saturate(LightLoopAndAfterLoop.w); float4 VectorConstruct = float4(LightLoopAndAfterLoop.xyz.x, LightLoopAndAfterLoop.xyz.y, LightLoopAndAfterLoop.xyz.z, SatOp); if (MayaHwFogEnabled) { float fogFactor = (1.0 - IN.FogFactor.x) * MayaHwFogColor.a; VectorConstruct.rgb = lerp(VectorConstruct.rgb, MayaHwFogColor.rgb, fogFactor); } OUT.Color = VectorConstruct; return OUT; } // -------------------------------------- ShaderPixelP1 -------------------------------------- struct PIXELDATAP1 { float4 Color0 : SV_Target0; float4 Color1 : SV_Target1; }; PIXELDATAP1 ShaderPixelP1(SHADERDATA IN) { PIXELDATAP1 OUT; DepthPeelOutput DepthPeel = DepthPeelFunc(IN.WorldPosition.xyz, view, viewPrj); OUT.Color0 = ShaderPixel(IN).Color; OUT.Color1 = DepthPeel.LinearDepth; return OUT; } // -------------------------------------- ShaderPixelP2 -------------------------------------- struct PIXELDATAP2 { float4 Color0 : SV_Target0; float4 Color1 : SV_Target1; }; PIXELDATAP2 ShaderPixelP2(SHADERDATA IN) { PIXELDATAP2 OUT; DepthPeelOutput DepthPeel = DepthPeelFunc(IN.WorldPosition.xyz, view, viewPrj); OUT.Color0 = ShaderPixel(IN).Color; OUT.Color1 = (DepthPeel.Peel * (OUT.Color0.w > 0.001f ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f))); return OUT; } // -------------------------------------- ShaderPixelP3 -------------------------------------- struct PIXELDATAP3 { float4 Color0 : SV_Target0; float4 Color1 : SV_Target1; }; PIXELDATAP3 ShaderPixelP3(SHADERDATA IN) { PIXELDATAP3 OUT; OUT.Color0 = ShaderPixel(IN).Color; OUT.Color1 = (OUT.Color0.w > 0.001f ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); return OUT; } // -------------------------------------- technique T0 --------------------------------------- technique11 T0 < bool overridesDrawState = false; int isTransparent = 0; > { pass P0 < string drawContext = "colorPass"; > { SetVertexShader(CompileShader(vs_5_0, ShaderVertex())); SetPixelShader(CompileShader(ps_5_0, ShaderPixel())); SetHullShader(NULL); SetDomainShader(NULL); SetGeometryShader(NULL); } pass P1 < string drawContext = "transparentPeel"; > { SetVertexShader(CompileShader(vs_5_0, ShaderVertex())); SetPixelShader(CompileShader(ps_5_0, ShaderPixelP1())); SetHullShader(NULL); SetDomainShader(NULL); SetGeometryShader(NULL); } pass P2 < string drawContext = "transparentPeelAndAvg"; > { SetVertexShader(CompileShader(vs_5_0, ShaderVertex())); SetPixelShader(CompileShader(ps_5_0, ShaderPixelP2())); SetHullShader(NULL); SetDomainShader(NULL); SetGeometryShader(NULL); } pass P3 < string drawContext = "transparentWeightedAvg"; > { SetVertexShader(CompileShader(vs_5_0, ShaderVertex())); SetPixelShader(CompileShader(ps_5_0, ShaderPixelP3())); SetHullShader(NULL); SetDomainShader(NULL); SetGeometryShader(NULL); } }
Work in progress (shader currently doesn't work, I have to fix texture samplers and insert proper matrices): Code (CSharp): Shader "Dota" { Properties { fresnelWarpColor ("Fresnel Warp Color", 2D) = "white" {} fresnelWarpRim ("Fresnel Warp Rim", 2D) = "white" {} fresnelWarpSpec ("Fresnel Warp Spec", 2D) = "white" {} cubeMap ("Cube Map", 2D) = "white" {} //color ("Color Map", 2D) = "white" {} normal ("Normal Map", 2D) = "white" {} specularMask ("Specular Mask", 2D) = "white" {} rimMask ("Rim Mask", 2D) = "white" {} selfIllumMask ("selfIllumMask", 2D) = "white" {} translucency ("translucency", 2D) = "white" {} metalnessMask ("metalnessMask", 2D) = "white" {} TransDepthTexture ("TransDepthTexture", 2D) = "white" {} OpaqueDepthTexture ("OpaqueDepthTexture", 2D) = "white" {} } SubShader { CGINCLUDE // ----------------------------------------- Header ------------------------------------------ #ifndef SFX_HLSL_5 #define SFX_HLSL_5 #endif #ifndef _MAYA_ #define _MAYA_ #endif #ifndef half #define half float #define half2 float2 #define half3 float3 #define half4 float4 #endif Texture2D fresnelWarpColor, fresnelWarpRim, fresnelWarpSpec, cubeMap, color, normal, specularMask, rimMask, selfIllumMask; Texture2D translucency, metalnessMask, TransDepthTexture, OpaqueDepthTexture; int ClampDynamicLights = 99; float4x4 world; float4x4 wvp; float4x4 viewI; float4x4 viewPrj; float4x4 view; bool MayaHwFogEnabled = false; int MayaHwFogMode = 0; float MayaHwFogStart = 0.0; float MayaHwFogEnd = 100.0; float MayaHwFogDensity = 0.1; float4 MayaHwFogColor = float4(0.5, 0.5, 0.5, 1.0 ); float3 specularColor = float3(0.854306,0.954687,1.000000); float specularExponent = 23.000000; float specularScale = 42.000000; float3 rimLightColor = float3(0.735357,0.906332,0.954687); float rimLightScale = 10.000000; float cubeMapScalar = 0.000000; /* SamplerState MMMLCCCSampler { Filter = MIN_MAG_MIP_LINEAR; AddressU = CLAMP; AddressV = CLAMP; AddressW = CLAMP; }; SamplerState MMMLWWWSampler { Filter = MIN_MAG_MIP_LINEAR; AddressU = WRAP; AddressV = WRAP; AddressW = WRAP; }; SamplerState MMMPBBW_255_255_255_255_Sampler { Filter = MIN_MAG_MIP_POINT; AddressU = BORDER; AddressV = BORDER; AddressW = WRAP; BorderColor = float4(1.000000,1.000000,1.000000,1.000000); }; */ sampler2D MMMLCCCSampler,MMMLWWWSampler,MMMPBBW_255_255_255_255_Sampler; float3 my_lerp( float3 a, float3 b, float w ) { return a + w * ( b - a ) ; }; float my_saturate( float x ) { return (x < 0.0) ? 0.0 : (1.0 < x) ? 1.0 : x; }; float3 calcReflectionVectorUnnormalized( float3 N, float3 L ){ return ( 2.0 * ( dot ( N, L ) ) * N ) - ( dot( N, N ) * L ); }; float2 calcCubeMapUV( float3 N ) { float nx_abs = abs( N.r ); float ny_abs = abs( N.g ); float nz_abs = abs( N.b ); float cubeU = 0; float cubeV = 0; if ( nx_abs > ny_abs && nx_abs > nz_abs ) { if ( N.r > 0.0 ) { cubeU = ( ( ( -1.0 * N.b ) / nx_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( -1.0 * N.g ) / nx_abs ) + 1.0 ) / 2.0; } else { cubeU = ( ( ( 1.0 * N.b ) / nx_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( -1.0 * N.g ) / nx_abs ) + 1.0 ) / 2.0; } } else if ( ny_abs > nx_abs && ny_abs > nz_abs ) { if ( N.g > 0.0 ) { cubeU = ( ( ( 1.0 * N.r ) / ny_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( 1.0 * N.b ) / ny_abs ) + 1.0 ) / 2.0; } else { cubeU = ( ( ( 1.0 * N.r ) / ny_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( -1.0 * N.b ) / ny_abs ) + 1.0 ) / 2.0; } } else { if ( N.b > 0.0 ) { cubeU = ( ( ( 1.0 * N.r ) / nz_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( -1.0 * N.g ) / nz_abs ) + 1.0 ) / 2.0; } else { cubeU = ( ( ( -1.0 * N.r ) / nz_abs ) + 1.0 ) / 2.0; cubeV = ( ( ( -1.0 * N.g ) / nz_abs ) + 1.0 ) / 2.0; } } return float2( cubeU, cubeV ); }; struct Dota2HeroOutput { float4 color; }; Dota2HeroOutput Dota2HeroFunc( float3 color, float3 normal, float3 specularMask, float3 specularColor, float specularExponent, float specularScale, float3 rimMask, float3 rimLightColor, float rimLightScale, float3 selfIllumMask, float cubeMapScale, float3 translucency, float3 metalnessMask, float3 Nn, float3 Tn, float3 Bn, float3 L ) { Dota2HeroOutput OUT; // // compute the diffuse element // normal.g = 1.0 - normal.g; normal = normal * 2 - 1.0; float3 N = normalize( (normal.x * Tn) + (normal.y * Bn) + (normal.z * Nn) ); float N_dot_L = 0; #ifdef SFX_HLSL_5 N_dot_L = saturate( dot( N, L ) ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) N_dot_L = my_saturate( dot( N, L ) ); #endif float halfLambert = ( N_dot_L * 0.5 ) + 0.5; float3 diffuse = float3( halfLambert, halfLambert, halfLambert ); // // compute the fresnel terms // float L_dot_N = 0; #ifdef SFX_HLSL_5 L_dot_N = saturate( dot( L, Nn ) ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) L_dot_N = my_saturate( dot( L, Nn ) ); #endif float fwRim = 0; float fwColor = 0; float fwSpec = 0; #ifdef SFX_HLSL_5 fwColor = fresnelWarpColor.Sample( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).r; fwRim = fresnelWarpRim.Sample( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).g; fwSpec = fresnelWarpSpec.Sample( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).b; #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) fwColor = tex2D( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).x; fwRim = tex2D( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).y; fwSpec = tex2D( MMMLCCCSampler, float2( L_dot_N, 0.5 ) ).z; #endif /** * TODO: NON-HLSL FUNCTIONS GO HERE */ // // compute the specular element // float3 R = reflect( L, N ); float R_dot_L = 0; #ifdef SFX_HLSL_5 R_dot_L = saturate( dot( L, -R.rgb ) ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) R_dot_L = my_saturate( dot( L, -R.rgb ) ); #endif float specularIntensity = 0; #ifdef SFX_HLSL_5 specularIntensity = saturate( N_dot_L ) * pow( max( 0.001, R_dot_L ), specularExponent ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) specularIntensity = my_saturate( N_dot_L ) * pow( max( 0.001, R_dot_L ), specularExponent ); #endif float3 spec = float3( specularIntensity, specularIntensity, specularIntensity ); spec *= specularScale; // // cubemap // float3 RU = calcReflectionVectorUnnormalized( L, N ); float2 cubeUV = calcCubeMapUV( RU ); float3 vCubemap = float3( 0, 0, 0 ); #ifdef SFX_HLSL_5 vCubemap = cubeMap.Sample( MMMLCCCSampler, cubeUV ).r ; #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) vCubemap = tex2D( MMMLCCCSampler, cubeUV ).r ; #endif spec += ( vCubemap.rgb * ( 1.0 - metalnessMask.r ) ); spec *= specularMask; float3 specTint = float3( 1, 1, 1 ); #ifdef SFX_HLSL_5 specTint = lerp( color, specularColor, specularMask ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) specTint = my_lerp( color, specularColor, specularMask ); #endif spec *= specTint; spec *= fwSpec; // // accumulate the final color // float3 accum = ( color * diffuse ) + spec; // // metalness // float3 metalness = spec; #ifdef SFX_HLSL_5 accum = lerp( accum, metalness, metalnessMask.r ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) accum = my_lerp( accum, metalness, metalnessMask.r ); #endif // // add rim light // float3 rimLight = rimLightColor * rimLightScale * rimMask; rimLight *= max(0, dot( Nn, float3( 0, 1, 0 ) ) ); rimLight *= fwRim; accum += rimLight; #ifdef SFX_HLSL_5 accum = lerp( accum, color, selfIllumMask.r ); #endif #if defined( SFX_CGFX_3 ) || defined( SFX_HLSL_3 ) accum = my_lerp( accum, color, selfIllumMask.r ); #endif OUT.color = float4( accum.r, accum.g, accum.b, translucency.r ); return OUT; }; float4 sampleTransDepthTex(float2 UV) { float4 col = float4(0,0,0,0); #if defined(SFX_CGFX_3) || defined(SFX_HLSL_3) col = tex2D( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #ifdef SFX_HLSL_5 #if defined(SFX_SWATCH) || defined(_3DSMAX_) col = TransDepthTexture.Sample( MMMPBBW_255_255_255_255_Sampler, UV ); #else col = TransDepthTexture.Sample( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #endif #ifdef SFX_GLSL_4 col = texture( TransDepthTexture, UV ); #endif #ifdef SFX_OGSFX col = texture( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #ifdef SFX_GLSL_1_2 col = texture2D( TransDepthTexture, UV ); #endif return col; } float4 sampleOpaqueDepthTex(float2 UV) { float4 col = float4(0,0,0,0); #if defined(SFX_CGFX_3) || defined(SFX_HLSL_3) col = tex2D( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #ifdef SFX_HLSL_5 #if defined(SFX_SWATCH) || defined(_3DSMAX_) col = OpaqueDepthTexture.Sample( MMMPBBW_255_255_255_255_Sampler, UV ); #else col = OpaqueDepthTexture.Sample( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #endif #ifdef SFX_GLSL_4 col = texture( OpaqueDepthTexture, UV ); #endif #ifdef SFX_OGSFX col = texture( MMMPBBW_255_255_255_255_Sampler, UV ); #endif #ifdef SFX_GLSL_1_2 col = texture2D( OpaqueDepthTexture, UV ); #endif return col; } struct DepthPeelOutput { float4 LinearDepth; float Peel; }; DepthPeelOutput DepthPeelFunc( float3 worldPos, float4x4 view, float4x4 viewPrj ) { DepthPeelOutput OUT; #ifdef SFX_CGFX_3 float currZ = abs( mul( view, float4(worldPos, 1.0f) ).z ); float4 Pndc = mul( viewPrj, float4(worldPos, 1.0f) ); float2 UV = Pndc.xy / Pndc.w * float2(0.5f, 0.5f) + 0.5f; float prevZ = sampleTransDepthTex(UV).r; float opaqZ = sampleOpaqueDepthTex(UV).r; float bias = 0.00002f; if (currZ < prevZ * (1.0f + bias) || currZ > opaqZ * (1.0f - bias)) { discard; } float ld = abs( mul( view, float4(worldPos, 1.0f) ).z ); OUT.LinearDepth = float4(ld, ld, ld, ld); #else #if defined(SFX_GLSL_1_2) || defined(SFX_GLSL_4) || defined(SFX_OGSFX) float currZ = abs( ( view * float4(worldPos, 1.0f) ).z ); float4 Pndc = viewPrj * float4(worldPos, 1.0f); float2 UV = Pndc.xy / Pndc.w * float2(0.5f, 0.5f) + 0.5f; float prevZ = sampleTransDepthTex(UV).r; float opaqZ = sampleOpaqueDepthTex(UV).r; float bias = 0.00002f; if (currZ < prevZ * (1.0f + bias) || currZ > opaqZ * (1.0f - bias)) { discard; } float ld = abs( ( view * float4(worldPos, 1.0f) ).z ); OUT.LinearDepth = float4(ld, ld, ld, ld); #else float currZ = abs( mul( float4(worldPos, 1.0f), view ).z ); float4 Pndc = mul( float4(worldPos, 1.0f), viewPrj ); float2 UV = Pndc.xy / Pndc.w * float2(0.5f, -0.5f) + 0.5f; float prevZ = sampleTransDepthTex(UV).r; float opaqZ = sampleOpaqueDepthTex(UV).r; float bias = 0.00002f; if (currZ < prevZ * (1.0f + bias) || currZ > opaqZ * (1.0f - bias)) { discard; } float ld = abs( mul( float4(worldPos, 1.0f), view ).z ); OUT.LinearDepth = float4(ld, ld, ld, ld); #endif #endif OUT.Peel = 1.0f; return OUT; } struct APPDATA { float3 Position : POSITION; float2 map1 : TEXCOORD0; float3 Normal : NORMAL; float3 Tangent : TANGENT; float3 BiNormal : TEXCOORD3; }; struct SHADERDATA { float4 Position : SV_Position; float4 map1 : TEXCOORD0; float4 Normal : NORMAL; float4 Tangent : TANGENT; float4 BiNormal : TEXCOORD3; float4 WorldPosition : TEXCOORD1; half3 FogFactor : TEXCOORD2; }; SHADERDATA ShaderVertex(APPDATA IN) { SHADERDATA OUT; OUT.Position = float4(IN.Position, 1); float4 OutUVs = float4(IN.map1.x, IN.map1.y, 0.000000, 0.000000); OUT.map1 = OutUVs; float3 MulOp = mul(IN.Normal, ((float3x3)world)); float3 NormalN = normalize(MulOp); float4 WorldNormal = float4(NormalN.x, NormalN.y, NormalN.z, 1.000000); OUT.Normal = WorldNormal; float3 MulOp431 = mul(IN.Tangent, ((float3x3)world)); float3 TangentNorm = normalize(MulOp431); float4 WorldTangent = float4(TangentNorm.x, TangentNorm.y, TangentNorm.z, 1.000000); OUT.Tangent = WorldTangent; float3 MulOp407 = mul(IN.BiNormal, ((float3x3)world)); float3 BiNormalNorm = normalize(MulOp407); float4 WorldBiNormal = float4(BiNormalNorm.x, BiNormalNorm.y, BiNormalNorm.z, 1.000000); OUT.BiNormal = WorldBiNormal; float4 WorldPos = mul(OUT.Position, world); OUT.WorldPosition = WorldPos; OUT.WorldPosition = (mul(float4(IN.Position,1), world)); float4 _HPosition = mul( float4(OUT.WorldPosition.xyz, 1), viewPrj ); float fogFactor = 0.0; if (MayaHwFogMode == 0) { fogFactor = saturate((MayaHwFogEnd - _HPosition.z) / (MayaHwFogEnd - MayaHwFogStart)); } else if (MayaHwFogMode == 1) { fogFactor = 1.0 / (exp(_HPosition.z * MayaHwFogDensity)); } else if (MayaHwFogMode == 2) { fogFactor = 1.0 / (exp(pow(_HPosition.z * MayaHwFogDensity, 2))); } OUT.FogFactor = float3(fogFactor, fogFactor, fogFactor); float4 WVSpace = mul(OUT.Position, wvp); OUT.Position = WVSpace; return OUT; } ENDCG Pass { Name "colorPass" CGPROGRAM #pragma vertex ShaderVertex #pragma fragment ShaderPixel #pragma target 5.0 struct PIXELDATA { float4 Color : SV_Target; }; PIXELDATA ShaderPixel(SHADERDATA IN) { PIXELDATA OUT; float4 LightLoopTotal11 = float4(0,0,0,0); for (int ActiveLightIndex = 0; ActiveLightIndex < 3; ++ActiveLightIndex) { if (ActiveLightIndex >= ClampDynamicLights) {continue;} LightLoopTotal11 += float4(0, 0, 0, 0); } float4 Sampler = color.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float4 Sampler378 = normal.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float4 Sampler463 = specularMask.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float3 PowOp = pow(Sampler463.xyz, float3(2.200000,2.200000,2.200000)); float4 Sampler491 = rimMask.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float3 PowOp506 = pow(Sampler491.xyz, float3(2.200000,2.200000,2.200000)); float4 Sampler520 = selfIllumMask.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float3 PowOp535 = pow(Sampler520.xyz, float3(2.200000,2.200000,2.200000)); float4 Sampler580 = translucency.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float3 PowOp595 = pow(Sampler580.xyz, float3(2.200000,2.200000,2.200000)); float4 Sampler607 = metalnessMask.Sample(MMMLWWWSampler, float2(IN.map1.xy.x, 1-IN.map1.xy.y)); float3 PowOp622 = pow(Sampler607.xyz, float3(2.200000,2.200000,2.200000)); float3 NormOp = normalize(IN.Normal.xyz); float3 NormOp439 = normalize(IN.Tangent.xyz); float3 NormOp415 = normalize(IN.BiNormal.xyz); float3 CameraPosition = viewI[3].xyz; float3 CamVec = (CameraPosition - IN.WorldPosition.xyz); float3 CamVecNorm = normalize(CamVec); Dota2HeroOutput CustomCode = Dota2HeroFunc(Sampler.xyz, Sampler378.xyz, PowOp, specularColor.xyz, specularExponent, specularScale, PowOp506, rimLightColor.xyz, rimLightScale, PowOp535, cubeMapScalar, PowOp595, PowOp622, NormOp, NormOp439, NormOp415, CamVecNorm); float4 LightLoopAndAfterLoop = (LightLoopTotal11 + CustomCode.color); float SatOp = saturate(LightLoopAndAfterLoop.w); float4 VectorConstruct = float4(LightLoopAndAfterLoop.xyz.x, LightLoopAndAfterLoop.xyz.y, LightLoopAndAfterLoop.xyz.z, SatOp); if (MayaHwFogEnabled) { float fogFactor = (1.0 - IN.FogFactor.x) * MayaHwFogColor.a; VectorConstruct.rgb = lerp(VectorConstruct.rgb, MayaHwFogColor.rgb, fogFactor); } OUT.Color = VectorConstruct; return OUT; } ENDCG } Pass { Name "transparentPeel" CGPROGRAM #pragma vertex ShaderVertex #pragma fragment ShaderPixel1 #pragma target 5.0 struct PIXELDATAP1 { float4 Color0 : SV_Target0; float4 Color1 : SV_Target1; }; PIXELDATAP1 ShaderPixelP1(SHADERDATA IN) { PIXELDATAP1 OUT; DepthPeelOutput DepthPeel = DepthPeelFunc(IN.WorldPosition.xyz, view, viewPrj); OUT.Color0 = ShaderPixel(IN).Color; OUT.Color1 = DepthPeel.LinearDepth; return OUT; } ENDCG } Pass { Name "transparentPeelAndAvg" CGPROGRAM #pragma vertex ShaderVertex #pragma fragment ShaderPixel2 #pragma target 5.0 struct PIXELDATAP2 { float4 Color0 : SV_Target0; float4 Color1 : SV_Target1; }; PIXELDATAP2 ShaderPixelP2(SHADERDATA IN) { PIXELDATAP2 OUT; DepthPeelOutput DepthPeel = DepthPeelFunc(IN.WorldPosition.xyz, view, viewPrj); OUT.Color0 = ShaderPixel(IN).Color; OUT.Color1 = (DepthPeel.Peel * (OUT.Color0.w > 0.001f ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f))); return OUT; } ENDCG } Pass { Name "transparentWeightedAvg" CGPROGRAM #pragma vertex ShaderVertex #pragma fragment ShaderPixel3 #pragma target 5.0 struct PIXELDATAP3 { float4 Color0 : SV_Target0; float4 Color1 : SV_Target1; }; PIXELDATAP3 ShaderPixelP3(SHADERDATA IN) { PIXELDATAP3 OUT; OUT.Color0 = ShaderPixel(IN).Color; OUT.Color1 = (OUT.Color0.w > 0.001f ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); return OUT; } ENDCG } } }