struct VertexOut { float4 Position :POSITION; float2 TexCoord :TEXCOORD; }; /* Vertex program for cloud rendering */ VertexOut VertexProgram( float4 Position :POSITION, float2 TexCoord:TEXCOORD, uniform float4x4 ModelViewProj :state.matrix.mvp ) { VertexOut Out; Out.TexCoord=TexCoord; Out.Position=mul(ModelViewProj, Position); Out.TexCoord.y=1-Out.TexCoord.y; return Out; } /* Fragment program for cloud rendering */ float3 FragmentProgram( VertexOut In, uniform sampler1D PosTex, uniform sampler2D PhaseTex, uniform sampler2D LVisMap, uniform sampler2D DirMap, uniform float3 LightRad, uniform float3 LightPosition):COLOR { const float eps=0.001; float3 Color=float3(0,0,0); float3 ParticlePos=tex1D(PosTex,In.TexCoord.x).rgb; ParticlePos=float3(0,0,0); float3 toLight=ParticlePos-LightPosition; float3 dir0=normalize(toLight); float2 angles; angles.y=asin(dir0.y); // -pi/2 -- pi/2 float2 d=normalize(dir0.xz); angles.x=acos(d.x)*sign(d.y); // -pi -- pi angles.x=angles.x/6.28+0.5; // 0 -- 1 angles.y=angles.y/3.14+0.5; // 0 -- 1 float nearestdir=tex2D(DirMap,angles).r; float nearestdir2=tex2D(DirMap,angles).g; float weight1=tex2D(DirMap,angles).b; float weight2=tex2D(DirMap,angles).a; if(tex2D(LVisMap,float2(In.TexCoord.x,nearestdir)).r!=0) { Color+=LightRad*weight1*tex2D(PhaseTex,float2(nearestdir,In.TexCoord.y)).r*0.6; } if(tex2D(LVisMap,float2(In.TexCoord.x,nearestdir2)).r!=0) { Color+=LightRad*weight2*tex2D(PhaseTex,float2(nearestdir2,In.TexCoord.y)).r*0.6; } if(abs(In.TexCoord.y-(1-nearestdir))