[UPDATE] - Fur - Deferred shading

Return to Code Snippets

[UPDATE] - Fur - Deferred shading

Postby Manou » Sun Jul 03, 2011 5:15 pm

--
Deferred shading & Fancy effects

VIDEO :
http://youtu.be/4nEV3nK7INs

Image

WORKING
- deferred shading : point and directional lights in view space, phong equation, bounding volumes for lights,
- doesn't rely on autoshader,
- custom g-buffers shader for normal maps,
- FXAA : Fast Approximate Anti-Aliasing,
- depth of field bokeh : one-pass effect based on Martins Upitis code,
- bleach bypass : b&w merged with color to enhance contrasts and desaturate colors,
- bloom,
- vignetting.

TODO
- material specular information written in g-buffer,
- linear depth buffer,
- try other light models,
- working shadows,
- sprite-based bokeh dof,
- fxaa last version,
- anamorphic lens flare,
- transparency,
- HDR tonemaping,
- speed.

PROBLEMS
- projection of shadows in the light bounding volumes
- change texture format

CODE INCOMING !

--

Hello all,
here a simple deferred shading system, only point lights atm, more to come.

You need panda buildbot version.

Image

The panda app :
Code: Select all
#####################################################
##  DEFERRED LIGHTING - POINT LIGHT IN VIEW SPACE  ##
#####################################################

### Imports ###
from panda3d.core import *
loadPrcFileData('', 'show-buffers 0')
from direct.showbase.ShowBase import ShowBase
from panda3d.egg import *
from direct.filter.FilterManager import *
from pandac.PandaModules import Vec3
from math import pi,sin,cos
import random

### Class constants ###
LIGHTS_NUMBER = 15

### Class Application ###
class Application(ShowBase):

    ### Constructor ###
    def __init__(self):
        ShowBase.__init__(self)

        self.setup_scene()

        taskMgr.add(self.update,"update")

        #disable mouse#
        base.disableMouse()

    ### Function setup ###
    def setup_scene(self):

        ### Camera setup ###
        self.light_cam = self.makeCamera(self.win)
        self.light_cam.reparentTo(self.cam)

        scene_mask = BitMask32(1)
        light_mask = BitMask32(2)

        self.cam.node().setCameraMask(scene_mask)
        self.light_cam.node().setCameraMask(light_mask)

        base.camera.setPos(0,-200,115)
        self.camera.setP(-30)

        self.cam.node().getDisplayRegion(0).setSort(1)
        self.light_cam.node().getDisplayRegion(0).setSort(2)
        self.win.setSort(3)

        self.light_cam.node().getDisplayRegion(0).setClearColor(Vec4(.0, .0, .0, 1))
        self.light_cam.node().getDisplayRegion(0).setClearColorActive(1)


        ### Scene creation ###
        self.scene = render.attachNewNode("scene")
        self.scene.hide(light_mask)
        self.scene.setShaderAuto()

        #create spheres
        for i in range(10):
            angleDegrees = i * 36
            angleRadians = angleDegrees * (pi / 180.0)

            sphere = loader.loadModel("test")
            sphere.setPos( sin(angleRadians)*40,cos(angleRadians)*40,0)
            sphere.setScale(10)
            sphere.reparentTo(self.scene)
            sphere.setAttrib(ShadeModelAttrib.make(ShadeModelAttrib.MSmooth))

        #create floor
        cm = CardMaker("floor")
        cm.setFrame(-100, 100, -100, 100)

        plane = render.attachNewNode(cm.generate())
        plane.setP(270)
        plane.setZ(-10)
        plane.reparentTo(self.scene)

        self.lights = []
        self.bulbs = []

        self.abs = []
        self.ords = []

        ### Buffers creation ###
        self.gbuffer_man = FilterManager(self.win, self.cam)

        depth = Texture()
        albedo = Texture()
        normal = Texture()

        self.gbuffer_man.renderSceneInto(colortex = albedo, depthtex = depth, auxtex = normal,auxbits = AuxBitplaneAttrib.ABOAuxNormal)

        ### Lights creation ###
        for i in range(LIGHTS_NUMBER):
            #light geometry
            light = loader.loadModel("misc/sphere")
            light.setPos(random.uniform(-40,40),random.uniform(-40,40),random.uniform(0,15))
            light.setColor(random.uniform(0,1),random.uniform(0,1),random.uniform(0,1))
            light.setScale(100)
            light.reparentTo(render)
            light.setAttrib(DepthTestAttrib.make(RenderAttrib.MLess))
            light.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullClockwise))
            #self.light.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise)
            light.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne, ColorBlendAttrib.OOne))
            light.setAttrib(DepthWriteAttrib.make(DepthWriteAttrib.MOff))

            #light shader
            light.setShader(loader.loadShader("def_light.cg"))
            light.setShaderInput("albedo", albedo)
            light.setShaderInput("depth", depth)
            light.setShaderInput("normal", normal)
            light.setShaderInput("Kd", Vec3(1,1,1))
            light.setShaderInput("Ks",Vec3(.8,.8,.8))
            light.setShaderInput("att_params",Vec3(0.1,0.2,0.003))
            light.setShaderInput("light_radius", light.getScale())
            light.setShaderInput("camera",base.camera)

            self.abs.append(light.getX())
            self.ords.append(light.getY())

            bulb = loader.loadModel("sphere")
            bulb.reparentTo(render)
            bulb.setPos(light.getPos())
            bulb.setColorScale(light.getColor())

            bulb.hide(light_mask)
            light.hide(scene_mask)

            self.bulbs.append(bulb)
            self.lights.append(light)

    ### Update per frame ###
    def update(self,task):
 
        for i in range(LIGHTS_NUMBER):
           
            self.lights[i].setZ(self.lights[i].getZ()+ sin(task.time)/20)

            self.bulbs[i].setZ(self.bulbs[i].getZ()+ sin(task.time)/20)
            angleDegrees = task.time * 6.0
            angleRadians = angleDegrees * (pi / 180.0)
            self.lights[i].setPos(self.abs[i] * sin(angleRadians), self.ords[i] * cos(angleRadians), 3)
            self.bulbs[i].setPos(self.abs[i] * sin(angleRadians), self.ords[i] * cos(angleRadians), 3)

        return task.cont


application = Application()
application.run()


The point light shader :
Code: Select all
//Cg

void vshader(
             float4 vtx_position : POSITION,
             out float4 l_position : POSITION,
             out float4 l_pos : TEXCOORD0,
             uniform float4x4 mat_modelproj)
{
    l_position = mul(mat_modelproj, vtx_position);
    l_pos = l_position;
   
}

void fshader(
             float4 l_position : TEXCOORD0,
             float4 l_normal    : TEXCOORD1,
             uniform sampler2D k_albedo : TEXUNIT0, // color map
             uniform sampler2D k_depth : TEXUNIT1, // depth map
             uniform sampler2D k_normal : TEXUNIT2, // normal map
             uniform float4 texpad_albedo,
             uniform float4 texpad_normal,
             uniform float4 texpad_depth,
             uniform float4 attr_color,
             uniform float3 att_params, // attenuation parameters
             uniform float3 light_radius,
             uniform float4 vspos_camera, // position of camera in view space
             uniform float3 Kd, // diffuse coef.
             uniform float3 Ks, // specular coef.
             uniform float4 vspos_model, // position of model in view space
             uniform float4x4 trans_clip_to_view,
             out float4 o_color0 : COLOR0)
{
    ////////////////////////////////////////////
    //   DEFERRED POINT LIGHT IN VIEW SPACE   //
    ////////////////////////////////////////////

    // fragment position in clip space
    l_position.xy /= l_position.w;

    // textures input
    float2 texcoords = float2(l_position.xy) * texpad_normal.xy + texpad_normal.xy;
    float4 albedo = tex2D(k_albedo, texcoords);
    float4 normal = tex2D(k_normal, texcoords);
    float4 depth = tex2D(k_depth, texcoords);

    // point illuminated
    float4 P;
    P.xy = l_position.xy;
    P.z = depth;
    P.w = 1;
    P = mul(trans_clip_to_view, P);
    P /= P.w*2;

    // normal
    float3 N;
    N = normal;
    N.xyz = N.xyz - float3(0.5,0.5,0.5);
    N.xyz = 2 * N.xyz;
    N = normalize(N);

    // light vector
    float3 L = (vspos_model - P);

    // ray length
    float l = length(L);

    // light attenuation
    float constant_att = att_params.x;
    float linear_att = att_params.y;
    float quadra_att = att_params.z;
    float attenuation = 1.0f / (constant_att + linear_att*l + quadra_att*l*l);

    // normalize light vector
    L = normalize(L);

    // compute diffuse light
    float diffuseLight = max(dot(L, N),0);
    float3 diffuse = diffuseLight * albedo * attr_color;

    // compute specular term
    float3 V = normalize(vspos_camera - P);
    float3 H = normalize(L + V);
    float specularLight = pow(max(dot(N, H), 0), 180);

    if (diffuseLight <= 0) specularLight = 0;
    float3 specular = Ks * attr_color * specularLight* albedo;

    // output
    o_color0.xyz = attenuation * diffuse + specular ;
    o_color0.w = 1;
 
}


Feel free to discuss, there may be errors or bad comments.
Last edited by Manou on Thu Aug 25, 2011 8:06 pm, edited 9 times in total.
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby ninth » Mon Jul 04, 2011 5:30 am

Panda 1.7.2 Win XP
GF 8600GT
Code: Select all
Known pipe types:
  wglGraphicsPipe
(all display modules loaded.)
:gobj(error): /d/work/panda3d/samples/diff_lights/def_light.cg: unrecognized par
ameter name (uniform in float3 att_params)
:gobj(error): /d/work/panda3d/samples/diff_lights/def_light.cg: unrecognized par
ameter name (uniform in float3 light_radius)
:gobj(error): /d/work/panda3d/samples/diff_lights/def_light.cg: invalid paramete
r name (uniform in float3 Kd)
:gobj(error): /d/work/panda3d/samples/diff_lights/def_light.cg: invalid paramete
r name (uniform in float3 Ks)
:gobj(error): Shader encountered an error.
Traceback (most recent call last):
  File "main.py", line 151, in <module>
    application = Application()
  File "main.py", line 25, in __init__
    self.setup_scene()
  File "main.py", line 115, in setup_scene
    light.setShaderInput("Kd", Vec3(1,1,1))
TypeError: Arguments must match one of:
setShaderInput(non-const NodePath this, const ShaderInput inp)
setShaderInput(non-const NodePath this, non-const InternalName id)
setShaderInput(non-const NodePath this, string id)
setShaderInput(non-const NodePath this, non-const InternalName id, const Vec4 v)

setShaderInput(non-const NodePath this, non-const InternalName id, const NodePat
h np)
setShaderInput(non-const NodePath this, non-const InternalName id, non-const Tex
ture tex)
setShaderInput(non-const NodePath this, string id, const Vec4 v)
setShaderInput(non-const NodePath this, string id, const NodePath np)
setShaderInput(non-const NodePath this, string id, non-const Texture tex)
setShaderInput(non-const NodePath this, non-const InternalName id, float n1)
setShaderInput(non-const NodePath this, string id, float n1)
setShaderInput(non-const NodePath this, non-const InternalName id, const Vec4 v,
 int priority)
setShaderInput(non-const NodePath this, non-const InternalName id, const NodePat
h np, int priority)
setShaderInput(non-const NodePath this, non-const InternalName id, non-const Tex
ture tex, int priority)
setShaderInput(non-const NodePath this, string id, const Vec4 v, int priority)
setShaderInput(non-const NodePath this, string id, const NodePath np, int priori
ty)
setShaderInput(non-const NodePath this, string id, non-const Texture tex, int pr
iority)
setShaderInput(non-const NodePath this, non-const InternalName id, float n1, flo
at n2)
setShaderInput(non-const NodePath this, string id, float n1, float n2)
setShaderInput(non-const NodePath this, non-const InternalName id, float n1, flo
at n2, float n3)
setShaderInput(non-const NodePath this, string id, float n1, float n2, float n3)

setShaderInput(non-const NodePath this, non-const InternalName id, float n1, flo
at n2, float n3, float n4)
setShaderInput(non-const NodePath this, string id, float n1, float n2, float n3,
 float n4)
setShaderInput(non-const NodePath this, non-const InternalName id, float n1, flo
at n2, float n3, float n4, int priority)
setShaderInput(non-const NodePath this, string id, float n1, float n2, float n3,
 float n4, int priority)
Vodka, bears, balalaika... hmm... sorry for my English =)
ninth
 
Posts: 352
Joined: Fri Jan 23, 2009 9:06 am
Location: Russia

Postby rdb » Mon Jul 04, 2011 5:52 am

Looks like the original code was written against Panda 1.8 (buildbot version), not 1.7.
rdb
 
Posts: 8545
Joined: Mon Dec 04, 2006 5:58 am
Location: Netherlands

Postby Manou » Sat Jul 16, 2011 5:05 pm

Deferred normal mapping has arrived !

Image
Code incoming.
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby Manou » Tue Jul 19, 2011 4:10 pm

Some news,

Image

I'm implementing various effects found on the web; I have a question about shader performances : I have a very simple scene with 10 spheres, I have the following effects on it :
- 2 deferred point lights (no shadows),
- 1 deferred dir light (no shadows),
- deferred normal maps,
- dof,
- color correction pass.

I get about 250 fps with a gtx 260 + e8400, do you think it will be ok with a real game or is it too slow already, (the dof shader being the most intensive) ?
How do I get the rendering time of frames with cg shaders on linux ?
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby Nemesis#13 » Tue Jul 19, 2011 7:14 pm

Nice effects you have there.
Last edited by Nemesis#13 on Thu Jul 28, 2011 6:07 pm, edited 1 time in total.
User avatar
Nemesis#13
 
Posts: 1040
Joined: Mon Aug 04, 2008 8:09 pm
Location: Germany

Postby Manou » Tue Jul 19, 2011 10:12 pm

Hey, I had to compute normals with trans-egg to get them display properly, try this sphere :
http://www.mediafire.com/?zf9bood0sb91oz0

What does the buffer display?

The first version relies on autoshader to get normals buffer.
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby Anon » Wed Jul 20, 2011 6:56 am

hey, is the dof shader available too? Did you use filtermanager?
Anon
 
Posts: 1556
Joined: Thu Oct 29, 2009 3:07 am

Postby Manou » Wed Jul 20, 2011 5:02 pm

Hello,

I'm implementing more effects atm; I'll post the code when it will be cleaner and faster.

The dof shader is the one Martins Upitis did : http://artmartinsh.blogspot.com/2010/02/glsl-lens-blur-filter-with-bokeh.html It's not the best method available (search for sprite based bokeh dof) but it's working and the effect looks better than simple fullscreen blur.

I'm using filter manager atm because it's the last effect applied and is fullscreen
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby Anon » Thu Jul 21, 2011 12:45 am

The thing is Panda3d doesn't have a built-in DOF filter (in the commonfilters), though I think it's used more ofthen then few other's which are included. It would be a nice addition to Panda3d, if you'd want to contribute, though I'm not sure if the devs would add a GLSL version.
Anon
 
Posts: 1556
Joined: Thu Oct 29, 2009 3:07 am

Postby Manou » Thu Jul 21, 2011 4:06 pm

Fxaa looks ok !
Doesn't work with basic shaders.

Performance hit : about 20 fps with gtx260 @1024x768

with :
Image

without :
Image

shader (ported from geeks3D glsl) :
Code: Select all
//Cg

varying vec4 posPos;
uniform float FXAA_SUBPIX_SHIFT = 1.0/4.0;
const float rt_w = 1024; // resolution width
const float rt_h = 768; // resolution height

void vshader(float4 vtx_position : POSITION,
             out float4 l_position : POSITION,
             out float2 l_texcoord : TEXCOORD0,
             out float4 l_posPos : TEXCOORD1,
             uniform float4 texpad_color,
             uniform float4x4 mat_modelproj)
{
  l_position = mul(mat_modelproj, vtx_position);
  l_texcoord = (vtx_position.xz * texpad_color.xy) + texpad_color.xy;
 
  vec2 rcpFrame = vec2(1.0/rt_w, 1.0/rt_h);
  posPos.xy = l_texcoord.xy;
  posPos.zw = l_texcoord.xy - (rcpFrame * (0.5 + FXAA_SUBPIX_SHIFT));

  l_posPos = posPos;
}


uniform float vx_offset;
uniform float FXAA_SPAN_MAX = 8.0;
uniform float FXAA_REDUCE_MUL = 1.0/8.0;

#define FxaaInt2 ivec2
#define FxaaFloat2 vec2
#define FxaaTexLod0(t, p) texture2DLod(t, p, 0.0)
#define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p.xy + (o * rcpFrame), 0, 0))

vec3 FxaaPixelShader(
  vec4 posPos, // Output of FxaaVertexShader interpolated across screen.
  sampler2D tex, // Input texture.
  vec2 rcpFrame) // Constant {1.0/frameWidth, 1.0/frameHeight}.
{
/*---------------------------------------------------------*/
    #define FXAA_REDUCE_MIN   (1.0/128.0)
    //#define FXAA_REDUCE_MUL   (1.0/8.0)
    //#define FXAA_SPAN_MAX     8.0
/*---------------------------------------------------------*/
    vec3 rgbNW = FxaaTexLod0(tex, posPos.zw).xyz;
    vec3 rgbNE = FxaaTexOff(tex, posPos.zw, FxaaInt2(1,0), rcpFrame.xy).xyz;
    vec3 rgbSW = FxaaTexOff(tex, posPos.zw, FxaaInt2(0,1), rcpFrame.xy).xyz;
    vec3 rgbSE = FxaaTexOff(tex, posPos.zw, FxaaInt2(1,1), rcpFrame.xy).xyz;
    vec3 rgbM  = FxaaTexLod0(tex, posPos.xy).xyz;
/*---------------------------------------------------------*/
    vec3 luma = vec3(0.299, 0.587, 0.114);
    float lumaNW = dot(rgbNW, luma);
    float lumaNE = dot(rgbNE, luma);
    float lumaSW = dot(rgbSW, luma);
    float lumaSE = dot(rgbSE, luma);
    float lumaM  = dot(rgbM,  luma);
/*---------------------------------------------------------*/
    float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
    float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
/*---------------------------------------------------------*/
    vec2 dir;
    dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
    dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));
/*---------------------------------------------------------*/
    float dirReduce = max(
        (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),
        FXAA_REDUCE_MIN);
    float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
    dir = min(FxaaFloat2( FXAA_SPAN_MAX,  FXAA_SPAN_MAX),
          max(FxaaFloat2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
          dir * rcpDirMin)) * rcpFrame.xy;
/*--------------------------------------------------------*/
    vec3 rgbA = (1.0/2.0) * (
        FxaaTexLod0(tex, posPos.xy + dir * (1.0/3.0 - 0.5)).xyz +
        FxaaTexLod0(tex, posPos.xy + dir * (2.0/3.0 - 0.5)).xyz);
    vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
        FxaaTexLod0(tex, posPos.xy + dir * (0.0/3.0 - 0.5)).xyz +
        FxaaTexLod0(tex, posPos.xy + dir * (3.0/3.0 - 0.5)).xyz);
    float lumaB = dot(rgbB, luma);
    if((lumaB < lumaMin) || (lumaB > lumaMax)) return rgbA;
    return rgbB; }

vec4 PostFX(float4 pos, sampler2D tex, vec2 uv, float time)
{
  vec4 c = vec4(0.0);
  vec2 rcpFrame = vec2(1.0/rt_w, 1.0/rt_h);
  c.rgb = FxaaPixelShader(pos, tex, rcpFrame);
  //c.rgb = 1.0 - texture2D(tex, pos.xy).rgb;
  c.a = 1.0;
  return c;
}

void fshader(float2 l_texcoord : TEXCOORD0,
             float4 l_posPos : TEXCOORD1,
             uniform sampler2D k_color : TEXUNIT0,
             uniform float k_active,
             uniform float4 texpix_color,
             uniform float4 texpad_color,
             out float4 o_color : COLOR)
{
  float4 without_fxaa = tex2D(k_color, l_texcoord);

  vec2 uv = l_texcoord.st;
  o_color = PostFX(l_posPos, k_color, uv, 0.0);

  if(k_active == 0) o_color = without_fxaa;
}


To use it, render whole scene to a fullscreen quad and just pass your colormap (linearly filtered) as input :
Code: Select all
quad.setShader(loader.loadShader("fxaa.cg"))
quad.setShaderInput("color", color_map)
quad.setShaderInput("active", 1)


Still needs more testing with proper scene, I don't know why the texture2DLod function doesn't throw error (should be tex2Dlod in cg).

Anon : I don't know how to do this atm, I'd prefer a real programmer to do it :p
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby Anon » Fri Jul 22, 2011 2:02 am

Manou wrote:Anon : I don't know how to do this atm, I'd prefer a real programmer to do it :p

Uh, do what?

PS. Youre not a real programmer? Off-topic, but how did you learn shader programming, Ive tried the GPU gems book, the Orange book and nothing. Or youre a maths person?
Anon
 
Posts: 1556
Joined: Thu Oct 29, 2009 3:07 am

Postby Manou » Fri Jul 22, 2011 5:19 pm

Uh, do what?

To implement the dof code into panda source, I don't know C++ :(

I'm hybrid art/coder in web applications, I have AS3 background.
About shader programming the nvidia Cg tutorial is very good. : http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter01.html
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby coppertop » Fri Jul 22, 2011 5:54 pm

Programmer or not, the work you're going is pretty bad ass. Keep it up! I'd love to see this integrated into Panda at some point.

If I may have a suggestion, it would be great if you kept a change log in the first post. Otherwise, once this thread grows, it will be difficult to keep up with what's available and what's not.

Also, I'd like to know if transparency will be supported in any way? I have little to no background on the subject, but I've read that deferred lighting doesn't work with transparent models well.
User avatar
coppertop
 
Posts: 526
Joined: Sat Apr 18, 2009 5:48 am

Postby Manou » Fri Jul 22, 2011 6:53 pm

thanks man!

I'd like to integrate this as well if it's possible in python, but I don't know how contributing to panda project works and if this code worth it. Can anybody add code to panda source, how does it work in general?

the changelog is good idea, I'm on it.

Speaking about transparency, you are right, this is the main limitation of the deferred shading, the solution is to use fixed pipeline to render transparent objects.
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby Anon » Sat Jul 23, 2011 7:15 am

To implement the dof code into panda source, I don't know C++

i think commonfilters is a python module. You can find it in "C:\Panda3D-1.X.X\direct\filter\CommonFilters.py". I didnt mean for you to do that though, you could just give an example of using the shader with filtermanager.
Anon
 
Posts: 1556
Joined: Thu Oct 29, 2009 3:07 am

Postby Manou » Sun Jul 24, 2011 12:54 am

The bloom code is working (2-pass blur + HDR), I don't know if the HDR tone mapping is really working, needs more testing.

I've added vignetting effect to the camera, the vignetting effect is function of the aperture size.

The quantity of light received by the lens is function of the aperture size.

I've simplified the dof code, it needs 24 texture lookups now.

I might make a video to show it in motion.
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby Anon » Sun Jul 24, 2011 11:42 am

Cool, you should join forces with Craig.
Anon
 
Posts: 1556
Joined: Thu Oct 29, 2009 3:07 am

Postby Manou » Mon Jul 25, 2011 3:27 am

Hello all,

I'm trying Strauss lighting model (http://wiki.gamedev.net/index.php/D3DBook:%28Lighting%29_Strauss), and I'm not so happy about the result, this should be a metal material :
Image
Also the color diffusion is not as smooth as in the phong model (look at red lighting):
Image :lol:

Anyone got experience with this model ? and what lighting model do you use in your own applications ?

Phong model :
Image

Btw, I can't set my texture format, setFormat(Texture.Format) doesn't have any incidence, I want to try fp16 textures for hdr, I've searched on the forums, someone asked for 128 bits textures format but he couldn't change the format of texture as well. What is the current state on this ? I've tried to include setFormat() in the filtermanager panda class but no success :(.

Thanks.

EDIT :
Image
Looks ok now.
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby Manou » Tue Jul 26, 2011 9:59 am

I'm trying to import custom models but I have still some uv mapping problems :evil: :

Image

I have a more serious question btw and I don't want to create new thread for this, do you still need samples or not (http://www.panda3d.org/forums/viewtopic.php?t=5050) ?
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby Anon » Tue Jul 26, 2011 11:21 am

absolutely :)
Anon
 
Posts: 1556
Joined: Thu Oct 29, 2009 3:07 am

Postby coppertop » Tue Jul 26, 2011 3:33 pm

So you want to change that "todo" into "done", and in the mean time provide better sample models? Are you made of awesomeness or what? ;D Seriously, I'm more and more impressed with your work.
User avatar
coppertop
 
Posts: 526
Joined: Sat Apr 18, 2009 5:48 am

Postby ThomasEgi » Wed Jul 27, 2011 1:24 pm

i am not easily impressed.. but.. in fact. i am impressed right now.
this looks seriously good.

while you are at it..
http://www.gamedev.net/page/resources/_/reference/programming/140/lighting-and-shading/a-simple-and-practical-approach-to-ssao-r2753?
*hint**hint*
User avatar
ThomasEgi
 
Posts: 2147
Joined: Fri Jul 28, 2006 10:43 am
Location: Germany,Koblenz

Postby Craig » Wed Jul 27, 2011 10:32 pm

I have a shader generator project ( http://www.panda3d.org/forums/viewtopic.php?t=10758 ) which I'm currently using in a game project of mine that uses deferred shading. Its still in the very early stages, and I'm making various major API braking changes pretty often so I don't suggest you doing anything with it yet (aside from maybe taking a look at it). Since my game I'm making it for is closed source, the samples are pretty lacking (I'm not going to maintain any decent samples until the API stabilizes). (Some old images of my game are here: http://craig.p3dp.com/MiscPics/fancy/ )


As I assume you may be noticing, having a lot of effects that differ on different objects in your scene can be a pain (writing awesome shader is fun; writing every version of awesome shader you need for you game is not). My shader generator is an attempt to provide a tool for managing and merging all these effects onto the various geoms in the scene. Unlike panda's shader generator, mine does not have major performance issues when you change the renderstate (I don't force regenerating shaders automatically, and my cache only looks at the parts of the render state than are specifically needed to generate the shaders, so updating shader inputs every frame works well).

Technically my shader generator isn't really a shader generator, its more of an implementation of a meta-language for writing custom shader generators, which you could use to make a customizable deferred alternative to panda's built in one. An example of is use is that in my game, some things have normal maps, and some don't, so I used a conditional shader input node to capture the normal map, and use another type of conditional node to select from a sample of that texture, or a plain vertex normal depending on availability. The result is a code generation time switch that writes the correct shader for the requested geom. (I'll mention that this is currently not working quite right, I think it has to do with the actor loading setup though.)

Anyway, when my shader generator is a bit further along, it can serve as a way for you to manage and share all your effects in an easy to use fashion. I'm not looking for much help with the shader generator, but I am looking for lots of help making effects/content/samples to use with it, and you seem to be good at that. If you have any questions regarding my projects, feel free to ask. I'd really like some input from a fellow shader programmer. I want to make sure I'm not missing anything important, and that its actually useful.

I also have tried and failed to have 16 bit textures/buffers.
Craig
 
Posts: 326
Joined: Thu Jul 02, 2009 8:55 pm

Postby Manou » Thu Jul 28, 2011 2:04 am

Hey,

I'll be happy to provide you effects and samples for your system, I need to clean the code before I post here. I'm currently having problems to deferr shadow maps. About your system do you plan to use different lighting models, and for buffer creation how do you plan to have different materials (for my game I'm planning to store materials information in the unused alpha channel as they do in various game, but for a general purpose generator it might be different). Nice screens you have there. More questions, do you allow dynamic branching in shader and what average user specs do you target with your new generator. It will be nice for your system if you or someone else finds a solution to set textures format.
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby Craig » Thu Jul 28, 2011 3:16 am

Manou wrote:Hey,

I'll be happy to provide you effects and samples for your system, I need to clean the code before I post here. I'm currently having problems to deferr shadow maps. About your system do you plan to use different lighting models, and for buffer creation how do you plan to have different materials (for my game I'm planning to store materials information in the unused alpha channel as they do in various game, but for a general purpose generator it might be different). Nice screens you have there. More questions, do you allow dynamic branching in shader and what average user specs do you target with your new generator. It will be nice for your system if you or someone else finds a solution to set textures format.


My generator system isn't really tied to any set of buffers/bitplanes. It works fine for forward shading, deferred, etc. I'll even probably use it for the lighting pass and post process shaders in my deferred setup. Its just a shader meta-language. The complexity of the shader generators made with it up to the user. I'd like to provide both low and high end samples, and have a system for doing quality fallbacks for performance (simply dump a quality constant, perhaps as a tag on render, into the renderstate before generating the shaders).

I'd love to have a big pile of lighting models to choose from. Theoretically it shoule be possible (when I add the feature of composite/hierarchical nodes to the generator) to implement a generic lighting model node that lets you select the lighting model based on tags in the scene graph (ex: provide the coefficients needed for lighting model X, and you automatically get it). Such a lighting node could be used in both forward and deferred configurations (though you might have to settle for a single lighting model for the whole scene with deferred)

Regarding static branching, its possible to generate any possible shader code with my system (you can put a whole custom fshader and vshader in as single nodes if you want), so yes, you can use static branching, but its not too practical. The current system is really great at generation time conditionals, and handling shaders with complex data-flow, but its not very good at runtime conditional stuff (currently any conditional stuff needs to be contained within a single node in the shader graph). In short: possible but not good to use with sub nodes and such. I'm thinking about possible fixes for the design deficiency, and I consider it a major issue. (In fact, conditionals are currently the only major issue I see with the design, and I will find a fix, even if it adds a lot of complexity. The main/worst case it applies is if you want an early exit via discard, its not yet practical to force it to occur as early as possible).

Anyway, while its not too relevant to my shader generator, it is relevant to your thread, so here is how my rendering setup works:

Currently my game renders to 3 buffers in the first pass (Diffuse, normals, misc). Misc holds glow and specular information. I also have a (some what experimental) decal rendering pass where I blend in projected decals (using the same projection approaches as the lights). I couldn't think of a good way for normal map them, so I don't render normals in that pass. Currently that renders to a second diffuse buffer and second misc buffer. Those textures are then pulled in along with the normals for the lighting phase, which generates a lighting buffer thats used along with the normals diffuse and misc to do the final rendering of the deferred shaded objects, including cartoon inking and cell shaded directional lighting. That is then rendered into the window (on a full screen quad), the sky box is then rendered, and then particles and other transparent effects will be rendered (not implemented yet). Then comes the bloom/glow post process, which currently uses alpha, but will use my misc buffer once I start drawing transparent things.

I currently don't have shadows.

I get the positions using the depth texture, and do the most basic normal encoding (norm/2+.5) and stick it in a regular 8bit per channel buffer. Not ideal, but without floating point/16 bit textures, that seems like the best choice.

Example use of my decal system: projecting symbols on the ground (shown in images). Perhaps an more interesting application is projecting damp areas (darken the color, increase the specular coefficient a ton, and the specular amount a bit), or flaming areas (project glow and red patches with no specular). I haven't really had a chance to try anything with it.


Your code is interesting. Your setup process is very different from mine. I create a bunch of custom buffer and cameras (4 camaeras) explicitly and set them all up, configure depth sharing, make most of my own full screen quads without the provided filter stuff and such. I don't touch any AuxBitplaneAttribs. I even see a setShaderAuto() in your code, which I don't touch. I have maybe 4-5 shaders just to do a basic rendering (skybox, models, lights, decals, inking+directional lights+assorted) and I'll need a lot more. My module for just setting up the buffers, cameras, display regions, shaders, lights etc. is just over 400 lines, more than double your entire code.


By the looks of your shader, you don't know about CG's 'lit' function. It and lots of other goodies here: http://http.developer.nvidia.com/CgTuto ... dix_e.html

Edit: I forgot, specifically regarding materials. On load I convert the material object from the egg files (exported from blender) into shader inputs. I also allow a material texture to be blended over this if provided. My shader generator could potentially make it easy to support models with other approaches, such as vertex data, tags, or something else. Mostly this data just ends up packed into the misc buffer. One good approach is to have a list of materials (256 of them) and use an index and lookup table (texture) for the data, but that required more setup so I didn't bother.
Craig
 
Posts: 326
Joined: Thu Jul 02, 2009 8:55 pm

Postby Manou » Fri Aug 12, 2011 2:58 pm

Import working, had to scale the normal map according to the scale of the model. I'll look at gpu particles now, and when finished will clean the overall codes and post.

Image
Image

http://youtu.be/TczKcE0iEyY

A question : how to get the maps directly from the .egg ?

At the moment, I'm sending the various maps as inputs to the shaders for each model, is there a way to have a simpler system (import a full working blender scene with multiple textures would be the goal).
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby Craig » Fri Aug 12, 2011 7:01 pm

Manou wrote:
A question : how to get the maps directly from the .egg ?

At the moment, I'm sending the various maps as inputs to the shaders for each model, is there a way to have a simpler system (import a full working blender scene with multiple textures would be the goal).


I have a rather complex model importer that does a lot of things (especially for my multi part actors). On load, I search for all the textures, and attach them to shader inputs. I have a texture naming convention, so whatever_norm goes on as a normal map etc. Then I use my shader generator to take the existing shader inputs and tags and generate the correct shaders. I'm planning to have a converter application that does most of this work, then dumps the models to bam files. Stuff that does not fit in bam files (shaders and shader inputs) will be put in tags and fixed on load. I believe the normal maps, if setup correctly, are available as some special shader input, but I like to only use my own manually setup ones.
Craig
 
Posts: 326
Joined: Thu Jul 02, 2009 8:55 pm

Postby Manou » Mon Aug 15, 2011 11:02 pm

Ok thanks.

I tried different particles rendering system. The particle system seen in the panda samples is nice but it gets slower when particles get closer to the camera (overdraw), apparently it's a problem with all engines. So I had a look at gpu gems 3 on nvidia site and here is the result :

Image
(particles ideally should come from the bottom of the ship :lol:)

I use a texture buffer for particles, the resolution is 1/8 of the main window, I have no more slowdowns now ! (from 30fps to 120fps). However I coulnd't make soft particles work, maybe because I render all the particles to a single texture buffer and composite it with the final lit scene. The bloom effect helps to reduce square effects anyway.

I've reused the cloud system from Flock author to make it work with deferred lighting, I'm using a few quads for each cloud, the lighting changes with the direction of the sun.

Image
(only one texture at the moment)

Also there is some halo effect around transparent textures, and I can't get true transparency with the deferred system.

Some preview of the upcoming samples :
Image
Image

VIDEO :
http://youtu.be/I4qzmBOV2ig

Still need to find a way to place lights visually...
User avatar
Manou
 
Posts: 144
Joined: Thu Jun 16, 2011 1:15 pm
Location: France

Postby redpanda » Mon Aug 22, 2011 6:14 am

You're doing a great job. Really hope you'll consider contributing these to the Panda3d source in the future. :)

Still need to find a way to place lights visually...

If I understood you correctly, you want to move the lights around with the mouse cursor? I could help with that.
Last edited by redpanda on Mon Aug 22, 2011 6:56 am, edited 1 time in total.
redpanda
 
Posts: 380
Joined: Wed Aug 03, 2011 6:34 am

Next

Return to Code Snippets

Who is online

Users browsing this forum: No registered users and 0 guests