Difference between revisions of "Shading Technique - Glow Mapping"
From Horde3D Wiki
(draft) |
(added a dump of my code until I actually finish writing this) |
||
Line 7: | Line 7: | ||
== Overview == | == Overview == | ||
For an in-depth overview of this technique, see the Gamasutra article [http://www.gamasutra.com/features/20040526/james_pfv.htm Real-Time Glow] by By Greg James and John O’Rorke. | For an in-depth overview of this technique, see the Gamasutra article [http://www.gamasutra.com/features/20040526/james_pfv.htm Real-Time Glow] by By Greg James and John O’Rorke. | ||
+ | |||
+ | == Temporary code dump == | ||
+ | Until I finish writing this article, here's the undocumented code ;) | ||
+ | |||
+ | '''Pipeline changes''' | ||
+ | |||
+ | {{CppSourceCode| | ||
+ | description= Setup the RenderTargets. If this is for HDR, then these RenderTargets will already exist, so just change depthBuf to "true" on the first one| | ||
+ | code= | ||
+ | <source lang="cpp" line="1"> | ||
+ | <stage id="Glow"> | ||
+ | <RenderTarget id="BLURBUF1" depthBuf="true" numColBufs="1" format="RGBA8" bilinear="true" scale="0.25" /> | ||
+ | <RenderTarget id="BLURBUF2" depthBuf="false" numColBufs="1" format="RGBA8" bilinear="true" scale="0.25" /> | ||
+ | </stage> | ||
+ | </source>}} | ||
+ | |||
+ | |||
+ | {{CppSourceCode| | ||
+ | description= insert this new stage after the "Geometry" stage.| | ||
+ | code= | ||
+ | <source lang="cpp" line="1"> | ||
+ | <stage id="Glow"> | ||
+ | <SwitchTarget target="BLURBUF1" /> | ||
+ | <ClearTarget depthBuf="true" colBuf0="true" /> | ||
+ | <DrawGeometry context="GLOWMASK" /> | ||
+ | |||
+ | <!-- Repeat these steps as many times as you like, it makes the bloom softer --> | ||
+ | <SwitchTarget target="BLURBUF2" /> | ||
+ | <BindBuffer texUnit="0" target="BLURBUF1" bufIndex="0" /> | ||
+ | <DrawQuad material="postGlow.material.xml" context="BLURV" /> | ||
+ | <SwitchTarget target="BLURBUF1" /> | ||
+ | <BindBuffer texUnit="0" target="BLURBUF2" bufIndex="0" /> | ||
+ | <DrawQuad material="postGlow.material.xml" context="BLURH" /> | ||
+ | |||
+ | <SwitchTarget target="BLURBUF2" /> | ||
+ | <BindBuffer texUnit="0" target="BLURBUF1" bufIndex="0" /> | ||
+ | <DrawQuad material="postGlow.material.xml" context="BLURV" /> | ||
+ | <SwitchTarget target="BLURBUF1" /> | ||
+ | <BindBuffer texUnit="0" target="BLURBUF2" bufIndex="0" /> | ||
+ | <DrawQuad material="postGlow.material.xml" context="BLURH" /> | ||
+ | |||
+ | <SwitchTarget target="BLURBUF2" /> | ||
+ | <BindBuffer texUnit="0" target="BLURBUF1" bufIndex="0" /> | ||
+ | <DrawQuad material="postGlow.material.xml" context="BLURV" /> | ||
+ | <SwitchTarget target="BLURBUF1" /> | ||
+ | <BindBuffer texUnit="0" target="BLURBUF2" bufIndex="0" /> | ||
+ | <DrawQuad material="postGlow.material.xml" context="BLURH" /> | ||
+ | |||
+ | <!-- In the HDR version, target should be set to "HDRBUF" --> | ||
+ | <SwitchTarget target="" /> | ||
+ | <BindBuffer texUnit="0" target="BLURBUF1" bufIndex="0" /> | ||
+ | <DrawQuad material="postGlow.material.xml" context="FINALPASS" /> | ||
+ | </stage> | ||
+ | </source>}} | ||
+ | |||
+ | |||
+ | '''New shader code''' | ||
+ | |||
+ | {{CppSourceCode| | ||
+ | description= This context is designed to be added to a copy of the parallax shader - parallax_glow.shader.xml| | ||
+ | code= | ||
+ | <source lang="cpp" line="1"> | ||
+ | <Context id="GLOWMASK"> | ||
+ | <!-- This material does glow - output colors masked by the alpha channel --> | ||
+ | <VertexShader> | ||
+ | <InsCode code="utilityLib/vertCommon.glsl" /> | ||
+ | <DefCode> | ||
+ | <![CDATA[ | ||
+ | uniform vec3 viewer; | ||
+ | attribute vec2 texCoords0; | ||
+ | attribute vec3 normal, tangent, bitangent; | ||
+ | varying vec3 eyeTS; | ||
+ | varying vec2 texCoords; | ||
+ | varying vec4 pos; | ||
+ | |||
+ | void main( void ) | ||
+ | { | ||
+ | // Transform tangent space basis | ||
+ | vec3 tsbTangent = normalize( calcWorldVec( tangent ) ); | ||
+ | vec3 tsbBitangent = normalize( calcWorldVec( bitangent ) ); | ||
+ | vec3 tsbNormal = normalize( calcWorldVec( normal ) ); | ||
+ | |||
+ | // Calculate world space position | ||
+ | pos = calcWorldPos( gl_Vertex ); | ||
+ | |||
+ | // Eye vector and eye vector in tangent space | ||
+ | eyeTS = calcTanVec( viewer - pos.xyz, tsbTangent, tsbBitangent, tsbNormal ); | ||
+ | |||
+ | // Calculate texture coordinates and clip space position | ||
+ | texCoords = texCoords0; | ||
+ | gl_Position = gl_ModelViewProjectionMatrix * pos; | ||
+ | } | ||
+ | ]]> | ||
+ | </DefCode> | ||
+ | </VertexShader> | ||
+ | |||
+ | <FragmentShader> | ||
+ | <DefCode> | ||
+ | <![CDATA[ | ||
+ | uniform sampler2D tex0; | ||
+ | varying vec3 eyeTS; | ||
+ | varying vec2 texCoords; | ||
+ | |||
+ | void main( void ) | ||
+ | { | ||
+ | const float plxScale = 0.03; | ||
+ | const float plxBias = -0.015; | ||
+ | |||
+ | // Iterative parallax mapping | ||
+ | vec3 newCoords = vec3( texCoords, 0 ); | ||
+ | vec3 eye = normalize( eyeTS ); | ||
+ | for( int i = 0; i < 4; ++i ) | ||
+ | { | ||
+ | vec4 nmap = texture2D( tex0, texCoords.st ); | ||
+ | float height = nmap.a * plxScale + plxBias; | ||
+ | newCoords += (height - newCoords.p) * nmap.z * eye; | ||
+ | } | ||
+ | |||
+ | vec4 glow = texture2D( tex0, newCoords.st ).rgba; | ||
+ | glow *= glow.a; | ||
+ | |||
+ | gl_FragColor = glow; | ||
+ | } | ||
+ | ]]> | ||
+ | </DefCode> | ||
+ | </FragmentShader> | ||
+ | </Context> | ||
+ | </source>}} | ||
+ | |||
+ | |||
+ | {{CppSourceCode| | ||
+ | description= This context is designed to be added to the original skinning shaders - skinning.shader.xml and skinning_metal.shader.xml| | ||
+ | code= | ||
+ | <source lang="cpp" line="1"> | ||
+ | <Context id="GLOWMASK"> | ||
+ | <!-- This material does not glow - output black pixels --> | ||
+ | <VertexShader> | ||
+ | <InsCode code="utilityLib/vertCommon.glsl" /> | ||
+ | <InsCode code="utilityLib/vertSkinning.glsl" /> | ||
+ | <DefCode> | ||
+ | <![CDATA[ | ||
+ | void main( void ) | ||
+ | { | ||
+ | // Calculate skinning matrices | ||
+ | mat4 skinningMat = calcSkinningMat(); | ||
+ | mat3 skinningMatVec = getSkinningMatVec( skinningMat ); | ||
+ | // Calculate world space position | ||
+ | vec4 pos = calcWorldPos( skinPos( gl_Vertex, skinningMat ) ); | ||
+ | // Calculate clip space position | ||
+ | gl_Position = gl_ModelViewProjectionMatrix * pos; | ||
+ | } | ||
+ | ]]> | ||
+ | </DefCode> | ||
+ | </VertexShader> | ||
+ | |||
+ | <FragmentShader> | ||
+ | <InsCode code="utilityLib/fragLighting.glsl" /> | ||
+ | <DefCode> | ||
+ | <![CDATA[ | ||
+ | void main( void ) | ||
+ | { | ||
+ | gl_FragColor.rgb = vec3(0,0,0); | ||
+ | } | ||
+ | ]]> | ||
+ | </DefCode> | ||
+ | </FragmentShader> | ||
+ | </Context> | ||
+ | </source>}} | ||
+ | |||
== Example Result == | == Example Result == |
Revision as of 10:09, 7 August 2008
|
|