[WIP] Atmospheric Scattering and Motion Blur (30 posts)

  • Profile picture of kwando kwando80p said 5 months, 2 weeks ago:

    This is a short wip of two shader effect I’d like to contribute to this project with.

    Atmospheric scattering as a dynamic skydome and post process scattering filter and motion blur as a post processing filter effect.

  • Profile picture of glaucomardano glaucomardano252p said 5 months, 2 weeks ago:

    Very nice! The motion blur looks like in Resident Evil 5 :D

  • Profile picture of pspeed pspeed815p said 5 months, 2 weeks ago:

    You motion blur looks very nice. :)

  • Profile picture of iamcreasy iamcreasy62p said 5 months, 2 weeks ago:

    Good job!

    What’s the basic logic behind Atmospheric scattering? Is it a light gradient overlay?

    You might want to do a little benchmark with both the motion blur we have right now :P Yours one looks very cool!

  • Profile picture of kwando kwando80p said 5 months, 2 weeks ago:

    The use of this motionblur implementation is sadly rather limited. It depends on camera movement and does not handle camera rotation or moving objects really well. I think it could be used in some flight or car simulation where camera rotation is not that negligible.

    @iamcreasy

    I’m using Hoffman and Preetham model for areal perspective. The sky is rendered as a small sphere before everything else is rendered. The sky colors are calculated in real time inside the vertex shader and then interpolated. Colors are based on optical density (essentially how much air a given light ray has travelled through) and the angle sun. I have plenty of references if someone is interrested.

  • Profile picture of iamcreasy iamcreasy62p said 5 months, 2 weeks ago:

    some basic reference would be great :)

  • Profile picture of kwando kwando80p said 5 months, 2 weeks ago:

    http://developer.amd.com/media/gpu_assets/GDC_02_HoffmanPreetham.pdf

    http://developer.amd.com/media/gpu_assets/ATI-LightScattering.pdf

    The basics can be found in the links above.

    Following article helped me understanding even though the implementation it’s not the same =)

  • Profile picture of pspeed pspeed815p said 5 months, 2 weeks ago:

    For the motion blur… do you have a basic estimate on what the frame hit is?

  • Profile picture of kwando kwando80p said 5 months, 2 weeks ago:

    Unlit HelloTerrain and atmospheric scattering, MotionBlur stats:

    16 samples ~390 fps
    8 samples ~420 fps
    1 sample ~420 fps
    No filter ~620 fps

    @2560×1440, 32bpp, 8xAA

    I think most of the cost is due to an extra post processing filter.

  • Profile picture of pspeed pspeed815p said 5 months, 2 weeks ago:

    Yeah, very reasonable.

  • Profile picture of pspeed pspeed815p said 5 months, 2 weeks ago:

    Any chance we can see the code? It might be worth incorporating into the core post processing effects.

    …and also, I’m interesting in potentially using the motion blur in Mythruna. :) Seems like it would be good for flying.

  • Profile picture of kwando kwando80p said 5 months, 2 weeks ago:

    @pspeed, sure =)

    MotionBlurFilter.java

    package motionblur;
    
    import com.jme3.asset.AssetManager;
    import com.jme3.material.Material;
    import com.jme3.math.FastMath;
    import com.jme3.math.Matrix4f;
    import com.jme3.post.Filter;
    import com.jme3.renderer.RenderManager;
    import com.jme3.renderer.ViewPort;
    import com.jme3.texture.FrameBuffer;
    
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    /**
     *
     * @author kwando
     */
    public class MotionBlurFilter extends Filter {
    
        private float strength;
        private float blendAmount;
    
        private ViewPort vp;
        private Matrix4f lastProjectionMatrix;
        private Matrix4f currentProjectionMatrix;
    
        @Override
        protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
            material = new Material(manager, "MatDefs/2D/MotionBlur.j3md");
            this.vp = vp;
            setStrength(1.3f);
            setBlendAmount(1f);
        }
    
        @Override
        protected Material getMaterial() {
            return material;
        }
    
        @Override
        protected boolean isRequiresDepthTexture() {
            return true;
        }
    
        public float getStrength() {
            return strength;
        }
    
        public void setStrength(float strength) {
            material.setFloat("Strength", strength);
            this.strength = strength;
        }
    
        public float getBlendAmount() {
            return blendAmount;
        }
    
        public void setBlendAmount(float blendAmount) {
            blendAmount = FastMath.clamp(blendAmount, 0f, 1f);
            material.setFloat("BlendAmount", blendAmount);
            this.blendAmount = blendAmount;
        }
    
        @Override
        protected void postFrame(RenderManager renderManager, ViewPort viewPort, FrameBuffer prevFilterBuffer, FrameBuffer sceneBuffer) {
            lastProjectionMatrix = currentProjectionMatrix;
            currentProjectionMatrix = vp.getCamera().getViewProjectionMatrix().clone();
            if (lastProjectionMatrix == null) {
                lastProjectionMatrix = currentProjectionMatrix;
            }
            material.setMatrix4("ViewProjectionInverse", currentProjectionMatrix.invert());
            material.setMatrix4("LastViewProjection", lastProjectionMatrix);
        }
    }
    

    MotionBlur.j3md

    MaterialDef MotionBlur {
    
        MaterialParameters {
            Texture2D Texture
            Texture2D DepthTexture
            Matrix4 ViewProjectionInverse
            Matrix4 LastViewProjection
            Float Strength
            Float BlendAmount
        }
    
        Technique {
            VertexShader GLSL100:   Shaders/2D/MotionBlur.vert
            FragmentShader GLSL100: Shaders/2D/MotionBlur.frag
    
            WorldParameters {
                FrameRate
            }
        }
    
    }
    

    Shaders
    Vertex Shader

    attribute vec4 inPosition;
    attribute vec2 inTexCoord;
    varying vec2 texCoord;
    
    void main() {
        gl_Position = inPosition * 2.0 - 1.0; //vec4(pos, 0.0, 1.0);
        texCoord = inTexCoord;
    }
    

    Fragment Shader

    uniform sampler2D m_DepthTexture;
    uniform sampler2D m_Texture;
    uniform mat4 m_ViewProjectionInverse;
    uniform mat4 m_LastViewProjection;
    uniform float g_FrameRate;
    uniform float m_Strength;
    uniform float m_BlendAmount;
    
    varying vec2 texCoord;
    
    void main() {
        float z = texture2D(m_DepthTexture, texCoord).r;
        vec4 H = vec4(texCoord*2.0-1.0, z * 2.0 -1.0, 1.0);
        vec4 D = m_ViewProjectionInverse*H;
        vec4 worldPos = D / D.w;
        vec4 color = worldPos;
    
        vec4 currentPos = H;
        vec4 previousPos = m_LastViewProjection * worldPos;
        previousPos = previousPos / previousPos.w;
    
        vec2 velocity = (currentPos - previousPos).xy*-45.0/g_FrameRate * m_Strength;
    
        vec4 realColor = color = texture2D(m_Texture, texCoord);
        int samples = 16;
        vec2 deltaTc = velocity/float(samples);
        vec2 tc = texCoord + deltaTc;
        for(int i = 0; i < samples; i++){
            tc.x = clamp(tc.x, 0.0, 1.0);
            tc.y = clamp(tc.y, 0.0, 1.0);
            vec4 cColor = texture2D(m_Texture, tc);
            color += cColor;
            tc += deltaTc;
        }
        gl_FragColor = mix(realColor,(color / float(samples + 1)), m_BlendAmount);
    }
    
  • Profile picture of androlo androlo323p said 5 months, 2 weeks ago:

    @kwando said:

    I’m using Hoffman and Preetham model for areal perspective. The sky is rendered as a small sphere before everything else is rendered. The sky colors are calculated in real time inside the vertex shader and then interpolated. Colors are based on optical density (essentially how much air a given light ray has travelled through) and the angle sun. I have plenty of references if someone is interrested.

    This is very nice. What prompted you to create the atmospheric scattering shader if i may ask? Are you interested in atmospheric rendering generally, or is it mostly shaders & filters?

  • Profile picture of mifth mifth132p said 5 months, 2 weeks ago:

    @kwando , thanks for sharing!

    Any chance for this cool shader to be in the JME-Core?

    @kwando , I did a shader library “ShaderBlow”. If you want you can be a developer there. I can add you as a member or as a committer, as you wish. http://code.google.com/p/jme-glsl-shaders/

  • Profile picture of pspeed pspeed815p said 5 months, 2 weeks ago:

    @mifth said:
    Any chance for this cool shader to be in the JME-Core?

    Yeah, that was the main reason I asked. I defer to @nehon on this stuff, though. He is the post-processing expert. :)