Пример #1
0
        /// <summary>
        /// Returns the pre defined Fusee uniform parameters of a vertex shader, depending on the given ShaderEffectProps.
        /// </summary>
        /// <param name="effectProps">The ShaderEffectProps.</param>
        /// <returns></returns>
        public static string FuseeUniforms(ShaderEffectProps effectProps)
        {
            var uniforms = new List <string>
            {
                GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.ModelView),
                GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.ModelViewProjection)
            };

            if (effectProps.MeshProbs.HasNormals)
            {
                uniforms.Add(GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.ITModelView));
            }

            if (effectProps.MatProbs.HasSpecular && !effectProps.MeshProbs.HasWeightMap)
            {
                uniforms.Add(GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.IModelView));
            }

            if (effectProps.MeshProbs.HasWeightMap)
            {
                uniforms.Add(GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.View));
                uniforms.Add(GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.Projection));
                uniforms.Add(GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.IModelView));
                uniforms.Add(GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.Bones + "[" + HeaderShard.BoneDefineVar + "]"));
            }

            return(string.Join("\n", uniforms));
        }
Пример #2
0
        /// <summary>
        /// Returns the in parameters for a ShaderEffect, depending on the given ShaderEffectProps.
        /// </summary>
        /// <param name="effectProps">The ShaderEffectProps.</param>
        /// <returns></returns>
        public static string InParams(ShaderEffectProps effectProps)
        {
            var pxIn = new List <string>
            {
                GLSL.CreateIn(GLSL.Type.Vec3, VaryingNameDeclarations.ViewDirection),
                GLSL.CreateIn(GLSL.Type.Vec4, VaryingNameDeclarations.Position),
                GLSL.CreateIn(GLSL.Type.Vec3, VaryingNameDeclarations.CameraPosition)
            };

            if (effectProps.MeshProbs.HasColors)
            {
                pxIn.Add(GLSL.CreateIn(GLSL.Type.Vec3, VaryingNameDeclarations.Color));
            }

            if (effectProps.MeshProbs.HasNormals)
            {
                pxIn.Add(GLSL.CreateIn(GLSL.Type.Vec3, VaryingNameDeclarations.Normal));
            }

            if (effectProps.MeshProbs.HasTangents && effectProps.MeshProbs.HasBiTangents)
            {
                pxIn.Add(GLSL.CreateIn(GLSL.Type.Vec4, VaryingNameDeclarations.Tangent));
                pxIn.Add(GLSL.CreateIn(GLSL.Type.Vec3, VaryingNameDeclarations.Bitangent));
            }

            if (effectProps.MeshProbs.HasUVs)
            {
                pxIn.Add(GLSL.CreateIn(GLSL.Type.Vec2, VaryingNameDeclarations.TextureCoordinates));
            }

            return(string.Join("\n", pxIn));
        }
Пример #3
0
 internal IEnumerable <ASLShaderVariable> GetOutputs()
 {
     foreach (var field in _shader.Fields)
     {
         if (field.HasCustomAttributes)
         {
             var attrs = field.CustomAttributes.Where(a => a.AttributeType.IsOut() && !a.AttributeType.IsBuiltIn());
             if (attrs.Count() > 0)
             {
                 var attr        = attrs.First();
                 var type        = GLSL.ToGLSL(field.FieldType);
                 var isArray     = field.FieldType.IsArray;
                 var arrayAttr   = field.CustomAttributes.Where(a => a.AttributeType.Is <ArraySizeAttribute>());
                 var arraySize   = (isArray && arrayAttr.Count() > 0 && arrayAttr.First().HasConstructorArguments) ? arrayAttr.First().ConstructorArguments.First().Value.ToString() : string.Empty;
                 var name        = field.Name;
                 var commentAttr = field.CustomAttributes.Where(a => a.AttributeType.Is <CommentAttribute>());
                 var u_comment   = (commentAttr.Count() > 0 && commentAttr.First().HasConstructorArguments) ? commentAttr.First().ConstructorArguments.First().Value.ToString() : string.Empty;
                 var d_comment   = DebugMode ? field.DeclaringType.FullName + "." + field.Name : string.Empty;
                 var layoutAttr  = (this is FragmentShader) ? field.CustomAttributes.Where(a => a.AttributeType.Is <FragmentShader.LayoutAttribute>()) :
                                   ((this is GeometryShader) ? field.CustomAttributes.Where(a => a.AttributeType.Is <GeometryShader.LayoutAttribute>()) : null);
                 var layout = (layoutAttr != null && layoutAttr.Count() > 0) ? layoutAttr.First() : null;
                 yield return(new ASLShaderVariable(type, isArray, arraySize, name, u_comment, d_comment, attr.AttributeType, layout));
             }
         }
     }
 }
Пример #4
0
        /// <summary>
        /// Method for calculation the ambient lighting component.
        /// </summary>
        public static string AmbientComponent()
        {
            var methodBody = new List <string>
            {
                $"return vec3(color.xyz * ambientCoefficient);"
            };

            return(GLSL.CreateMethod(GLSL.Type.Vec3, "ambientLighting",
                                     new[] { GLSL.CreateVar(GLSL.Type.Float, "ambientCoefficient"), GLSL.CreateVar(GLSL.Type.Vec4, "color") }, methodBody));
        }
Пример #5
0
            public static string ToGLSLParamType(ParameterDefinition p)
            {
                var t = GLSL.ToGLSL(p.ParameterType.Resolve());

                if (p.ParameterType.IsByReference)
                {
                    return((p.IsOut ? "out " : "inout ") + t);
                }

                return(t);
            }
Пример #6
0
        /// <summary>
        /// Calculates the attenuation of a point light.
        /// </summary>
        /// <returns></returns>
        public static string AttenuationPointComponent()
        {
            var methodBody = new List <string>
            {
                $"float distanceToLight = length(lightPos - fragPos);",
                "float distance = pow(distanceToLight / lightMaxDistance, 2.0);",
                "return (clamp(1.0 - pow(distance, 2.0), 0.0, 1.0)) / (pow(distance, 2.0) + 1.0);",
            };

            return(GLSL.CreateMethod(GLSL.Type.Float, "attenuationPointComponent",
                                     new[] { GLSL.CreateVar(GLSL.Type.Vec3, "fragPos"), GLSL.CreateVar(GLSL.Type.Vec3, "lightPos"), GLSL.CreateVar(GLSL.Type.Float, "lightMaxDistance") }, methodBody));
        }
Пример #7
0
        //TODO: At the moment Blender's Principled BSDF material gets translated into a MaterialPBR and internally uses this lighting method for the specular component.
        //This is not the same lighting method as is used in Blender and will therefor only produce approximately visually correct results.
        /// <summary>
        /// Method for calculation the specular lighting component.
        /// Replaces the standard specular calculation with the Cook-Torrance-Shader
        /// </summary>
        public static string PbrSpecularComponent()
        {
            var methodBody = new List <string>
            {
                $"float roughnessValue = {UniformNameDeclarations.RoughnessValue}; // 0 : smooth, 1: rough",            // roughness
                $"float F0 = {UniformNameDeclarations.FresnelReflectance}; // fresnel reflectance at normal incidence", // fresnel => Specular from Blender
                "float NdotL = max(dot(N, L), 0.0);",
                "float specular = 0.0;",
                "float BlinnSpecular = 0.0;",
                "",
                "if(dot(N, L) > 0.0)",
                "{",
                "     // calculate intermediary values",
                "     vec3 H = normalize(L + V);",
                "     float NdotH = max(dot(N, H), 0.0); ",
                "     float NdotV = max(dot(N, L), 0.0); // note: this is NdotL, which is the same value",
                "     float VdotH = max(dot(V, H), 0.0);",
                "     float mSquared = roughnessValue * roughnessValue;",
                "",
                "",
                "",
                "",
                "     // -- geometric attenuation",
                "     //[Schlick's approximation of Smith's shadow equation]",
                "     float k= roughnessValue * sqrt(0.5 * 3.14159265);",
                "     float one_minus_k= 1.0 - k;",
                "     float geoAtt = ( NdotL / (NdotL * one_minus_k + k) ) * ( NdotV / (NdotV * one_minus_k + k) );",
                "",
                "     // -- roughness (or: microfacet distribution function)",
                "     // Trowbridge-Reitz or GGX, GTR2",
                "     float a2 = mSquared * mSquared;",
                "     float d = (NdotH * a2 - NdotH) * NdotH + 1.0;",
                "     float roughness = a2 / (3.14 * d * d);",
                "",
                "     // -- fresnel",
                "     // [Schlick 1994, An Inexpensive BRDF Model for Physically-Based Rendering]",
                "     float fresnel = pow(1.0 - VdotH, 5.0);",
                $"    fresnel = clamp((50.0 * {UniformNameDeclarations.SpecularColor}.y), 0.0, 1.0) * fresnel + (1.0 - fresnel);",
                "",
                $"     specular = (fresnel * geoAtt * roughness) / (NdotV * NdotL * 3.14);",
                "     ",
                "}",
                "",
                $"return (k + specular * (1.0-k));"
            };

            return(GLSL.CreateMethod(GLSL.Type.Float, "specularLighting",
                                     new[]
            {
                GLSL.CreateVar(GLSL.Type.Vec3, "N"), GLSL.CreateVar(GLSL.Type.Vec3, "L"), GLSL.CreateVar(GLSL.Type.Vec3, "V"),
                GLSL.CreateVar(GLSL.Type.Float, "k")
            }, methodBody));
        }
Пример #8
0
        /// <summary>
        /// Returns all uniforms, as they are given in the <see cref="MaterialProps"/> object.
        /// </summary>
        /// <param name="effectProps">The ShaderEffectProps.</param>
        /// <returns></returns>
        public static string MaterialPropsUniforms(ShaderEffectProps effectProps)
        {
            var matPropUnifroms = new List <string>();

            if (effectProps.MatProbs.HasSpecular)
            {
                matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Vec4, UniformNameDeclarations.SpecularColor));

                if (effectProps.MatType == MaterialType.MaterialPbr)
                {
                    matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Float, UniformNameDeclarations.RoughnessValue));
                    matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Float, UniformNameDeclarations.FresnelReflectance));
                    matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Float, UniformNameDeclarations.DiffuseFraction));
                }
                else if (effectProps.MatType == MaterialType.Standard)
                {
                    matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Float, UniformNameDeclarations.SpecularShininess));
                    matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Float, UniformNameDeclarations.SpecularIntensity));
                }
            }

            if (effectProps.MatProbs.HasAlbedo)
            {
                matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Vec4, UniformNameDeclarations.AlbedoColor));
            }

            if (effectProps.MatProbs.HasEmissive)
            {
                matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Vec4, UniformNameDeclarations.EmissiveColor));
            }

            //Textures
            if (effectProps.MatProbs.HasNormalMap)
            {
                matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Sampler2D, UniformNameDeclarations.NormalMap));
                matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Float, UniformNameDeclarations.NormalMapIntensity));
            }

            if (effectProps.MatProbs.HasAlbedoTexture)
            {
                matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Sampler2D, UniformNameDeclarations.AlbedoTexture));
                matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Float, UniformNameDeclarations.AlbedoMix));
            }

            if (effectProps.MatProbs.HasEmissiveTexture)
            {
                matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Sampler2D, UniformNameDeclarations.EmissiveTexture));
                matPropUnifroms.Add(GLSL.CreateUniform(GLSL.Type.Float, UniformNameDeclarations.EmissiveMix));
            }

            return(string.Join("\n", matPropUnifroms));
        }
Пример #9
0
            internal static string GetSignature(MethodDefinition m)
            {
                var arraySize = string.Empty;

                if (m.ReturnType.IsArray && m.MethodReturnType.HasCustomAttributes)
                {
                    var attr = m.MethodReturnType.CustomAttributes.Where(a => a.AttributeType.Is <ArraySizeAttribute>()).First();
                    arraySize = attr.ConstructorArguments.First().Value.ToString();
                }
                return(GLSL.ToGLSL(m.ReturnType) + (m.ReturnType.IsArray ? "[" + arraySize + "]" : string.Empty)
                       + " " +
                       m.Name + "(" + GetParameterString(m) + ")");
            }
Пример #10
0
        /// <summary>
        /// Method for calculation the diffuse lighting component.
        /// </summary>
        public static string DiffuseComponent()
        {
            var methodBody = new List <string>
            {
                "return max(dot(N, L), 0.0);"
            };

            return(GLSL.CreateMethod(GLSL.Type.Float, "diffuseLighting",
                                     new[]
            {
                GLSL.CreateVar(GLSL.Type.Vec3, "N"), GLSL.CreateVar(GLSL.Type.Vec3, "L")
            }, methodBody));
        }
Пример #11
0
        /// <summary>
        /// Creates the method for calculating whether a fragment is in shadow or not, by using a shadow map (sampler2DCube).
        /// The cube map is used when calculating the shadows for a point light.
        /// </summary>
        /// <returns></returns>
        public static string ShadowCalculationCubeMap()
        {
            var methodBody = new List <string>()
            {
                "float pcfKernelSize = pcfKernelHalfSize + pcfKernelHalfSize + 1.0;",
                "pcfKernelSize *= pcfKernelSize;",

                "vec3 sampleOffsetDirections[20] = vec3[]",
                "(",
                "   vec3(pcfKernelHalfSize, pcfKernelHalfSize, pcfKernelHalfSize), vec3(pcfKernelHalfSize, -pcfKernelHalfSize, pcfKernelHalfSize), vec3(-pcfKernelHalfSize, -pcfKernelHalfSize, pcfKernelHalfSize), vec3(-pcfKernelHalfSize, pcfKernelHalfSize, pcfKernelHalfSize),",
                "   vec3(pcfKernelHalfSize, pcfKernelHalfSize, -pcfKernelHalfSize), vec3(pcfKernelHalfSize, -pcfKernelHalfSize, -pcfKernelHalfSize), vec3(-pcfKernelHalfSize, -pcfKernelHalfSize, -pcfKernelHalfSize), vec3(-pcfKernelHalfSize, pcfKernelHalfSize, -pcfKernelHalfSize),",
                "   vec3(pcfKernelHalfSize, pcfKernelHalfSize, 0), vec3(pcfKernelHalfSize, -pcfKernelHalfSize, 0), vec3(-pcfKernelHalfSize, -pcfKernelHalfSize, 0), vec3(-pcfKernelHalfSize, pcfKernelHalfSize, 0),",
                "   vec3(pcfKernelHalfSize, 0, pcfKernelHalfSize), vec3(-pcfKernelHalfSize, 0, pcfKernelHalfSize), vec3(pcfKernelHalfSize, 0, -pcfKernelHalfSize), vec3(-pcfKernelHalfSize, 0, -pcfKernelHalfSize),",
                "   vec3(0, pcfKernelHalfSize, pcfKernelHalfSize), vec3(0, -pcfKernelHalfSize, pcfKernelHalfSize), vec3(0, -pcfKernelHalfSize, -pcfKernelHalfSize), vec3(0, pcfKernelHalfSize, -pcfKernelHalfSize)",
                ");",

                "// get vector between fragment position and light position",
                "vec3 fragToLight = (fragPos - lightPos) * -1.0;",
                "// now get current linear depth as the length between the fragment and light position",
                "float currentDepth = length(fragToLight);",

                "float shadow = 0.0;",
                "float thisBias = max(bias * (1.0 - dot(normal, lightDir)), bias * 0.01);//0.15;",
                "int samples = 20;",
                $"vec3 camPos = {UniformNameDeclarations.IView}[3].xyz;",
                "float viewDistance = length(camPos - fragPos);",

                "float diskRadius = 0.5; //(1.0 + (viewDistance / farPlane)) / pcfKernelSize;",
                "for (int i = 0; i < samples; ++i)",
                "{",
                "   float closestDepth = texture(shadowMap, fragToLight + sampleOffsetDirections[i] * diskRadius).r;",
                "   closestDepth *= farPlane;   // Undo mapping [0;1]",
                "   if (currentDepth - thisBias > closestDepth)",
                "       shadow += 1.0;",
                "}",
                "shadow /= float(samples);",
                "return shadow;"
            };

            return(GLSL.CreateMethod(GLSL.Type.Float, "ShadowCalculationCubeMap", new[]
            {
                GLSL.CreateVar(GLSL.Type.SamplerCube, "shadowMap"),
                GLSL.CreateVar(GLSL.Type.Vec3, "fragPos"),
                GLSL.CreateVar(GLSL.Type.Vec3, "lightPos"),
                GLSL.CreateVar(GLSL.Type.Float, "farPlane"),
                GLSL.CreateVar(GLSL.Type.Vec3, "normal"),
                GLSL.CreateVar(GLSL.Type.Vec3, "lightDir"),
                GLSL.CreateVar(GLSL.Type.Float, "bias"),
                GLSL.CreateVar(GLSL.Type.Float, "pcfKernelHalfSize")
            }, methodBody));
        }
Пример #12
0
        /// <summary>
        /// Creates the in (with prefix "fu") and out parameters of the vertex shader, depending on the given ShaderEffectProps.
        /// </summary>
        /// <param name="effectProps">>The ShaderEffectProps.</param>
        /// <returns></returns>
        public static string InAndOutParams(ShaderEffectProps effectProps)
        {
            var vertProps = new List <string>
            {
                GLSL.CreateOut(GLSL.Type.Vec3, VaryingNameDeclarations.CameraPosition),
                GLSL.CreateOut(GLSL.Type.Vec4, VaryingNameDeclarations.Position)
            };

            vertProps.Add(GLSL.CreateIn(GLSL.Type.Vec3, UniformNameDeclarations.Vertex));

            if (effectProps.MeshProbs.HasTangents && effectProps.MeshProbs.HasBiTangents)
            {
                vertProps.Add(GLSL.CreateIn(GLSL.Type.Vec4, UniformNameDeclarations.TangentAttribName));
                vertProps.Add(GLSL.CreateIn(GLSL.Type.Vec3, UniformNameDeclarations.BitangentAttribName));

                vertProps.Add(GLSL.CreateOut(GLSL.Type.Vec4, VaryingNameDeclarations.Tangent));
                vertProps.Add(GLSL.CreateOut(GLSL.Type.Vec3, VaryingNameDeclarations.Bitangent));
            }

            if (effectProps.MatProbs.HasSpecular)
            {
                vertProps.Add(GLSL.CreateOut(GLSL.Type.Vec3, VaryingNameDeclarations.ViewDirection));
            }

            if (effectProps.MeshProbs.HasWeightMap)
            {
                vertProps.Add(GLSL.CreateIn(GLSL.Type.Vec4, UniformNameDeclarations.BoneIndex));
                vertProps.Add(GLSL.CreateIn(GLSL.Type.Vec4, UniformNameDeclarations.BoneWeight));
            }

            if (effectProps.MeshProbs.HasNormals)
            {
                vertProps.Add(GLSL.CreateIn(GLSL.Type.Vec3, UniformNameDeclarations.Normal));
                vertProps.Add(GLSL.CreateOut(GLSL.Type.Vec3, VaryingNameDeclarations.Normal));
            }

            if (effectProps.MeshProbs.HasUVs)
            {
                vertProps.Add(GLSL.CreateIn(GLSL.Type.Vec2, UniformNameDeclarations.TextureCoordinates));
                vertProps.Add(GLSL.CreateOut(GLSL.Type.Vec2, VaryingNameDeclarations.TextureCoordinates));
            }

            if (effectProps.MeshProbs.HasColors)
            {
                vertProps.Add(GLSL.CreateIn(GLSL.Type.Vec4, UniformNameDeclarations.Color));
                vertProps.Add(GLSL.CreateOut(GLSL.Type.Vec4, VaryingNameDeclarations.Color));
            }

            return(string.Join("\n", vertProps));
        }
Пример #13
0
        /// <summary>
        /// Creates the uniform texture parameters for the lighting pass, as used in deferred rendering.
        /// </summary>
        /// <returns></returns>
        public static string DeferredTextureUniforms()
        {
            var uniforms = new List <string>();
            var texCount = 0;

            for (var i = 0; i < UniformNameDeclarations.DeferredRenderTextures.Count; i++)
            {
                var texName = UniformNameDeclarations.DeferredRenderTextures[i];

                uniforms.Add(GLSL.CreateUniform(GLSL.Type.Sampler2D, texName));
                texCount++;
            }
            return(string.Join("\n", uniforms));
        }
Пример #14
0
        /// <summary>
        /// Returns the pre defined Fusee uniform parameters of a fragment shader, depending on the given ShaderEffectProps.
        /// </summary>
        /// <returns></returns>
        public static string FuseeMatrixUniforms()
        {
            var pxFusUniforms = new List <string>
            {
                GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.ModelView),
                GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.IModelView),
                GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.ITView),
                GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.IView),
                GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.View),
                GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.ITModelView)
            };

            return(string.Join("\n", pxFusUniforms));
        }
Пример #15
0
        /// <summary>
        /// Calculates the cone component of the attenuation of a spot light.
        /// </summary>
        /// <returns></returns>
        public static string AttenuationConeComponent()
        {
            var methodBody = new List <string>
            {
                "vec3 coneDir = lightDir;",
                "float lightToSurfaceAngleCos = dot(coneDir, -fragToLightDir);",

                "float epsilon = cos(innerConeAngle) - cos(outerConeAngle);",
                "float t = (lightToSurfaceAngleCos - cos(outerConeAngle)) / epsilon;",
                "return clamp(t, 0.0, 1.0);"
            };

            return(GLSL.CreateMethod(GLSL.Type.Float, "attenuationConeComponent",
                                     new[] { GLSL.CreateVar(GLSL.Type.Vec3, "lightDir"), GLSL.CreateVar(GLSL.Type.Vec3, "fragToLightDir"), GLSL.CreateVar(GLSL.Type.Float, "innerConeAngle"), GLSL.CreateVar(GLSL.Type.Float, "outerConeAngle") }, methodBody));
        }
Пример #16
0
        /// <summary>
        /// Creates the method for calculating whether a fragment is in shadow or not, by using a shadow map (sampler2D).
        /// </summary>
        /// <returns></returns>
        public static string ShadowCalculation()
        {
            var methodBody = new List <string>()
            {
                "float shadow = 0.0;",
                "int pcfLoop = int(pcfKernelHalfSize);",
                "float pcfKernelSize = pcfKernelHalfSize + pcfKernelHalfSize + 1.0;",
                "pcfKernelSize *= pcfKernelSize;",

                "// perform perspective divide",
                "vec4 projCoords = fragPosLightSpace / fragPosLightSpace.w;",
                "projCoords = projCoords * 0.5 + 0.5;",
                "//float closestDepth = texture(shadowMap, projCoords.xy).r;",
                "float currentDepth = projCoords.z;",

                "float thisBias = max(bias * (1.0 - dot(normal, lightDir)), bias / 100.0);",

                "vec2 texelSize = 1.0 / vec2(textureSize(shadowMap, 0));",

                "//use this for using sampler2DShadow (automatic PCF) instead of sampler2D",
                "//float depth = texture(shadowMap, projCoords.xyz).r;",
                "//shadow += (currentDepth - thisBias) > depth ? 1.0 : 0.0;",

                "for (int x = -pcfLoop; x <= pcfLoop; ++x)",
                "{",
                "for (int y = -pcfLoop; y <= pcfLoop; ++y)",
                "{",
                "float pcfDepth = texture(shadowMap, projCoords.xy + vec2(x, y) * texelSize).r;",
                "shadow += (currentDepth - thisBias) > pcfDepth ? 1.0 : 0.0;",
                "}",
                "}",
                "shadow /= pcfKernelSize;",

                "return shadow;"
            };

            return(GLSL.CreateMethod(GLSL.Type.Float, "ShadowCalculation", new[]
            {
                GLSL.CreateVar(GLSL.Type.Sampler2D, "shadowMap"),
                GLSL.CreateVar(GLSL.Type.Vec4, "fragPosLightSpace"),
                GLSL.CreateVar(GLSL.Type.Vec3, "normal"),
                GLSL.CreateVar(GLSL.Type.Vec3, "lightDir"),
                GLSL.CreateVar(GLSL.Type.Float, "bias"),
                GLSL.CreateVar(GLSL.Type.Float, "pcfKernelHalfSize")
            }, methodBody));
        }
Пример #17
0
        private static string CreateDeferredLightingPixelShader(Light lc, bool isCascaded = false, int numberOfCascades = 0, bool debugCascades = false)
        {
            var frag = new StringBuilder();

            frag.Append(HeaderShard.Version300Es);
            frag.Append("#extension GL_ARB_explicit_uniform_location : enable\n");
            frag.Append("#extension GL_ARB_gpu_shader5 : enable\n");
            frag.Append(HeaderShard.EsPrecisionHighpFloat);

            frag.Append(FragPropertiesShard.DeferredTextureUniforms());
            frag.Append(FragPropertiesShard.FuseeMatrixUniforms());

            frag.Append(LightingShard.LightStructDeclaration);
            frag.Append(FragPropertiesShard.DeferredLightAndShadowUniforms(lc, isCascaded, numberOfCascades));

            frag.Append(GLSL.CreateIn(GLSL.Type.Vec2, VaryingNameDeclarations.TextureCoordinates));

            frag.Append(FragPropertiesShard.ColorOut());

            //Shadow calculation methods
            //--------------------------------------
            if (lc.Type != LightType.Point)
            {
                frag.Append(LightingShard.ShadowCalculation());
            }
            else
            {
                frag.Append(LightingShard.ShadowCalculationCubeMap());
            }

            //Lighting methods
            //------------------------------------------
            frag.Append(LightingShard.AmbientComponent());
            frag.Append(LightingShard.SpecularComponent());
            frag.Append(LightingShard.DiffuseComponent());
            frag.Append(LightingShard.AttenuationPointComponent());
            frag.Append(LightingShard.AttenuationConeComponent());

            frag.Append(LightingShard.ApplyLightDeferred(lc, isCascaded, numberOfCascades, debugCascades));

            return(frag.ToString());
        }
Пример #18
0
        /// <summary>
        /// Method for calculation the specular lighting component.
        /// </summary>
        public static string SpecularComponent()
        {
            var methodBody = new List <string>
            {
                "float specularTerm = 0.0;",
                "if(dot(N, L) > 0.0)",
                "{",
                "   // half vector",
                "vec3 reflectDir = reflect(-L, N);",
                $"  specularTerm = pow(max(0.0, dot(V, reflectDir)), shininess);",
                "}",
                "return specularTerm;"
            };

            return(GLSL.CreateMethod(GLSL.Type.Float, "specularLighting",
                                     new[]
            {
                GLSL.CreateVar(GLSL.Type.Vec3, "N"), GLSL.CreateVar(GLSL.Type.Vec3, "L"), GLSL.CreateVar(GLSL.Type.Vec3, "V"),
                GLSL.CreateVar(GLSL.Type.Float, "shininess")
            }, methodBody));
        }
Пример #19
0
        /// <summary>
        /// Creates the uniforms for the deferred lighting pass for one light.
        /// </summary>
        /// <param name="lc">The light component, needed to decide if we have a Shadow Cube Map or a standard shadow map.</param>
        /// <param name="isCascaded">If cascaded shadow mapping is used, this should be set to true.</param>
        /// <param name="numberOfCascades">If cascaded shadow mapping is used this is the number of cascades.</param>
        public static string DeferredLightAndShadowUniforms(Light lc, bool isCascaded, int numberOfCascades)
        {
            var uniforms = new List <string>
            {
                "uniform Light light;"
            };

            if (!isCascaded)
            {
                if (lc.IsCastingShadows)
                {
                    if (lc.Type != LightType.Point)
                    {
                        uniforms.Add(GLSL.CreateUniform(GLSL.Type.Sampler2D, UniformNameDeclarations.ShadowMap));
                    }
                    else
                    {
                        uniforms.Add(GLSL.CreateUniform(GLSL.Type.SamplerCube, UniformNameDeclarations.ShadowCubeMap));
                    }
                }
                uniforms.Add(GLSL.CreateUniform(GLSL.Type.Mat4, UniformNameDeclarations.LightSpaceMatrix));
            }
            else
            {
                //No implementation for GLSL.CreateArrayUniform yet...
                uniforms.Add($"uniform {GLSL.DecodeType(GLSL.Type.Sampler2D)}[{numberOfCascades}] ShadowMaps;\n");
                uniforms.Add($"uniform {GLSL.DecodeType(GLSL.Type.Vec2)}[{numberOfCascades}] ClipPlanes;\n");
                uniforms.Add($"uniform {GLSL.DecodeType(GLSL.Type.Mat4)}[{numberOfCascades}] LightSpaceMatrices;\n");
            }

            uniforms.Add(GLSL.CreateUniform(GLSL.Type.Int, UniformNameDeclarations.RenderPassNo));
            uniforms.Add(GLSL.CreateUniform(GLSL.Type.Int, UniformNameDeclarations.SsaoOn));

            uniforms.Add(GLSL.CreateUniform(GLSL.Type.Vec4, UniformNameDeclarations.BackgroundColor));
            return(string.Join("\n", uniforms));
        }
Пример #20
0
 public static void ValidateType(TypeReference t)
 {
     GLSL.ToGLSL(t); // throws if t is not valid
 }
Пример #21
0
 /// <summary>
 /// Creates a single color (vec4) out parameter.
 /// </summary>
 public static string ColorOut()
 {
     return(GLSL.CreateOut(GLSL.Type.Vec4, OutColorName));
 }
Пример #22
0
        /// <summary>
        /// Wraps all the lighting methods into a single one.
        /// </summary>
        public static string ApplyLightForward(ShaderEffectProps effectProps)
        {
            var bumpNormals = new List <string>
            {
                "///////////////// Normal mapping, tangent space ///////////////////",
                $"vec3 N = ((texture({UniformNameDeclarations.NormalMap}, {VaryingNameDeclarations.TextureCoordinates}).rgb * 2.0) - 1.0f) * vec3({UniformNameDeclarations.NormalMapIntensity}, {UniformNameDeclarations.NormalMapIntensity}, 1.0);",
                $"N = (N.x * vec3({VaryingNameDeclarations.Tangent})) + (N.y * {VaryingNameDeclarations.Bitangent}) + (N.z * {VaryingNameDeclarations.Normal});",
                "N = normalize(N);"
            };

            var normals = new List <string>
            {
                $"vec3 N = normalize({VaryingNameDeclarations.Normal});"
            };

            var fragToLightDirAndLightInit = new List <string>
            {
                "vec3 L = vec3(0.0, 0.0, 0.0);",
                "if(lightType == 1){L = -normalize(direction);}",
                "else",
                "{",
                $"   L = normalize(position - {VaryingNameDeclarations.Position}.xyz);",
                "}",
                $"vec3 V = normalize(-{VaryingNameDeclarations.Position}.xyz);",
                "if(lightType == 3) {",
                "   L = normalize(vec3(0.0,0.0,-1.0));",
                "}",
                $"vec2 o_texcoords = {VaryingNameDeclarations.TextureCoordinates};",
                "",
                "vec3 Idif = vec3(0);",
                "vec3 Ispe = vec3(0);",
                ""
            };

            var applyLightParams = new List <string>();

            applyLightParams.AddRange(effectProps.MatProbs.HasNormalMap ? bumpNormals : normals);
            applyLightParams.AddRange(fragToLightDirAndLightInit);

            if (effectProps.MatProbs.HasAlbedo)
            {
                //TODO: Test alpha blending between diffuse and texture
                if (effectProps.MatProbs.HasAlbedoTexture)
                {
                    applyLightParams.Add(
                        $"vec3 blendedCol = mix({UniformNameDeclarations.AlbedoColor}.rgb, texture({UniformNameDeclarations.AlbedoTexture}, {VaryingNameDeclarations.TextureCoordinates}).rgb, {UniformNameDeclarations.AlbedoMix});" +
                        $"Idif = blendedCol * diffuseLighting(N, L) * intensities.rgb;");
                }
                else
                {
                    applyLightParams.Add($"Idif = vec3({UniformNameDeclarations.AlbedoColor}.rgb * intensities.rgb * diffuseLighting(N, L));");
                }
            }

            if (effectProps.MatProbs.HasSpecular)
            {
                if (effectProps.MatType == MaterialType.Standard)
                {
                    applyLightParams.Add($"float specularTerm = specularLighting(N, L, V, {UniformNameDeclarations.SpecularShininess});");
                    applyLightParams.Add($"Ispe = vec3(({ UniformNameDeclarations.SpecularColor}.rgb * { UniformNameDeclarations.SpecularIntensity} *intensities.rgb) *specularTerm);");
                }
                else if (effectProps.MatType == MaterialType.MaterialPbr)
                {
                    applyLightParams.Add($"float k = 1.0 - {UniformNameDeclarations.DiffuseFraction};");
                    applyLightParams.Add("float specular = specularLighting(N, L, V, k);");
                    applyLightParams.Add($"Ispe = intensities.rgb * {UniformNameDeclarations.SpecularColor}.rgb * (k + specular * (1.0 - k));");
                }
            }

            var pointLight = new List <string>
            {
                $"float att = attenuationPointComponent({VaryingNameDeclarations.Position}.xyz, position, maxDistance);",
                "lighting = (Idif * att) + (Ispe * att);",
                "lighting *= strength;"
            };

            //No attenuation!
            var parallelLight = new List <string>
            {
                "lighting = Idif + Ispe;",
                "lighting *= strength;"
            };

            var spotLight = new List <string>
            {
                $"float att = attenuationPointComponent({VaryingNameDeclarations.Position}.xyz, position, maxDistance) * attenuationConeComponent(direction, L, innerConeAngle, outerConeAngle);",

                "lighting = (Idif * att) + (Ispe * att);",
                "lighting *= strength;"
            };

            // - Disable GammaCorrection for better colors

            /*var gammaCorrection = new List<string>()
             * {
             *  "vec3 gamma = vec3(1.0/2.2);",
             *  "result = pow(result, gamma);"
             * };*/

            var methodBody = new List <string>();

            methodBody.AddRange(applyLightParams);
            methodBody.Add("vec3 lighting = vec3(0);");
            methodBody.Add("");
            //methodBody.AddRange(attenuation);
            methodBody.Add("if(lightType == 0) // PointLight");
            methodBody.Add("{");
            methodBody.AddRange(pointLight);
            methodBody.Add("}");
            methodBody.Add("else if(lightType == 1 || lightType == 3) // ParallelLight or LegacyLight");
            methodBody.Add("{");
            methodBody.AddRange(parallelLight);
            methodBody.Add("}");
            methodBody.Add("else if(lightType == 2) // SpotLight");
            methodBody.Add("{");
            methodBody.AddRange(spotLight);
            methodBody.Add("}");
            methodBody.Add("");
            //methodBody.AddRange(gammaCorrection); // - Disable GammaCorrection for better colors
            methodBody.Add("");

            methodBody.Add("return lighting;");

            return(GLSL.CreateMethod(GLSL.Type.Vec3, "ApplyLight",
                                     new[]
            {
                GLSL.CreateVar(GLSL.Type.Vec3, "position"), GLSL.CreateVar(GLSL.Type.Vec4, "intensities"),
                GLSL.CreateVar(GLSL.Type.Vec3, "direction"), GLSL.CreateVar(GLSL.Type.Float, "maxDistance"),
                GLSL.CreateVar(GLSL.Type.Float, "strength"), GLSL.CreateVar(GLSL.Type.Float, "outerConeAngle"),
                GLSL.CreateVar(GLSL.Type.Float, "innerConeAngle"), GLSL.CreateVar(GLSL.Type.Int, "lightType"),
            }, methodBody));
        }
Пример #23
0
 public override StringBuilder VisitMemberType(MemberType memberType, int data)
 {
     return(new StringBuilder(GLSL.ToGLSL(memberType.Annotation <TypeReference>())));
 }
Пример #24
0
        internal IEnumerable <ASLShaderStruct> GetStructures()
        {
            foreach (var structure in _shader.NestedTypes)
            {
                var           isInterfaceBlock   = structure.HasCustomAttributes && structure.HasAttribute <InterfaceBlockAttribute>();
                TypeReference interfaceBlockType = null;

                if (isInterfaceBlock)
                {
                    var attrs = structure.CustomAttributes.Where(a => a.AttributeType.IsIn() || a.AttributeType.IsOut() || a.AttributeType.IsUniform());
                    if (attrs.Count() == 0)
                    {
                        throw new ASLException("ASL Error: An interface block have to have a qualifier which can be in, out or uniform.");
                    }
                    if (attrs.Count() > 1)
                    {
                        throw new ASLException("ASL Error: An interface block have to have only one qualifier, which can be in, out or uniform.");
                    }
                    interfaceBlockType = attrs.First().AttributeType;
                }

                List <ASLShaderVariable> fields = new List <ASLShaderVariable>();
                foreach (var field in structure.Fields)
                {
                    var           type        = GLSL.ToGLSL(field.FieldType);
                    var           isArray     = field.FieldType.IsArray;
                    var           arrayAttr   = field.CustomAttributes.Where(a => a.AttributeType.Is <ArraySizeAttribute>());
                    var           arraySize   = (isArray && arrayAttr.Count() > 0 && arrayAttr.First().HasConstructorArguments) ? arrayAttr.First().ConstructorArguments.First().Value.ToString() : string.Empty;
                    var           name        = field.Name;
                    var           commentAttr = field.CustomAttributes.Where(a => a.AttributeType.Is <CommentAttribute>());
                    var           u_comment   = (commentAttr.Count() > 0 && commentAttr.First().HasConstructorArguments) ? commentAttr.First().ConstructorArguments.First().Value.ToString() : string.Empty;
                    var           d_comment   = DebugMode ? field.DeclaringType.FullName + "." + field.Name : string.Empty;
                    TypeReference attrType    = null;
                    if (isInterfaceBlock)
                    {
                        var attrs = field.CustomAttributes.Where(a => a.AttributeType.IsIn() || a.AttributeType.IsOut() || a.AttributeType.IsUniform());
                        if (attrs.Count() > 1)
                        {
                            throw new ASLException("ASL Error: An interface block member have to have only one qualifier, which can be in, out or uniform, according to the interface block qualifier.");
                        }
                        if (attrs.Count() > 0)
                        {
                            if ((interfaceBlockType.IsIn() && (attrs.First().AttributeType.IsOut() || attrs.First().AttributeType.IsUniform())) || (interfaceBlockType.IsUniform() && (attrs.First().AttributeType.IsOut() || attrs.First().AttributeType.IsIn())) || (interfaceBlockType.IsOut() && (attrs.First().AttributeType.IsIn() || attrs.First().AttributeType.IsUniform())))
                            {
                                throw new ASLException("ASL Error: An interface block member have to have (if he has one) a similar qualifier than the interface block.");
                            }
                            attrType = attrs.First().AttributeType;
                        }
                    }
                    var varLayoutAttr = (this is VertexShader) ? field.CustomAttributes.Where(a => a.AttributeType.Is <VertexShader.LayoutAttribute>()) :
                                        ((this is FragmentShader) ? field.CustomAttributes.Where(a => a.AttributeType.Is <FragmentShader.LayoutAttribute>()) :
                                         ((this is GeometryShader) ? field.CustomAttributes.Where(a => a.AttributeType.Is <GeometryShader.LayoutAttribute>()) : null));
                    var varLayout = (varLayoutAttr != null && varLayoutAttr.Count() > 0) ? varLayoutAttr.First() : null;
                    fields.Add(new ASLShaderVariable(type, isArray, arraySize, name, u_comment, d_comment, attrType, varLayout));
                }

                var layoutAttr = (this is VertexShader) ? structure.CustomAttributes.Where(a => a.AttributeType.Is <VertexShader.LayoutAttribute>()) :
                                 ((this is FragmentShader) ? structure.CustomAttributes.Where(a => a.AttributeType.Is <FragmentShader.LayoutAttribute>()) :
                                  ((this is GeometryShader) ? structure.CustomAttributes.Where(a => a.AttributeType.Is <GeometryShader.LayoutAttribute>()) : null));
                var layout = (layoutAttr != null && layoutAttr.Count() > 0) ? layoutAttr.First() : null;

                yield return(new ASLShaderStruct(structure.Name, isInterfaceBlock, interfaceBlockType, fields, layout));
            }
        }