///////// ///This example shader demonstrates how to use the sprite particle type added by the GTP to OGRE's particle types. ///These sprites are quads with zero size, they should be scaled and rotated towards the camera by the vertex shader. ///All four vertices of the quad are placed in the center of the particle, the z and w components of their texture coordinates ///gives us the offset they should be moved in camera space (these components store the corner direction multiplied by the particle size). ///The x and y components of the texture coordinates store the defult uv for texturing. //////// struct VS_OUT { float4 hPosition : POSITION; float4 texCoord : TEXCOORD0; float4 color : COLOR0; }; VS_OUT Sprite_VS(float4 position : POSITION, float4 texCoord : TEXCOORD0, float4 color : COLOR0, uniform float4x4 worldView, uniform float4x4 Proj) { VS_OUT OUT; ///transform to camera space and create a sprite with vertex offset //texCoord.y = 1.0 - texCoord.y; float2 offset = texCoord.zw; float4 cPosition = mul(worldView, position); cPosition.xy += offset; // cPosition = float4(100*texCoord.xy,0,1); ///projection OUT.hPosition = mul( Proj, cPosition ); OUT.texCoord = texCoord; // OUT.color = float4(offset,1,1.0); OUT.color = color; return OUT; } ///Simple texture mapping float4 Sprite_PS(VS_OUT IN , uniform sampler2D colorTexture : register(s0)):COLOR { return 1; return tex2D( colorTexture, IN.texCoord.xy) * IN.color; } ////////// ///These shaders uses the sprite particle type. They demonstrate the "spherical billboards" (SBB) particle rendering method. ///SBB alter the opacity of a particle according to the objects of the scene it intersects. To find out the correct opacity ///we store scene depth values in a previous step, we assume that the particle is sphere shaped and find the length of the viewray ///that travells inside a particle before reaching an object. ////////// struct SBB_VS_OUT { float4 hPosition : POSITION; float4 texCoord : TEXCOORD0; float3 P : TEXCOORD1; float3 Q : TEXCOORD2; float r : TEXCOORD3; float2 screenCoord : TEXCOORD4; float4 color : COLOR0; }; SBB_VS_OUT SBB_Sprite_VS (float4 position : POSITION, float4 texCoord : TEXCOORD0, float4 color : COLOR, uniform float width, uniform float height, uniform float4x4 worldView, uniform float4x4 Proj) { SBB_VS_OUT OUT; ///transform to camera space and create a sprite with vertex offset float2 offset = texCoord.zw; float4 cPosition; float4 wPosition = position; cPosition = mul(worldView, wPosition); /// P is the particle sphere center OUT.P = cPosition.xyz; OUT.P.z = - 1 * OUT.P.z; cPosition.xy += offset; /// Q is the shaded point (it is moved backwards to avoid unwanted frontplane clipping) OUT.Q = cPosition.xyz; OUT.Q.z = OUT.P.z; OUT.r = abs(texCoord.z); /// calculate screen space position OUT.hPosition = mul( Proj, cPosition ); OUT.screenCoord = (OUT.hPosition.xy / OUT.hPosition.w + 1.0) / 2.0; OUT.screenCoord.y = 1.0 - OUT.screenCoord.y; OUT.screenCoord += float2(0.5/width, 0.5/height); OUT.texCoord = texCoord; OUT.color = color; return OUT; } float4 SBB_Sprite_PS(SBB_VS_OUT IN , // in screenCoord : VPOS, uniform float nearplane, uniform float farplane, uniform float4 color, uniform sampler2D colorTexture : register(s0), uniform sampler2D DepthMap : register(s1), uniform sampler2D PlanckMap : register(s2) ) : COLOR { float4 Color = IN.color; float alpha = 0; /// get the depth values from the depthMap and calculate ray length in sphere float d = length( IN.Q - IN.P ); float Zs; if( d < IN.r ) { float w = sqrt( IN.r * IN.r - d * d ); alpha = w / IN.r; alpha *= pow( (IN.r-d) / IN.r , 2); float F = IN.Q.z - w; float B = IN.Q.z + w; Zs = tex2D( DepthMap, IN.screenCoord ).r; if(Zs == 0) Zs = farplane; float ds = min( Zs, B ) - max( nearplane, F ); // float ds = min( Zs, B ) - F; alpha *= ds / w * 0.5; } /// fetch opacity from a texture Color.a *= tex2D( colorTexture, IN.texCoord.xy).r ; //Color.a *= IN.color.a; Color.a *= alpha; /// address a color map (colors of fire eg.) with the alpha //Color.rgb = tex2D( PlanckMap, Color.aa).rgb; return Color * color; } struct SBB_ILLUM_VS_OUT { float4 hPosition : POSITION; float4 texCoord : TEXCOORD0; float3 P : TEXCOORD1; float3 Q : TEXCOORD2; float r : TEXCOORD3; float2 screenCoord : TEXCOORD4; float4 lightCoord : TEXCOORD5; float4 color : COLOR0; }; SBB_ILLUM_VS_OUT SBB_Sprite_Illum_VS (float4 position : POSITION, float4 texCoord : TEXCOORD0, float4 color : COLOR, uniform float width, uniform float height, uniform float4x4 worldView, uniform float4x4 Proj, uniform float4x4 worldViewInv, uniform float4x4 lightViewProj) { SBB_ILLUM_VS_OUT OUT; ///transform to camera space and create a sprite with vertex offset float2 offset = texCoord.zw; float4 cPosition; float4 wPosition = position; cPosition = mul(worldView, wPosition); /// P is the particle sphere center OUT.P = cPosition.xyz; OUT.P.z = - 1 * OUT.P.z; cPosition.xy += offset; /// Q is the shaded point (it is moved backwards to avoid unwanted frontplane clipping) OUT.Q = cPosition.xyz; OUT.Q.z = OUT.P.z; OUT.r = abs(texCoord.z); /// calculate screen space position OUT.hPosition = mul( Proj, cPosition ); OUT.screenCoord = (OUT.hPosition.xy / OUT.hPosition.w + 1.0) / 2.0; OUT.screenCoord.y = 1.0 - OUT.screenCoord.y; OUT.screenCoord += float2(0.5/width, 0.5/height); OUT.texCoord = texCoord; OUT.color = color; wPosition = mul(worldViewInv, cPosition); OUT.lightCoord = mul(lightViewProj, wPosition); return OUT; } float4 SBB_Sprite_Illum_PS(SBB_ILLUM_VS_OUT IN , // in screenCoord : VPOS, uniform float nearplane, uniform float farplane, uniform float4 color, uniform sampler2D colorTexture : register(s0), uniform sampler2D DepthMap : register(s1), uniform sampler2D illumVolume : register(s2) ) : COLOR { ///identify light volume slices and interpolation float2 lightCoord; lightCoord = (IN.lightCoord.xy + float2(1.0, 1.0)) / 2.0; lightCoord.y = 1.0 - lightCoord.y; float z = IN.lightCoord.z / IN.lightCoord.w; float4 extintion = tex2D(illumVolume, lightCoord); float intensities[5]; intensities[0] = 1.0; intensities[1] = extintion.r; intensities[2] = extintion.g; intensities[3] = extintion.b; intensities[4] = extintion.a; float3 start; float3 end; float3 temp = 1.0; float t; float4 planes = float4(0.33, 0.5, 0.66, 1); if(z < planes.x) { start = intensities[0]; end = intensities[1]; t = z / planes.x; temp = lerp(start, end, t); } if(z > planes.x && z < planes.y) { start = intensities[1]; end = intensities[2]; t = (z - planes.x) / (planes.y - planes.x); temp = lerp(start, end, t); } if(z > planes.y && z < planes.z) { start = intensities[2]; end = intensities[3]; t = (z - planes.y) / (planes.z - planes.y); temp = lerp(start, end, t); } if(z > planes.z) { start = intensities[3]; end = intensities[4]; t = (z - planes.z) / (planes.a - planes.z); temp = lerp(start, end, t); } IN.color.rgb *= temp; /////////////// float4 Color = IN.color; float alpha = 0; /// get the depth values from the depthMap and calculate ray length in sphere float d = length( IN.Q - IN.P ); float Zs; if( d < IN.r ) { float w = sqrt( IN.r * IN.r - d * d ); alpha = w / IN.r; alpha *= pow( (IN.r-d) / IN.r , 2); float F = IN.Q.z - w; float B = IN.Q.z + w; Zs = tex2D( DepthMap, IN.screenCoord ).r; if(Zs == 0) Zs = farplane; float ds = min( Zs, B ) - max( nearplane, F ); // float ds = min( Zs, B ) - F; alpha *= ds / w * 0.5; } /// fetch opacity from a texture Color.a *= tex2D( colorTexture, IN.texCoord.xy).r ; //Color.a *= IN.color.a; Color.a *= alpha; /// address a color map (colors of fire eg.) with the alpha //Color.rgb = tex2D( PlanckMap, Color.aa).rgb; return Color * color; }