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 MoriaDust_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 MoriaDust_PS(SBB_VS_OUT IN , // in screenCoord : VPOS, uniform float nearplane, uniform float farplane, uniform float4 lightCPos, uniform float lightPower, uniform float4 color, uniform float symmetry, uniform sampler2D colorTexture : register(s0), uniform sampler2D DepthMap : register(s1), uniform sampler2D PhaseMap : register(s2) ) : COLOR { float4 Color = IN.color * 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 *= alpha; //illumination lightCPos.z *= -1; float2 L = lightCPos.xy - IN.Q.xy; float ld = length(L); L = L / ld; float3 V = normalize(-IN.Q); float phase;// = /*lightPower / (ld*ld) * */tex2D(PhaseMap, float2(symmetry, dot(L,V)) * 0.5 + 0.5).r; // float phase = (dot(L, V) + 1.0) * 0.5; float ld2 = max(0.01, ld * ld); phase = lightPower / ld2; Color.rgb *= phase; return Color; }