コード例 #1
0
ファイル: ShaderManager.cs プロジェクト: edwardL/axiom3d
        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));
        }
コード例 #2
0
 public HLSLFixedFunctionProgram()
 {
     vertexProgramUsage   = new GpuProgramUsage(GpuProgramType.Vertex, null);
     fragmentProgramUsage = new GpuProgramUsage(GpuProgramType.Fragment, null);
     fixedFunctionState   = new FixedFunctionState();
 }
コード例 #3
0
 public abstract String GetShaderSource( String vertexProgramName, String fragmentProgramName,
                                         VertexBufferDeclaration vertexBufferDeclaration,
                                         FixedFunctionState fixedFuncState );
コード例 #4
0
        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);
        }
コード例 #5
0
 public HLSLFixedFunctionProgram()
 {
     vertexProgramUsage = new GpuProgramUsage( GpuProgramType.Vertex, null );
     fragmentProgramUsage = new GpuProgramUsage( GpuProgramType.Fragment, null );
     fixedFunctionState = new FixedFunctionState();
 }
コード例 #6
0
 public abstract String GetShaderSource(String vertexProgramName, String fragmentProgramName,
                                        VertexBufferDeclaration vertexBufferDeclaration,
                                        FixedFunctionState fixedFuncState);
コード例 #7
0
ファイル: ShaderManager.cs プロジェクト: edwardL/axiom3d
        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);
        }