// FastShader_fragment.cg // #include "Maya_Blends.cgh" #include "Maya_EnvironmentMap.cgh" #if !defined (BLEND_MODE1) // The blend function between layers 0 and 1: Default none #define BLEND_MODE1 kBlendNone #endif #if !defined (ALPHA_LUMIANANCE) // Use the alpha channel as luminance : Default off #define ALPHA_LUMIANANCE 0 #endif // Default switch settings // #define PASS_NORMAL // Pass normal data to the fragment #define WORLD_SPACE // Lighting calculations in world space #define PHONG_SHADE // Phong base material shading #if defined (BLINN_SHADING_MODEL) #define BLINN_PHONG_SHADE // Use the fast blinn phong shader for blinn materials #undef PHONG_SHADE // Undefine phong shading as we aren't going to use it #endif // Lighting input values // #define PASS_LIGHT_CONSTS // Pass in lighting constants #define PASS_EYE_POS // Pass in the camera (eye) position // Only one of these (POINT_LIGHT, SPOT_LIGHT, DIR_LIGHT, AMBIENT_LIGHT) should // be enabled within a compile. // #if defined (POINT_LIGHT) #define GEN_LIGHT_DIRECT // Generate the light direction from position data #define PASS_LIGHT_POS // Pass in the light position #elif defined (AMBIENT_LIGHT) #define GEN_LIGHT_DIRECT // Generate the light direction from position data #define PASS_LIGHT_POS // Pass in the light position #define AMBIENT_SHADE // Set the shading to an ambient only term #elif defined (DIR_LIGHT) #define PASS_LIGHT_DIRECT // Pass in the lights direction #elif defined (SPOT_LIGHT) #define SPOT_LIGHT_DATA // Pass in the additional spot light data #define GEN_LIGHT_DIRECT // Generate the light direction from position data #define PASS_LIGHT_POS // Pass in the light position #endif // Light-specific uniforms #include "Maya_Lighting.cgh" // Conditionals // #if defined (OBJECT_NORMAL) // Object space normal map #define PASS_BUMP_UV // Pass in the bump texture uv set #undef PASS_NORMAL // Don't pass in the normals as they are over writen #undef WORLD_SPACE // We need to work in object space for the ligthing calculation #define BUMP_2DSAMPLER // Pass in the object space normals in the bump texture #endif #if defined (BUMP_MAP) // Local space (tangent) normal maps #define PASS_BUMP_UV // Pass in the bump texture uv set #define PASS_TANGENT // Pass in a tangent (w coordinate contains sign of binormal) #define BUMP_2DSAMPLER // Pass in a bump map sampler #endif #if !defined (CONSTANT_COLOR) // there is a texture map #if defined (LAYER_TWO) // There is at least two layers #define PASS_TEX1_UV // Pass in the texture coordinates #define TEX1_2DSAMPLER // Pass in a texture sampler #define PASS_TEX1_CONST_ALPHA // Modulate the alpha by a constant value #endif #define PASS_TEX0_UV #define TEX0_2DSAMPLER #endif #if defined (CONSTANT_TRANSPARENCY) #define PASS_TEX0_CONST_ALPHA // The alpha is controlled by a constant #else #define PASS_TEX0_ALPHA_UV // First layer transperence needs a uv set #define TEX0_2DSAMPLER_ALPHA // The alpha texture sampler for the first pass #undef PASS_TEX0_CONST_ALPHA // The alpha is defined by a texture not a constant now #endif // CONSTANT_TRANSPARENCY #if defined (PASS_TEX1_ALPHA_UV) #define TEX1_2DSAMPLER_ALPHA // The alpha texture in the second pass #undef PASS_TEX1_CONST_ALPHA // The alpha is defined by a texture not a constant now #endif #if defined (COLOR_PER_VERTEX) #define PASS_VERTEX_COLOR // Pass in the vertex color #if !defined (CPV_BLEND) #define CPV_BLEND kBlendAdd #endif #elif defined (PASS_TEX1_COLOR_MOD) #undef PASS_TEX1_COLOR_MOD // If we don't have a vertex color don't modulate #endif #if defined (PASS_TEX1_COLOR_MOD) #undef CPV_BLEND // Vertex color is a modulator so don't blend #endif // Fragment structure // struct vert2frag { float4 hPosition : POSITION; // Clip-space vertex position float4 position : TEXCOORD0; // World/Object-space vertex position #if defined (PASS_NORMAL) float3 normal : TEXCOORD1; // World/Object-space normal vector #endif // PASS_NORMAL #if defined (PASS_TANGENT) float4 tangent : TEXCOORD2; // World-space tangent vector + possible sign of binormal #endif // PASS_TANGENT #if defined (PASS_BUMP_UV) float2 bumpTexUv : TEXCOORD3; // Object space normal map #endif // PASS_BUMP_UV #if defined (PASS_TEX0_UV) || defined (PASS_TEX0_ALPHA_UV) #if defined (PASS_TEX0_ALPHA_UV) float4 colorTexUv : TEXCOORD4; // Color base layer + alpha packed #else float2 colorTexUv : TEXCOORD4; // Color base layer only #endif #endif #if defined (PASS_TEX1_UV) #if defined (PASS_TEX1_ALPHA_UV) float4 pass2TexUv : TEXCOORD5; // Used by second layer + alpha packed #else float2 pass2TexUv : TEXCOORD5; // Used by second layer #endif #endif // PASS_TEX1_UV #if defined (PASS_VERTEX_COLOR) float4 vertexColor : TEXCOORD7; // User defined CPV either unclamped or as a layer modulator #endif float4 vertexBaseColor : COLOR0; // Base Color map #if defined(TWO_SIDED_LIGHTING) float4 frontColor : COLOR1; // Secondary front color (currently use only to pass side information) float4 backColor : BCOL1; // Secondary back color (currently use only to pass side information) #endif }; // Uniforms common to projective light textures or shadow maps. // #if defined (PROJ_LIGHT_TEXTURE) || defined (SHADOW_MAP) uniform float4 worldToProjLightMatrix0; // would like to make this a single matrix uniform float4 worldToProjLightMatrix1; uniform float4 worldToProjLightMatrix2; uniform float4 worldToProjLightMatrix3; #endif // PROJ_LIGHT_TEXTURE || SHADOW_MAP // Uniforms specific to shadow map. // #if defined(SHADOW_MAP) uniform sampler2D shadowTex; #endif // SHADOW_MAP // Uniforms specific to projective light texture. // #if defined (PROJ_LIGHT_TEXTURE) uniform sampler2D lightColorTex; uniform float lightIntensity; uniform float lightScale; #endif // PROJ_LIGHT_TEXTURE #if defined (BUMP_2DSAMPLER) uniform sampler bumpTex; #endif // BUMP_2DSAMPLER #if defined (TEX0_2DSAMPLER) uniform sampler colorTex; #endif #if defined (TEX0_2DSAMPLER_ALPHA) uniform sampler transpTex; #endif #if defined(PASS_TEX0_CONST_ALPHA) uniform float3 constantTransparency; #endif #if defined (TEX1_2DSAMPLER) uniform sampler pass2Tex; #endif #if defined (TEX1_2DSAMPLER_ALPHA) uniform sampler pass2AlphaTex; #elif defined (PASS_TEX1_CONST_ALPHA) uniform float pass2TexAlpha; #endif #if defined (PASS_LIGHT_POS) uniform float3 wLightPos; #endif #if defined (PASS_LIGHT_DIRECT) uniform float3 wLightDir; #endif #if ( defined (PASS_TEX0_ENV_SPHERE) || defined (PASS_TEX0_ENV_CUBE) ) #define GEN_LOOKUP0 #define ENV_MATRIX #endif #if (defined (PASS_TEX1_ENV_CUBE) || defined (PASS_TEX1_ENV_SPHERE)) // uses the same look up vector #if !defined (GEN_LOOKUP) #define GEN_LOOKUP1 #endif #if !defined (ENV_MATRIX) #define ENV_MATRIX #endif #endif // Default uniforms // #if defined (PASS_EYE_POS) uniform float4 gWorldEyePos; // World or object eye position #endif #if defined (PASS_LIGHT_CONSTS) // Lighting constants uniform float3 lightColor; // Pre-multiplied by intensity. uniform float4 constantColor; #endif // Explicit matrix to transform object space normal vector to world space // #if defined(OBJECT_SPACE) uniform float4x4 objToWorldMatrix; #endif // Explicit matrix to transform object space vector to enviroment space // #if defined(ENV_MATRIX) uniform float4x4 enviromentMatrix; #endif #if defined (BUMP_MAP) float3 getLightNormal(float2 bumpTexUv, float4 in_tangent, float3 in_normal) // { // Compute an orthonormal basis to transform from tangent space // to world space, and vice-versa. // float3 tangent = normalize(in_tangent.xyz); float3 normal = normalize(in_normal); #if defined (BINORMAL_SIGN) float3 binormal = cross(normal, tangent) * in_tangent.w; #else float3 binormal = cross(normal, tangent); #endif // Get the local normals float3 lBumpedNormal = normalize(tex2D(bumpTex, bumpTexUv).xyz * 2.0 - 1.0); // Transform to world space float3 bumpedNormal = lBumpedNormal.x * tangent + lBumpedNormal.y * binormal + lBumpedNormal.z * normal; return bumpedNormal; } #endif #if defined (OBJECT_NORMAL) // NOTE: this compiles // float3 getNormal(float2 bumpTexUv, float4 in_tangent, float3 in_normal) // float3 getLightNormal(float2 bumpTexUv) // get the lighting normal { return normalize(tex2D(bumpTex, bumpTexUv).xyz * 2.0 - 1.0); } #endif //////////////////////////////// // Main fragment program // float4 main(vert2frag IN) : COLOR { #if defined (PASS_LIGHT_DIRECT) // Get the incoming light direction // float3 lightDir = wLightDir; #endif #if defined (PASS_LIGHT_POS) // Get the incoming light position // float3 lightPos = wLightPos; #endif #if defined GEN_LIGHT_DIRECT // Compute the unnormalized light direction vector, expressed // in world space. // float3 lightVector = (lightPos - IN.position.xyz).xyz; float3 lightDir = normalize(lightVector); #endif // Calculate view direction in object/world space, // from point to eye. // float3 viewDirection = normalize(gWorldEyePos.xyz - IN.position.xyz); #if defined (OBJECT_NORMAL) // get the normal for the lighting equation in object normal space // float3 normal = getLightNormal(IN.bumpTexUv); #elif defined (BUMP_MAP) // get the normal for the lighting equation in world space from tangent space // float3 normal = getLightNormal(IN.bumpTexUv, IN.tangent, IN.normal); #else // Default vertex normal interpulate // float3 normal = normalize(IN.normal); #endif #if defined (TWO_SIDED_LIGHTING) // Note we want to support the FACE semanitic for this but is supported only in FP40 float faceMultiplier = IN.frontColor.x > 0.3 ? 1.0 : -1.0; // Single sided rendering is handled in the vertex shader. normal *= faceMultiplier; #endif #if defined (GEN_LOOKUP0) // Treat this as a normal lookup, not a reflection lookup, since it's mapped to color. #if defined (PASS_NORMAL0_LOOKUP) // normal lookup float3 lookupVector = normal; #else // reflective lookup float3 lookupVector = reflect(-viewDirection, normal); #endif #if defined (OBJECT_SPACE) // convert this to world space (this should be combined with the enviroment matrix below). lookupVector = mul(objToWorldMatrix, float4(lookupVector, 0.0)).xyz; #endif #if defined (ENV_MATRIX) lookupVector = mul(enviromentMatrix, float4(lookupVector, 0.0)).xyz; #endif #endif #if defined (GEN_LOOKUP1) // Treat this as a normal lookup, not a reflection lookup, since it's mapped to color. #if defined(PASS_NORMAL1_LOOKUP) // normal lookup float3 lookupVector1 = normal; #else // reflective lookup float3 lookupVector1 = reflect(-viewDirection, normal); #endif #if defined (OBJECT_SPACE) // convert this to world space (this should be combined with the enviroment matrix below). lookupVector1 = mul(objToWorldMatrix, float4(lookupVector1, 0.0)).xyz; #endif #if defined (ENV_MATRIX) lookupVector1 = mul(enviromentMatrix, float4(lookupVector1, 0.0)).xyz; #endif #endif //////////////////////////////////////////////////////////////////////////// // Compute attenuated light colour value // float3 attenuatedLightColor = lightColor; #if defined (SHADOW_MAP) float isLit = MAYA_notInShadow(IN.position.xyz, shadowTex, worldToProjLightMatrix0, worldToProjLightMatrix1, worldToProjLightMatrix2, worldToProjLightMatrix3); attenuatedLightColor.rgb = attenuatedLightColor.rgb * isLit; #endif // SHADOW_MAP #if defined(POINT_LIGHT) // Get the attenuated lighting color // attenuatedLightColor = MAYA_PointLight(attenuatedLightColor, lightVector); #elif defined (SPOT_LIGHT) // Get the attenuated lighting color // attenuatedLightColor = MAYA_SpotLight(attenuatedLightColor, lightDir, lightVector); #endif // POINT_LIGHT /////////////////////////////////////////////////////////////////// // Compute texture maps /////////////////////////////////////////////////////////////////// // Compute the base colour // #if defined (CONSTANT_COLOR) // The base color is constant // float4 baseColor = constantColor; #elif defined (PASS_TEX0_UV) float4 baseColor; // Single texture pass on diffuseAndAmbient // #if defined (PASS_TEX0_ENV_SPHERE) baseColor = MAYA_environmentLookup(lookupVector, colorTex, kEnvironmentSphere ); #elif defined (PASS_TEX0_ENV_CUBE) baseColor = MAYA_environmentLookup(lookupVector, colorTex, kEnvironmentCube ); #else baseColor = tex2D(colorTex, IN.colorTexUv.xy); #endif #endif #if defined (PASS_TEX0_CONST_ALPHA) #if defined (OPACITY_IN_COLOR_ALPHA) // This is alway blck in this case and isn't used currently // baseColor.a *= 1.0 - MAYA_computeLuminance(constantTransparency); #else baseColor.a = MAYA_computeLuminance(constantTransparency); #endif #elif defined (PASS_TEX0_ALPHA_UV) // alpha is being passed as a different texture. float4 alphaColor = tex2D(transpTex, IN.colorTexUv.zw); baseColor.a *= 1.0f - MAYA_computeLuminance(alphaColor.rgb); #endif // Compute layers // #if defined (PASS_TEX1_UV) // Second texture pass on diffuseAndAmbient // float4 layerColor; #if defined(PASS_TEX1_ENV_SPHERE) layerColor = MAYA_environmentLookup(lookupVector1, pass2Tex, kEnvironmentSphere ); #elif defined(PASS_TEX1_ENV_CUBE) layerColor = MAYA_environmentLookup(lookupVector1, pass2Tex, kEnvironmentCube ); #else layerColor = tex2D(pass2Tex, IN.pass2TexUv.xy); #endif #if defined (PASS_TEX1_ALPHA_UV) // The modulation is controlled by an alpha texture // // The modulation is controlled by an alpha texture // float4 layerAlphaColor = tex2D(pass2AlphaTex, IN.pass2TexUv.zw); float layerAlpha = MAYA_computeLuminance( layerAlphaColor.rgb ); layerColor.a *= layerAlpha; #elif defined (PASS_TEX1_CONST_ALPHA) // The modulation is controlled by constant alpha // layerColor.a *= pass2TexAlpha; #endif #if defined (PASS_TEX1_COLOR_MOD) // TO DO this isn't going to be able to support per color blending. // baseColor = layerColor * IN.vertexColor + (1.0 - IN.vertexColor) * baseColor; #else MAYA_computeLayeredBlend(baseColor, layerColor, BLEND_MODE1, ALPHA_LUMIANANCE); #endif #endif //////////////////////////////////////////////////////////////////// // Material calculations //////////////////////////////////////////////////////////////////// float4 diffuseAndAmbientColor = float4 (0,0,0,1); float3 specularColor = float3 (0,0,0); #if defined (AMBIENT_LIGHT) // Fast Ambient only calculation // MAYA_AmbientShade(diffuseAndAmbientColor.rgb, specularColor, attenuatedLightColor, lightDir, normal); #elif defined (BLINN_SHADING_MODEL) // Blinn material calculation // MAYA_BlinnShade(diffuseAndAmbientColor.rgb, specularColor, attenuatedLightColor, lightDir, viewDirection, normal); #else // Phong material calculation // MAYA_PhongShade (diffuseAndAmbientColor.rgb, specularColor, attenuatedLightColor, lightDir, viewDirection, normal); #endif //////////////////////////////////////////////////////////////////// // Post Vertex color blending //////////////////////////////////////////////////////////////////// #if defined(COLOR_PER_VERTEX) && defined (CPV_BLEND) MAYA_computeLayeredBlend(diffuseAndAmbientColor, IN.vertexColor, CPV_BLEND, 0); #endif // (CPV_BLEND) //////////////////////////////////////////////////////////////////// // Final color blend //////////////////////////////////////////////////////////////////// // Pick up the vertex calculated lighting // diffuseAndAmbientColor.rgb += IN.vertexBaseColor.rgb; // currently not used. diffuseAndAmbientColor.rgb *= baseColor.rgb; diffuseAndAmbientColor.a *= baseColor.a; float3 opacityColor = diffuseAndAmbientColor.aaa; #if defined(SPECULAR_IS_AFFECTED_BY_OPACITY) float4 finalColor = float4(opacityColor * (diffuseAndAmbientColor.rgb + specularColor), 1.0); #else float4 finalColor = float4(opacityColor * diffuseAndAmbientColor.rgb + specularColor, 1.0); #endif return finalColor; }