|
|
|
Return to Code Snippets
by Manou » Sun Jul 03, 2011 5:15 pm
--
Deferred shading & Fancy effects
VIDEO :
http://youtu.be/4nEV3nK7INs
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.
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.
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by 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
by 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
-
by Manou » Sat Jul 16, 2011 5:05 pm
Deferred normal mapping has arrived !
Code incoming.
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by Manou » Tue Jul 19, 2011 4:10 pm
Some news,
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 ?
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by 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.
-

Nemesis#13
-
- Posts: 1040
- Joined: Mon Aug 04, 2008 8:09 pm
- Location: Germany
by 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.
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by 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
by 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
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by 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
by 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 :
without :
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
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by 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
by 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.
-

coppertop
-
- Posts: 526
- Joined: Sat Apr 18, 2009 5:48 am
by 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.
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by 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
by 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.
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by 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
by 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 :
Also the color diffusion is not as smooth as in the phong model (look at red lighting):
Anyone got experience with this model ? and what lighting model do you use in your own applications ?
Phong model :
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 :
Looks ok now.
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by Manou » Tue Jul 26, 2011 9:59 am
I'm trying to import custom models but I have still some uv mapping problems  :
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) ?
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by Anon » Tue Jul 26, 2011 11:21 am
absolutely 
-
Anon
-
- Posts: 1556
- Joined: Thu Oct 29, 2009 3:07 am
by 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.
-

coppertop
-
- Posts: 526
- Joined: Sat Apr 18, 2009 5:48 am
by ThomasEgi » Wed Jul 27, 2011 1:24 pm
-

ThomasEgi
-
- Posts: 2147
- Joined: Fri Jul 28, 2006 10:43 am
- Location: Germany,Koblenz
by 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
by 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.
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by 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
by 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.
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).
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by 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
by 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 :
(particles ideally should come from the bottom of the ship  )
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.
(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 :
VIDEO :
http://youtu.be/I4qzmBOV2ig
Still need to find a way to place lights visually...
-

Manou
-
- Posts: 144
- Joined: Thu Jun 16, 2011 1:15 pm
- Location: France
-
by 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
Return to Code Snippets
Who is online
Users browsing this forum: No registered users and 0 guests
| | |