//------------------------------------ float4x4 g_mWorldView; // World View Matrix float4x4 g_mView; // View Matrix float4x4 g_mProj; // Projection Matrix float4x4 g_mWorldViewProjection; // World View Projection Matrix //float4x4 MatIP; // Inverse Projection Matrix //float3 ParticlePosition; // Particle's center in world coordinates //float2 CurrentPattern; // Current pattern offset. //float2 PatternSize; // Pattern size. float ParticleSize; // Particle's size in world units. float ReciprocalParticleSize; // 1/Particle size. //float4 ParticleColor; // Particle color and opacity. //float ScreenSpaceRotation; // Rotation of particle in radiants. float NearPlaneDistance; // Distance of the near plane. float FarPlaneMinusNearPlane; // Distance of the far plane minus distance of the near plane. texture g_txCurrentTexture; texture g_txDepthBuffer; //------------------------------------ struct vertexInput { float3 position : POSITION; float4 texCoord : TEXCOORD0; }; struct vertexOutput { float4 HPosition : POSITION; float4 ColorTextureCoord : TEXCOORD0; float2 DepthBufferCoord : TEXCOORD1; float ParticleDepth : TEXCOORD2; }; struct pixelOutput { float4 color : COLOR; }; struct depthVertexInput { float4 position : POSITION; float4 texCoord : TEXCOORD0; }; struct depthVertexOutput { float4 HPosition : POSITION; float4 texCoord : TEXCOORD0; }; //------------------------------------ #define SAMPLER_LINEAR(g_samplerMap, g_txMap); \ sampler2D g_samplerMap = sampler_state { \ Texture = ; \ MinFilter = Linear; \ MagFilter = Linear; \ MipFilter = Linear; \ AddressU = BORDER; \ AddressV = BORDER; \ }; #define SAMPLER_POINT(g_samplerMap, g_txMap); \ sampler2D g_samplerMap = sampler_state { \ Texture = ; \ MinFilter = Point; \ MagFilter = Point; \ MipFilter = Point; \ AddressU = BORDER; \ AddressV = BORDER; \ }; SAMPLER_LINEAR(g_samplerCurrentTexture, g_txCurrentTexture); //SAMPLER_POINT(g_samplerDepthBuffer, g_txDepthBuffer); SAMPLER_LINEAR(g_samplerDepthBuffer, g_txDepthBuffer); //sampler DepthBuffer; //---------------------------------------------- depthVertexOutput DepthPassVS(depthVertexInput IN) { depthVertexOutput OUT; float4 vertexpos = float4(IN.position.xyz, 1.0); float4 eyespace = mul(vertexpos, g_mWorldViewProjection); OUT.HPosition = eyespace; float tempDepth = saturate(eyespace.z/FarPlaneMinusNearPlane); IN.texCoord.a = tempDepth; OUT.texCoord = IN.texCoord; return OUT; } pixelOutput DepthPassPS(depthVertexOutput IN) { pixelOutput OUT; float depth = IN.texCoord.a; OUT.color = float4(depth, depth, depth, depth); return OUT; } //------------------------------------ vertexOutput DepthImposterVS(vertexInput IN) { vertexOutput OUT; // Calculate particle's center position in eye space. //float4 vertexpos = float4(ParticlePosition.xyz, 1.0); float4 vertexpos = float4(IN.position.xyz, 1.0); float4 eyespace = mul(vertexpos, g_mWorldView); // Calculate offset and size for this vertex depending on input position. /*float2 offset = float2(IN.position.xy) * ParticleSize; // Include screen space rotation. float anglesin = sin(ScreenSpaceRotation); float anglecos = cos(ScreenSpaceRotation); float2x2 rotmatrix; rotmatrix[0][0] = anglecos; rotmatrix[1][0] = -anglesin; rotmatrix[0][1] = anglesin; rotmatrix[1][1] = anglecos; float2 rotate = mul(rotmatrix, offset); eyespace += float4(rotate.xy, -ParticleSize, 0.0);*/ eyespace.z += ParticleSize; // Write linear depth of this vertex to the output. //OUT.ParticleDepth = (eyespace.z); // Multiplicate with projection matrix to get final vertex position. float4 finalpos = mul(eyespace, g_mProj); OUT.HPosition = finalpos; OUT.ParticleDepth = finalpos.z/FarPlaneMinusNearPlane; //Dividieren durch zfar usw // Apply w-division to get normalized device coordinates [-1,1]. float2 devicecoords = finalpos.xy / finalpos.w; // No transform them into texture coordinates [0,1]. devicecoords = devicecoords * 0.5 + 0.5; devicecoords.y = 1.0 - devicecoords.y; OUT.DepthBufferCoord = devicecoords; // Texture coordinate depends on current pattern index and pattern size. /*OUT.ColorTextureCoord = IN.texCoord * float4(PatternSize.xy, 0.0, 1.0) + float4(CurrentPattern.xy, 0.0, 1.0);*/ OUT.ColorTextureCoord = IN.texCoord; return OUT; } //------------------------------------ pixelOutput DepthImposterPS(vertexOutput IN) { pixelOutput OUT; // Do a lookup in the depth buffer. float4 lookup = float4(IN.DepthBufferCoord.xy, 0.0, 1.0); float depth = tex2D(g_samplerDepthBuffer, lookup).a; // Calculate linear depth /*float4 transform; transform.x = IN.DepthBufferCoord.x * 2.0 - 1.0; transform.y = ((1.0 - IN.DepthBufferCoord.y) * 2.0 - 1.0); transform.z = depth; transform.w = 1.0; float4 aftertransform = mul(transform, MatIP); aftertransform.xyz /= aftertransform.w;*/ // Calculate visible range of the particle. //float difference = abs(aftertransform.z - IN.ParticleDepth); float difference = abs(depth - IN.ParticleDepth); difference *= ReciprocalParticleSize; difference = min(difference, 1.0); // Multiply texel by input color. float4 texturecolor = tex2D(g_samplerCurrentTexture, IN.ColorTextureCoord); texturecolor.a *= difference; //texturecolor.rgb *= difference; //texturecolor.rgb = float3(1, 0, 0); OUT.color = texturecolor;// * ParticleColor; return OUT; } // // Effect // #define Technique(name); \ technique name \ { \ pass p0 \ { \ VertexShader = compile vs_3_0 name##VS(); \ PixelShader = compile ps_3_0 name##PS(); \ } \ } Technique( DepthImposter ); Technique( DepthPass );