Search in sources :

Example 31 with Shader

use of com.jme3.shader.Shader in project jmonkeyengine by jMonkeyEngine.

the class GLSLLoader method loadNode.

/**
     * Creates a {@link ShaderDependencyNode} from a stream representing shader code.
     * 
     * @param in The input stream containing shader code
     * @param nodeName
     * @return
     * @throws IOException 
     */
private ShaderDependencyNode loadNode(Reader reader, String nodeName) {
    ShaderDependencyNode node = new ShaderDependencyNode(nodeName);
    StringBuilder sb = new StringBuilder();
    StringBuilder sbExt = new StringBuilder();
    BufferedReader bufReader = null;
    try {
        bufReader = new BufferedReader(reader);
        String ln;
        if (!nodeName.equals("[main]")) {
            sb.append("// -- begin import ").append(nodeName).append(" --\n");
        }
        while ((ln = bufReader.readLine()) != null) {
            if (ln.trim().startsWith("#import ")) {
                ln = ln.trim().substring(8).trim();
                if (ln.startsWith("\"") && ln.endsWith("\"") && ln.length() > 3) {
                    // import user code
                    // remove quotes to get filename
                    ln = ln.substring(1, ln.length() - 1);
                    if (ln.equals(nodeName)) {
                        throw new IOException("Node depends on itself.");
                    }
                    // check cache first
                    ShaderDependencyNode dependNode = dependCache.get(ln);
                    if (dependNode == null) {
                        Reader dependNodeReader = assetManager.loadAsset(new ShaderDependencyKey(ln));
                        dependNode = loadNode(dependNodeReader, ln);
                    }
                    node.addDependency(sb.length(), dependNode);
                }
            } else if (ln.trim().startsWith("#extension ")) {
                sbExt.append(ln).append('\n');
            } else {
                sb.append(ln).append('\n');
            }
        }
        if (!nodeName.equals("[main]")) {
            sb.append("// -- end import ").append(nodeName).append(" --\n");
        }
    } catch (IOException ex) {
        if (bufReader != null) {
            try {
                bufReader.close();
            } catch (IOException ex1) {
            }
        }
        throw new AssetLoadException("Failed to load shader node: " + nodeName, ex);
    }
    node.setSource(sb.toString());
    node.setExtensions(sbExt.toString());
    dependCache.put(nodeName, node);
    return node;
}
Also used : BufferedReader(java.io.BufferedReader) BufferedReader(java.io.BufferedReader) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) IOException(java.io.IOException) AssetLoadException(com.jme3.asset.AssetLoadException)

Example 32 with Shader

use of com.jme3.shader.Shader in project jmonkeyengine by jMonkeyEngine.

the class GLRenderer method updateShaderData.

public void updateShaderData(Shader shader) {
    int id = shader.getId();
    boolean needRegister = false;
    if (id == -1) {
        // create program
        id = gl.glCreateProgram();
        if (id == 0) {
            throw new RendererException("Invalid ID (" + id + ") received when trying to create shader program.");
        }
        shader.setId(id);
        needRegister = true;
    }
    // If using GLSL 1.5, we bind the outputs for the user
    // For versions 3.3 and up, user should use layout qualifiers instead.
    boolean bindFragDataRequired = false;
    for (ShaderSource source : shader.getSources()) {
        if (source.isUpdateNeeded()) {
            updateShaderSourceData(source);
        }
        if (source.getType() == ShaderType.Fragment && source.getLanguage().equals("GLSL150")) {
            bindFragDataRequired = true;
        }
        gl.glAttachShader(id, source.getId());
    }
    if (bindFragDataRequired) {
        // Check if GLSL version is 1.5 for shader
        gl3.glBindFragDataLocation(id, 0, "outFragColor");
        // For MRT
        for (int i = 0; i < limits.get(Limits.FrameBufferMrtAttachments); i++) {
            gl3.glBindFragDataLocation(id, i, "outFragData[" + i + "]");
        }
    }
    // Link shaders to program
    gl.glLinkProgram(id);
    // Check link status
    gl.glGetProgram(id, GL.GL_LINK_STATUS, intBuf1);
    boolean linkOK = intBuf1.get(0) == GL.GL_TRUE;
    String infoLog = null;
    if (VALIDATE_SHADER || !linkOK) {
        gl.glGetProgram(id, GL.GL_INFO_LOG_LENGTH, intBuf1);
        int length = intBuf1.get(0);
        if (length > 3) {
            // get infos
            infoLog = gl.glGetProgramInfoLog(id, length);
        }
    }
    if (linkOK) {
        if (infoLog != null) {
            logger.log(Level.WARNING, "Shader linked successfully. Linker warnings: \n{0}", infoLog);
        } else {
            logger.fine("Shader linked successfully.");
        }
        shader.clearUpdateNeeded();
        if (needRegister) {
            // Register shader for clean up if it was created in this method.
            objManager.registerObject(shader);
            statistics.onNewShader();
        } else {
            // OpenGL spec: uniform locations may change after re-link
            resetUniformLocations(shader);
        }
    } else {
        if (infoLog != null) {
            throw new RendererException("Shader failed to link, shader:" + shader + "\n" + infoLog);
        } else {
            throw new RendererException("Shader failed to link, shader:" + shader + "\ninfo: <not provided>");
        }
    }
}
Also used : ShaderSource(com.jme3.shader.Shader.ShaderSource)

Example 33 with Shader

use of com.jme3.shader.Shader in project jmonkeyengine by jMonkeyEngine.

the class SinglePassAndImageBasedLightingLogic method updateLightListUniforms.

/**
     * Uploads the lights in the light list as two uniform arrays.<br/><br/> *
     * <p>
     * <code>uniform vec4 g_LightColor[numLights];</code><br/> //
     * g_LightColor.rgb is the diffuse/specular color of the light.<br/> //
     * g_Lightcolor.a is the type of light, 0 = Directional, 1 = Point, <br/> //
     * 2 = Spot. <br/> <br/>
     * <code>uniform vec4 g_LightPosition[numLights];</code><br/> //
     * g_LightPosition.xyz is the position of the light (for point lights)<br/>
     * // or the direction of the light (for directional lights).<br/> //
     * g_LightPosition.w is the inverse radius (1/r) of the light (for
     * attenuation) <br/> </p>
     */
protected int updateLightListUniforms(Shader shader, Geometry g, LightList lightList, int numLights, RenderManager rm, int startIndex, int lastTexUnit) {
    if (numLights == 0) {
        // this shader does not do lighting, ignore.
        return 0;
    }
    Uniform lightData = shader.getUniform("g_LightData");
    //8 lights * max 3
    lightData.setVector4Length(numLights * 3);
    Uniform ambientColor = shader.getUniform("g_AmbientLightColor");
    Uniform lightProbeData = shader.getUniform("g_LightProbeData");
    lightProbeData.setVector4Length(1);
    Uniform lightProbeIrrMap = shader.getUniform("g_IrradianceMap");
    Uniform lightProbePemMap = shader.getUniform("g_PrefEnvMap");
    lightProbe = null;
    if (startIndex != 0) {
        // apply additive blending for 2nd and future passes
        rm.getRenderer().applyRenderState(ADDITIVE_LIGHT);
        ambientColor.setValue(VarType.Vector4, ColorRGBA.Black);
    } else {
        lightProbe = extractIndirectLights(lightList, true);
        ambientColor.setValue(VarType.Vector4, ambientLightColor);
    }
    //If there is a lightProbe in the list we force it's render on the first pass
    if (lightProbe != null) {
        BoundingSphere s = (BoundingSphere) lightProbe.getBounds();
        lightProbeData.setVector4InArray(lightProbe.getPosition().x, lightProbe.getPosition().y, lightProbe.getPosition().z, 1f / s.getRadius(), 0);
        //assigning new texture indexes
        int irrUnit = lastTexUnit++;
        int pemUnit = lastTexUnit++;
        rm.getRenderer().setTexture(irrUnit, lightProbe.getIrradianceMap());
        lightProbeIrrMap.setValue(VarType.Int, irrUnit);
        rm.getRenderer().setTexture(pemUnit, lightProbe.getPrefilteredEnvMap());
        lightProbePemMap.setValue(VarType.Int, pemUnit);
    } else {
        //Disable IBL for this pass
        lightProbeData.setVector4InArray(0, 0, 0, -1, 0);
    }
    int lightDataIndex = 0;
    TempVars vars = TempVars.get();
    Vector4f tmpVec = vars.vect4f1;
    int curIndex;
    int endIndex = numLights + startIndex;
    for (curIndex = startIndex; curIndex < endIndex && curIndex < lightList.size(); curIndex++) {
        Light l = lightList.get(curIndex);
        if (l.getType() == Light.Type.Ambient) {
            endIndex++;
            continue;
        }
        ColorRGBA color = l.getColor();
        if (l.getType() != Light.Type.Probe) {
            lightData.setVector4InArray(color.getRed(), color.getGreen(), color.getBlue(), l.getType().getId(), lightDataIndex);
            lightDataIndex++;
        }
        switch(l.getType()) {
            case Directional:
                DirectionalLight dl = (DirectionalLight) l;
                Vector3f dir = dl.getDirection();
                //Data directly sent in view space to avoid a matrix mult for each pixel
                tmpVec.set(dir.getX(), dir.getY(), dir.getZ(), 0.0f);
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), -1, lightDataIndex);
                lightDataIndex++;
                //PADDING
                lightData.setVector4InArray(0, 0, 0, 0, lightDataIndex);
                lightDataIndex++;
                break;
            case Point:
                PointLight pl = (PointLight) l;
                Vector3f pos = pl.getPosition();
                float invRadius = pl.getInvRadius();
                tmpVec.set(pos.getX(), pos.getY(), pos.getZ(), 1.0f);
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRadius, lightDataIndex);
                lightDataIndex++;
                //PADDING
                lightData.setVector4InArray(0, 0, 0, 0, lightDataIndex);
                lightDataIndex++;
                break;
            case Spot:
                SpotLight sl = (SpotLight) l;
                Vector3f pos2 = sl.getPosition();
                Vector3f dir2 = sl.getDirection();
                float invRange = sl.getInvSpotRange();
                float spotAngleCos = sl.getPackedAngleCos();
                tmpVec.set(pos2.getX(), pos2.getY(), pos2.getZ(), 1.0f);
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRange, lightDataIndex);
                lightDataIndex++;
                tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0.0f);
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos, lightDataIndex);
                lightDataIndex++;
                break;
            default:
                throw new UnsupportedOperationException("Unknown type of light: " + l.getType());
        }
    }
    vars.release();
    //Padding of unsued buffer space
    while (lightDataIndex < numLights * 3) {
        lightData.setVector4InArray(0f, 0f, 0f, 0f, lightDataIndex);
        lightDataIndex++;
    }
    return curIndex;
}
Also used : BoundingSphere(com.jme3.bounding.BoundingSphere) TempVars(com.jme3.util.TempVars)

Example 34 with Shader

use of com.jme3.shader.Shader in project jmonkeyengine by jMonkeyEngine.

the class SinglePassLightingLogic method render.

@Override
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, int lastTexUnit) {
    int nbRenderedLights = 0;
    Renderer renderer = renderManager.getRenderer();
    int batchSize = renderManager.getSinglePassLightBatchSize();
    if (lights.size() == 0) {
        updateLightListUniforms(shader, geometry, lights, batchSize, renderManager, 0);
        renderer.setShader(shader);
        renderMeshFromGeometry(renderer, geometry);
    } else {
        while (nbRenderedLights < lights.size()) {
            nbRenderedLights = updateLightListUniforms(shader, geometry, lights, batchSize, renderManager, nbRenderedLights);
            renderer.setShader(shader);
            renderMeshFromGeometry(renderer, geometry);
        }
    }
}
Also used : Renderer(com.jme3.renderer.Renderer)

Example 35 with Shader

use of com.jme3.shader.Shader in project jmonkeyengine by jMonkeyEngine.

the class SinglePassLightingLogic method updateLightListUniforms.

/**
     * Uploads the lights in the light list as two uniform arrays.<br/><br/> *
     * <p>
     * <code>uniform vec4 g_LightColor[numLights];</code><br/> //
     * g_LightColor.rgb is the diffuse/specular color of the light.<br/> //
     * g_Lightcolor.a is the type of light, 0 = Directional, 1 = Point, <br/> //
     * 2 = Spot. <br/> <br/>
     * <code>uniform vec4 g_LightPosition[numLights];</code><br/> //
     * g_LightPosition.xyz is the position of the light (for point lights)<br/>
     * // or the direction of the light (for directional lights).<br/> //
     * g_LightPosition.w is the inverse radius (1/r) of the light (for
     * attenuation) <br/> </p>
     */
protected int updateLightListUniforms(Shader shader, Geometry g, LightList lightList, int numLights, RenderManager rm, int startIndex) {
    if (numLights == 0) {
        // this shader does not do lighting, ignore.
        return 0;
    }
    Uniform lightData = shader.getUniform("g_LightData");
    //8 lights * max 3
    lightData.setVector4Length(numLights * 3);
    Uniform ambientColor = shader.getUniform("g_AmbientLightColor");
    if (startIndex != 0) {
        // apply additive blending for 2nd and future passes
        rm.getRenderer().applyRenderState(ADDITIVE_LIGHT);
        ambientColor.setValue(VarType.Vector4, ColorRGBA.Black);
    } else {
        ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList, true, ambientLightColor));
    }
    int lightDataIndex = 0;
    TempVars vars = TempVars.get();
    Vector4f tmpVec = vars.vect4f1;
    int curIndex;
    int endIndex = numLights + startIndex;
    for (curIndex = startIndex; curIndex < endIndex && curIndex < lightList.size(); curIndex++) {
        Light l = lightList.get(curIndex);
        if (l.getType() == Light.Type.Ambient) {
            endIndex++;
            continue;
        }
        ColorRGBA color = l.getColor();
        //Color
        lightData.setVector4InArray(color.getRed(), color.getGreen(), color.getBlue(), l.getType().getId(), lightDataIndex);
        lightDataIndex++;
        switch(l.getType()) {
            case Directional:
                DirectionalLight dl = (DirectionalLight) l;
                Vector3f dir = dl.getDirection();
                //Data directly sent in view space to avoid a matrix mult for each pixel
                tmpVec.set(dir.getX(), dir.getY(), dir.getZ(), 0.0f);
                rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
                //                        tmpVec.divideLocal(tmpVec.w);
                //                        tmpVec.normalizeLocal();
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), -1, lightDataIndex);
                lightDataIndex++;
                //PADDING
                lightData.setVector4InArray(0, 0, 0, 0, lightDataIndex);
                lightDataIndex++;
                break;
            case Point:
                PointLight pl = (PointLight) l;
                Vector3f pos = pl.getPosition();
                float invRadius = pl.getInvRadius();
                tmpVec.set(pos.getX(), pos.getY(), pos.getZ(), 1.0f);
                rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
                //tmpVec.divideLocal(tmpVec.w);
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRadius, lightDataIndex);
                lightDataIndex++;
                //PADDING
                lightData.setVector4InArray(0, 0, 0, 0, lightDataIndex);
                lightDataIndex++;
                break;
            case Spot:
                SpotLight sl = (SpotLight) l;
                Vector3f pos2 = sl.getPosition();
                Vector3f dir2 = sl.getDirection();
                float invRange = sl.getInvSpotRange();
                float spotAngleCos = sl.getPackedAngleCos();
                tmpVec.set(pos2.getX(), pos2.getY(), pos2.getZ(), 1.0f);
                rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
                // tmpVec.divideLocal(tmpVec.w);
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRange, lightDataIndex);
                lightDataIndex++;
                //We transform the spot direction in view space here to save 5 varying later in the lighting shader
                //one vec4 less and a vec4 that becomes a vec3
                //the downside is that spotAngleCos decoding happens now in the frag shader.
                tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0.0f);
                rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
                tmpVec.normalizeLocal();
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos, lightDataIndex);
                lightDataIndex++;
                break;
            case Probe:
                break;
            default:
                throw new UnsupportedOperationException("Unknown type of light: " + l.getType());
        }
    }
    vars.release();
    //Padding of unsued buffer space
    while (lightDataIndex < numLights * 3) {
        lightData.setVector4InArray(0f, 0f, 0f, 0f, lightDataIndex);
        lightDataIndex++;
    }
    return curIndex;
}
Also used : Vector4f(com.jme3.math.Vector4f) ColorRGBA(com.jme3.math.ColorRGBA) DirectionalLight(com.jme3.light.DirectionalLight) SpotLight(com.jme3.light.SpotLight) Light(com.jme3.light.Light) PointLight(com.jme3.light.PointLight) DirectionalLight(com.jme3.light.DirectionalLight) Vector3f(com.jme3.math.Vector3f) Uniform(com.jme3.shader.Uniform) TempVars(com.jme3.util.TempVars) PointLight(com.jme3.light.PointLight) SpotLight(com.jme3.light.SpotLight)

Aggregations

Uniform (com.jme3.shader.Uniform)8 Renderer (com.jme3.renderer.Renderer)6 Caps (com.jme3.renderer.Caps)5 DirectionalLight (com.jme3.light.DirectionalLight)4 PointLight (com.jme3.light.PointLight)4 SpotLight (com.jme3.light.SpotLight)4 Material (com.jme3.material.Material)4 Vector3f (com.jme3.math.Vector3f)4 Shader (com.jme3.shader.Shader)4 IOException (java.io.IOException)4 ShaderNodeDefinitionKey (com.jme3.asset.ShaderNodeDefinitionKey)3 Light (com.jme3.light.Light)3 ColorRGBA (com.jme3.math.ColorRGBA)3 ShaderType (com.jme3.shader.Shader.ShaderType)3 VarType (com.jme3.shader.VarType)3 TempVars (com.jme3.util.TempVars)3 Statement (com.jme3.util.blockparser.Statement)3 AssetLoadException (com.jme3.asset.AssetLoadException)2 AssetNotFoundException (com.jme3.asset.AssetNotFoundException)2 MatParam (com.jme3.material.MatParam)2