private void PSPBRBody(StringBuilder ps, MaterialPBRComponent mpbr) { ParseLights(ps); AddNormalVec(ps); AddCameraVec(ps); if (!_hasSpecular) { ps.Append(" varying vec3 vViewDir;\n"); } AddcooktorrancePBRMat(ps, mpbr); ps.Append("\n\n void main()\n {\n"); ps.Append(" vec3 result = vec3(0, 0, 0);\n\n"); // ApplyLight() is always called ps.Append("\n for(int i = 0; i < 3000; i++) { \n "); ps.Append("\n if(i > MAX_LIGHTS) break; \n "); ps.Append("\n result += ApplyLight(allLights[i]); \n "); ps.Append("\n vec3 gamma = vec3(1.0/2.2);\n "); ps.Append("\n vec3 final_light = pow(result, gamma); \n "); ps.Append("\n gl_FragColor = vec4(final_light, 1.0);\n"); ps.Append(" }\n\n"); }
public void ConvMaterial(MaterialPBRComponent matComp) { var effect = LookupMaterial(matComp); _currentNode.Components.Add(new ShaderEffectComponent { Effect = effect }); }
private ShaderEffect LookupMaterial(MaterialPBRComponent mc) { if (_pbrComponent.TryGetValue(mc, out var mat)) { return(mat); } mat = ShaderCodeBuilder.MakeShaderEffectFromMatComp(mc, _currentNode.GetWeights()); _pbrComponent.Add(mc, mat); return(mat); }
/* * struct SurfaceOutput { * half3 Albedo; * half3 Normal; * half3 Emission; * half Specular; * half Gloss; * half Alpha; * }; */ /// <summary> /// If we have a MaterialPBRComponent this constructor is called. /// </summary> /// <param name="mlc">The MaterialLightComponent</param> /// <param name="pbrMaterialPbrComponent"></param> /// <param name="mesh">The Mesh</param> /// <param name="wc">WeightCompoennt for animations</param> public LegacyShaderCodeBuilder(MaterialPBRComponent pbrMaterialPbrComponent, Mesh mesh, WeightComponent wc = null) { // Check WC if (wc != null) { _hasWeightMap = true; _nBones = wc.Joints.Count; } else { _nBones = 0; } //float f1 = 1; //var type = f1.GetType(); _normalizeNormals = true; // Check for mesh if (mesh != null) { AnalyzeMesh(mesh); } else { _hasVertices = _hasNormals = _hasUVs = true; } // Analyze the Material AnalyzeMaterial(pbrMaterialPbrComponent); // VS StringBuilder vs = new StringBuilder(); MeshInputDeclarations(vs); MatrixDeclarations(vs); VSBody(vs); _vs = vs.ToString(); // PS StringBuilder ps = new StringBuilder(); PixelInputDeclarations(ps); PSPBRBody(ps, pbrMaterialPbrComponent); _ps = ps.ToString(); }
private void AnalyzeMaterial(MaterialPBRComponent mlc) { _hasDiffuse = mlc.HasDiffuse; if (_hasDiffuse) { _hasDiffuseTexture = (mlc.Diffuse.Texture != null); } _hasSpecular = mlc.HasSpecular; if (_hasSpecular) { _hasSpecularTexture = (mlc.Specular.Texture != null); } _hasEmissive = mlc.HasEmissive; if (_hasEmissive) { _hasEmissiveTexture = (mlc.Emissive.Texture != null); } _hasBump = mlc.HasBump; // always has a texture... }
private void AddcooktorrancePBRMat(StringBuilder ps, MaterialPBRComponent mpbr) { /* * * uniform struct Light { * vec4 position; * vec3 intensities; * float attenuation; * float ambientCoefficient; * float coneAngle; * vec3 coneDirection; * float lightType; * } allLights[MAX_LIGHTS]; * * * SpecularBaseColor * light.intensities * light.ambientCoefficient * SpecularIntensity * DiffuseBaseColor * */ if (_hasEmissive) { ps.Append("\n\n //*********** Emissive *********\n"); AddChannelBaseColorCalculation(ps, _hasEmissiveTexture, "Emissive"); } ps.Append("\n\n //*********** DIFFUSE *********\n"); AddChannelBaseColorCalculation(ps, _hasDiffuseTexture, "Diffuse"); ps.Append("\n\n //*********** Specular *********\n"); AddChannelBaseColorCalculation(ps, _hasSpecularTexture, "Specular"); // needed for spotlight ps.Append("\n\n varying vec4 surfacePos; \n"); ps.Append("\n\n varying mat4 FUSEE_ITMV; \n"); // needed for CookTorrance ps.Append("\n\n varying vec3 oNormal; \n"); // TODO: Vars from SceneRenderer. ps.Append("vec3 ApplyLight(Light light) { \n\n"); ps.Append(" \n\n" + "float roughnessValue = "); // CultureInfo needed for float conversion fullstop, otherwise he formats floats to: #,## ps.AppendFormat("{0} ;\n", mpbr.RoughnessValue.ToString("00000.00", CultureInfo.InvariantCulture)); ps.AppendFormat("float F0 = {0};\n", mpbr.FresnelReflectance.ToString("00000.00", CultureInfo.InvariantCulture)); ps.AppendFormat("float k = {0};\n", mpbr.DiffuseFraction.ToString("00000.00", CultureInfo.InvariantCulture)); ps.Append("vec3 lightColor = light.intensities;\n\n" + "vec3 normal = Normal;\n\n" + "// do the lighting calculation for each fragment.\n" + "float NdotL = max(dot(normal, normalize(Camera)), 0.0);\n\n" + " float specular = 0.0;\n\n" + "if(NdotL > 0.0) {\n\n" + "vec3 eyeDir = vViewDir;\n" + "// calculate intermediary values\n" + "vec3 halfVector = normalize(eyeDir + Camera);\n" + "float NdotH = max(dot(normal, halfVector), 0.0); \n" + "float NdotV = max(dot(normal, eyeDir), 0.0); // note: this could also be NdotL, which is the same value\n" + "float VdotH = max(dot(eyeDir, halfVector), 0.0);\n" + "float mSquared = roughnessValue * roughnessValue;\n\n" + "// geometric attenuation\n" + "float NH2 = 2.0 * NdotH;\n" + "float g1 = (NH2 * NdotV) / VdotH;\n" + "float g2 = (NH2 * NdotL) / VdotH;\n" + "float geoAtt = min(1.0, min(g1, g2));\n\n" + " // roughness (or: microfacet distribution function)\n" + " // beckmann distribution function\n" + "float r1 = 1.0 / ( 4.0 * mSquared * pow(NdotH, 4.0));\n" + "float r2 = (NdotH * NdotH - 1.0) / (mSquared * NdotH * NdotH);\n" + "float roughness = r1 * exp(r2);\n\n" + "// fresnel - Schlick approximation\n" + "float fresnel = pow(1.0 - VdotH, 5.0);\n" + "fresnel *= (1.0 - F0);\n" + "fresnel += F0;\n" + "specular = SpecularBaseColor * ( (fresnel * geoAtt * roughness) / (NdotV * NdotL * 3.14));\n\n" + "}\n\n" + "return light.ambientCoefficient * DiffuseBaseColor * lightColor * NdotL * (k + specular * (1.0 - k));\n"); ps.Append("} \n\n"); }