Volumetric Lighting

Everything about the development of Urho3D.

Volumetric Lighting

PostPosted by artgolf1000 » 03 Nov 2016, 07:39

Hi,

I have ported http://www.alexandre-pestana.com/volumetric-lights/ into 'forwardlights' command, it works, but still has some issues.
I have commented the second 'forwardlights' command now, it will override generated volumetric light QUAT unexpectedly.

Edit: The engine does not support multiply forward lighting passes, so I have to use the alpha channel to store the volumetric light value instead.
Last edited by artgolf1000 on 05 Nov 2016, 05:02, edited 3 times in total.
User avatar
artgolf1000
Have some posts
Have some posts
 
Posts: 38
Joined: 31 Aug 2016, 08:49

Re: Volumetric Lighting

PostPosted by franck22000 » 03 Nov 2016, 09:34

Nice, do you have any screenshots or video to show ?

Are you planning to do this for deferred renderpath ?
User avatar
franck22000
Some active
Some active
 
Posts: 50
Joined: 13 Dec 2014, 16:35

Re: Volumetric Lighting

PostPosted by artgolf1000 » 03 Nov 2016, 13:56

I'll try deferred render-path tomorrow, no screenshots or videos yet.
User avatar
artgolf1000
Have some posts
Have some posts
 
Posts: 38
Joined: 31 Aug 2016, 08:49

Re: Volumetric Lighting

PostPosted by artgolf1000 » 04 Nov 2016, 05:03

Figure it out! It works in both forward mode and deferred mode now!

It support multiple directional lights, point lights and spot lights casting shadows, but use only one light to cast shadow is recommended.

To test volumetric lighting effect, just replace the original files with the modified version, the volumetric lighting effect should appears.

The forward mode can run on mobile devices, if you use only one directional light to cast shadow, the performance is excellent, I notice no cpu increase.

This demo has one directional light behind a wall, light beams come through the windows, you can see the volumetric lighting effect when light direction changes.

Youtube: https://youtu.be/ZkkazPduyW4


Forward.xml:
Code: Select all
<renderpath>
    <rendertarget name="fullscreen" sizedivisor="1 1" format="rgba" filter="true" />
    <command type="clear" color="0 0 0 0" depth="1.0" stencil="0" output="fullscreen" />
    <command type="scenepass" pass="base" vsdefines="VOLUMETRICLIGHT" psdefines="VOLUMETRICLIGHT" vertexlights="true" metadata="base" output="fullscreen" />
    <command type="forwardlights" pass="light" vsdefines="VOLUMETRICLIGHT" psdefines="VOLUMETRICLIGHT" output="fullscreen" />
    <rendertarget name="blurv" tag="Bloom" sizedivisor="4 4" format="rgb" filter="true" />
    <rendertarget name="blurh" tag="Bloom" sizedivisor="4 4" format="rgb" filter="true" />
    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="BRIGHT VOLUMETRICLIGHT" output="blurv">
        <parameter name="BloomThreshold" value="0.0" />
        <texture unit="diffuse" name="fullscreen" />
    </command>
    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="BLURH" output="blurh">
        <texture unit="diffuse" name="blurv" />
    </command>
    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="BLURV" output="blurv">
        <texture unit="diffuse" name="blurh" />
    </command>
    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="COMBINE" output="viewport">
        <parameter name="BloomMix" value="1.0 1.0" />
        <texture unit="diffuse" name="fullscreen" />
        <texture unit="normal" name="blurv" />
    </command>
    <command type="scenepass" pass="postopaque" />
    <command type="scenepass" pass="refract">
        <texture unit="environment" name="viewport" />
    </command>
    <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" />
    <command type="scenepass" pass="postalpha" sort="backtofront" />
</renderpath>


Deferred.xml:
Code: Select all
<renderpath>
    <rendertarget name="albedo" sizedivisor="1 1" format="rgba" />
    <rendertarget name="normal" sizedivisor="1 1" format="rgba" />
    <rendertarget name="depth" sizedivisor="1 1" format="lineardepth" />
    <rendertarget name="fullscreen" sizedivisor="1 1" format="rgba" filter="true" />
    <command type="clear" color="0 0 0 0" depth="1.0" stencil="0" output="fullscreen" />
    <command type="scenepass" pass="deferred" vsdefines="VOLUMETRICLIGHT" psdefines="VOLUMETRICLIGHT" marktostencil="true" vertexlights="true" metadata="gbuffer">
        <output index="0" name="fullscreen" />
        <output index="1" name="albedo" />
        <output index="2" name="normal" />
        <output index="3" name="depth" />
    </command>
    <command type="lightvolumes" vs="DeferredLight" ps="DeferredLight" vsdefines="VOLUMETRICLIGHT" psdefines="VOLUMETRICLIGHT" output="fullscreen">
        <texture unit="albedo" name="albedo" />
        <texture unit="normal" name="normal" />
        <texture unit="depth" name="depth" />
    </command>
    <rendertarget name="blurv" tag="Bloom" sizedivisor="4 4" format="rgb" filter="true" />
    <rendertarget name="blurh" tag="Bloom" sizedivisor="4 4" format="rgb" filter="true" />
    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="BRIGHT VOLUMETRICLIGHT" output="blurv">
        <parameter name="BloomThreshold" value="0.0" />
        <texture unit="diffuse" name="fullscreen" />
    </command>
    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="BLURH" output="blurh">
        <texture unit="diffuse" name="blurv" />
    </command>
    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="BLURV" output="blurv">
        <texture unit="diffuse" name="blurh" />
    </command>
    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="COMBINE" output="viewport">
        <parameter name="BloomMix" value="1.0 1.0" />
        <texture unit="diffuse" name="fullscreen" />
        <texture unit="normal" name="blurv" />
    </command>
    <command type="scenepass" pass="postopaque" />
    <command type="scenepass" pass="refract">
        <texture unit="environment" name="viewport" />
    </command>
    <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" />
    <command type="scenepass" pass="postalpha" sort="backtofront" />
</renderpath>


Bloom.glsl:
Code: Select all
#include "Uniforms.glsl"
#include "Samplers.glsl"
#include "Transform.glsl"
#include "ScreenPos.glsl"

varying vec2 vTexCoord;
varying vec2 vScreenPos;

#ifdef COMPILEPS
uniform float cBloomThreshold;
uniform vec2 cBloomMix;
uniform vec2 cBlurHInvSize;
#endif

void VS()
{
    mat4 modelMatrix = iModelMatrix;
    vec3 worldPos = GetWorldPos(modelMatrix);
    gl_Position = GetClipPos(worldPos);
    vTexCoord = GetQuadTexCoord(gl_Position);
    vScreenPos = GetScreenPosPreDiv(gl_Position);
}

void PS()
{
#ifdef BRIGHT
    #ifndef VOLUMETRICLIGHT
        vec3 rgb = texture2D(sDiffMap, vScreenPos).rgb;
    #else
        vec3 rgb = texture2D(sDiffMap, vScreenPos).aaa;
    #endif
    gl_FragColor = vec4((rgb - vec3(cBloomThreshold, cBloomThreshold, cBloomThreshold)) / (1.0 - cBloomThreshold), 1.0);
#endif
   
#ifdef BLURH
    vec3 rgb = texture2D(sDiffMap, vTexCoord + vec2(-2.0, 0.0) * cBlurHInvSize).rgb * 0.1;
    rgb += texture2D(sDiffMap, vTexCoord + vec2(-1.0, 0.0) * cBlurHInvSize).rgb * 0.25;
    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 0.0) * cBlurHInvSize).rgb * 0.3;
    rgb += texture2D(sDiffMap, vTexCoord + vec2(1.0, 0.0) * cBlurHInvSize).rgb * 0.25;
    rgb += texture2D(sDiffMap, vTexCoord + vec2(2.0, 0.0) * cBlurHInvSize).rgb * 0.1;
    gl_FragColor = vec4(rgb, 1.0);
#endif
   
#ifdef BLURV
    vec3 rgb = texture2D(sDiffMap, vTexCoord + vec2(0.0, -2.0) * cBlurHInvSize).rgb * 0.1;
    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, -1.0) * cBlurHInvSize).rgb * 0.25;
    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 0.0) * cBlurHInvSize).rgb * 0.3;
    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 1.0) * cBlurHInvSize).rgb * 0.25;
    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 2.0) * cBlurHInvSize).rgb * 0.1;
    gl_FragColor = vec4(rgb, 1.0);
#endif
   
#ifdef COMBINE
    vec3 original = texture2D(sDiffMap, vScreenPos).rgb * cBloomMix.x;
    vec3 bloom = texture2D(sNormalMap, vTexCoord).rgb  * cBloomMix.y;
    // Prevent oversaturation
    original *= max(vec3(1.0) - bloom, vec3(0.0));
    gl_FragColor = vec4(original + bloom, 1.0);
#endif
}


DeferredLight.glsl:
Code: Select all
#include "Uniforms.glsl"
#include "Samplers.glsl"
#include "Transform.glsl"
#include "ScreenPos.glsl"
#include "Lighting.glsl"

#ifdef DIRLIGHT
    varying vec2 vScreenPos;
#else
    varying vec4 vScreenPos;
#endif
varying vec3 vFarRay;
#ifdef ORTHO
    varying vec3 vNearRay;
#endif

void VS()
{
    mat4 modelMatrix = iModelMatrix;
    vec3 worldPos = GetWorldPos(modelMatrix);
    gl_Position = GetClipPos(worldPos);
    #ifdef DIRLIGHT
        vScreenPos = GetScreenPosPreDiv(gl_Position);
        vFarRay = GetFarRay(gl_Position);
        #ifdef ORTHO
            vNearRay = GetNearRay(gl_Position);
        #endif
    #else
        vScreenPos = GetScreenPos(gl_Position);
        vFarRay = GetFarRay(gl_Position) * gl_Position.w;
        #ifdef ORTHO
            vNearRay = GetNearRay(gl_Position) * gl_Position.w;
        #endif
    #endif
}


#ifdef SHADOW
    #ifdef VOLUMETRICLIGHT
        float ComputeScattering(float lightDotView)
        {
            const float G_SCATTERING = 0.5;
            const float PI = 3.14159265358979323846;
            float result = 1.0 - G_SCATTERING * G_SCATTERING;
            result /= (4.0 * PI * pow(1.0 + G_SCATTERING * G_SCATTERING - (2.0 * G_SCATTERING) * lightDotView, 1.5));
            return result;
        }

        float rand(highp vec2 co){
            return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
        }
    #endif
#endif

void PS()
{
    // If rendering a directional light quad, optimize out the w divide
    #ifdef DIRLIGHT
        #ifdef HWDEPTH
            float depth = ReconstructDepth(texture2D(sDepthBuffer, vScreenPos).r);
        #else
            float depth = DecodeDepth(texture2D(sDepthBuffer, vScreenPos).rgb);
        #endif
        #ifdef ORTHO
            vec3 worldPos = mix(vNearRay, vFarRay, depth);
        #else
            vec3 worldPos = vFarRay * depth;
        #endif
        vec4 albedoInput = texture2D(sAlbedoBuffer, vScreenPos);
        vec4 normalInput = texture2D(sNormalBuffer, vScreenPos);
    #else
        #ifdef HWDEPTH
            float depth = ReconstructDepth(texture2DProj(sDepthBuffer, vScreenPos).r);
        #else
            float depth = DecodeDepth(texture2DProj(sDepthBuffer, vScreenPos).rgb);
        #endif
        #ifdef ORTHO
            vec3 worldPos = mix(vNearRay, vFarRay, depth) / vScreenPos.w;
        #else
            vec3 worldPos = vFarRay * depth / vScreenPos.w;
        #endif
        vec4 albedoInput = texture2DProj(sAlbedoBuffer, vScreenPos);
        vec4 normalInput = texture2DProj(sNormalBuffer, vScreenPos);
    #endif

    // Position acquired via near/far ray is relative to camera. Bring position to world space
    vec3 eyeVec = -worldPos;
    worldPos += cCameraPosPS;
   
    vec3 normal = normalize(normalInput.rgb * 2.0 - 1.0);
    vec4 projWorldPos = vec4(worldPos, 1.0);
    vec3 lightColor;
    vec3 lightDir;
   
    float diff = GetDiffuse(normal, worldPos, lightDir);

    #ifdef SHADOW
        diff *= GetShadowDeferred(projWorldPos, normal, depth);
        #ifdef VOLUMETRICLIGHT
            highp vec3 rayDirection = normalize(worldPos-cCameraPosPS);
            float accumFog = 0.0;
            const int NB_STEPS = 15;
            #ifdef DIRLIGHT
                float ditherValue = rand(vScreenPos);
            #else
                float ditherValue = rand(vScreenPos.xy/vScreenPos.w);
            #endif
            for (int n = 0; n < NB_STEPS; n++) {
                highp vec4 projWorldPosSpace = vec4(cCameraPosPS+(float(n)+ditherValue)*(worldPos-cCameraPosPS)/float(NB_STEPS), 1.0);
                accumFog += GetShadowDeferred(projWorldPosSpace, vec3(0.0), float(n)*depth/float(NB_STEPS))*ComputeScattering(dot(rayDirection, lightDir));
            }
            accumFog /= float(NB_STEPS);
        #endif
    #endif
   
    #if defined(SPOTLIGHT)
        vec4 spotPos = projWorldPos * cLightMatricesPS[0];
        lightColor = spotPos.w > 0.0 ? texture2DProj(sLightSpotMap, spotPos).rgb * cLightColor.rgb : vec3(0.0);
    #elif defined(CUBEMASK)
        mat3 lightVecRot = mat3(cLightMatricesPS[0][0].xyz, cLightMatricesPS[0][1].xyz, cLightMatricesPS[0][2].xyz);
        lightColor = textureCube(sLightCubeMap, (worldPos - cLightPosPS.xyz) * lightVecRot).rgb * cLightColor.rgb;
    #else
        lightColor = cLightColor.rgb;
    #endif

    #ifdef SPECULAR
        float spec = GetSpecular(normal, eyeVec, lightDir, normalInput.a * 255.0);
        vec3 finalColor = diff * lightColor * (albedoInput.rgb + spec * cLightColor.a * albedoInput.aaa);
    #else
        vec3 finalColor = diff * lightColor * albedoInput.rgb;
    #endif

    float finalAlpha = 0.0;
    #ifdef SHADOW
        #ifdef VOLUMETRICLIGHT
            finalAlpha = accumFog;
        #endif
    #endif

    gl_FragColor = vec4(finalColor, finalAlpha);
}


LitSolid.glsl:
Code: Select all
#include "Uniforms.glsl"
#include "Samplers.glsl"
#include "Transform.glsl"
#include "ScreenPos.glsl"
#include "Lighting.glsl"
#include "Fog.glsl"

#ifdef NORMALMAP
    varying vec4 vTexCoord;
    varying vec4 vTangent;
#else
    varying vec2 vTexCoord;
#endif
varying vec3 vNormal;
varying vec4 vWorldPos;
#ifdef VERTEXCOLOR
    varying vec4 vColor;
#endif
#ifdef PERPIXEL
    #ifdef SHADOW
        #ifndef GL_ES
            varying vec4 vShadowPos[NUMCASCADES];
            #ifdef VOLUMETRICLIGHT
                varying vec2 vScreenPos;
                varying vec4 vShadowPosCamera[NUMCASCADES];
                varying vec4 vShadowPosTarget[NUMCASCADES];
            #endif
        #else
            varying highp vec4 vShadowPos[NUMCASCADES];
            #ifdef VOLUMETRICLIGHT
                varying highp vec2 vScreenPos;
                varying highp vec4 vShadowPosCamera[NUMCASCADES];
                varying highp vec4 vShadowPosTarget[NUMCASCADES];
            #endif
        #endif
    #endif
    #ifdef SPOTLIGHT
        varying vec4 vSpotPos;
    #endif
    #ifdef POINTLIGHT
        varying vec3 vCubeMaskVec;
    #endif
#else
    varying vec3 vVertexLight;
    varying vec4 vScreenPos;
    #ifdef ENVCUBEMAP
        varying vec3 vReflectionVec;
    #endif
    #if defined(LIGHTMAP) || defined(AO)
        varying vec2 vTexCoord2;
    #endif
#endif

void VS()
{
    mat4 modelMatrix = iModelMatrix;
    vec3 worldPos = GetWorldPos(modelMatrix);
    gl_Position = GetClipPos(worldPos);
    vNormal = GetWorldNormal(modelMatrix);
    vWorldPos = vec4(worldPos, GetDepth(gl_Position));

    #ifdef VERTEXCOLOR
        vColor = iColor;
    #endif

    #ifdef NORMALMAP
        vec3 tangent = GetWorldTangent(modelMatrix);
        vec3 bitangent = cross(tangent, vNormal) * iTangent.w;
        vTexCoord = vec4(GetTexCoord(iTexCoord), bitangent.xy);
        vTangent = vec4(tangent, bitangent.z);
    #else
        vTexCoord = GetTexCoord(iTexCoord);
    #endif

    #ifdef PERPIXEL
        // Per-pixel forward lighting
        vec4 projWorldPos = vec4(worldPos, 1.0);

        #ifdef SHADOW
            // Shadow projection: transform from world space to shadow space
            for (int i = 0; i < NUMCASCADES; i++)
                vShadowPos[i] = GetShadowPos(i, vNormal, projWorldPos);
            #ifdef VOLUMETRICLIGHT
                // Shadow projection: transform from world space to shadow space
                for (int i = 0; i < NUMCASCADES; i++)
                    vShadowPosCamera[i] = GetShadowPos(i, vec3(0), vec4(cCameraPos, 1.0));
                // Shadow projection: transform from world space to shadow space
                for (int i = 0; i < NUMCASCADES; i++)
                    vShadowPosTarget[i] = GetShadowPos(i, vec3(0), projWorldPos);
                vScreenPos = GetScreenPosPreDiv(gl_Position);
            #endif
        #endif

        #ifdef SPOTLIGHT
            // Spotlight projection: transform from world space to projector texture coordinates
            vSpotPos = projWorldPos * cLightMatrices[0];
        #endif
   
        #ifdef POINTLIGHT
            vCubeMaskVec = (worldPos - cLightPos.xyz) * mat3(cLightMatrices[0][0].xyz, cLightMatrices[0][1].xyz, cLightMatrices[0][2].xyz);
        #endif
    #else
        // Ambient & per-vertex lighting
        #if defined(LIGHTMAP) || defined(AO)
            // If using lightmap, disregard zone ambient light
            // If using AO, calculate ambient in the PS
            vVertexLight = vec3(0.0, 0.0, 0.0);
            vTexCoord2 = iTexCoord1;
        #else
            vVertexLight = GetAmbient(GetZonePos(worldPos));
        #endif
       
        #ifdef NUMVERTEXLIGHTS
            for (int i = 0; i < NUMVERTEXLIGHTS; ++i)
                vVertexLight += GetVertexLight(i, worldPos, vNormal) * cVertexLights[i * 3].rgb;
        #endif
       
        vScreenPos = GetScreenPos(gl_Position);

        #ifdef ENVCUBEMAP
            vReflectionVec = worldPos - cCameraPos;
        #endif
    #endif
}

#ifdef SHADOW
    #ifdef VOLUMETRICLIGHT
        float ComputeScattering(float lightDotView)
        {
            const float G_SCATTERING = 0.5;
            const float PI = 3.14159265358979323846;
            float result = 1.0 - G_SCATTERING * G_SCATTERING;
            result /= (4.0 * PI * pow(1.0 + G_SCATTERING * G_SCATTERING - (2.0 * G_SCATTERING) * lightDotView, 1.5));
            return result;
        }

        float rand(highp vec2 co){
            return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
        }
    #endif
#endif

void PS()
{
    // Get material diffuse albedo
    #ifdef DIFFMAP
        vec4 diffInput = texture2D(sDiffMap, vTexCoord.xy);
        #ifdef ALPHAMASK
            if (diffInput.a < 0.5)
                discard;
        #endif
        vec4 diffColor = cMatDiffColor * diffInput;
    #else
        vec4 diffColor = cMatDiffColor;
    #endif

    #ifdef VERTEXCOLOR
        diffColor *= vColor;
    #endif
   
    // Get material specular albedo
    #ifdef SPECMAP
        vec3 specColor = cMatSpecColor.rgb * texture2D(sSpecMap, vTexCoord.xy).rgb;
    #else
        vec3 specColor = cMatSpecColor.rgb;
    #endif

    // Get normal
    #ifdef NORMALMAP
        mat3 tbn = mat3(vTangent.xyz, vec3(vTexCoord.zw, vTangent.w), vNormal);
        vec3 normal = normalize(tbn * DecodeNormal(texture2D(sNormalMap, vTexCoord.xy)));
    #else
        vec3 normal = normalize(vNormal);
    #endif

    // Get fog factor
    #ifdef HEIGHTFOG
        float fogFactor = GetHeightFogFactor(vWorldPos.w, vWorldPos.y);
    #else
        float fogFactor = GetFogFactor(vWorldPos.w);
    #endif

    #if defined(PERPIXEL)
        // Per-pixel forward lighting
        vec3 lightColor;
        vec3 lightDir;
        vec3 finalColor;

        float diff = GetDiffuse(normal, vWorldPos.xyz, lightDir);

        #ifdef SHADOW
            diff *= GetShadow(vShadowPos, vWorldPos.w);
            #ifdef VOLUMETRICLIGHT
                highp vec3 rayDirection = normalize(vWorldPos.xyz-cCameraPosPS);
                float accumFog = 0.0;
                const int NB_STEPS = 15;
                float ditherValue = rand(vScreenPos);
                for (int n = 0; n < NB_STEPS; n++) {
                    highp vec4 vShadowPosSpace[NUMCASCADES];
                    for (int i = 0; i < NUMCASCADES; i++) {
                        vShadowPosSpace[i] = vShadowPosCamera[i]+(float(n)+ditherValue)*(vShadowPosTarget[i]-vShadowPosCamera[i])/float(NB_STEPS);
                    }
                    accumFog += GetShadow(vShadowPosSpace, float(n)*vWorldPos.w/float(NB_STEPS))*ComputeScattering(dot(rayDirection, lightDir));
                }
                accumFog /= float(NB_STEPS);
            #endif
        #endif
   
        #if defined(SPOTLIGHT)
            lightColor = vSpotPos.w > 0.0 ? texture2DProj(sLightSpotMap, vSpotPos).rgb * cLightColor.rgb : vec3(0.0, 0.0, 0.0);
        #elif defined(CUBEMASK)
            lightColor = textureCube(sLightCubeMap, vCubeMaskVec).rgb * cLightColor.rgb;
        #else
            lightColor = cLightColor.rgb;
        #endif
   
        #ifdef SPECULAR
            float spec = GetSpecular(normal, cCameraPosPS - vWorldPos.xyz, lightDir, cMatSpecColor.a);
            finalColor = diff * lightColor * (diffColor.rgb + spec * specColor * cLightColor.a);
        #else
            finalColor = diff * lightColor * diffColor.rgb;
        #endif

        #ifdef AMBIENT
            finalColor += cAmbientColor.rgb * diffColor.rgb;
            finalColor += cMatEmissiveColor;
            finalColor = GetFog(finalColor, fogFactor);
        #else
            finalColor = GetLitFog(finalColor, fogFactor);
        #endif
   
        #ifndef VOLUMETRICLIGHT
            float finalAlpha = diffColor.a;
        #else
            float finalAlpha = 0.0;
        #endif
   
        #ifdef SHADOW
            #ifdef VOLUMETRICLIGHT
                finalAlpha = accumFog;
            #endif
        #endif
        gl_FragColor = vec4(finalColor, finalAlpha);
    #elif defined(PREPASS)
        // Fill light pre-pass G-Buffer
        float specPower = cMatSpecColor.a / 255.0;

        gl_FragData[0] = vec4(normal * 0.5 + 0.5, specPower);
        gl_FragData[1] = vec4(EncodeDepth(vWorldPos.w), 0.0);
    #elif defined(DEFERRED)
        // Fill deferred G-buffer
        float specIntensity = specColor.g;
        float specPower = cMatSpecColor.a / 255.0;

        vec3 finalColor = vVertexLight * diffColor.rgb;
        #ifdef AO
            // If using AO, the vertex light ambient is black, calculate occluded ambient here
            finalColor += texture2D(sEmissiveMap, vTexCoord2).rgb * cAmbientColor.rgb * diffColor.rgb;
        #endif

        #ifdef ENVCUBEMAP
            finalColor += cMatEnvMapColor * textureCube(sEnvCubeMap, reflect(vReflectionVec, normal)).rgb;
        #endif
        #ifdef LIGHTMAP
            finalColor += texture2D(sEmissiveMap, vTexCoord2).rgb * diffColor.rgb;
        #endif
        #ifdef EMISSIVEMAP
            finalColor += cMatEmissiveColor * texture2D(sEmissiveMap, vTexCoord.xy).rgb;
        #else
            finalColor += cMatEmissiveColor;
        #endif

        #ifndef VOLUMETRICLIGHT
            gl_FragData[0] = vec4(GetFog(finalColor, fogFactor), 1.0);
        #else
            gl_FragData[0] = vec4(GetFog(finalColor, fogFactor), 0.0);
        #endif
        gl_FragData[1] = fogFactor * vec4(diffColor.rgb, specIntensity);
        gl_FragData[2] = vec4(normal * 0.5 + 0.5, specPower);
        gl_FragData[3] = vec4(EncodeDepth(vWorldPos.w), 0.0);
    #else
        // Ambient & per-vertex lighting
        vec3 finalColor = vVertexLight * diffColor.rgb;
        #ifdef AO
            // If using AO, the vertex light ambient is black, calculate occluded ambient here
            finalColor += texture2D(sEmissiveMap, vTexCoord2).rgb * cAmbientColor.rgb * diffColor.rgb;
        #endif
       
        #ifdef MATERIAL
            // Add light pre-pass accumulation result
            // Lights are accumulated at half intensity. Bring back to full intensity now
            vec4 lightInput = 2.0 * texture2DProj(sLightBuffer, vScreenPos);
            vec3 lightSpecColor = lightInput.a * lightInput.rgb / max(GetIntensity(lightInput.rgb), 0.001);

            finalColor += lightInput.rgb * diffColor.rgb + lightSpecColor * specColor;
        #endif

        #ifdef ENVCUBEMAP
            finalColor += cMatEnvMapColor * textureCube(sEnvCubeMap, reflect(vReflectionVec, normal)).rgb;
        #endif
        #ifdef LIGHTMAP
            finalColor += texture2D(sEmissiveMap, vTexCoord2).rgb * diffColor.rgb;
        #endif
        #ifdef EMISSIVEMAP
            finalColor += cMatEmissiveColor * texture2D(sEmissiveMap, vTexCoord.xy).rgb;
        #else
            finalColor += cMatEmissiveColor;
        #endif

        gl_FragColor = vec4(GetFog(finalColor, fogFactor), diffColor.a);
    #endif
}
Last edited by artgolf1000 on 05 Nov 2016, 04:58, edited 2 times in total.
User avatar
artgolf1000
Have some posts
Have some posts
 
Posts: 38
Joined: 31 Aug 2016, 08:49

Re: Volumetric Lighting

PostPosted by franck22000 » 04 Nov 2016, 10:19

Excellent, looking forward to see if you are able to port it for deferred rendering.
User avatar
franck22000
Some active
Some active
 
Posts: 50
Joined: 13 Dec 2014, 16:35

Re: Volumetric Lighting

PostPosted by artgolf1000 » 05 Nov 2016, 05:09

The deferred mode is ready, it support both forward lighting mode and deferred lighting mode now!

I have to use the alpha channel to store volumetric lighting value, it may cause alpha lighting incorrect, if this happens, put 'vsexcludes="VOLUMETRICLIGHT"' and 'psexcludes="VOLUMETRICLIGHT"' to the litalpha and light pass, such as 'DiffAlpha.xml', it should solve the issue.

I can not figure out how to let lighting pass support multiple render target at present.
User avatar
artgolf1000
Have some posts
Have some posts
 
Posts: 38
Joined: 31 Aug 2016, 08:49

Re: Volumetric Lighting

PostPosted by dragonCASTjosh » 05 Nov 2016, 17:11

Does it support the PBR render path? because i think it would look amazing alongside PBR
User avatar
dragonCASTjosh
Moderator
Moderator
 
Posts: 205
Joined: 04 Aug 2015, 18:59

Re: Volumetric Lighting

PostPosted by artgolf1000 » 06 Nov 2016, 05:09

I am not familiar with PBR, you may look into DeferredLight.glsl, I guess it not difficult to port to PBR.
User avatar
artgolf1000
Have some posts
Have some posts
 
Posts: 38
Joined: 31 Aug 2016, 08:49

Re: Volumetric Lighting

PostPosted by dragonCASTjosh » 06 Nov 2016, 23:57

as long as it doesnt make changes to the diffuse or specular then i dont see it causing a problem to implement
User avatar
dragonCASTjosh
Moderator
Moderator
 
Posts: 205
Joined: 04 Aug 2015, 18:59


Return to Developer Talk

Who is online

Users browsing this forum: No registered users and 0 guests

cron