protected String buildShader(List<ShaderNode> shaderNodes, ShaderGenerationInfo info, ShaderType type) {
        if (type == ShaderType.TessellationControl ||
            type == ShaderType.TessellationEvaluation ||
            type == ShaderType.Geometry) {
            // TODO: Those are not supported.
            // Too much code assumes that type is either Vertex or Fragment
            return null;
        }

        imports.clear();

        indent = 0;

        StringBuilder sourceDeclaration = new StringBuilder();
        StringBuilder source = new StringBuilder();

        generateUniforms(sourceDeclaration, info, type);

        if (type == ShaderType.Vertex) {
            generateAttributes(sourceDeclaration, info);
        }
        generateVaryings(sourceDeclaration, info, type);

        generateStartOfMainSection(source, info, type);

        generateDeclarationAndMainBody(shaderNodes, sourceDeclaration, source, info, type);

        generateEndOfMainSection(source, info, type);

        //insert imports backward
        int insertIndex = sourceDeclaration.length();
        for (String importSource : imports.values()) {
            sourceDeclaration.insert(insertIndex, importSource);
        }

        sourceDeclaration.append(source);

        return moveExtensionsUp(sourceDeclaration);
    }
This method is responsible for the shader generation.

@param shaderNodes the list of shader nodes
@param info the ShaderGenerationInfo filled during the Technique loading
@param type the type of shader to generate
@return the code of the generated vertex shader
jme3-core/src/main/java/com/jme3/shader/ShaderGenerator.java