From: <axl...@us...> - 2009-08-08 13:00:29
|
Revision: 460 http://hgengine.svn.sourceforge.net/hgengine/?rev=460&view=rev Author: axlecrusher Date: 2009-08-08 13:00:20 +0000 (Sat, 08 Aug 2009) Log Message: ----------- more improvements for lights Modified Paths: -------------- Mercury2/Themes/default/File/scenegraphDeferred.xml Mercury2/Themes/default/Graphic/differedStep1.frag Mercury2/Themes/default/Graphic/differedStep1.vert Mercury2/Themes/default/Graphic/differedStep2.frag Mercury2/Themes/default/Graphic/differedStep2.vert Mercury2/src/Camera.cpp Mercury2/src/Frustum.cpp Mercury2/src/Frustum.h Mercury2/src/Light.cpp Mercury2/src/Light.h Mercury2/src/RenderDifferedLights.cpp Mercury2/src/Shader.h Mercury2/src/Viewport.cpp Modified: Mercury2/Themes/default/File/scenegraphDeferred.xml =================================================================== --- Mercury2/Themes/default/File/scenegraphDeferred.xml 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/Themes/default/File/scenegraphDeferred.xml 2009-08-08 13:00:20 UTC (rev 460) @@ -1,10 +1,10 @@ <SceneGraph name="root"> <node type="viewport" fov="45" aspect="1.3333" near="0.01" far="100" name="vp"> <node type="cameranode" movx="0" movz="0" movy="0" rotx="0" roty="0" rotz="0" name="camera"> - <node type="mercuryfbo" width="640" height="480" depth="true" tnum="2" name="screenFBO" usescreensize="true" colorbyte0="RGBA16F" colorbyte1="RGBA16F"> + <node type="mercuryfbo" width="640" height="480" depth="true" tnum="1" name="screenFBO" usescreensize="true" colorbyte0="RGBA16F" colorbyte1="RGBA16F"> <asset type="shader" file="GRAPHIC:differedStep1"/> - <asset type="light" atten="10,0,0" fullscreen="true"/> -<!-- <asset type="shader" file="GRAPHIC:test"/> --> +<!-- <asset type="light" atten="10,0,0" fullscreen="true"/> + <asset type="shader" file="GRAPHIC:test"/> --> <node type="transformnode" rotx="-90" movz="-10" movx="0" movy="-5"> <asset type="texture" file="MODEL:map.png"/> <asset type="hgmdlmodel" file="MODEL:map.hgmdl" /> @@ -15,7 +15,7 @@ <node type="transformnode" rotx="-90" > <asset type="texture" file="MODEL:lamp.png"/> <asset type="hgmdlmodel" file="MODEL:lampN.hgmdl" /> - <asset type="light" atten="0.7,50,0.0" /> + <node type="light" atten="0.7,100,0.0" shader="GRAPHIC:differedStep2" /> </node> <node type="billboardnode" billboardaxis="0,1,0" spheremode="true" > <node type="transformnode" roty="180" scalex="0.1" scaley="0.1" alphaPath="true"> @@ -41,7 +41,6 @@ </node> <asset type="texture" file="screenFBO_0" dynamic="true"/> <asset type="texture" file="screenFBO_1" dynamic="true"/> - <asset type="shader" file="GRAPHIC:differedStep2"/> <asset type="renderdifferedlights"/> </node> </node> Modified: Mercury2/Themes/default/Graphic/differedStep1.frag =================================================================== --- Mercury2/Themes/default/Graphic/differedStep1.frag 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/Themes/default/Graphic/differedStep1.frag 2009-08-08 13:00:20 UTC (rev 460) @@ -1,12 +1,27 @@ varying vec3 normal; varying vec3 pos; +varying float dist; +uniform vec4 HG_DepthRange; +uniform vec4 HG_EyePos; +vec2 CartesianToSpherical(vec3 cartesian) +{ + vec2 spherical; + + spherical.x = atan2(cartesian.y, cartesian.x) / 3.14159; + spherical.y = cartesian.z; + + return spherical * 0.5 + 0.5; +} + void main() { - //store position - gl_FragData[0] = vec4(pos, 1.0); + //linear clip space depth + float d = -dist/HG_DepthRange.z; //store normal, a unused - gl_FragData[1] = vec4( normalize(normal), 1.0); + vec3 n = normalize(normal); + n.xy = CartesianToSpherical( n ); + gl_FragData[0] = vec4( n.xy, d, 1.0); } Modified: Mercury2/Themes/default/Graphic/differedStep1.vert =================================================================== --- Mercury2/Themes/default/Graphic/differedStep1.vert 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/Themes/default/Graphic/differedStep1.vert 2009-08-08 13:00:20 UTC (rev 460) @@ -1,7 +1,9 @@ +uniform vec4 HG_EyePos; uniform mat4 HG_ModelMatrix; - +uniform vec4 HG_DepthRange; varying vec3 normal; varying vec3 pos; +varying float dist; void main() { @@ -10,8 +12,10 @@ vec4 n = vec4(gl_Normal, 0); - //normalize in fragment - normal = (HG_ModelMatrix * n).xyz; + //viewspace normal + normal = (gl_ModelViewMatrix * n).xyz; - pos = (HG_ModelMatrix * gl_Vertex).xyz; + //clip space depth + pos = (gl_ModelViewMatrix * gl_Vertex).xyz; + dist = pos.z; } Modified: Mercury2/Themes/default/Graphic/differedStep2.frag =================================================================== --- Mercury2/Themes/default/Graphic/differedStep2.frag 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/Themes/default/Graphic/differedStep2.frag 2009-08-08 13:00:20 UTC (rev 460) @@ -1,25 +1,47 @@ uniform sampler2D HG_Texture0; -uniform sampler2D HG_Texture1; -uniform sampler2D HG_Texture2; uniform vec4 HG_EyePos; uniform ivec4 HG_ViewPort; uniform vec4 HG_LightPos; uniform vec4 HG_LightAtten; uniform vec4 HG_LightColor; +uniform mat4 HG_ModelMatrix; +uniform vec4 HG_DepthRange; + +varying vec3 ecEye; +varying vec3 ecLight; +varying vec3 ecFrag; + +vec3 SphericalToCartesian(vec2 spherical) +{ + vec2 sinCosTheta, sinCosPhi; + + spherical = spherical * 2.0 - 1.0; + sincos(spherical.x * 3.14159, sinCosTheta.x, sinCosTheta.y); + sinCosPhi = vec2(sqrt(1.0 - spherical.y * spherical.y), spherical.y); + + return vec3(sinCosTheta.y * sinCosPhi.x, sinCosTheta.x * sinCosPhi.x, sinCosPhi.y); +} + void main() { - vec2 coord = gl_FragCoord.xy / vec2(HG_ViewPort.zw); - vec3 pos = texture2D(HG_Texture0, coord).xyz; - vec3 norm = texture2D(HG_Texture1, coord).rgb; + vec2 coord = gl_FragCoord.xy / vec2(HG_ViewPort.zw - HG_ViewPort.xy); + vec4 t1 = texture2D(HG_Texture0, coord); +// vec3 norm = texture2D(HG_Texture1, coord).rgb; + vec3 norm = SphericalToCartesian( t1.rg ); + float depth = t1.b; -// norm = normalize(norm); + vec3 ray = ecFrag * (HG_DepthRange.y/-ecFrag.z); + vec3 pos = ray * depth; - vec3 eyeVec = normalize(HG_EyePos.xyz - pos); - vec3 lightDir = HG_LightPos.xyz - pos; + vec3 eyeVec = normalize(ecEye - pos); + vec3 lightDir = ecLight - pos; float dist = length(lightDir); lightDir /= dist; //normalize +// gl_FragColor = vec4(vec3(mod(depth,0.998)), 1.0); +// gl_FragColor = vec4((norm+1.0)*0.5, 1.0); + float NdotL = max(dot(norm, lightDir),0.0); if((dist > HG_LightAtten.w) || (NdotL <= 0.0)) discard; @@ -34,12 +56,12 @@ vec3 color = att * (HG_LightColor.rgb * NdotL); - vec3 hv = normalize( lightDir+(HG_EyePos.xyz-pos) ); + vec3 hv = normalize( lightDir+(ecEye-pos) ); float NdotHV = max(dot(norm,hv),0.0); //pow(max(dot(H, normal.xyz), 0.0) color += att * materialSpec * lightSpec * pow(max(NdotHV, 0.0), 100.0); - gl_FragColor.rgb = clamp(color, 0.0, 1.0); + color = clamp(color, 0.0, 1.0); + gl_FragColor = vec4(color, 1.0); } - Modified: Mercury2/Themes/default/Graphic/differedStep2.vert =================================================================== --- Mercury2/Themes/default/Graphic/differedStep2.vert 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/Themes/default/Graphic/differedStep2.vert 2009-08-08 13:00:20 UTC (rev 460) @@ -1,9 +1,20 @@ -uniform mat4 HG_WorldMatrix; -//vec3 lightPos; +uniform mat4 HG_ModelMatrix; +uniform vec4 HG_EyePos; +uniform vec4 HG_LightPos; +//uniform vec4 HG_NearClip; +uniform vec4 HG_FarClip; +//uniform vec4 HG_ClipExtends; + +varying vec3 ecEye; +varying vec3 ecLight; +varying vec3 ecFrag; + void main() { -// gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = ftransform(); -// lightPos = (HG_WorldMatrix * vec4(0,0,0,1)).xyz; + ecFrag = (gl_ModelViewMatrix * gl_Vertex).xyz; //world position + + ecEye = (gl_ModelViewMatrix * HG_EyePos).xyz; + ecLight = (gl_ModelViewMatrix * vec4(0,0,0,1)).xyz; } Modified: Mercury2/src/Camera.cpp =================================================================== --- Mercury2/src/Camera.cpp 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/src/Camera.cpp 2009-08-08 13:00:20 UTC (rev 460) @@ -23,6 +23,12 @@ void CameraNode::Render(const MercuryMatrix& matrix) { VIEWMATRIX = m_viewMatrix; + + ShaderAttribute sa; + sa.type = ShaderAttribute::TYPE_MATRIX; + sa.value.matrix = m_viewMatrix.Ptr(); + Shader::SetAttribute("HG_ViewMatrix", sa); + TransformNode::Render(matrix); } @@ -66,6 +72,7 @@ sa.value.fFloatV4[0] = EYE.GetX(); sa.value.fFloatV4[1] = EYE.GetY(); sa.value.fFloatV4[2] = EYE.GetZ(); + sa.value.fFloatV4[3] = 1.0f; Shader::SetAttribute("HG_EyePos", sa); // EYE.Print(); Modified: Mercury2/src/Frustum.cpp =================================================================== --- Mercury2/src/Frustum.cpp 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/src/Frustum.cpp 2009-08-08 13:00:20 UTC (rev 460) @@ -89,6 +89,15 @@ aux.NormalizeSelf(); normal = Y.CrossProduct(aux); m_planes[PRIGHT].Setup(m_nc+X*m_nw,normal); + + + //near frustum points + m_ntl = m_planes[PNEAR].GetCenter() + (Y * m_nh/2.0f) - (X * m_nw/2.0f); + m_nbr = m_planes[PNEAR].GetCenter() - (Y * m_nh/2.0f) + (X * m_nw/2.0f); + + //far frustum points + m_ftl = m_planes[PFAR].GetCenter() + (Y * m_fh/2.0f) - (X * m_fw/2.0f); + m_fbr = m_planes[PFAR].GetCenter() - (Y * m_fh/2.0f) + (X * m_fw/2.0f); } void Frustum::Ortho(float left, float right, float bottom, float top, float near, float far) Modified: Mercury2/src/Frustum.h =================================================================== --- Mercury2/src/Frustum.h 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/src/Frustum.h 2009-08-08 13:00:20 UTC (rev 460) @@ -28,6 +28,11 @@ inline float ZNear() const { return m_zNear; } inline float ZFar() const { return m_zFar; } inline float DepthRange() const { return m_zFar - m_zNear; } + + inline float NearWidth() const { return m_nw; } + inline float NearHeight() const { return m_nh; } + inline float FarWidth() const { return m_fw; } + inline float FarHeight() const { return m_fh; } private: MercuryPlane m_planes[6]; @@ -37,6 +42,7 @@ float m_nh, m_nw, m_fh, m_fw; MercuryVector m_nc, m_fc; + MercuryVertex m_ntl, m_nbr, m_ftl, m_fbr; }; extern const Frustum* FRUSTUM; Modified: Mercury2/src/Light.cpp =================================================================== --- Mercury2/src/Light.cpp 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/src/Light.cpp 2009-08-08 13:00:20 UTC (rev 460) @@ -7,10 +7,10 @@ #include <Shader.h> -REGISTER_ASSET_TYPE(Light); +REGISTER_NODE_TYPE(Light); Light::Light() - :MercuryAsset() + :MercuryNode(), m_boundingVolume( NULL ) { m_atten[0] = m_atten[1] = m_atten[2] = 0.0f; m_color[0] = m_color[1] = m_color[2] = 1.0f; @@ -22,12 +22,13 @@ { } -void Light::Render(const MercuryNode* node) +void Light::Render(const MercuryMatrix& matrix) { - m_worldPosition = glGetMatrix(GL_MODELVIEW_MATRIX); - m_worldPosition2 = node->FindGlobalMatrix(); +// printf("render!\n"); + m_worldPosition = FindModelViewMatrix(); + m_worldPosition2 = FindGlobalMatrix(); CURRENTRENDERGRAPH->AddDifferedLight( this ); - m_parent = node; +// m_parent = node; } void Light::LoadFromXML(const XMLNode& node) @@ -38,9 +39,25 @@ if ( !node.Attribute("fullscreen").empty() ) m_fullscreen = node.Attribute("fullscreen")=="true"?true:false; + if ( !node.Attribute("shader").empty() ) + { + MString key = node.Attribute("shader"); + MAutoPtr< MercuryAsset > asset( AssetFactory::GetInstance().Generate( "shader", key ) ); + if ( asset.IsValid() ) + { + Shader* shader = dynamic_cast<Shader*>( asset.Ptr() ); +// shader->LoadFromXML( node ); + shader->LoadShader(key, 0); + SetShader( shader ); +// shader->Init( this ); + } + + m_fullscreen = node.Attribute("fullscreen")=="true"?true:false; + } + ComputeRadius(); - MercuryAsset::LoadFromXML( node ); + MercuryNode::LoadFromXML( node ); } void Light::StrTo3Float(const MString& s, float* a) @@ -96,19 +113,24 @@ glLoadMatrix( m_worldPosition ); if ( !m_boundingVolume ) return; + m_shader->Render( this ); + BoundingBox* bb = (BoundingBox*)m_boundingVolume; // bb->Render(); MercuryVertex p(0,0,0,1); p = m_worldPosition2 * p; -// p.Print(); - ShaderAttribute sa; + sa.type = ShaderAttribute::TYPE_MATRIX; + sa.value.matrix = m_worldPosition2.Ptr(); + Shader::SetAttribute("HG_ModelMatrix", sa); + sa.type = ShaderAttribute::TYPE_FLOATV4; sa.value.fFloatV4[0] = p.GetX(); sa.value.fFloatV4[1] = p.GetY(); sa.value.fFloatV4[2] = p.GetZ(); + sa.value.fFloatV4[3] = 1.0f; Shader::SetAttribute("HG_LightPos", sa); sa.value.fFloatV4[0] = m_atten[0]; @@ -125,11 +147,14 @@ if (m_fullscreen) { glCullFace(GL_BACK); - m_fullScreenQuad.Render( m_parent ); + m_fullScreenQuad.Render( this ); glCullFace(GL_FRONT); } else bb->RenderFaces(); + + m_shader->PostRender( this); + } /**************************************************************************** Modified: Mercury2/src/Light.h =================================================================== --- Mercury2/src/Light.h 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/src/Light.h 2009-08-08 13:00:20 UTC (rev 460) @@ -1,10 +1,11 @@ -#include <MercuryAsset.h> -#include <FullscreenQuad.h> - #ifndef MLIGHT_H #define MLIGHT_H -class Light : public MercuryAsset +#include <MercuryNode.h> +#include <FullscreenQuad.h> +#include <Shader.h> + +class Light : public MercuryNode { public: Light(); @@ -17,7 +18,7 @@ Currently only occlusion culling test is run here.**/ // virtual void PreRender(const MercuryNode* node); - virtual void Render(const MercuryNode* node); + virtual void Render(const MercuryMatrix& matrix); // virtual void PostRender(const MercuryNode* node) {}; ///Loads an asset from an XMLAsset representing itself @@ -26,6 +27,7 @@ static Light* Generate(); void DifferedRender(); + inline void SetShader( Shader* shader) { m_shader = shader; } private: void StrTo3Float(const MString& s, float* a); void ComputeRadius(); @@ -37,9 +39,13 @@ MercuryMatrix m_worldPosition2; bool m_fullscreen; - const MercuryNode* m_parent; +// const MercuryNode* m_parent; FullscreenQuad m_fullScreenQuad; + + MAutoPtr< Shader > m_shader; + + BoundingVolume* m_boundingVolume; }; #endif Modified: Mercury2/src/RenderDifferedLights.cpp =================================================================== --- Mercury2/src/RenderDifferedLights.cpp 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/src/RenderDifferedLights.cpp 2009-08-08 13:00:20 UTC (rev 460) @@ -29,9 +29,8 @@ } glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_POLYGON_BIT); -// glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); - + glDisable(GL_DEPTH_TEST); glDepthMask(false); glBlendFunc(GL_ONE, GL_ONE); @@ -39,7 +38,6 @@ CURRENTRENDERGRAPH->DoDifferedLightPass(); glPopAttrib( ); -// glCullFace(GL_BACK); } RenderDifferedLights* RenderDifferedLights::Generate() Modified: Mercury2/src/Shader.h =================================================================== --- Mercury2/src/Shader.h 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/src/Shader.h 2009-08-08 13:00:20 UTC (rev 460) @@ -89,8 +89,8 @@ ///Explicitly get the OpenGL ProgramID in the event you need it for advanced techniques unsigned int GetProgramID() { return iProgramID; } inline static Shader* GetCurrentShader() { return CurrentShader; } + void LoadShader( const MString& path, float priority ); private: - void LoadShader( const MString& path, float priority ); int32_t GetUniformLocation(const MString& n); Modified: Mercury2/src/Viewport.cpp =================================================================== --- Mercury2/src/Viewport.cpp 2009-08-05 11:16:57 UTC (rev 459) +++ Mercury2/src/Viewport.cpp 2009-08-08 13:00:20 UTC (rev 460) @@ -60,6 +60,28 @@ sa.value.fFloatV4[2] = m_frustum.DepthRange(); sa.value.fFloatV4[3] = 1.0f/m_frustum.DepthRange(); Shader::SetAttribute("HG_DepthRange", sa); + + sa.type = ShaderAttribute::TYPE_FLOATV4; + sa.value.fFloatV4[0] = m_frustum.ZNear(); + sa.value.fFloatV4[1] = m_frustum.ZFar(); + sa.value.fFloatV4[2] = m_frustum.DepthRange(); + sa.value.fFloatV4[3] = 1.0f/m_frustum.DepthRange(); + Shader::SetAttribute("HG_DepthRange", sa); + + sa.type = ShaderAttribute::TYPE_FLOATV4; + m_frustum.GetPlane(PNEAR).GetCenter().ConvertToVector3( sa.value.fFloatV4 ); + Shader::SetAttribute("HG_NearClip", sa); + + sa.type = ShaderAttribute::TYPE_FLOATV4; + m_frustum.GetPlane(PFAR).GetCenter().ConvertToVector3( sa.value.fFloatV4 ); + Shader::SetAttribute("HG_FarClip", sa); + + sa.type = ShaderAttribute::TYPE_FLOATV4; + sa.value.fFloatV4[0] = m_frustum.NearWidth()*0.5f; + sa.value.fFloatV4[1] = m_frustum.NearHeight()*0.5f; + sa.value.fFloatV4[2] = m_frustum.FarWidth()*0.5f; + sa.value.fFloatV4[3] = m_frustum.FarHeight()*0.5f; + Shader::SetAttribute("HG_ClipExtends", sa); } void Viewport::PostRender(const MercuryMatrix& matrix) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |