示例#1
0
        public override ShaderSource GenerateShaderSource(ShaderGeneratorContext context, MaterialComputeColorKeys baseKeys)
        {
            if (string.IsNullOrEmpty(MixinReference))
            {
                return(new ShaderClassSource("ComputeColor"));
            }
            var mixinName = MixinReference;

            object[] generics = null;
            if (Generics.Count > 0)
            {
                // TODO: correct generic order
                var mixinGenerics = new List <object>();
                foreach (var genericKey in Generics.Keys)
                {
                    var generic = Generics[genericKey];
                    if (generic is ComputeColorParameterTexture)
                    {
                        var textureParameter = ((ComputeColorParameterTexture)generic);
                        var textureKey       = context.GetTextureKey(textureParameter.Texture, baseKeys);
                        mixinGenerics.Add(textureKey.ToString());
                    }
                    else if (generic is ComputeColorParameterSampler)
                    {
                        var pk = context.GetSamplerKey((ComputeColorParameterSampler)generic);
                        mixinGenerics.Add(pk.ToString());
                    }
                    else if (generic is ComputeColorParameterFloat)
                    {
                        mixinGenerics.Add(((ComputeColorParameterFloat)generic).Value.ToString(CultureInfo.InvariantCulture));
                    }
                    else if (generic is ComputeColorParameterInt)
                    {
                        mixinGenerics.Add(((ComputeColorParameterInt)generic).Value.ToString(CultureInfo.InvariantCulture));
                    }
                    else if (generic is ComputeColorParameterFloat2)
                    {
                        mixinGenerics.Add(MaterialUtility.GetAsShaderString(((ComputeColorParameterFloat2)generic).Value));
                    }
                    else if (generic is ComputeColorParameterFloat3)
                    {
                        mixinGenerics.Add(MaterialUtility.GetAsShaderString(((ComputeColorParameterFloat3)generic).Value));
                    }
                    else if (generic is ComputeColorParameterFloat4)
                    {
                        mixinGenerics.Add(MaterialUtility.GetAsShaderString(((ComputeColorParameterFloat4)generic).Value));
                    }
                    else if (generic is ComputeColorStringParameter)
                    {
                        mixinGenerics.Add(((ComputeColorStringParameter)generic).Value);
                    }
                    else
                    {
                        throw new Exception("[Material] Unknown node type: " + generic.GetType());
                    }
                }
                generics = mixinGenerics.ToArray();
            }

            var shaderClassSource = new ShaderClassSource(mixinName, generics);

            if (CompositionNodes.Count == 0)
            {
                return(shaderClassSource);
            }

            var mixin = new ShaderMixinSource();

            mixin.Mixins.Add(shaderClassSource);

            foreach (var comp in CompositionNodes)
            {
                if (comp.Value != null)
                {
                    var compShader = comp.Value.GenerateShaderSource(context, baseKeys);
                    if (compShader != null)
                    {
                        mixin.Compositions.Add(comp.Key, compShader);
                    }
                }
            }

            return(mixin);
        }
        public override ShaderSource GenerateShaderSource(ShaderGeneratorContext context, MaterialComputeColorKeys baseKeys)
        {
            if (!Enabled || Texture == null) // generate shader from default value when the texture is null or disabled
            {
                var fallbackValue = GenerateShaderFromFallbackValue(context, baseKeys);
                if (fallbackValue != null)
                {
                    return(fallbackValue);
                }
            }

            // generate shader from the texture
            // TODO: Use a generated UsedTexcoordIndex when backing textures
            var usedTexcoord = "TEXCOORD" + MaterialUtility.GetTextureIndex(TexcoordIndex);

            var textureKey = context.GetTextureKey(this, baseKeys);
            var samplerKey = context.GetSamplerKey(Sampler);

            UsedKey = textureKey;

            var scale       = Scale;
            var scaleFactor = context.CurrentOverrides.UVScale;

            if (scaleFactor != Vector2.One)
            {
                scale *= scaleFactor;
            }

            var channelStr = GetTextureChannelAsString();

            // "TTEXTURE", "TStream"
            ShaderClassSource shaderSource;

            // TODO: Workaround bad to have to copy all the new ShaderClassSource(). Check how to improve this
            if (context.OptimizeMaterials)
            {
                var scaleStr  = MaterialUtility.GetAsShaderString(scale);
                var offsetStr = MaterialUtility.GetAsShaderString(Offset);

                // If materials are optimized, we precompute best shader combination (note: will generate shader permutations!)
                if (context.IsNotPixelStage)
                {
                    if (Offset != Vector2.Zero)
                    {
                        shaderSource = new ShaderClassSource("ComputeColorTextureLodScaledOffsetSampler", textureKey, usedTexcoord, samplerKey, channelStr, scaleStr, offsetStr, 0.0f);
                    }
                    else if (scale != Vector2.One)
                    {
                        shaderSource = new ShaderClassSource("ComputeColorTextureLodScaledSampler", textureKey, usedTexcoord, samplerKey, channelStr, scaleStr, 0.0f);
                    }
                    else
                    {
                        shaderSource = new ShaderClassSource("ComputeColorTextureLodSampler", textureKey, usedTexcoord, samplerKey, channelStr, 0.0f);
                    }
                }
                else
                {
                    if (Offset != Vector2.Zero)
                    {
                        shaderSource = new ShaderClassSource("ComputeColorTextureScaledOffsetSampler", textureKey, usedTexcoord, samplerKey, channelStr, scaleStr, offsetStr);
                    }
                    else if (scale != Vector2.One)
                    {
                        shaderSource = new ShaderClassSource("ComputeColorTextureScaledSampler", textureKey, usedTexcoord, samplerKey, channelStr, scaleStr);
                    }
                    else
                    {
                        shaderSource = new ShaderClassSource("ComputeColorTextureSampler", textureKey, usedTexcoord, samplerKey, channelStr);
                    }
                }
            }
            else
            {
                // Try to avoid shader permutations, by putting UV scaling/offset in shader parameters
                var textureScale  = (ValueParameterKey <Vector2>)context.GetParameterKey(MaterialKeys.TextureScale);
                var textureOffset = (ValueParameterKey <Vector2>)context.GetParameterKey(MaterialKeys.TextureOffset);

                context.Parameters.Set(textureScale, scale);
                context.Parameters.Set(textureOffset, Offset);

                if (context.IsNotPixelStage)
                {
                    shaderSource = new ShaderClassSource("ComputeColorTextureLodScaledOffsetDynamicSampler", textureKey, usedTexcoord, samplerKey, channelStr, textureScale, textureOffset, 0.0f);
                }
                else
                {
                    shaderSource = new ShaderClassSource("ComputeColorTextureScaledOffsetDynamicSampler", textureKey, usedTexcoord, samplerKey, channelStr, textureScale, textureOffset);
                }
            }

            return(shaderSource);
        }
        public override ShaderSource GenerateShaderSource(ShaderGeneratorContext context, MaterialComputeColorKeys baseKeys)
        {
            if (!Enabled || Texture == null) // generate shader from default value when the texture is null or disabled
            {
                var fallbackValue = GenerateShaderFromFallbackValue(context, baseKeys);
                if (fallbackValue != null)
                    return fallbackValue;
            }

            // generate shader from the texture
            // TODO: Use a generated UsedTexcoordIndex when backing textures
            var usedTexcoord = "TEXCOORD" + MaterialUtility.GetTextureIndex(TexcoordIndex);

            var textureKey = context.GetTextureKey(this, baseKeys);
            var samplerKey = context.GetSamplerKey(Sampler);
            UsedKey = textureKey;

            var scale = Scale;
            var scaleFactor = context.CurrentOverrides.UVScale;
            if (scaleFactor != Vector2.One)
            {
                scale *= scaleFactor;
            }

            var channelStr = GetTextureChannelAsString();

            // "TTEXTURE", "TStream"
            ShaderClassSource shaderSource;

            // TODO: Workaround bad to have to copy all the new ShaderClassSource(). Check how to improve this
            if (context.OptimizeMaterials)
            {
                var scaleStr = MaterialUtility.GetAsShaderString(scale);
                var offsetStr = MaterialUtility.GetAsShaderString(Offset);

                // If materials are optimized, we precompute best shader combination (note: will generate shader permutations!)
                if (context.IsNotPixelStage)
                {
                    if (Offset != Vector2.Zero)
                        shaderSource = new ShaderClassSource("ComputeColorTextureLodScaledOffsetSampler", textureKey, usedTexcoord, samplerKey, channelStr, scaleStr, offsetStr, 0.0f);
                    else if (scale != Vector2.One)
                        shaderSource = new ShaderClassSource("ComputeColorTextureLodScaledSampler", textureKey, usedTexcoord, samplerKey, channelStr, scaleStr, 0.0f);
                    else
                        shaderSource = new ShaderClassSource("ComputeColorTextureLodSampler", textureKey, usedTexcoord, samplerKey, channelStr, 0.0f);
                }
                else
                {
                    if (Offset != Vector2.Zero)
                        shaderSource = new ShaderClassSource("ComputeColorTextureScaledOffsetSampler", textureKey, usedTexcoord, samplerKey, channelStr, scaleStr, offsetStr);
                    else if (scale != Vector2.One)
                        shaderSource = new ShaderClassSource("ComputeColorTextureScaledSampler", textureKey, usedTexcoord, samplerKey, channelStr, scaleStr);
                    else
                        shaderSource = new ShaderClassSource("ComputeColorTextureSampler", textureKey, usedTexcoord, samplerKey, channelStr);
                }
            }
            else
            {
                // Try to avoid shader permutations, by putting UV scaling/offset in shader parameters
                var textureScale = (ValueParameterKey<Vector2>)context.GetParameterKey(MaterialKeys.TextureScale);
                var textureOffset = (ValueParameterKey<Vector2>)context.GetParameterKey(MaterialKeys.TextureOffset);

                context.Parameters.Set(textureScale, scale);
                context.Parameters.Set(textureOffset, Offset);

                if (context.IsNotPixelStage)
                {
                    shaderSource = new ShaderClassSource("ComputeColorTextureLodScaledOffsetDynamicSampler", textureKey, usedTexcoord, samplerKey, channelStr, textureScale, textureOffset, 0.0f);
                }
                else
                {
                    shaderSource = new ShaderClassSource("ComputeColorTextureScaledOffsetDynamicSampler", textureKey, usedTexcoord, samplerKey, channelStr, textureScale, textureOffset);
                }
            }

            return shaderSource;
        }