/*********************************************************************NVMH3**** Path: NVSDK\Common\media\cgfx File: $Id: //sw/devtools/FXComposer2/Alpha4+/SDK/MEDIA/CgFX1.4/stainedglass.cgfx#1 $ Copyright NVIDIA Corporation 2002 TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Comments: light in "light" coordinates project through "window" coordinates For use in Maya, make a connection between a control node's WorldInverseMatrix and the (hidden) shader parameter "WindowIXf" ******************************************************************************/ // string description = "Volume Lighting Textures"; // string keywords = "texture,lighting"; /************* UNTWEAKABLES **************/ float4x4 WorldITXf : WorldInverseTranspose; float4x4 WorldViewProjXf : WorldViewProjection; float4x4 WorldXf : World; float4x4 ViewITXf : ViewInverse; ///////////////////////////////////////////////////////////////////////////// /// TWEAKABLES ////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////// lamp 1 float4 LightPos : Position < string Object = "PointLight"; string Space = "World"; > = {100.0f, 100.0f, 100.0f, 1.0f}; float LightIntensity < string UIWidget = "slider"; float uimin = 1.0; float uimax = 1000.0; float uistep = 1.0; string UIName = "lamp power"; > = 10.0; float3 LightColor : Specular < string UIName = "Window Light Color"; > = {1.00f, 1.00f, 1.00f}; ////////////////////////////////////////////// window /* float4 coordSys0 = {1.0f, 0.0f, 0.0f, 0.0f}; float4 coordSys1 = {0.0f, 0.0f, 0.0f, 0.0f}; float4 coordSys2 = {0.0f, 1.0f, 1.0f, 0.0f}; float4 coordSys3 = {0.0f, 0.0f, 0.0f, 1.0f}; */ float4x4 WindowIXf; // will not appear in Maya display!!! ////////////////////////////////////////////// surface float3 AmbiColor : Ambient < string UIName = "Ambient Light Color"; > = {0.07f, 0.07f, 0.07f}; float3 SurfColor : Diffuse < string UIName = "Surface Color"; > = {1.0f, 1.0f, 1.0f}; float Kd < string UIWidget = "slider"; float uimin = 0.0; float uimax = 1.5; float uistep = 0.01; string UIName = "diffuse"; > = 1.0; float Ks < string UIWidget = "slider"; float uimin = 0.0; float uimax = 1.5; float uistep = 0.01; string UIName = "specular"; > = 1.0; float SpecExpon : Power < string UIWidget = "slider"; float uimin = 1.0; float uimax = 128.0; float uistep = 1.0; string UIName = "specular power"; > = 12.0; float Bumpy < string UIWidget = "slider"; float uimin = 0.0; float uimax = 10.0; float uistep = 0.1; string UIName = "bump power"; > = 1.0; float Kr < string UIWidget = "slider"; float uimin = 0.0; float uimax = 1.5; float uistep = 0.01; string UIName = "shine power"; > = 1.0; float KrMin < string UIWidget = "slider"; float uimin = 0.0; float uimax = 0.2; float uistep = 0.001; string UIName = "shine min"; > = 0.002; float FresExp : Power < string UIWidget = "slider"; float uimin = 1.0; float uimax = 7.0; float uistep = 0.1; string UIName = "edging"; > = 5.0; //////////////////////////////////////////// // Textures //////////////////////////////// //////////////////////////////////////////// texture WindowTexture < string File = "default_color.dds"; string TextureType = "2D"; >; sampler2D WindowGlassSampler = sampler_state { Texture = ; MagFilter = Linear; MinFilter = LinearMipmapLinear; WrapS = Clamp; WrapT = Clamp; BorderColor = 0; // (0,0,0,0); }; /////// texture colorTexture : DiffuseMap < string File = "default_color.dds"; string TextureType = "2D"; >; sampler2D ColorSampler = sampler_state { Texture = ; MagFilter = Linear; MinFilter = LinearMipmapLinear; }; /////// texture normalTexture : DiffuseMap < string File = "default_bump_normal.dds"; string TextureType = "2D"; >; sampler2D NormalSampler = sampler_state { Texture = ; MagFilter = Linear; MinFilter = LinearMipmapLinear; }; /////// texture glossTexture : SpecularMap < string File = "default_gloss.dds"; string TextureType = "2D"; >; sampler2D GlossSampler = sampler_state { Texture = ; MagFilter = Linear; MinFilter = LinearMipmapLinear; }; /////// texture envTexture : Environment < string File = "default_reflection.dds"; string TextureType = "Cube"; >; samplerCUBE EnvSampler = sampler_state { Texture = ; MagFilter = Linear; MinFilter = LinearMipmapLinear; WrapS = ClampToEdge; WrapT = ClampToEdge; WrapR = ClampToEdge; }; /************* DATA STRUCTS **************/ /* data from application vertex buffer */ struct appdata { float3 Position : POSITION; float4 UV : TEXCOORD0; float4 Normal : NORMAL; float4 Tangent : TEXCOORD1; float4 Binormal : TEXCOORD2; }; /* data passed from vertex shader to pixel shader */ struct vertexOutput { float4 HPosition : POSITION; float4 TexCoord : TEXCOORD0; float4 LightVec : TEXCOORD1; float3 WorldNormal : TEXCOORD2; float3 WorldView : TEXCOORD3; float3 WorldTangent : TEXCOORD4; float3 WorldBinorm : TEXCOORD5; float3 CoordPos : TEXCOORD6; float3 CoordLPos : TEXCOORD7; }; /*********** vertex shader ******/ vertexOutput mainVS(appdata IN) { vertexOutput OUT; OUT.WorldNormal = mul(WorldITXf, IN.Normal).xyz; OUT.WorldTangent = mul(WorldITXf, IN.Tangent).xyz; OUT.WorldBinorm = mul(WorldITXf, IN.Binormal).xyz; float4 Po = float4(IN.Position.x,IN.Position.y,IN.Position.z,1.0); float4 Pw = mul(WorldXf, Po); float3 Pc = mul(WindowIXf, Pw).xyz; // "P" in stainglass coords float3 Lc = mul(WindowIXf, LightPos).xyz; // "LightPos" in stainglass coords float3 Lvc = Lc - Pc; Lvc = Lvc / Lvc.z; float3 suv = Pc - Pc.z*Lvc; // adjust to size & shape of Maya "place3dTexture" node OUT.CoordPos = 0.5 * (suv+((1.0).xxx)); float3 L = -Pc; // ?? float lxy = length(L.xy); float ta = abs(lxy/L.z); OUT.LightVec = float4(L.xyz,ta); OUT.TexCoord = IN.UV; OUT.WorldView = normalize(ViewITXf[3].xyz - Pw.xyz); OUT.HPosition = mul(WorldViewProjXf, Po); return OUT; } /********* pixel shader ********/ float4 mainPS(vertexOutput IN) : COLOR { float4 map = tex2D(ColorSampler,IN.TexCoord.xy); float3 bumps = Bumpy * (tex2D(NormalSampler,IN.TexCoord.xy).xyz-(0.5).xxx); float gloss = Ks * tex2D(GlossSampler,IN.TexCoord.xy).x; float3 Nn = normalize(IN.WorldNormal); float3 Tn = normalize(IN.WorldTangent); float3 Bn = normalize(IN.WorldBinorm); float3 Nb = Nn + (bumps.x * Tn + bumps.y * Bn); Nb = normalize(Nb); float3 Vn = normalize(IN.WorldView); float3 Ln = normalize(IN.LightVec.xyz); float3 Hn = normalize(Vn + Ln); float hdn = pow(max(0,dot(Hn,Nb)),SpecExpon) * gloss; float ldn = dot(Ln,Nb); ldn = max(0.0,ldn) * LightIntensity; float3 windowColor = LightColor * tex2D(WindowGlassSampler,IN.CoordPos.xy).xyz; float3 diffContrib = (ldn*windowColor); float3 specContrib = ((ldn * hdn) * windowColor); float3 reflVect = reflect(Vn,Nb); float vdn = dot(Vn,Nb); float fres = KrMin + (Kr-KrMin) * pow((1.0-abs(vdn)),FresExp); float3 reflColor = fres * texCUBE(EnvSampler,reflVect).xyz; float3 result = ((SurfColor*map.xyz*(Kd*diffContrib+AmbiColor)) + specContrib + reflColor); return float4(result.xyz,map.w); } //////// do projection in pixel shader, not vertex shader ///// vertexOutput mainVSa(appdata IN) { vertexOutput OUT; OUT.WorldNormal = mul(WorldITXf, IN.Normal).xyz; OUT.WorldTangent = mul(WorldITXf, IN.Tangent).xyz; OUT.WorldBinorm = mul(WorldITXf, IN.Binormal).xyz; float4 Po = float4(IN.Position.x,IN.Position.y,IN.Position.z,1.0); float4 Pw = mul(WorldXf, Po); float3 Pc = mul(WindowIXf, Pw).xyz; // "P" in stainglass coords float3 Lc = mul(WindowIXf, LightPos).xyz; // "LightPos" in stainglass coords OUT.CoordLPos = Lc; OUT.CoordPos = Pc; float3 L = -Pc; // ?? OUT.LightVec = float4(L.xyz,1.0); OUT.TexCoord = IN.UV; OUT.WorldView = normalize(ViewITXf[3].xyz - Pw.xyz); OUT.HPosition = mul(WorldViewProjXf, Po); return OUT; } // more-accurate -- do projection in pixel shader float4 mainPSa(vertexOutput IN) : COLOR { float3 Pc = IN.CoordPos; float3 Lc = IN.CoordLPos; float3 Lvc = Lc - Pc; Lvc = Lvc / Lvc.z; float3 suv = Pc - Pc.z*Lvc; // adjust to size & shape of Maya "place3dTexture" node suv = 0.5 * (suv+((1.0).xxx)); float4 map = tex2D(ColorSampler,IN.TexCoord.xy); float3 bumps = Bumpy * (tex2D(NormalSampler,IN.TexCoord.xy).xyz-(0.5).xxx); float gloss = Ks * tex2D(GlossSampler,IN.TexCoord.xy).x; float3 Nn = normalize(IN.WorldNormal); float3 Tn = normalize(IN.WorldTangent); float3 Bn = normalize(IN.WorldBinorm); float3 Nb = Nn + (bumps.x * Tn + bumps.y * Bn); Nb = normalize(Nb); float3 Vn = normalize(IN.WorldView); float3 Ln = normalize(IN.LightVec.xyz); float3 Hn = normalize(Vn + Ln); float hdn = pow(max(0,dot(Hn,Nb)),SpecExpon) * gloss; float ldn = dot(Ln,Nb); ldn = max(0.0,ldn) * LightIntensity; // float4 windowColor = tex2D(WindowGlassSampler,IN.CoordPos.xy); float3 windowColor = LightColor * tex2D(WindowGlassSampler,suv.xy).xyz; float3 diffContrib = (ldn*windowColor); float3 specContrib = ((ldn * hdn) * windowColor); float3 reflVect = reflect(Vn,Nb); float vdn = dot(Vn,Nb); float fres = KrMin + (Kr-KrMin) * pow((1.0-abs(vdn)),FresExp); float3 reflColor = fres * texCUBE(EnvSampler,reflVect).xyz; float3 result = ((SurfColor*map.xyz*(Kd*diffContrib+AmbiColor)) + specContrib + reflColor); // return diffContrib ; // result; return float4(result.xyz,map.w); } /// ps_1_1 fallback //////////////////////////////// /* data passed from vertex shader to pixel shader */ struct vertexOutput11 { float4 HPosition : POSITION; float3 CoordPos : TEXCOORD0; }; vertexOutput11 mainVS11(appdata IN) { vertexOutput11 OUT; float4 Po = float4(IN.Position.x,IN.Position.y,IN.Position.z,1.0); float4 Pw = mul(WorldXf, Po); float3 Pc = mul(WindowIXf, Pw).xyz; // "P" in stainglass coords float3 Lc = mul(WindowIXf, LightPos).xyz; // "LightPos" in stainglass coords float3 Lvc = Lc - Pc; Lvc = Lvc / Lvc.z; float3 suv = Pc - Pc.z*Lvc; suv = 0.5 * (suv + ((1).xxx)); OUT.CoordPos = suv; OUT.HPosition = mul(WorldViewProjXf, Po); return OUT; } float4 mainPS11(vertexOutput11 IN) : COLOR { float4 stain = tex2D(WindowGlassSampler,IN.CoordPos.xy); return stain; } /*************/ technique accurate { pass p0 { VertexProgram = compile arbvp1 mainVSa(); DepthTestEnable = true; DepthMask = true; CullFaceEnable = false; FragmentProgram = compile arbfp1 mainPSa(); } } technique fast { pass p0 { VertexProgram = compile arbvp1 mainVS(); DepthTestEnable = true; DepthMask = true; CullFaceEnable = false; FragmentProgram = compile arbfp1 mainPS(); } } technique dx8 { pass p0 { VertexProgram = compile arbvp1 mainVS11(); DepthTestEnable = true; DepthMask = true; CullFaceEnable = false; FragmentProgram = compile arbfp1 mainPS11(); } } /***************************** eof ***/