public FixedFunctionPrograms GetShaderPrograms(String generatorName, VertexBufferDeclaration vertexBufferDeclaration, FixedFunctionState state) { // Search the maps for a matching program State2Declaration2ProgramsMap languageMaps; language2State2Declaration2ProgramsMap.TryGetValue(generatorName, out languageMaps); if (languageMaps != null) { VertexBufferDeclaration2FixedFunctionProgramsMap fixedFunctionStateMaps; languageMaps.TryGetValue(state, out fixedFunctionStateMaps); if (fixedFunctionStateMaps != null) { FixedFunctionPrograms programs; fixedFunctionStateMaps.TryGetValue(vertexBufferDeclaration, out programs); if (programs != null) { return(programs); } } } // If we are here, then one did not exist. // Create it. return(createShaderPrograms(generatorName, vertexBufferDeclaration, state)); }
public HLSLFixedFunctionProgram() { vertexProgramUsage = new GpuProgramUsage(GpuProgramType.Vertex, null); fragmentProgramUsage = new GpuProgramUsage(GpuProgramType.Fragment, null); fixedFunctionState = new FixedFunctionState(); }
public abstract String GetShaderSource( String vertexProgramName, String fragmentProgramName, VertexBufferDeclaration vertexBufferDeclaration, FixedFunctionState fixedFuncState );
public override string GetShaderSource(string vertexProgramName, string fragmentProgramName, VertexBufferDeclaration vertexBufferDeclaration, FixedFunctionState fixedFunctionState) { var bNeedsMatIT = false; var bHasColor = vertexBufferDeclaration.HasColor; var bHasSpecular = false; var bHasNormal = false; var bHasTexcoord = vertexBufferDeclaration.HasTexCoord; int texcoordCount = vertexBufferDeclaration.TexCoordCount; texCordVecType.Clear(); otherCoordVecType.Clear(); var shaderSource = "/***************************************************************************************\n" + " * This shader was generated by a tool; any changes made to this file may be lost\n" + " * Axiom Fixed Function Emulation Layer\n" + " * Vertex Program Entry Point : " + vertexProgramName + "\n" + " * Fragment Program Entry Point : " + fragmentProgramName + "\n" + " * Vertex Buffer Delcaration : " + vertexBufferDeclaration + "\n" + " * Fixed Function State : " + fixedFunctionState + "\n" + " ***************************************************************************************/\n"; //can't include a file when shaders are loaded from sources? //shaderSource += "#include \"FixedFunctionStructs.inc\"\n"; //basic struct for light types //shaderSource += "struct PointLight\n{\n\tfloat4 Ambient;\n\tfloat4 Diffuse;\n\tfloat4 Specular;\n\tfloat3 Position;\n\tfloat3 Range;\n\tfloat3 Attenuation;\n};\n"; //shaderSource += "struct DirectionLight\n{\n\tfloat4 Ambient;\n\tfloat4 Diffuse;\n\tfloat4 Specular;\n\tfloat3 Direction;\n};\n"; //shaderSource += "struct SpotLight\n{\n\tfloat4 Ambient;\n\tfloat4 Diffuse;\n\tfloat4 Specular;\n\tfloat3 Position;\n\tfloat3 Direction;\n\tfloat4 Spot;\n\tfloat3 Attenuation;\n};\n"; // #region struct input declaration shaderSource += "struct VS_INPUT\n{\n"; var semanticCount = new ushort[100]; var vertexBufferElements = vertexBufferDeclaration.VertexBufferElements; foreach (var element in vertexBufferElements) { var semantic = element.VertexElementSemantic; var type = element.VertexElementType; var thisElementSemanticCount = semanticCount[(int)semantic].ToString(); semanticCount[(int)semantic]++; var parameterType = ""; var parameterName = ""; var parameterShaderTypeName = ""; switch (type) { case VertexElementType.Float1: parameterType = "float"; break; case VertexElementType.Float2: parameterType = "float2"; break; case VertexElementType.Float3: parameterType = "float3"; break; case VertexElementType.Float4: parameterType = "float4"; break; case VertexElementType.Color: case VertexElementType.Color_ABGR: case VertexElementType.Color_ARGB: parameterType = "float4"; break; case VertexElementType.Short1: parameterType = "short"; break; case VertexElementType.Short2: parameterType = "short2"; break; case VertexElementType.Short3: parameterType = "short3"; break; case VertexElementType.Short4: parameterType = "short4"; break; case VertexElementType.UByte4: parameterType = "int"; break; } switch (semantic) { case VertexElementSemantic.Position: parameterName = "Position"; parameterShaderTypeName = "POSITION"; parameterType = "float4"; // position must be float4 (and not float3 like in the buffer) break; case VertexElementSemantic.BlendWeights: parameterName = "BlendWeight"; parameterShaderTypeName = "BLENDWEIGHT"; break; case VertexElementSemantic.BlendIndices: parameterName = "BlendIndices"; parameterShaderTypeName = "BLENDINDICES"; break; case VertexElementSemantic.Normal: parameterName = "Normal"; parameterShaderTypeName = "NORMAL"; bHasNormal = true; break; case VertexElementSemantic.Diffuse: parameterName = "DiffuseColor"; parameterShaderTypeName = "COLOR"; break; case VertexElementSemantic.Specular: parameterName = "SpecularColor"; parameterShaderTypeName = "COLOR"; thisElementSemanticCount = semanticCount[(int)VertexElementSemantic.Diffuse].ToString(); // Diffuse is the "COLOR" count... semanticCount[(int)VertexElementSemantic.Diffuse]++; bHasSpecular = true; break; case VertexElementSemantic.TexCoords: //all texcoord are not texture coordinates! //we should differentiate them somehow switch (type) { case VertexElementType.Float1: parameterName = "Texcoord"; break; case VertexElementType.Float2: parameterName = "Texcoord"; texCordVecType[semanticCount[(int)semantic] - 1] = type; break; case VertexElementType.Float3: parameterName = "Texcoord"; break; } texCordVecType[semanticCount[(int)semantic] - 1] = type; parameterShaderTypeName = "TEXCOORD"; /*parameterName = "Texcoord"; * texCordVecType[(int)semanticCount[(int)semantic] - 1] = type; * parameterShaderTypeName = "TEXCOORD";*/ break; case VertexElementSemantic.Binormal: parameterName = "Binormal"; parameterShaderTypeName = "BINORMAL"; break; case VertexElementSemantic.Tangent: parameterName = "Tangent"; parameterShaderTypeName = "TANGENT"; break; } shaderSource += "\t" + parameterType + " " + parameterName + thisElementSemanticCount + " : " + parameterShaderTypeName + thisElementSemanticCount + ";\n"; } shaderSource += "};\n\n"; #endregion #region globales declaration shaderSource += "float4x4 World;\n"; shaderSource += "float4x4 View;\n"; shaderSource += "float4x4 Projection;\n"; shaderSource += "float4x4 ViewIT;\n"; shaderSource += "float4x4 WorldViewIT;\n"; var textures = 0; for ( ; textures < fixedFunctionState.TextureLayerStates.Count; textures++) { var layerCounter = Convert.ToString(textures); shaderSource += "shared float4x4 TextureMatrix" + layerCounter + "; //technique: " + fixedFunctionState.TextureLayerStates[textures].TexCoordCalcMethod + "\n"; } switch (fixedFunctionState.GeneralFixedFunctionState.FogMode) { case FogMode.None: break; case FogMode.Exp: case FogMode.Exp2: shaderSource += "float4 FogDensity;\n"; shaderSource += "float4 FogColor;\n"; break; case FogMode.Linear: shaderSource += "float4 FogStart;\n"; shaderSource += "float4 FogEnd;\n"; shaderSource += "float4 FogColor;\n"; break; } shaderSource += "float4 BaseLightAmbient;\n"; if (fixedFunctionState.GeneralFixedFunctionState.EnableLighting) { for (var i = 0; i < fixedFunctionState.Lights.Count; i++) { var prefix = "Light" + i + "_"; shaderSource += "float4 " + prefix + "Ambient;\n"; shaderSource += "float4 " + prefix + "Diffuse;\n"; shaderSource += "float4 " + prefix + "Specular;\n"; switch (fixedFunctionState.Lights[i]) { case LightType.Point: shaderSource += "float3 " + prefix + "Position;\n"; shaderSource += "float " + prefix + "Range;\n"; shaderSource += "float3 " + prefix + "Attenuation;\n"; break; case LightType.Directional: shaderSource += "float3 " + prefix + "Direction;\n"; break; case LightType.Spotlight: shaderSource += "float3 " + prefix + "Position;\n"; shaderSource += "float3 " + prefix + "Direction;\n"; shaderSource += "float3 " + prefix + "Attenuation;\n"; shaderSource += "float3 " + prefix + "Spot;\n"; break; } } } shaderSource += "float4 MaterialAmbient=float4(1,1,1,1);\n"; shaderSource += "float4 MaterialDiffuse=float4(1,1,1,1);\n"; shaderSource += "float4 MaterialSpecular=(float4)0;\n"; //shaderSource += "float4 MaterialEmissive=(float4)0;\n"; //shaderSource += "float MaterialShininess=(float4)0;\n"; #endregion #region struct output declaration shaderSource += "\nstruct VS_OUTPUT\n"; shaderSource += "{\n"; shaderSource += "\tfloat4 Pos : POSITION;\n"; for (var i = 0; i < fixedFunctionState.TextureLayerStates.Count; i++) { var layerCounter = Convert.ToString(i); if (fixedFunctionState.TextureLayerStates[i].TexCoordCalcMethod == TexCoordCalcMethod.EnvironmentMapReflection) { bNeedsMatIT = true; } if (fixedFunctionState.TextureLayerStates[i].TexCoordCalcMethod == TexCoordCalcMethod.ProjectiveTexture) { shaderSource += "\tfloat4 Texcoord" + layerCounter + " : TEXCOORD" + layerCounter + ";\n"; bNeedsMatIT = true; } else { switch (fixedFunctionState.TextureLayerStates[i].TextureType) { case TextureType.OneD: shaderSource += "\tfloat1 Texcoord" + layerCounter + " : TEXCOORD" + layerCounter + ";\n"; break; case TextureType.TwoD: shaderSource += "\tfloat2 Texcoord" + layerCounter + " : TEXCOORD" + layerCounter + ";\n"; break; case TextureType.CubeMap: shaderSource += "\tfloat3 Texcoord" + layerCounter + " : TEXCOORD" + layerCounter + ";\n"; break; case TextureType.ThreeD: shaderSource += "\tfloat3 Texcoord" + layerCounter + " : TEXCOORD" + layerCounter + ";\n"; break; } } } /*for (int i = 0; i < fixedFunctionState.TextureLayerStates.Count; i++) * { * String layerCounter = Convert.ToString(i); * //depends of the tex calculation method * switch (fixedFunctionState.TextureLayerStates[i].TexCoordCalcMethod) * { * case TexCoordCalcMethod.None: * case TexCoordCalcMethod.EnvironmentMap: * case TexCoordCalcMethod.EnvironmentMapNormal: //? not sure * case TexCoordCalcMethod.EnvironmentMapPlanar: //? not sure * shaderSource += "\tfloat2 Texcoord" + layerCounter + " : TEXCOORD" + layerCounter + ";\n"; * break; * * case TexCoordCalcMethod.EnvironmentMapReflection: * shaderSource += "\tfloat3 Texcoord" + layerCounter + " : TEXCOORD" + layerCounter + ";\n"; * break; * * case TexCoordCalcMethod.ProjectiveTexture: * shaderSource += "\tfloat4 Texcoord" + layerCounter + " : TEXCOORD" + layerCounter + ";\n"; * break; * } * }*/ shaderSource += "\tfloat4 Color: COLOR0;\n"; shaderSource += "\tfloat4 ColorSpec: COLOR1;\n"; if (fixedFunctionState.GeneralFixedFunctionState.FogMode != FogMode.None) { shaderSource += "\tfloat fogDist : COLOR2;\n"; } shaderSource += "};\n"; #endregion #region vertex shader main shaderSource += "\nVS_OUTPUT " + vertexProgramName + "( VS_INPUT input )\n"; shaderSource += "{\n"; shaderSource += "\tVS_OUTPUT output = (VS_OUTPUT)0;\n"; //w coord in position is passed separatly as position in fixed function pipeline can't be float4 //so I suppose ? we should pass it back in the position.w //it makes shadows appears on the ground in stencil modulative, //but still some tweaks are needed //as they dont show well if (texCordVecType.ContainsKey(0)) { if (texCordVecType[0] == VertexElementType.Float1) { shaderSource += "\tinput.Position0.w = input.Texcoord0;\n"; } } shaderSource += "\tfloat4 worldPos = mul( World, input.Position0);\n"; shaderSource += "\tfloat4 cameraPos = mul( View, worldPos );\n"; shaderSource += "\toutput.Pos = mul( Projection, cameraPos );\n"; //just to check if we can get some more frames by giving the shader to transpose the matrix //inverse really costs a lot, maybe we could find a function to do that in shader //calculate ViewIT and worldViewIT transpose only if lights or projective texture if (fixedFunctionState.Lights.Count > 0 || bNeedsMatIT) { shaderSource += "\tViewIT = transpose(ViewIT);\n"; shaderSource += "\tWorldViewIT = transpose(WorldViewIT);\n"; } if (bHasNormal) { shaderSource += "\tfloat3 Normal = input.Normal0;\n"; } else { shaderSource += "\tfloat3 Normal = float3(0.0, 0.0, 0.0);\n"; } //textures states for (var i = 0; i < fixedFunctionState.TextureLayerStates.Count; i++) { var curTextureLayerState = fixedFunctionState.TextureLayerStates[i]; var layerCounter = Convert.ToString(i); var coordIdx = Convert.ToString(curTextureLayerState.CoordIndex); shaderSource += "\t//debug info : texture stage " + i + " coordindex: " + coordIdx + "\n"; shaderSource += "\t{\n"; switch (curTextureLayerState.TexCoordCalcMethod) { case TexCoordCalcMethod.None: //check if texCoord are given in vertex declaration if (texCordVecType.ContainsKey(curTextureLayerState.CoordIndex)) { switch (texCordVecType[curTextureLayerState.CoordIndex]) { case VertexElementType.Float1: shaderSource += "\t\toutput.Texcoord" + layerCounter + " = input.Texcoord" + coordIdx + ";\n"; //shaderSource += "\t\tfloat4 texCordWithMatrix = float4(input.Texcoord" + coordIdx + ",1, 1, 1);\n"; //shaderSource += "\t\ttexCordWithMatrix = mul(texCordWithMatrix, TextureMatrix" + layerCounter + " );\n"; //shaderSource += "\t\toutput.Texcoord" + layerCounter + " = texCordWithMatrix.x;\n"; break; case VertexElementType.Float2: shaderSource += "\t\tfloat4 texCordWithMatrix = float4(input.Texcoord" + coordIdx + ", 1, 1);\n"; shaderSource += "\t\ttexCordWithMatrix = mul(texCordWithMatrix, TextureMatrix" + layerCounter + " );\n"; shaderSource += "\t\toutput.Texcoord" + layerCounter + " = texCordWithMatrix.xy;\n"; break; case VertexElementType.Float3: shaderSource += "\t\toutput.Texcoord" + layerCounter + " = input.Texcoord" + coordIdx + ";\n"; //shaderSource += "\t\tfloat4 texCordWithMatrix = float4(input.Texcoord" + coordIdx + ",1);\n"; //shaderSource += "\t\ttexCordWithMatrix = mul(texCordWithMatrix, TextureMatrix" + layerCounter + ");\n"; //shaderSource += "\t\toutput.Texcoord" + layerCounter + " = texCordWithMatrix.xyz;\n"; break; } } else //a texture is declared in texture states but not in the vertex declaration so we dont know the coordinate { //but they dont seemt to change anything anyway shaderSource += "\t\tfloat4 texCordWithMatrix = float4(1,1,1,1);\n"; shaderSource += "\t\ttexCordWithMatrix = mul(texCordWithMatrix, TextureMatrix" + layerCounter + " );\n"; shaderSource += "\t\toutput.Texcoord" + layerCounter + " = texCordWithMatrix.xyz;\n"; //shaderSource += "\t\toutput.Texcoord" + layerCounter + " = input.Texcoord" + coordIdx + ";\n"; } break; case TexCoordCalcMethod.EnvironmentMap: shaderSource += "\t\tfloat3 u = normalize(cameraPos.xyz);\n"; shaderSource += "\t\tfloat3 r = reflect(u, Normal);\n"; shaderSource += "\t\tfloat m = 2.0 * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0));\n"; shaderSource += "\t\toutput.Texcoord" + layerCounter + " = float2 (r.x / m + 0.5, r.y / m + 0.5);\n"; break; case TexCoordCalcMethod.EnvironmentMapPlanar: //break; case TexCoordCalcMethod.EnvironmentMapReflection: shaderSource += "\t\tNormal = mul(float4(Normal, 0),World).xyz;\n"; shaderSource += "\t\tfloat3 eye= float3(ViewIT[3][0],ViewIT[3][1],ViewIT[3][2]);\n"; shaderSource += "\t\tfloat4 LookAt= float4(worldPos-eye,0) ;\n"; shaderSource += "\t\tLookAt = normalize(LookAt);\n"; shaderSource += "\t\tNormal= normalize(Normal);\n"; shaderSource += "\t\toutput.Texcoord" + layerCounter + " = reflect(LookAt.xyz,Normal);\n"; break; case TexCoordCalcMethod.EnvironmentMapNormal: break; case TexCoordCalcMethod.ProjectiveTexture: //render to texture and shadows demos use this part //but in different ways, have to find something to differentiate them shaderSource += "\t\tfloat4x4 scalemat = float4x4( 0.5,0,0,0.5,0,-0.5,0, 0.5,0,0, 0.5, 0.5,0,0,0,1);\n"; shaderSource += "\t\toutput.Texcoord" + layerCounter + " = mul(scalemat, output.Pos);\n"; break; } shaderSource += "\t}\n"; } //all the textures have been handled in the textures states, //even if sometimes there are more texture states than texCoord in vertex declaration //it is not a problem since many textures refer to the same coords. //for BSP Scene Manager the input vertex declaration is always like this : (from bspLevel.cs) // // float4 Position0 : POSITION0; // float3 Normal0 : NORMAL0; // float2 Texcoord0 : TEXCOORD0; // float2 Texcoord1 : TEXCOORD1; // float4 DiffuseColor0 : COLOR0; // this is for texture lighting color and alpha // float2 Other2 : TEXCOORD2; // this is for texture lighting coords // if (bHasSpecular) { shaderSource += "\toutput.ColorSpec = input.SpecularColor;\n"; } else //if(fixedFunctionState.MaterialEnabled) { shaderSource += "\toutput.ColorSpec =MaterialSpecular;\n"; } //else shaderSource += "\toutput.ColorSpec = float4(0.0, 0.0, 0.0, 0.0);\n"; if (fixedFunctionState.GeneralFixedFunctionState.EnableLighting && fixedFunctionState.Lights.Count > 0) { shaderSource += "\toutput.Color +=BaseLightAmbient;\n"; if (bHasColor) { shaderSource += "\toutput.Color +=input.DiffuseColor0;\n"; } else { //shaderSource += "\toutput.Color =MaterialAmbient;\n"; shaderSource += "\toutput.Color *=MaterialDiffuse;\n"; } shaderSource += "\tfloat3 N = mul((float3x3)WorldViewIT, Normal);\n"; shaderSource += "\tfloat3 V = -normalize(cameraPos);\n"; shaderSource += "\t#define fMaterialPower 16.f\n"; for (var i = 0; i < fixedFunctionState.Lights.Count; i++) { var prefix = "Light" + i + "_"; switch (fixedFunctionState.Lights[i]) { case LightType.Point: shaderSource += "{\n"; shaderSource += " float3 PosDiff = " + prefix + "Position-(float3)mul(World,input.Position0);\n"; shaderSource += " float3 L = mul((float3x3)ViewIT, normalize((PosDiff)));\n"; shaderSource += " float NdotL = dot(N, L);\n"; shaderSource += " float4 Color = " + prefix + "Ambient;\n"; shaderSource += " float4 ColorSpec = 0;\n"; shaderSource += " float fAtten = 1.f;\n"; shaderSource += " if(NdotL >= 0.f)\n"; shaderSource += " {\n"; shaderSource += " //compute diffuse color\n"; shaderSource += " Color += NdotL * " + prefix + "Diffuse;\n"; shaderSource += " //add specular component\n"; shaderSource += " float3 H = normalize(L + V); //half vector\n"; shaderSource += " ColorSpec = pow(max(0, dot(H, N)), fMaterialPower) * " + prefix + "Specular;\n"; shaderSource += " float LD = length(PosDiff);\n"; shaderSource += " if(LD > " + prefix + "Range.x)\n"; shaderSource += " {\n"; shaderSource += " fAtten = 0.f;\n"; shaderSource += " }\n"; shaderSource += " else\n"; shaderSource += " {\n"; shaderSource += " fAtten *= 1.f/(" + prefix + "Attenuation.x + " + prefix + "Attenuation.y*LD + " + prefix + "Attenuation.z*LD*LD);\n"; shaderSource += " }\n"; shaderSource += " Color *= fAtten;\n"; shaderSource += " ColorSpec *= fAtten;\n"; shaderSource += " output.Color += Color;\n"; shaderSource += " output.ColorSpec += ColorSpec;\n"; shaderSource += " }\n"; shaderSource += "}\n"; break; case LightType.Directional: shaderSource += "{\n"; shaderSource += " float3 L = mul((float3x3)ViewIT, -normalize(" + prefix + "Direction));\n"; shaderSource += " float NdotL = dot(N, L);\n"; shaderSource += " float4 Color = " + prefix + "Ambient;\n"; shaderSource += " float4 ColorSpec = 0;\n"; shaderSource += " if(NdotL > 0.f)\n"; shaderSource += " {\n"; shaderSource += " //compute diffuse color\n"; shaderSource += " Color += NdotL * " + prefix + "Diffuse;\n"; shaderSource += " //add specular component\n"; shaderSource += " float3 H = normalize(L + V); //half vector\n"; shaderSource += " ColorSpec = pow(max(0, dot(H, N)), fMaterialPower) * " + prefix + "Specular;\n"; shaderSource += " output.Color += Color;\n"; shaderSource += " output.ColorSpec += ColorSpec;\n"; shaderSource += " }\n"; shaderSource += "}\n"; break; case LightType.Spotlight: shaderSource += "{\n"; shaderSource += " float3 PosDiff = " + prefix + "Position-(float3)mul(World,input.Position0);\n"; shaderSource += " float3 L = mul((float3x3)ViewIT, normalize((PosDiff)));\n"; shaderSource += " float NdotL = dot(N, L);\n"; shaderSource += " output.Color = " + prefix + "Ambient;\n"; shaderSource += " output.ColorSpec = 0;\n"; shaderSource += " float fAttenSpot = 1.f;\n"; shaderSource += " if(NdotL >= 0.f)\n"; shaderSource += " {\n"; shaderSource += " //compute diffuse color\n"; shaderSource += " output.Color += NdotL * " + prefix + "Diffuse;\n"; shaderSource += " //add specular component\n"; shaderSource += " float3 H = normalize(L + V); //half vector\n"; shaderSource += " output.ColorSpec = pow(max(0, dot(H, N)), fMaterialPower) * " + prefix + "Specular;\n"; shaderSource += " float LD = length(PosDiff);\n"; shaderSource += " if(LD >" + prefix + "Attenuation.x)\n"; shaderSource += " {\n"; shaderSource += " fAttenSpot = 0.f;\n"; shaderSource += " }\n"; shaderSource += " else\n"; shaderSource += " {\n"; shaderSource += " fAttenSpot *= 1.f/(" + prefix + "Attenuation.x + " + prefix + "Attenuation.y*LD + " + prefix + "Attenuation.z*LD*LD);\n"; shaderSource += " }\n"; shaderSource += " //spot cone computation\n"; shaderSource += " float3 L2 = mul((float3x3)ViewIT, -normalize(" + prefix + "Direction));\n"; shaderSource += " float rho = dot(L, L2);\n"; shaderSource += " fAttenSpot *= pow(saturate((rho - " + prefix + "Spot.y)/(" + prefix + "Spot.x - " + prefix + "Spot.y)), " + prefix + "Spot.z);\n"; shaderSource += " output.Color *= fAttenSpot;\n"; shaderSource += " output.ColorSpec *= fAttenSpot;\n"; shaderSource += " output.Color += output.Color;\n"; shaderSource += " output.ColorSpec += output.ColorSpec;\n"; shaderSource += " }\n"; shaderSource += "}\n"; break; } } } else { if (bHasColor) { shaderSource += "\toutput.Color = input.DiffuseColor0;\n"; } else { //if(fixedFunctionState.MaterialEnabled) shaderSource += "\toutput.Color = MaterialAmbient;\n"; //*MaterialDiffuse;\n"; //else // shaderSource += "\toutput.Color = float4(1,1,1,1);\n"; } } switch (fixedFunctionState.GeneralFixedFunctionState.FogMode) { case FogMode.None: break; case FogMode.Exp: case FogMode.Exp2: case FogMode.Linear: shaderSource += "output.fogDist = length( cameraPos.xyz );\r\n"; break; } switch (fixedFunctionState.GeneralFixedFunctionState.FogMode) { case FogMode.None: break; case FogMode.Exp: shaderSource += "\t#define E 2.71828\n"; shaderSource += "\toutput.fogDist = 1.0 / pow( E, output.fogDist * FogDensity );\n"; shaderSource += "\toutput.fogDist = clamp( output.fogDist, 0, 1 );\n"; break; case FogMode.Exp2: shaderSource += "\t#define E 2.71828\n"; shaderSource += "\toutput.fogDist = 1.0 / pow( E, output.fogDist * output.fogDist * FogDensity * FogDensity );\n"; shaderSource += "\toutput.fogDist = clamp( output.fogDist, 0, 1 );\n"; break; case FogMode.Linear: //shaderSource += "\toutput.fogDist = saturate( ( output.fogDist - FogStart ) / ( FogEnd - FogStart ) / FogDensity );\n"; shaderSource += "\toutput.fogDist = ( FogEnd - output.fogDist ) / ( FogEnd - FogStart );\n"; shaderSource += "\toutput.fogDist = clamp( output.fogDist, 0, 1 );\n"; break; } shaderSource += "\treturn output;\n}\n\n"; #endregion #region pixel shader ///////////////////////////////////// // here starts the fragment shader // ///////////////////////////////////// for (var i = 0; i < fixedFunctionState.TextureLayerStates.Count; i++) { var layerCounter = Convert.ToString(i); switch (fixedFunctionState.TextureLayerStates[i].TextureType) { case TextureType.OneD: shaderSource += "sampler1D Texture" + layerCounter + " : register(s" + layerCounter + ");\r\n"; break; case TextureType.TwoD: shaderSource += "sampler2D Texture" + layerCounter + " : register(s" + layerCounter + ");\r\n"; break; case TextureType.CubeMap: shaderSource += "samplerCUBE Texture" + layerCounter + " : register(s" + layerCounter + ");\r\n"; break; case TextureType.ThreeD: shaderSource += "sampler3D Texture" + layerCounter + " : register(s" + layerCounter + ");\r\n"; break; } } shaderSource += "\nfloat4 " + fragmentProgramName + "( VS_OUTPUT input ) : COLOR\n"; shaderSource += "{\n"; shaderSource += "\tfloat4 finalColor= input.Color + input.ColorSpec;\n"; for (var i = 0; i < fixedFunctionState.TextureLayerStates.Count; i++) { shaderSource += "\t{\n\t\tfloat4 texColor=float4(1.0,1.0,1.0,1.0);\n"; var curTextureLayerState = fixedFunctionState.TextureLayerStates[i]; var layerCounter = Convert.ToString(i); switch (curTextureLayerState.TextureType) { case TextureType.OneD: { shaderSource += "\t\ttexColor = tex1D(Texture" + layerCounter + ", input.Texcoord" + layerCounter + ");\n"; } break; case TextureType.TwoD: switch (fixedFunctionState.TextureLayerStates[i].TexCoordCalcMethod) { case TexCoordCalcMethod.None: case TexCoordCalcMethod.EnvironmentMap: case TexCoordCalcMethod.EnvironmentMapNormal: //? case TexCoordCalcMethod.EnvironmentMapPlanar: //? case TexCoordCalcMethod.EnvironmentMapReflection: shaderSource += "\t\ttexColor = tex2D(Texture" + layerCounter + ", input.Texcoord" + layerCounter + ");\n"; break; case TexCoordCalcMethod.ProjectiveTexture: if (texCordVecType.ContainsKey(curTextureLayerState.CoordIndex)) { switch (texCordVecType[curTextureLayerState.CoordIndex]) { case VertexElementType.Float1: shaderSource += "\t\ttexColor = tex2D(Texture" + layerCounter + ",input.Texcoord" + layerCounter + ");\n"; break; case VertexElementType.Float2: shaderSource += "\t\tfloat2 final =input.Texcoord" + layerCounter + ".xy / input.Texcoord" + layerCounter + ".w;\n"; shaderSource += "\t\ttexColor = tex2D(Texture" + layerCounter + ", final);\n"; break; case VertexElementType.Float3: //shaderSource += "\t\ttexColor = tex2D(Texture" + layerCounter + ", input.Texcoord" + layerCounter + ".xyz);\n"; break; } } else { shaderSource += "\t\tfloat2 final =input.Texcoord" + layerCounter + ".xy / input.Texcoord" + layerCounter + ".w;\n"; shaderSource += "\t\ttexColor = tex2D(Texture" + layerCounter + ", final);\n"; } break; } break; case TextureType.CubeMap: //mimaps seem to be ok now shaderSource += "\t\ttexColor = texCUBE(Texture" + layerCounter + ", input.Texcoord" + layerCounter + ");\n"; //shaderSource += "\t\ttexColor = texCUBElod(Texture" + layerCounter + ", float4(input.Texcoord" + layerCounter + ",0));\n"; break; case TextureType.ThreeD: if (texCordVecType.ContainsKey(curTextureLayerState.CoordIndex)) { switch (texCordVecType[i]) { case VertexElementType.Float1: shaderSource = shaderSource + "\t\t texColor = tex3D(Texture" + layerCounter + ", float3(input.Texcoord" + layerCounter + ", 0.0, 0.0));\r\n"; break; case VertexElementType.Float2: shaderSource = shaderSource + "\t\t texColor = tex3D(Texture" + layerCounter + ", float3(input.Texcoord" + layerCounter + ".x, input.Texcoord" + layerCounter + ".y, 0.0));\r\n"; break; case VertexElementType.Float3: shaderSource = shaderSource + "\t\t texColor = tex3D(Texture" + layerCounter + ", input.Texcoord" + layerCounter + ");\r\n"; break; } } else { shaderSource += "\t\t texColor = tex3D(Texture" + layerCounter + ", input.Texcoord" + layerCounter + ");\n"; } break; } #region blending /*-----------------Blending----------------------------------------*/ var blend = curTextureLayerState.LayerBlendMode; if (blend != null) { switch (blend.source1) { case LayerBlendSource.Current: shaderSource += "\t\tfloat4 source1 = finalColor;\n"; break; case LayerBlendSource.Texture: shaderSource += "\t\tfloat4 source1 = texColor;\n"; break; case LayerBlendSource.Diffuse: shaderSource += "\t\tfloat4 source1 = input.Color;\n"; break; case LayerBlendSource.Specular: shaderSource += "\t\tfloat4 source1 = input.ColorSpec;\n"; break; case LayerBlendSource.Manual: shaderSource += "\t\tfloat4 Texture" + layerCounter + "_colourArg1=float4(" + blend.colorArg1.r + "," + blend.colorArg1.g + "," + blend.colorArg1.b + "," + blend.colorArg1.a + ");\r\n"; shaderSource += "\t\tfloat4 source1 = Texture" + layerCounter + "_colourArg1;\n"; break; } switch (blend.source2) { case LayerBlendSource.Current: shaderSource += "\t\tfloat4 source2 = finalColor;\n"; break; case LayerBlendSource.Texture: shaderSource += "\t\tfloat4 source2 = texColor;\n"; break; case LayerBlendSource.Diffuse: shaderSource += "\t\tfloat4 source2 = input.Color;\n"; break; case LayerBlendSource.Specular: shaderSource += "\t\tfloat4 source2 = input.ColorSpec;\n"; break; case LayerBlendSource.Manual: shaderSource += "\t\tfloat4 Texture" + layerCounter + "_colourArg2=float4(" + blend.colorArg2.r + "," + blend.colorArg2.g + "," + blend.colorArg2.b + "," + blend.colorArg2.a + ");\r\n"; shaderSource += "\t\tfloat4 source2 = Texture" + layerCounter + "_colourArg2;\n"; break; } switch (blend.operation) { case LayerBlendOperationEx.Source1: shaderSource += "\t\tfinalColor = source1;\n"; break; case LayerBlendOperationEx.Source2: shaderSource += "\t\tfinalColor = source2;\n"; break; case LayerBlendOperationEx.Modulate: shaderSource += "\t\tfinalColor = source1 * source2;\n"; break; case LayerBlendOperationEx.ModulateX2: shaderSource += "\t\tfinalColor = source1 * source2 * 2.0;\n"; break; case LayerBlendOperationEx.ModulateX4: shaderSource += "\t\tfinalColor = source1 * source2 * 4.0;\n"; break; case LayerBlendOperationEx.Add: shaderSource += "\t\tfinalColor = source1 + source2;\n"; break; case LayerBlendOperationEx.AddSigned: shaderSource += "\t\tfinalColor = source1 + source2 - 0.5;\n"; break; case LayerBlendOperationEx.AddSmooth: shaderSource += "\t\tfinalColor = source1 + source2 - (source1 * source2);\n"; break; case LayerBlendOperationEx.Subtract: shaderSource += "\t\tfinalColor = source1 - source2;\n"; break; case LayerBlendOperationEx.BlendDiffuseAlpha: shaderSource += "\t\tfinalColor = source1 * input.Color.w + source2 * (1.0 - input.Color.w);\n"; break; case LayerBlendOperationEx.BlendTextureAlpha: shaderSource += "\t\tfinalColor = source1 * texColor.w + source2 * (1.0 - texColor.w);\n"; break; case LayerBlendOperationEx.BlendCurrentAlpha: shaderSource += "\t\tfinalColor = source1 * finalColor.w + source2 * (1.0 - finalColor.w);\n"; break; case LayerBlendOperationEx.BlendManual: shaderSource += "\t\tfinalColor = source1 * " + Convert.ToString(blend.blendFactor) + " + source2 * (1.0 - " + Convert.ToString(blend.blendFactor) + ");\n"; break; case LayerBlendOperationEx.DotProduct: shaderSource += "\t\tfinalColor = product(source1,source2);\n"; break; } } shaderSource += "\t}\n"; } #endregion if (fixedFunctionState.GeneralFixedFunctionState.FogMode != FogMode.None) { shaderSource += "\tfinalColor = input.fogDist * finalColor + (1.0 - input.fogDist) * FogColor;\n"; } shaderSource += "\treturn finalColor;\n}\n"; #endregion return(shaderSource); }
public HLSLFixedFunctionProgram() { vertexProgramUsage = new GpuProgramUsage( GpuProgramType.Vertex, null ); fragmentProgramUsage = new GpuProgramUsage( GpuProgramType.Fragment, null ); fixedFunctionState = new FixedFunctionState(); }
public abstract String GetShaderSource(String vertexProgramName, String fragmentProgramName, VertexBufferDeclaration vertexBufferDeclaration, FixedFunctionState fixedFuncState);
protected FixedFunctionPrograms createShaderPrograms(String generatorName, VertexBufferDeclaration vertexBufferDeclaration, FixedFunctionState state) { const String vertexProgramName = "VS"; const String fragmentProgramName = "FP"; var shaderGenerator = shaderGeneratorMap[generatorName]; var shaderSource = shaderGenerator.GetShaderSource(vertexProgramName, fragmentProgramName, vertexBufferDeclaration, state); if (Root.Instance.RenderSystem.ConfigOptions["Save Generated Shaders"].Value == "Yes") { saveShader(state.GetHashCode().ToString(), shaderSource); } // Vertex program details var vertexProgramUsage = new GpuProgramUsage(GpuProgramType.Vertex, null); // Fragment program details var fragmentProgramUsage = new GpuProgramUsage(GpuProgramType.Fragment, null); HighLevelGpuProgram vs; HighLevelGpuProgram fs; shaderCount++; vs = HighLevelGpuProgramManager.Instance.CreateProgram("VS_" + shaderCount, ResourceGroupManager.DefaultResourceGroupName, shaderGenerator.Language, GpuProgramType.Vertex); LogManager.Instance.Write("Created VertexShader {0}", "VS_" + shaderCount); vs.Source = shaderSource; vs.Properties["entry_point"] = vertexProgramName; vs.Properties["target"] = shaderGenerator.VPTarget; vs.Load(); vertexProgramUsage.Program = vs; //vertexProgramUsage.Params = vs.CreateParameters(); fs = HighLevelGpuProgramManager.Instance.CreateProgram("FS_" + shaderCount, ResourceGroupManager.DefaultResourceGroupName, shaderGenerator.Language, GpuProgramType.Fragment); LogManager.Instance.Write("Created FragmentProgram {0}", "FS_" + shaderCount); fs.Source = shaderSource; fs.Properties["entry_point"] = fragmentProgramName; fs.Properties["target"] = shaderGenerator.FPTarget; fs.Load(); fragmentProgramUsage.Program = fs; //fragmentProgramUsage.Params = fs.CreateParameters(); var newPrograms = shaderGenerator.CreateFixedFunctionPrograms(); newPrograms.FixedFunctionState = state; newPrograms.FragmentProgramUsage = fragmentProgramUsage; newPrograms.VertexProgramUsage = vertexProgramUsage; //then save the new program language2State2Declaration2ProgramsMap[generatorName][state][vertexBufferDeclaration] = newPrograms; programsToDeleteAtTheEnd.Add(newPrograms); return(newPrograms); }