Jump to content
  • Advertisement
Sign in to follow this  
ekba89

DX11 nvidia rain demo

This topic is 2439 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to render rain with dx11 and hlsl and there aren't a lot of examples to create realistic rain. The best I've found so far is nvidia's rain demo from their directx 10 sdk. I've managed to convert it to directx 11 and it is working but I'm having hard time to understand the main part of their code which i added below.
My first problem is how they indexed their streak images. There are 370 rain streak images and if I'm not mistaken the maximum index value can be 368.
And my second problem is "if"s in the code. I didn't understand their purpose. And why they are using is_EpLp_angle_ccw to invert only one of the horizontal texture coordinates.
Also if there are any other rain tutorial that you can suggest I would like to check it out.

void rainResponse(PSSceneIn input, float3 lightVector, float lightIntensity, float3 lightColor, float3 eyeVector, bool fallOffFactor, inout float4 rainResponseVal)
{

float opacity = 0.0;
float fallOff;
if(fallOffFactor)
{
float distToLight = length(lightVector);
fallOff = 1.0/( distToLight * distToLight);
fallOff = saturate(fallOff);
}
else
{ fallOff = 1;
}
if(fallOff > 0.01 && lightIntensity > 0.01 )
{
float3 dropDir = g_TotalVel;
#define MAX_VIDX 4
#define MAX_HIDX 8
// Inputs: lightVector, eyeVector, dropDir
float3 L = normalize(lightVector);
float3 E = normalize(eyeVector);
float3 N = normalize(dropDir);

bool is_EpLp_angle_ccw = true;
float hangle = 0;
float vangle = abs( (acos(dot(L,N)) * 180/PI) - 90 ); // 0 to 90

{
float3 Lp = normalize( L - dot(L,N)*N );
float3 Ep = normalize( E - dot(E,N)*N );
hangle = acos( dot(Ep,Lp) ) * 180/PI; // 0 to 180
hangle = (hangle-10)/20.0; // -0.5 to 8.5
is_EpLp_angle_ccw = dot( N, cross(Ep,Lp)) > 0;
}

if(vangle>=88.0)
{
hangle = 0;
is_EpLp_angle_ccw = true;
}

vangle = (vangle-10.0)/20.0; // -0.5 to 4.5

// Outputs:
// verticalLightIndex[1|2] - two indices in the vertical direction
// t - fraction at which the vangle is between these two indices (for lerp)
int verticalLightIndex1 = floor(vangle); // 0 to 5
int verticalLightIndex2 = min(MAX_VIDX, (verticalLightIndex1 + 1) );
verticalLightIndex1 = max(0, verticalLightIndex1);
float t = frac(vangle);
// textureCoordsH[1|2] used in case we need to flip the texture horizontally
float textureCoordsH1 = input.tex.x;
float textureCoordsH2 = input.tex.x;

// horizontalLightIndex[1|2] - two indices in the horizontal direction
// s - fraction at which the hangle is between these two indices (for lerp)
int horizontalLightIndex1 = 0;
int horizontalLightIndex2 = 0;
float s = 0;

s = frac(hangle);
horizontalLightIndex1 = floor(hangle); // 0 to 8
horizontalLightIndex2 = horizontalLightIndex1+1;
if( horizontalLightIndex1 < 0 )
{
horizontalLightIndex1 = 0;
horizontalLightIndex2 = 0;
}

if( is_EpLp_angle_ccw )
{
if( horizontalLightIndex2 > MAX_HIDX )
{
horizontalLightIndex2 = MAX_HIDX;
textureCoordsH2 = 1.0 - textureCoordsH2;
}
}
else
{
textureCoordsH1 = 1.0 - textureCoordsH1;
if( horizontalLightIndex2 > MAX_HIDX )
{
horizontalLightIndex2 = MAX_HIDX;
} else
{
textureCoordsH2 = 1.0 - textureCoordsH2;
}
}

if( verticalLightIndex1 >= MAX_VIDX )
{
textureCoordsH2 = input.tex.x;
horizontalLightIndex1 = 0;
horizontalLightIndex2 = 0;
s = 0;
}

// Generate the final texture coordinates for each sample
uint type = input.type;
uint2 texIndicesV1 = uint2(verticalLightIndex1*90 + horizontalLightIndex1*10 + type,
verticalLightIndex1*90 + horizontalLightIndex2*10 + type);
float3 tex1 = float3(textureCoordsH1, input.tex.y, texIndicesV1.x);
float3 tex2 = float3(textureCoordsH2, input.tex.y, texIndicesV1.y);
if( (verticalLightIndex1<4) && (verticalLightIndex2>=4) )
{
s = 0;
horizontalLightIndex1 = 0;
horizontalLightIndex2 = 0;
textureCoordsH1 = input.tex.x;
textureCoordsH2 = input.tex.x;
}

uint2 texIndicesV2 = uint2(verticalLightIndex2*90 + horizontalLightIndex1*10 + type,
verticalLightIndex2*90 + horizontalLightIndex2*10 + type);
float3 tex3 = float3(textureCoordsH1, input.tex.y, texIndicesV2.x);
float3 tex4 = float3(textureCoordsH2, input.tex.y, texIndicesV2.y);
// Sample opacity from the textures
float col1 = rainTextureArray.Sample( samAniso, tex1) * g_rainfactors[texIndicesV1.x];
float col2 = rainTextureArray.Sample( samAniso, tex2) * g_rainfactors[texIndicesV1.y];
float col3 = rainTextureArray.Sample( samAniso, tex3) * g_rainfactors[texIndicesV2.x];
float col4 = rainTextureArray.Sample( samAniso, tex4) * g_rainfactors[texIndicesV2.y];
// Compute interpolated opacity using the s and t factors
float hOpacity1 = lerp(col1,col2,s);
float hOpacity2 = lerp(col3,col4,s);
opacity = lerp(hOpacity1,hOpacity2,t);
opacity = pow(opacity,0.7); // inverse gamma correction (expand dynamic range)
opacity = 4*lightIntensity * opacity * fallOff;
}

rainResponseVal = float4(lightColor,opacity);
}

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!