Added caustics; Added underwater dust; Fixed sparks; Added waterfall mist; Fixed various bugs;
BIN
Build/CausticsRender_001.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_002.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_003.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_004.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_005.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_006.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_007.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_008.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_009.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_010.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_011.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_012.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_013.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_014.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_015.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
Build/CausticsRender_016.bmp
Normal file
After Width: | Height: | Size: 192 KiB |
|
@ -6,6 +6,8 @@
|
|||
#define MODELTYPE_PICKUP 5
|
||||
#define MODELTYPE_LARA 6
|
||||
#define MODELTYPE_SKY 7
|
||||
#define MODELTYPE_WATER_SURFACE 8
|
||||
#define MODELTYPE_ROOM_UNDERWATER 9
|
||||
|
||||
#define DEPTH_BIAS 0.0f
|
||||
#define TEXEL_SIZE 1.0f / 2048.0f
|
||||
|
@ -42,7 +44,7 @@ sampler VertexColorSampler = sampler_state
|
|||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
|
||||
/*texture2D ShadowMap;
|
||||
sampler ShadowSampler = sampler_state
|
||||
{
|
||||
|
@ -136,9 +138,14 @@ float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
|||
float3 diffuseColor = tex2D(ColorSampler, input.TextureCoordinate).rgb;
|
||||
float3 ambientColor = tex2D(VertexColorSampler, input.TextureCoordinate).rgb;
|
||||
float4 light = tex2D(LightSampler, input.TextureCoordinate);
|
||||
int pixelFlags = tex2D(NormalSampler, input.TextureCoordinate).w * 64.0f;
|
||||
/*int pixelFlags = tex2D(NormalSampler, input.TextureCoordinate).w * 64.0f;
|
||||
int modelType = pixelFlags % 32;
|
||||
bool underwater = (pixelFlags / 32 == 1);
|
||||
int pixelFlags = normalData.w * 64.0f;
|
||||
bool underwater = ((pixelFlags / 32) == 1);
|
||||
if (pixelFlags >= 32) pixelFlags -= 32;
|
||||
int modelType = pixelFlags;*/
|
||||
int modelType = round(tex2D(NormalSampler, input.TextureCoordinate).w * 16.0f);
|
||||
//if (underwater)
|
||||
// return float4(0, 0, 1, 1);
|
||||
|
||||
|
@ -150,7 +157,7 @@ float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
|||
|
||||
float shadowOcclusion = 1.0f;
|
||||
|
||||
if (modelType == MODELTYPE_ROOM)
|
||||
if (modelType == MODELTYPE_ROOM || modelType == MODELTYPE_ROOM_UNDERWATER)
|
||||
{
|
||||
if (CastShadows)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#define MODELTYPE_PICKUP 5
|
||||
#define MODELTYPE_LARA 6
|
||||
#define MODELTYPE_SKY 7
|
||||
#define MODELTYPE_WATER_SURFACE 8
|
||||
#define MODELTYPE_ROOM_UNDERWATER 9
|
||||
|
||||
#define BLENDMODE_OPAQUE 0
|
||||
#define BLENDMODE_ALPHATEST 1
|
||||
|
@ -57,6 +59,7 @@ int ModelType;
|
|||
int BlendMode;
|
||||
bool UseSkinning;
|
||||
bool Underwater;
|
||||
float4 AmbientLight;
|
||||
|
||||
texture TextureAtlas;
|
||||
sampler2D TextureAtlasSampler = sampler_state {
|
||||
|
@ -67,6 +70,17 @@ sampler2D TextureAtlasSampler = sampler_state {
|
|||
AddressV = Wrap;
|
||||
};
|
||||
|
||||
texture2D CausticsMap;
|
||||
sampler CausticsSampler = sampler_state
|
||||
{
|
||||
Texture = (CausticsMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
|
@ -77,18 +91,18 @@ VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
|
|||
if (UseSkinning)
|
||||
{
|
||||
worldPosition = mul(float4(input.Position, 1), mul(Bones[input.Bone], World));
|
||||
normal = mul(float4(input.Normal, 1), mul(Bones[input.Bone], World));
|
||||
normal = mul(float4(input.Normal, 1), Bones[input.Bone]);
|
||||
}
|
||||
else
|
||||
{
|
||||
worldPosition = mul(float4(input.Position, 1), World);
|
||||
normal = mul(float4(input.Normal, 1), World);
|
||||
normal = float4(input.Normal, 1.0f); // mul(float4(input.Normal, 1), World);
|
||||
}
|
||||
|
||||
float4 viewPosition = mul(worldPosition, View);
|
||||
|
||||
output.Position = mul(viewPosition, Projection);
|
||||
output.Normal = normalize(input.Normal);
|
||||
output.Normal = normalize(normal.xyz);
|
||||
output.TextureCoordinate = input.TextureCoordinate;
|
||||
output.Color = input.Color;
|
||||
output.WorldPosition = worldPosition;
|
||||
|
@ -103,7 +117,7 @@ PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
|
|||
PixelShaderOutput output;
|
||||
|
||||
float4 vertexColors = float4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if (ModelType == MODELTYPE_ROOM)
|
||||
if (ModelType == MODELTYPE_ROOM || ModelType == MODELTYPE_ROOM_UNDERWATER)
|
||||
{
|
||||
float3 colorMul = min(input.Color.xyz * 2.0f, 1.0f);
|
||||
vertexColors = float4(colorMul, 1.0f);
|
||||
|
@ -118,17 +132,42 @@ PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
|
|||
output.Color.a = 0.1f;
|
||||
|
||||
output.Normal.xyz = 0.5f * (input.Normal.xyz + 1.0f);
|
||||
float pixelFlags = ModelType;
|
||||
if (Underwater) pixelFlags += 32.0f;
|
||||
output.Normal.w = pixelFlags / 64.0f;
|
||||
output.Normal.w = ModelType / 16.0f;
|
||||
//float pixelFlags = ModelType;
|
||||
//if (Underwater) pixelFlags += 32.0f;
|
||||
//output.Normal.w = pixelFlags / 64.0f;
|
||||
//output.Normal.w = 1.0f;
|
||||
|
||||
output.Depth = input.PositionCopy.z / input.PositionCopy.w; // , 0.0f, 0.0f, 1.0f); // float4(d, 0.0f, 0.0f, 1.0f);
|
||||
output.Depth = input.PositionCopy.z / input.PositionCopy.w;
|
||||
|
||||
if (ModelType == MODELTYPE_ROOM)
|
||||
if (ModelType == MODELTYPE_ROOM_UNDERWATER)
|
||||
{
|
||||
float3 position = input.WorldPosition.xyz;
|
||||
float3 normal = input.Normal.xyz;
|
||||
|
||||
float fracX = position.x - floor(position.x / 2048.0f) * 2048.0f;
|
||||
float fracY = position.y - floor(position.y / 2048.0f) * 2048.0f;
|
||||
float fracZ = position.z - floor(position.z / 2048.0f) * 2048.0f;
|
||||
|
||||
float attenuation = saturate(dot(float3(0.0f, -1.0f, 0.0f), normal));
|
||||
|
||||
float3 blending = abs(normal);
|
||||
blending = normalize(max(blending, 0.00001f));
|
||||
float b = (blending.x + blending.y + blending.z);
|
||||
blending /= float3(b, b, b);
|
||||
|
||||
float3 p = float3(fracX, fracY, fracZ) / 2048.0f;
|
||||
float3 xaxis = tex2D(CausticsSampler, p.yz).rgb;
|
||||
float3 yaxis = tex2D(CausticsSampler, p.xz).rgb;
|
||||
float3 zaxis = tex2D(CausticsSampler, p.xy).rgb;
|
||||
|
||||
vertexColors += float4((xaxis * blending.x + yaxis * blending.y + zaxis * blending.z).xyz, 0.0f) * attenuation;
|
||||
}
|
||||
|
||||
if (ModelType == MODELTYPE_ROOM || ModelType == MODELTYPE_ROOM_UNDERWATER)
|
||||
output.VertexColor = vertexColors;
|
||||
else
|
||||
output.VertexColor = float4(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
output.VertexColor = float4(AmbientLight.rgb, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
544
Build/Light.fx
|
@ -1,250 +1,296 @@
|
|||
#define LIGHTTYPE_SUN 0
|
||||
#define LIGHTTYPE_POINT 1
|
||||
#define LIGHTTYPE_SPOT 2
|
||||
#define LIGHTTYPE_SHADOW 3
|
||||
|
||||
#define MODELTYPE_HORIZON 0
|
||||
#define MODELTYPE_ROOM 1
|
||||
#define MODELTYPE_MOVEABLE 2
|
||||
#define MODELTYPE_STATIC 3
|
||||
#define MODELTYPE_INVENTORY 4
|
||||
#define MODELTYPE_PICKUP 5
|
||||
#define MODELTYPE_LARA 6
|
||||
#define MODELTYPE_SKY 7
|
||||
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float3 Position : POSITION0;
|
||||
float2 TextureCoordinate : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : POSITION0;
|
||||
float2 TextureCoordinate : TEXCOORD0;
|
||||
float4 ScreenPosition : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct PixelShaderOutput
|
||||
{
|
||||
float4 Light : COLOR0;
|
||||
float4 Shadow : COLOR1;
|
||||
};
|
||||
|
||||
float4 LightPosition;
|
||||
float4 LightDirection;
|
||||
float4 LightColor;
|
||||
int LightType;
|
||||
float LightIn;
|
||||
float LightOut;
|
||||
float LightIntensity;
|
||||
float LightRange;
|
||||
bool LightDynamic;
|
||||
bool CastShadows;
|
||||
|
||||
float3 CameraPosition;
|
||||
|
||||
float4x4 World;
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjectionInverse;
|
||||
float4x4 LightView;
|
||||
float4x4 LightProjection;
|
||||
|
||||
bool AmbientPass;
|
||||
|
||||
float HalfPixelX = 1.0f / 800.0f;
|
||||
float HalfPixelY = 1.0f / 600.0f;
|
||||
|
||||
texture2D ColorMap;
|
||||
sampler ColorSampler = sampler_state
|
||||
{
|
||||
Texture = (ColorMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
texture2D DepthMap;
|
||||
sampler DepthSampler = sampler_state
|
||||
{
|
||||
Texture = (DepthMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
Mipfilter = POINT;
|
||||
};
|
||||
|
||||
texture2D NormalMap;
|
||||
sampler NormalSampler = sampler_state
|
||||
{
|
||||
Texture = (NormalMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
Mipfilter = POINT;
|
||||
};
|
||||
|
||||
texture2D VertexColorMap;
|
||||
sampler VertexColorSampler = sampler_state
|
||||
{
|
||||
Texture = (VertexColorMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
/*textureCUBE ShadowMapCube;
|
||||
samplerCUBE ShadowMapCubeSampler = sampler_state {
|
||||
texture = (ShadowMapCube);
|
||||
MinFilter = Point;
|
||||
MagFilter = Point;
|
||||
MipFilter = None;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};*/
|
||||
|
||||
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
|
||||
if (LightType == LIGHTTYPE_SUN)
|
||||
output.Position = float4(input.Position, 1.0f);
|
||||
else
|
||||
{
|
||||
float4 worldPosition = mul(float4(input.Position, 1.0f), World);
|
||||
float4 viewPosition = mul(worldPosition, View);
|
||||
output.Position = mul(viewPosition, Projection);
|
||||
}
|
||||
|
||||
output.TextureCoordinate = input.TextureCoordinate - float2(HalfPixelX, HalfPixelY);
|
||||
output.ScreenPosition = output.Position;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
||||
{
|
||||
float4 output;
|
||||
output = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
float2 texCoord = input.TextureCoordinate;
|
||||
if (LightType != LIGHTTYPE_SUN)
|
||||
{
|
||||
input.ScreenPosition.xy /= input.ScreenPosition.w;
|
||||
texCoord = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1);
|
||||
texCoord -= float2(0.5f / 800.0f, 0.5f / 600.0f);
|
||||
}
|
||||
|
||||
// Get the normal and transform back to -1 ... 1
|
||||
float4 normalData = tex2D(NormalSampler, texCoord);
|
||||
float3 normal = 2.0f * normalData - 1.0f;
|
||||
|
||||
//normal.z = sqrt(1.0f - normal.x * normal.x - normal.y * normal.y);
|
||||
|
||||
int modelType = (int)(normalData.w * 16.0f);
|
||||
float specularPower = 1.0f; // normalData.w;
|
||||
|
||||
// Get the depth value
|
||||
float depthVal = tex2D(DepthSampler, texCoord).r;
|
||||
|
||||
// We lit room geometry only in the case of dynamic lights
|
||||
if (modelType == MODELTYPE_ROOM && !LightDynamic)
|
||||
{
|
||||
// Is this light dynamic? In not, then I don't do any further calculations
|
||||
return output;
|
||||
}
|
||||
|
||||
// Get specular intensity
|
||||
float specularIntensity = tex2D(ColorSampler, texCoord).a;
|
||||
|
||||
// Now the shader is different according to light type
|
||||
if (LightType == LIGHTTYPE_SUN)
|
||||
{
|
||||
// Compute screen-space position
|
||||
float4 position;
|
||||
position.x = input.TextureCoordinate.x * 2.0f - 1.0f;
|
||||
position.y = -(input.TextureCoordinate.y * 2.0f - 1.0f);
|
||||
position.z = depthVal;
|
||||
position.w = 1.0f;
|
||||
|
||||
// Transform to world space
|
||||
position = mul(position, ViewProjectionInverse);
|
||||
position /= position.w;
|
||||
|
||||
// Surface-to-light vector
|
||||
float3 lightVector = -normalize(LightDirection);
|
||||
|
||||
// Compute diffuse light
|
||||
float NdL = max(0, dot(normal, lightVector));
|
||||
float3 diffuseLight = NdL * LightColor.rgb;
|
||||
|
||||
// Reflection vector
|
||||
float3 reflectionVector = normalize(reflect(lightVector, normal));
|
||||
|
||||
// Camera-to-surface vector
|
||||
float3 directionToCamera = normalize(CameraPosition - position);
|
||||
|
||||
// Compute specular light
|
||||
float specularLight = specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);
|
||||
|
||||
// Output the two lights
|
||||
output = float4(diffuseLight.rgb, specularLight);
|
||||
}
|
||||
else if (LightType == LIGHTTYPE_POINT)
|
||||
{
|
||||
// Compute screen-space position
|
||||
float4 position;
|
||||
position.xy = input.ScreenPosition.xy;
|
||||
position.z = depthVal;
|
||||
position.w = 1.0f;
|
||||
|
||||
// Transform to world space
|
||||
position = mul(position, ViewProjectionInverse);
|
||||
position /= position.w;
|
||||
|
||||
// Surface-to-light vector
|
||||
float3 lightVector = LightPosition - position;
|
||||
|
||||
// Compute attenuation based on distance - linear attenuation
|
||||
float attenuation = saturate(1.0f - length(lightVector) / LightOut);
|
||||
|
||||
// Normalize light vector
|
||||
lightVector = normalize(lightVector);
|
||||
|
||||
// Compute diffuse light
|
||||
float NdL = pow((dot(normal, lightVector) * 0.5f) + 0.5f, 2); //max(0, dot(normal, lightVector));
|
||||
float3 diffuseLight = NdL * LightColor.rgb;
|
||||
|
||||
// Reflection vector
|
||||
float3 reflectionVector = normalize(reflect(-lightVector, normal));
|
||||
|
||||
// Camera-to-surface vector
|
||||
float3 directionToCamera = normalize(CameraPosition - position);
|
||||
|
||||
// Compute specular light
|
||||
float specularLight = specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);
|
||||
|
||||
// Take into account attenuation and lightIntensity.
|
||||
output = attenuation * LightIntensity * float4(diffuseLight.rgb, specularLight) * 0.75f;
|
||||
}
|
||||
|
||||
//output.a = 0.5f;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
technique Light
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
VertexShader = compile vs_3_0 VertexShaderFunction();
|
||||
PixelShader = compile ps_3_0 PixelShaderFunction();
|
||||
}
|
||||
#define LIGHTTYPE_SUN 0
|
||||
#define LIGHTTYPE_POINT 1
|
||||
#define LIGHTTYPE_SPOT 2
|
||||
#define LIGHTTYPE_SHADOW 3
|
||||
|
||||
#define MODELTYPE_HORIZON 0
|
||||
#define MODELTYPE_ROOM 1
|
||||
#define MODELTYPE_MOVEABLE 2
|
||||
#define MODELTYPE_STATIC 3
|
||||
#define MODELTYPE_INVENTORY 4
|
||||
#define MODELTYPE_PICKUP 5
|
||||
#define MODELTYPE_LARA 6
|
||||
#define MODELTYPE_SKY 7
|
||||
#define MODELTYPE_WATER_SURFACE 8
|
||||
#define MODELTYPE_ROOM_UNDERWATER 9
|
||||
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float3 Position : POSITION0;
|
||||
float2 TextureCoordinate : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : POSITION0;
|
||||
float2 TextureCoordinate : TEXCOORD0;
|
||||
float4 ScreenPosition : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct PixelShaderOutput
|
||||
{
|
||||
float4 Light : COLOR0;
|
||||
float4 Shadow : COLOR1;
|
||||
};
|
||||
|
||||
float4 LightPosition;
|
||||
float4 LightDirection;
|
||||
float4 LightColor;
|
||||
int LightType;
|
||||
float LightIn;
|
||||
float LightOut;
|
||||
float LightIntensity;
|
||||
float LightRange;
|
||||
bool LightDynamic;
|
||||
bool CastShadows;
|
||||
|
||||
float3 CameraPosition;
|
||||
|
||||
float4x4 World;
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjectionInverse;
|
||||
float4x4 LightView;
|
||||
float4x4 LightProjection;
|
||||
|
||||
bool AmbientPass;
|
||||
|
||||
float HalfPixelX = 1.0f / 800.0f;
|
||||
float HalfPixelY = 1.0f / 600.0f;
|
||||
|
||||
texture2D ColorMap;
|
||||
sampler ColorSampler = sampler_state
|
||||
{
|
||||
Texture = (ColorMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
texture2D DepthMap;
|
||||
sampler DepthSampler = sampler_state
|
||||
{
|
||||
Texture = (DepthMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
Mipfilter = POINT;
|
||||
};
|
||||
|
||||
texture2D NormalMap;
|
||||
sampler NormalSampler = sampler_state
|
||||
{
|
||||
Texture = (NormalMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
Mipfilter = POINT;
|
||||
};
|
||||
|
||||
texture2D VertexColorMap;
|
||||
sampler VertexColorSampler = sampler_state
|
||||
{
|
||||
Texture = (VertexColorMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
/*texture2D CausticsMap;
|
||||
sampler CausticsSampler = sampler_state
|
||||
{
|
||||
Texture = (CausticsMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};*/
|
||||
|
||||
/*textureCUBE ShadowMapCube;
|
||||
samplerCUBE ShadowMapCubeSampler = sampler_state {
|
||||
texture = (ShadowMapCube);
|
||||
MinFilter = Point;
|
||||
MagFilter = Point;
|
||||
MipFilter = None;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};*/
|
||||
|
||||
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
|
||||
if (LightType == LIGHTTYPE_SUN)
|
||||
output.Position = float4(input.Position, 1.0f);
|
||||
else
|
||||
{
|
||||
float4 worldPosition = mul(float4(input.Position, 1.0f), World);
|
||||
float4 viewPosition = mul(worldPosition, View);
|
||||
output.Position = mul(viewPosition, Projection);
|
||||
}
|
||||
|
||||
output.TextureCoordinate = input.TextureCoordinate - float2(HalfPixelX, HalfPixelY);
|
||||
output.ScreenPosition = output.Position;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
||||
{
|
||||
float4 output;
|
||||
output = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
float2 texCoord = input.TextureCoordinate;
|
||||
if (LightType != LIGHTTYPE_SUN)
|
||||
{
|
||||
input.ScreenPosition.xy /= input.ScreenPosition.w;
|
||||
texCoord = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1);
|
||||
texCoord -= float2(0.5f / 800.0f, 0.5f / 600.0f);
|
||||
}
|
||||
|
||||
// Get the normal and transform back to -1 ... 1
|
||||
float4 normalData = tex2D(NormalSampler, texCoord);
|
||||
int modelType = round(normalData.w * 16.0f);
|
||||
float3 normal = normalize(2.0f * normalData.xyz - 1.0f);
|
||||
|
||||
//normal.z = sqrt(1.0f - normal.x * normal.x - normal.y * normal.y);
|
||||
|
||||
float specularPower = 1.0f; // normalData.w;
|
||||
|
||||
// Get the depth value
|
||||
float depthVal = tex2D(DepthSampler, texCoord).r;
|
||||
|
||||
// Sample caustics if needed
|
||||
/*float4 caustics = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
if (modelType == MODELTYPE_ROOM_UNDERWATER)
|
||||
{
|
||||
//return float4(1, 0, 0, 1);
|
||||
|
||||
// Compute screen-space position
|
||||
float4 position;
|
||||
position.xy = input.ScreenPosition.xy;
|
||||
position.z = depthVal;
|
||||
position.w = 1.0f;
|
||||
|
||||
// Transform to world space
|
||||
position = mul(position, ViewProjectionInverse);
|
||||
position /= position.w;
|
||||
|
||||
float fracX = position.x - floor(position.x / 2048.0f) * 2048.0f;
|
||||
float fracY = position.y - floor(position.y / 2048.0f) * 2048.0f;
|
||||
float fracZ = position.z - floor(position.z / 2048.0f) * 2048.0f;
|
||||
float attenuation = saturate(dot(float3(0.0f, -1.0f, 0.0f), normal));
|
||||
|
||||
float3 blending = abs(normal);
|
||||
blending = normalize(max(blending, 0.00001f));
|
||||
float b = (blending.x + blending.y + blending.z);
|
||||
blending /= float3(b, b, b);
|
||||
|
||||
float3 p = float3(fracX, fracY, fracZ) / 2048.0f;
|
||||
float3 xaxis = tex2D(CausticsSampler, p.yz).rgb;
|
||||
float3 yaxis = tex2D(CausticsSampler, p.xz).rgb;
|
||||
float3 zaxis = tex2D(CausticsSampler, p.xy).rgb;
|
||||
output += float4((xaxis * blending.x + yaxis * blending.y + zaxis * blending.z).xyz, 0.0f) * 0.10f * attenuation;
|
||||
}*/
|
||||
|
||||
// We lit room geometry only in the case of dynamic lights
|
||||
if ((modelType == MODELTYPE_ROOM || modelType == MODELTYPE_ROOM_UNDERWATER) && !LightDynamic)
|
||||
{
|
||||
// Is this light dynamic? In not, then I don't do any further calculations
|
||||
return (output);
|
||||
}
|
||||
|
||||
// Get specular intensity
|
||||
float specularIntensity = tex2D(ColorSampler, texCoord).a;
|
||||
|
||||
// Now the shader is different according to light type
|
||||
if (LightType == LIGHTTYPE_SUN)
|
||||
{
|
||||
// Compute screen-space position
|
||||
float4 position;
|
||||
position.x = input.TextureCoordinate.x * 2.0f - 1.0f;
|
||||
position.y = -(input.TextureCoordinate.y * 2.0f - 1.0f);
|
||||
position.z = depthVal;
|
||||
position.w = 1.0f;
|
||||
|
||||
// Transform to world space
|
||||
position = mul(position, ViewProjectionInverse);
|
||||
position /= position.w;
|
||||
|
||||
// Surface-to-light vector
|
||||
float3 lightVector = -normalize(LightDirection);
|
||||
|
||||
// Compute diffuse light
|
||||
float NdL = max(0, dot(normal, lightVector));
|
||||
float3 diffuseLight = NdL * LightColor.rgb;
|
||||
|
||||
// Reflection vector
|
||||
float3 reflectionVector = normalize(reflect(lightVector, normal));
|
||||
|
||||
// Camera-to-surface vector
|
||||
float3 directionToCamera = normalize(CameraPosition - position);
|
||||
|
||||
// Compute specular light
|
||||
float specularLight = specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);
|
||||
|
||||
// Output the two lights
|
||||
output = float4(diffuseLight.rgb, specularLight);
|
||||
}
|
||||
else if (LightType == LIGHTTYPE_POINT)
|
||||
{
|
||||
// Compute screen-space position
|
||||
float4 position;
|
||||
position.xy = input.ScreenPosition.xy;
|
||||
position.z = depthVal;
|
||||
position.w = 1.0f;
|
||||
|
||||
// Transform to world space
|
||||
position = mul(position, ViewProjectionInverse);
|
||||
position /= position.w;
|
||||
|
||||
// Surface-to-light vector
|
||||
float3 lightVector = LightPosition - position;
|
||||
|
||||
// Compute attenuation based on distance - linear attenuation
|
||||
float attenuation = saturate(1.0f - length(lightVector) / LightOut);
|
||||
|
||||
// Normalize light vector
|
||||
lightVector = normalize(lightVector);
|
||||
|
||||
// Compute diffuse light
|
||||
float NdL = pow((dot(normal, lightVector) * 0.5f) + 0.5f, 2); //max(0, dot(normal, lightVector));
|
||||
float3 diffuseLight = NdL * LightColor.rgb;
|
||||
|
||||
// Reflection vector
|
||||
float3 reflectionVector = normalize(reflect(-lightVector, normal));
|
||||
|
||||
// Camera-to-surface vector
|
||||
float3 directionToCamera = normalize(CameraPosition - position);
|
||||
|
||||
// Compute specular light
|
||||
float specularLight = specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);
|
||||
|
||||
// Take into account attenuation and lightIntensity.
|
||||
output = attenuation * LightIntensity * float4(diffuseLight.rgb, specularLight) * 0.75f;
|
||||
}
|
||||
|
||||
//output.a = 0.5f;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
technique Light
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
VertexShader = compile vs_3_0 VertexShaderFunction();
|
||||
PixelShader = compile ps_3_0 PixelShaderFunction();
|
||||
}
|
||||
}
|
|
@ -168,7 +168,7 @@ __int32 __cdecl ControlPhase(__int32 numFrames, __int32 demoMode)
|
|||
CalculateSpotCameras();
|
||||
else
|
||||
CalculateCamera();
|
||||
|
||||
|
||||
Wibble = (Wibble + 4) & 0xFC;
|
||||
|
||||
UpdateSparks();
|
||||
|
@ -216,8 +216,8 @@ void __cdecl DoTitle(__int32 index)
|
|||
{
|
||||
DB_Log(2, "DoTitle - DLL");
|
||||
printf("DoTitle\n");
|
||||
gfLevelFlags |= 1;
|
||||
DoLevel(10, 124);
|
||||
//gfLevelFlags |= 1;
|
||||
DoLevel(2, 124);
|
||||
return;
|
||||
|
||||
S_LoadLevelFile(0);
|
||||
|
|
|
@ -210,6 +210,8 @@
|
|||
#define Sparks ARRAY_(0x00E5F380, SPARKS, [128])
|
||||
#define Drips ARRAY_(0x00E4D740, DRIP_STRUCT, [32])
|
||||
#define Bubbles ARRAY_(0x00E4D160, BUBBLE_STRUCT, [40])
|
||||
#define Splashes ARRAY_(0x00E6CA00, SPLASH_STRUCT, [4])
|
||||
#define Ripples ARRAY_(0x00E5C600, RIPPLE_STRUCT, [32])
|
||||
|
||||
#define SkyPos1 VAR_U_(0x00E6E4B0, __int16)
|
||||
#define SkyPos2 VAR_U_(0x00E6D73E, __int16)
|
||||
|
|
|
@ -28,7 +28,8 @@ typedef enum MODEL_TYPES {
|
|||
MODEL_TYPE_PICKUP = 5,
|
||||
MODEL_TYPE_LARA = 6,
|
||||
MODEL_TYPE_SKY = 7,
|
||||
MODEL_TYPE_WATER_SURFACE = 8
|
||||
MODEL_TYPE_WATER_SURFACE = 8,
|
||||
MODEL_TYPE_ROOM_UNDERWATER = 9
|
||||
};
|
||||
|
||||
typedef enum LIGHT_TYPES {
|
||||
|
@ -57,6 +58,11 @@ typedef enum RENDERER_BLENDSTATE {
|
|||
BLENDSTATE_SPECIAL_Z_BUFFER
|
||||
};
|
||||
|
||||
typedef enum RENDERER_SPRITE_TYPE {
|
||||
SPRITE_TYPE_BILLBOARD,
|
||||
SPRITE_TYPE_3D
|
||||
};
|
||||
|
||||
#define SHADOW_MAP_SIZE 2048
|
||||
|
||||
#define TEXTURE_ATLAS_SIZE 4096
|
||||
|
@ -92,9 +98,15 @@ typedef enum RENDERER_BLENDSTATE {
|
|||
#define SNOW_MAX_ANGLE_H 360
|
||||
#define SNOW_DELTA_Y 128.0f
|
||||
|
||||
#define NUM_UNDERWATER_DUST_PARTICLES 128
|
||||
#define UNDERWATER_DUST_PARTICLES_SIZE 48.0f
|
||||
#define UNDERWATER_DUST_PARTICLES_RADIUS (8 * 1024)
|
||||
|
||||
#define NUM_SPRITES_PER_BUCKET 4096
|
||||
#define NUM_LINES_PER_BUCKET 4096
|
||||
|
||||
#define NUM_CAUSTICS_TEXTURES 16
|
||||
|
||||
#define FADEMODE_NONE 0
|
||||
#define FADEMODE_FADEIN 1
|
||||
#define FADEMODE_FADEOUT 2
|
||||
|
|
|
@ -452,23 +452,37 @@ bool Renderer::Initialise(__int32 w, __int32 h, bool windowed, HWND handle)
|
|||
m_shaderTransparent->Compile();
|
||||
if (m_shaderTransparent->GetEffect() == NULL)
|
||||
return false;
|
||||
|
||||
|
||||
m_sphereMesh = new RendererSphere(m_device, 1280.0f, 6);
|
||||
m_quad = new RendererQuad(m_device, 1024.0f);
|
||||
m_skyQuad = new RendererQuad(m_device, 9728.0f);
|
||||
|
||||
|
||||
m_halfPixelX = 0.5f / (float)ScreenWidth;
|
||||
m_halfPixelY = 0.5f / (float)ScreenHeight;
|
||||
|
||||
|
||||
D3DXCreateTextureFromFileEx(m_device, "SSAO.png", D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, 0, 0,
|
||||
D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
|
||||
D3DCOLOR_XRGB(255, 255, 255), NULL, NULL, &m_randomTexture);
|
||||
|
||||
char* causticsNames[NUM_CAUSTICS_TEXTURES] = { "CausticsRender_001.bmp","CausticsRender_002.bmp", "CausticsRender_003.bmp",
|
||||
"CausticsRender_004.bmp", "CausticsRender_005.bmp", "CausticsRender_006.bmp",
|
||||
"CausticsRender_007.bmp", "CausticsRender_008.bmp","CausticsRender_009.bmp","CausticsRender_010.bmp",
|
||||
"CausticsRender_011.bmp",
|
||||
"CausticsRender_012.bmp", "CausticsRender_013.bmp", "CausticsRender_014.bmp",
|
||||
"CausticsRender_015.bmp", "CausticsRender_016.bmp" };
|
||||
|
||||
for (__int32 i = 0; i < NUM_CAUSTICS_TEXTURES; i++)
|
||||
{
|
||||
D3DXCreateTextureFromFileEx(m_device, causticsNames[i], D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, 0, 0,
|
||||
D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
|
||||
D3DCOLOR_XRGB(255, 255, 255), NULL, NULL, &m_caustics[i]);
|
||||
}
|
||||
|
||||
res = m_device->CreateVertexBuffer(NUM_SPRITES_PER_BUCKET * 4 * sizeof(RendererVertex), D3DUSAGE_WRITEONLY,
|
||||
0, D3DPOOL_MANAGED, &m_spritesVertexBuffer, NULL);
|
||||
if (res != S_OK)
|
||||
return false;
|
||||
|
||||
|
||||
res = m_device->CreateIndexBuffer(NUM_SPRITES_PER_BUCKET * 6 * 4, D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_MANAGED,
|
||||
&m_spritesIndexBuffer, NULL);
|
||||
if (res != S_OK)
|
||||
|
@ -860,7 +874,7 @@ bool Renderer::PrepareDataForTheRenderer()
|
|||
ZeroMemory(buffer, TEXTURE_ATLAS_SIZE * TEXTURE_ATLAS_SIZE * 4);
|
||||
|
||||
__int32 typ = LaraDrawType;
|
||||
if (gfLevelFlags & 1 || m_youngLara)
|
||||
if (gfLevelFlags & 1)
|
||||
{
|
||||
memcpy(m_laraSkinJointRemap, m_youngLaraSkinJointRemap, 15 * 32 * 2);
|
||||
}
|
||||
|
@ -971,7 +985,7 @@ bool Renderer::PrepareDataForTheRenderer()
|
|||
tr5_room_layer* layer = &layers[l];
|
||||
if (layer->NumLayerVertices == 0)
|
||||
continue;
|
||||
|
||||
|
||||
byte* polygons = (byte*)layer->PolyOffset;
|
||||
tr5_room_vertex* vertices = (tr5_room_vertex*)layer->VerticesOffset;
|
||||
|
||||
|
@ -982,7 +996,7 @@ bool Renderer::PrepareDataForTheRenderer()
|
|||
tr4_mesh_face4* poly = (tr4_mesh_face4*)polygons;
|
||||
|
||||
// Get the real texture index and if double sided
|
||||
__int16 textureIndex = poly->Texture & 0x7FFF;
|
||||
__int16 textureIndex = poly->Texture & 0x3FFF;
|
||||
bool doubleSided = (poly->Texture & 0x8000) >> 15;
|
||||
|
||||
// Get the object texture
|
||||
|
@ -1082,7 +1096,7 @@ bool Renderer::PrepareDataForTheRenderer()
|
|||
tr4_mesh_face3* poly = (tr4_mesh_face3*)polygons;
|
||||
|
||||
// Get the real texture index and if double sided
|
||||
__int16 textureIndex = poly->Texture & 0x7FFF;
|
||||
__int16 textureIndex = poly->Texture & 0x3FFF;
|
||||
bool doubleSided = (poly->Texture & 0x8000) >> 15;
|
||||
|
||||
// Get the object texture
|
||||
|
@ -1247,7 +1261,8 @@ bool Renderer::PrepareDataForTheRenderer()
|
|||
objNum == ID_AI_FOLLOW || objNum == ID_AI_GUARD || objNum == ID_AI_MODIFY ||
|
||||
objNum == ID_AI_PATROL1 || objNum == ID_AI_PATROL2 || objNum == ID_AI_X1 ||
|
||||
objNum == ID_AI_X2 || objNum == ID_DART_EMITTER || objNum == ID_HOMING_DART_EMITTER ||
|
||||
objNum == ID_ROPE || objNum == ID_KILL_ALL_TRIGGERS || objNum == ID_EARTHQUAKE)
|
||||
objNum == ID_ROPE || objNum == ID_KILL_ALL_TRIGGERS || objNum == ID_EARTHQUAKE ||
|
||||
objNum == ID_CAMERA_TARGET || objNum == ID_WATERFALLMIST)
|
||||
{
|
||||
moveable->DoNotDraw = true;
|
||||
}
|
||||
|
@ -2369,11 +2384,11 @@ void Renderer::UpdateLaraAnimations()
|
|||
ZeroMemory(m_hairVertices, m_numHairVertices * 2 * sizeof(RendererObject));
|
||||
ZeroMemory(m_hairIndices, m_numHairIndices * 2 * 4);
|
||||
|
||||
for (__int32 p = 0; p < (m_youngLara ? 2 : 1); p++)
|
||||
for (__int32 p = 0; p < ((gfLevelFlags & 1) ? 2 : 1); p++)
|
||||
{
|
||||
// We can't use hardware skinning here, however hairs have just a few vertices so
|
||||
// it's not so bad doing skinning in software
|
||||
if (m_youngLara)
|
||||
if (gfLevelFlags & 1)
|
||||
{
|
||||
if (p == 1)
|
||||
{
|
||||
|
@ -3694,10 +3709,13 @@ bool Renderer::DrawSceneLightPrePass(bool dump)
|
|||
|
||||
effect->SetMatrix(effect->GetParameterByName(NULL, "View"), &ViewMatrix);
|
||||
effect->SetMatrix(effect->GetParameterByName(NULL, "Projection"), &ProjectionMatrix);
|
||||
effect->SetInt(effect->GetParameterByName(NULL, "ModelType"), MODEL_TYPES::MODEL_TYPE_ROOM);
|
||||
effect->SetTexture(effect->GetParameterByName(NULL, "TextureAtlas"), m_textureAtlas);
|
||||
effect->SetBool(effect->GetParameterByName(NULL, "UseSkinning"), false);
|
||||
effect->SetVector(effect->GetParameterByName(NULL, "Color"), &D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
effect->SetTexture(effect->GetParameterByName(NULL, "CausticsMap"), m_caustics[m_currentCausticsFrame / 2]);
|
||||
|
||||
m_currentCausticsFrame++;
|
||||
m_currentCausticsFrame %= 32;
|
||||
|
||||
D3DXMATRIX world;
|
||||
|
||||
|
@ -3831,7 +3849,7 @@ bool Renderer::DrawSceneLightPrePass(bool dump)
|
|||
effect->SetTexture(effect->GetParameterByName(NULL, "ColorMap"), m_colorBuffer->GetTexture());
|
||||
effect->SetTexture(effect->GetParameterByName(NULL, "NormalMap"), m_normalBuffer->GetTexture());
|
||||
effect->SetTexture(effect->GetParameterByName(NULL, "DepthMap"), m_depthBuffer->GetTexture());
|
||||
|
||||
|
||||
effect->SetBool(effect->GetParameterByName(NULL, "AmbientPass"), false);
|
||||
effect->SetVector(effect->GetParameterByName(NULL, "CameraPosition"), &D3DXVECTOR4(Camera.pos.x, Camera.pos.y, Camera.pos.z, 1.0f));
|
||||
effect->SetFloat(effect->GetParameterByName(NULL, "HalfPixelX"), m_halfPixelX);
|
||||
|
@ -4085,6 +4103,8 @@ bool Renderer::DrawSceneLightPrePass(bool dump)
|
|||
DrawSparks();
|
||||
DrawBubbles();
|
||||
DrawDrips();
|
||||
DrawRipples();
|
||||
DrawUnderwaterDust();
|
||||
|
||||
// Do weather
|
||||
if (WeatherType == WEATHER_TYPES::WEATHER_RAIN)
|
||||
|
@ -4212,7 +4232,7 @@ bool Renderer::DrawLaraLPP(RENDERER_BUCKETS bucketIndex, RENDERER_PASSES pass)
|
|||
|
||||
ITEM_INFO* item = LaraItem;
|
||||
OBJECT_INFO* obj = &Objects[0];
|
||||
|
||||
|
||||
RendererLightInfo* light = &m_itemsLightInfo[0];
|
||||
LPD3DXEFFECT effect;
|
||||
if (pass == RENDERER_PASSES::RENDERER_PASS_SHADOW_MAP)
|
||||
|
@ -4228,6 +4248,7 @@ bool Renderer::DrawLaraLPP(RENDERER_BUCKETS bucketIndex, RENDERER_PASSES pass)
|
|||
effect->SetInt(effect->GetParameterByName(NULL, "ModelType"), MODEL_TYPES::MODEL_TYPE_LARA);
|
||||
effect->SetMatrixArray(effect->GetParameterByName(NULL, "Bones"), laraObj->AnimationTransforms, laraObj->ObjectMeshes.size());
|
||||
effect->SetMatrix(effect->GetParameterByName(NULL, "World"), &m_LaraWorldMatrix);
|
||||
effect->SetVector(effect->GetParameterByName(NULL, "AmbientLight"), &m_rooms[LaraItem->roomNumber]->AmbientLight);
|
||||
|
||||
if (bucketIndex == RENDERER_BUCKETS::RENDERER_BUCKET_SOLID || bucketIndex == RENDERER_BUCKETS::RENDERER_BUCKET_SOLID_DS)
|
||||
effect->SetInt(effect->GetParameterByName(NULL, "BlendMode"), BLEND_MODES::BLENDMODE_OPAQUE);
|
||||
|
@ -4372,8 +4393,8 @@ bool Renderer::DrawLaraLPP(RENDERER_BUCKETS bucketIndex, RENDERER_PASSES pass)
|
|||
|
||||
// Draw Lara's hairs
|
||||
if (bucketIndex == 0)
|
||||
{
|
||||
SetGpuStateForBucket(bucketIndex);
|
||||
{
|
||||
SetGpuStateForBucket(bucketIndex);
|
||||
|
||||
if (m_moveableObjects.find(ID_HAIR) != m_moveableObjects.end())
|
||||
{
|
||||
|
@ -4387,8 +4408,8 @@ bool Renderer::DrawLaraLPP(RENDERER_BUCKETS bucketIndex, RENDERER_PASSES pass)
|
|||
effect->CommitChanges();
|
||||
|
||||
m_device->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0,
|
||||
m_numHairVertices*(m_youngLara ? 2 : 1),
|
||||
m_numHairIndices*(m_youngLara ? 2 : 1) / 3,
|
||||
m_numHairVertices*((gfLevelFlags & 1) ? 2 : 1),
|
||||
m_numHairIndices*((gfLevelFlags & 1) ? 2 : 1) / 3,
|
||||
m_hairIndices, D3DFMT_INDEX32, m_hairVertices, sizeof(RendererVertex));
|
||||
|
||||
effect->EndPass();
|
||||
|
@ -4430,6 +4451,7 @@ bool Renderer::DrawItemLPP(RendererItemToDraw* itemToDraw, RENDERER_BUCKETS buck
|
|||
effect->SetInt(effect->GetParameterByName(NULL, "ModelType"), MODEL_TYPES::MODEL_TYPE_MOVEABLE);
|
||||
effect->SetMatrixArray(effect->GetParameterByName(NULL, "Bones"), moveableObj->AnimationTransforms, moveableObj->ObjectMeshes.size());
|
||||
effect->SetMatrix(effect->GetParameterByName(NULL, "World"), &itemToDraw->World);
|
||||
effect->SetVector(effect->GetParameterByName(NULL, "AmbientLight"), &m_rooms[item->roomNumber]->AmbientLight);
|
||||
|
||||
if (bucketIndex == RENDERER_BUCKETS::RENDERER_BUCKET_SOLID || bucketIndex == RENDERER_BUCKETS::RENDERER_BUCKET_SOLID_DS)
|
||||
effect->SetInt(effect->GetParameterByName(NULL, "BlendMode"), BLEND_MODES::BLENDMODE_OPAQUE);
|
||||
|
@ -4461,7 +4483,7 @@ bool Renderer::DrawItemLPP(RendererItemToDraw* itemToDraw, RENDERER_BUCKETS buck
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Renderer::DrawRoomLPP(__int32 roomIndex, RENDERER_BUCKETS bucketIndex, RENDERER_PASSES pass)
|
||||
{
|
||||
D3DXMATRIX world;
|
||||
|
@ -4490,14 +4512,13 @@ bool Renderer::DrawRoomLPP(__int32 roomIndex, RENDERER_BUCKETS bucketIndex, REND
|
|||
else if (pass == RENDERER_PASSES::RENDERER_PASS_GBUFFER)
|
||||
effect = m_shaderFillGBuffer->GetEffect();
|
||||
else
|
||||
effect = m_shaderTransparent->GetEffect();
|
||||
|
||||
effect = m_shaderTransparent->GetEffect();
|
||||
|
||||
D3DXMatrixTranslation(&world, r->x, r->y, r->z);
|
||||
|
||||
effect->SetBool(effect->GetParameterByName(NULL, "UseSkinning"), false);
|
||||
effect->SetInt(effect->GetParameterByName(NULL, "ModelType"), MODEL_TYPES::MODEL_TYPE_ROOM);
|
||||
effect->SetMatrix(effect->GetParameterByName(NULL, "World"), &world);
|
||||
|
||||
|
||||
if (bucketIndex == RENDERER_BUCKETS::RENDERER_BUCKET_SOLID || bucketIndex == RENDERER_BUCKETS::RENDERER_BUCKET_SOLID_DS)
|
||||
effect->SetInt(effect->GetParameterByName(NULL, "BlendMode"), BLEND_MODES::BLENDMODE_OPAQUE);
|
||||
else
|
||||
|
@ -4506,9 +4527,9 @@ bool Renderer::DrawRoomLPP(__int32 roomIndex, RENDERER_BUCKETS bucketIndex, REND
|
|||
if (pass == RENDERER_PASSES::RENDERER_PASS_GBUFFER)
|
||||
{
|
||||
if (IsRoomUnderwater(roomIndex))
|
||||
effect->SetBool(effect->GetParameterByName(NULL, "Underwater"), true);
|
||||
effect->SetInt(effect->GetParameterByName(NULL, "ModelType"), MODEL_TYPES::MODEL_TYPE_ROOM_UNDERWATER);
|
||||
else
|
||||
effect->SetBool(effect->GetParameterByName(NULL, "Underwater"), false);
|
||||
effect->SetInt(effect->GetParameterByName(NULL, "ModelType"), MODEL_TYPES::MODEL_TYPE_ROOM);
|
||||
}
|
||||
|
||||
m_device->SetStreamSource(0, bucket->GetVertexBuffer(), 0, sizeof(RendererVertex));
|
||||
|
@ -4563,6 +4584,7 @@ bool Renderer::DrawStaticLPP(__int32 roomIndex, __int32 staticIndex, RENDERER_BU
|
|||
effect->SetBool(effect->GetParameterByName(NULL, "UseSkinning"), false);
|
||||
effect->SetInt(effect->GetParameterByName(NULL, "ModelType"), MODEL_TYPES::MODEL_TYPE_STATIC);
|
||||
effect->SetMatrix(effect->GetParameterByName(NULL, "World"), &world);
|
||||
effect->SetVector(effect->GetParameterByName(NULL, "AmbientLight"), &m_rooms[roomIndex]->AmbientLight);
|
||||
|
||||
if (bucketIndex == RENDERER_BUCKETS::RENDERER_BUCKET_SOLID || bucketIndex == RENDERER_BUCKETS::RENDERER_BUCKET_SOLID_DS)
|
||||
effect->SetInt(effect->GetParameterByName(NULL, "BlendMode"), BLEND_MODES::BLENDMODE_OPAQUE);
|
||||
|
@ -4830,13 +4852,13 @@ bool Renderer::DrawSkyLPP()
|
|||
|
||||
color = D3DXVECTOR4((SkyStormColor[0] + 44) / 255.0f, SkyStormColor[1] / 255.0f, SkyStormColor[2] / 255.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
D3DXMATRIX world;
|
||||
D3DXMATRIX translation;
|
||||
D3DXMATRIX rotation;
|
||||
D3DXMATRIX scale;
|
||||
UINT cPasses = 1;
|
||||
|
||||
|
||||
LPD3DXEFFECT effect = m_shaderFillGBuffer->GetEffect();
|
||||
|
||||
effect->SetTexture(effect->GetParameterByName(NULL, "TextureAtlas"), m_skyTexture);
|
||||
|
@ -4887,21 +4909,7 @@ bool Renderer::DrawSkyLPP()
|
|||
m_device->SetStreamSource(0, bucket->GetVertexBuffer(), 0, sizeof(RendererVertex));
|
||||
m_device->SetIndices(bucket->GetIndexBuffer());
|
||||
|
||||
if (i == RENDERER_BUCKET_TRANSPARENT || i == RENDERER_BUCKET_TRANSPARENT_DS)
|
||||
{
|
||||
// Setup additive blending
|
||||
m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
|
||||
m_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
m_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
|
||||
m_device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ZERO);
|
||||
m_device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO);
|
||||
m_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
m_device->SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
|
||||
}
|
||||
SetGpuStateForBucket((RENDERER_BUCKETS)i);
|
||||
|
||||
for (int iPass = 0; iPass < cPasses; iPass++)
|
||||
{
|
||||
|
@ -4986,16 +4994,6 @@ bool Renderer::DrawSprites()
|
|||
SetBlendState(RENDERER_BLENDSTATE::BLENDSTATE_ADDITIVE);
|
||||
SetDepthWrite(false);
|
||||
|
||||
/*m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
|
||||
m_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
m_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
|
||||
m_device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ZERO);
|
||||
m_device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO);
|
||||
m_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
m_device->SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD);
|
||||
m_device->SetRenderState(D3DRS_ZWRITEENABLE, false);
|
||||
m_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);*/
|
||||
|
||||
UINT cPasses = 1;
|
||||
LPD3DXEFFECT effect = m_shaderSprites->GetEffect();
|
||||
m_device->BeginScene();
|
||||
|
@ -5018,81 +5016,145 @@ bool Renderer::DrawSprites()
|
|||
{
|
||||
RendererSpriteToDraw* spr = m_spritesToDraw[i];
|
||||
|
||||
float halfWidth = spr->Width / 2.0f;
|
||||
float halfHeight = spr->Height / 2.0f;
|
||||
if (spr->Type == RENDERER_SPRITE_TYPE::SPRITE_TYPE_BILLBOARD)
|
||||
{
|
||||
float halfWidth = spr->Width / 2.0f;
|
||||
float halfHeight = spr->Height / 2.0f;
|
||||
|
||||
D3DXMATRIX billboardMatrix;
|
||||
CreateBillboardMatrix(&billboardMatrix, &D3DXVECTOR3(spr->X, spr->Y, spr->Z),
|
||||
&D3DXVECTOR3(Camera.pos.x, Camera.pos.y, Camera.pos.z));
|
||||
D3DXMATRIX billboardMatrix;
|
||||
CreateBillboardMatrix(&billboardMatrix, &D3DXVECTOR3(spr->X, spr->Y, spr->Z),
|
||||
&D3DXVECTOR3(Camera.pos.x, Camera.pos.y, Camera.pos.z));
|
||||
|
||||
D3DXVECTOR3 p0 = D3DXVECTOR3(-halfWidth, -halfHeight, 0);
|
||||
D3DXVECTOR3 p1 = D3DXVECTOR3(halfWidth, -halfHeight, 0);
|
||||
D3DXVECTOR3 p2 = D3DXVECTOR3(halfWidth, halfHeight, 0);
|
||||
D3DXVECTOR3 p3 = D3DXVECTOR3(-halfWidth, halfHeight, 0);
|
||||
D3DXVECTOR3 p0 = D3DXVECTOR3(-halfWidth, -halfHeight, 0);
|
||||
D3DXVECTOR3 p1 = D3DXVECTOR3(halfWidth, -halfHeight, 0);
|
||||
D3DXVECTOR3 p2 = D3DXVECTOR3(halfWidth, halfHeight, 0);
|
||||
D3DXVECTOR3 p3 = D3DXVECTOR3(-halfWidth, halfHeight, 0);
|
||||
|
||||
D3DXVECTOR4 p0t;
|
||||
D3DXVECTOR4 p1t;
|
||||
D3DXVECTOR4 p2t;
|
||||
D3DXVECTOR4 p3t;
|
||||
D3DXVECTOR4 p0t;
|
||||
D3DXVECTOR4 p1t;
|
||||
D3DXVECTOR4 p2t;
|
||||
D3DXVECTOR4 p3t;
|
||||
|
||||
D3DXVec3Transform(&p0t, &p0, &billboardMatrix);
|
||||
D3DXVec3Transform(&p1t, &p1, &billboardMatrix);
|
||||
D3DXVec3Transform(&p2t, &p2, &billboardMatrix);
|
||||
D3DXVec3Transform(&p3t, &p3, &billboardMatrix);
|
||||
D3DXVec3Transform(&p0t, &p0, &billboardMatrix);
|
||||
D3DXVec3Transform(&p1t, &p1, &billboardMatrix);
|
||||
D3DXVec3Transform(&p2t, &p2, &billboardMatrix);
|
||||
D3DXVec3Transform(&p3t, &p3, &billboardMatrix);
|
||||
|
||||
RendererVertex v;
|
||||
__int32 baseVertex = m_spritesVertices.size();
|
||||
RendererVertex v;
|
||||
__int32 baseVertex = m_spritesVertices.size();
|
||||
|
||||
v.x = p0t.x;
|
||||
v.y = p0t.y;
|
||||
v.z = p0t.z;
|
||||
v.u = spr->Sprite->UV[0].x;
|
||||
v.v = spr->Sprite->UV[0].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
v.x = p0t.x;
|
||||
v.y = p0t.y;
|
||||
v.z = p0t.z;
|
||||
v.u = spr->Sprite->UV[0].x;
|
||||
v.v = spr->Sprite->UV[0].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
|
||||
v.x = p1t.x;
|
||||
v.y = p1t.y;
|
||||
v.z = p1t.z;
|
||||
v.u = spr->Sprite->UV[1].x;
|
||||
v.v = spr->Sprite->UV[1].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
v.x = p1t.x;
|
||||
v.y = p1t.y;
|
||||
v.z = p1t.z;
|
||||
v.u = spr->Sprite->UV[1].x;
|
||||
v.v = spr->Sprite->UV[1].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
|
||||
v.x = p2t.x;
|
||||
v.y = p2t.y;
|
||||
v.z = p2t.z;
|
||||
v.u = spr->Sprite->UV[2].x;
|
||||
v.v = spr->Sprite->UV[2].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
v.x = p2t.x;
|
||||
v.y = p2t.y;
|
||||
v.z = p2t.z;
|
||||
v.u = spr->Sprite->UV[2].x;
|
||||
v.v = spr->Sprite->UV[2].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
|
||||
v.x = p3t.x;
|
||||
v.y = p3t.y;
|
||||
v.z = p3t.z;
|
||||
v.u = spr->Sprite->UV[3].x;
|
||||
v.v = spr->Sprite->UV[3].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
v.x = p3t.x;
|
||||
v.y = p3t.y;
|
||||
v.z = p3t.z;
|
||||
v.u = spr->Sprite->UV[3].x;
|
||||
v.v = spr->Sprite->UV[3].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
|
||||
m_spritesIndices.push_back(baseVertex + 0);
|
||||
m_spritesIndices.push_back(baseVertex + 1);
|
||||
m_spritesIndices.push_back(baseVertex + 2);
|
||||
m_spritesIndices.push_back(baseVertex + 0);
|
||||
m_spritesIndices.push_back(baseVertex + 2);
|
||||
m_spritesIndices.push_back(baseVertex + 3);
|
||||
m_spritesIndices.push_back(baseVertex + 0);
|
||||
m_spritesIndices.push_back(baseVertex + 1);
|
||||
m_spritesIndices.push_back(baseVertex + 2);
|
||||
m_spritesIndices.push_back(baseVertex + 0);
|
||||
m_spritesIndices.push_back(baseVertex + 2);
|
||||
m_spritesIndices.push_back(baseVertex + 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3DXVECTOR3 p0t = D3DXVECTOR3(spr->X1, spr->Y1, spr->Z1);
|
||||
D3DXVECTOR3 p1t = D3DXVECTOR3(spr->X2, spr->Y2, spr->Z2);
|
||||
D3DXVECTOR3 p2t = D3DXVECTOR3(spr->X3, spr->Y3, spr->Z3);
|
||||
D3DXVECTOR3 p3t = D3DXVECTOR3(spr->X4, spr->Y4, spr->Z4);
|
||||
|
||||
RendererVertex v;
|
||||
__int32 baseVertex = m_spritesVertices.size();
|
||||
|
||||
v.x = p0t.x;
|
||||
v.y = p0t.y;
|
||||
v.z = p0t.z;
|
||||
v.u = spr->Sprite->UV[0].x;
|
||||
v.v = spr->Sprite->UV[0].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
|
||||
v.x = p1t.x;
|
||||
v.y = p1t.y;
|
||||
v.z = p1t.z;
|
||||
v.u = spr->Sprite->UV[1].x;
|
||||
v.v = spr->Sprite->UV[1].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
|
||||
v.x = p2t.x;
|
||||
v.y = p2t.y;
|
||||
v.z = p2t.z;
|
||||
v.u = spr->Sprite->UV[2].x;
|
||||
v.v = spr->Sprite->UV[2].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
|
||||
v.x = p3t.x;
|
||||
v.y = p3t.y;
|
||||
v.z = p3t.z;
|
||||
v.u = spr->Sprite->UV[3].x;
|
||||
v.v = spr->Sprite->UV[3].y;
|
||||
v.r = spr->R / 255.0f;
|
||||
v.g = spr->G / 255.0f;
|
||||
v.b = spr->B / 255.0f;
|
||||
v.a = 1.0f;
|
||||
m_spritesVertices.push_back(v);
|
||||
|
||||
m_spritesIndices.push_back(baseVertex + 0);
|
||||
m_spritesIndices.push_back(baseVertex + 1);
|
||||
m_spritesIndices.push_back(baseVertex + 2);
|
||||
m_spritesIndices.push_back(baseVertex + 0);
|
||||
m_spritesIndices.push_back(baseVertex + 2);
|
||||
m_spritesIndices.push_back(baseVertex + 3);
|
||||
}
|
||||
|
||||
lastSprite++;
|
||||
}
|
||||
|
@ -5148,7 +5210,7 @@ bool Renderer::DrawSprites()
|
|||
return true;
|
||||
}
|
||||
|
||||
void Renderer::AddSprite(RendererSprite* sprite, __int32 x, __int32 y, __int32 z, byte r, byte g, byte b, float rotation, float scale, float width, float height)
|
||||
void Renderer::AddSpriteBillboard(RendererSprite* sprite, float x, float y, float z, byte r, byte g, byte b, float rotation, float scale, float width, float height)
|
||||
{
|
||||
scale = 1.0f;
|
||||
|
||||
|
@ -5156,6 +5218,7 @@ void Renderer::AddSprite(RendererSprite* sprite, __int32 x, __int32 y, __int32 z
|
|||
height *= scale;
|
||||
|
||||
RendererSpriteToDraw* spr = new RendererSpriteToDraw();
|
||||
spr->Type = RENDERER_SPRITE_TYPE::SPRITE_TYPE_BILLBOARD;
|
||||
spr->Sprite = sprite;
|
||||
spr->X = x;
|
||||
spr->Y = y;
|
||||
|
@ -5183,7 +5246,7 @@ void Renderer::DrawFires()
|
|||
FIRE_SPARKS* spark = &FireSparks[i];
|
||||
if (spark->on)
|
||||
{
|
||||
AddSprite(m_sprites[spark->def],
|
||||
AddSpriteBillboard(m_sprites[spark->def],
|
||||
fire->x + spark->x, fire->y + spark->y, fire->z + spark->z,
|
||||
spark->r, spark->g, spark->b,
|
||||
TR_ANGLE_TO_RAD(spark->rotAng), spark->scalar, spark->size * 4.0f, spark->size * 4.0f);
|
||||
|
@ -5200,7 +5263,7 @@ void Renderer::DrawSmokes()
|
|||
SMOKE_SPARKS* spark = &SmokeSparks[i];
|
||||
if (spark->On)
|
||||
{
|
||||
AddSprite(m_sprites[spark->Def],
|
||||
AddSpriteBillboard(m_sprites[spark->Def],
|
||||
spark->x, spark->y, spark->z,
|
||||
spark->Shade, spark->Shade, spark->Shade,
|
||||
TR_ANGLE_TO_RAD(spark->RotAng), spark->Scalar, spark->Size * 4.0f, spark->Size * 4.0f);
|
||||
|
@ -5210,14 +5273,14 @@ void Renderer::DrawSmokes()
|
|||
|
||||
void Renderer::DrawSparks()
|
||||
{
|
||||
for (__int32 i = 0; i < 128; i++)
|
||||
for (__int32 i = 0; i < 1024; i++)
|
||||
{
|
||||
SPARKS* spark = &Sparks[i];
|
||||
if (spark->on)
|
||||
{
|
||||
if (spark->flags & SP_DEF)
|
||||
{
|
||||
AddSprite(m_sprites[spark->def],
|
||||
AddSpriteBillboard(m_sprites[spark->def],
|
||||
spark->x, spark->y, spark->z,
|
||||
spark->r, spark->g, spark->b,
|
||||
TR_ANGLE_TO_RAD(spark->rotAng), spark->scalar, spark->size * 12.0f, spark->size * 12.0f);
|
||||
|
@ -5239,7 +5302,7 @@ void Renderer::DrawBlood()
|
|||
BLOOD_STRUCT* blood = &Blood[i];
|
||||
if (blood->On)
|
||||
{
|
||||
AddSprite(m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + 15],
|
||||
AddSpriteBillboard(m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + 15],
|
||||
blood->x, blood->y, blood->z,
|
||||
blood->Shade * 244, blood->Shade * 0, blood->Shade * 0,
|
||||
TR_ANGLE_TO_RAD(blood->RotAng), 1.0f, blood->Size * 8.0f, blood->Size * 8.0f);
|
||||
|
@ -5425,7 +5488,7 @@ bool Renderer::DoSnow()
|
|||
continue;
|
||||
}
|
||||
|
||||
AddSprite(m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + 14], snow->X, snow->Y, snow->Z, 255, 255, 255,
|
||||
AddSpriteBillboard(m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + 14], snow->X, snow->Y, snow->Z, 255, 255, 255,
|
||||
0.0f, 1.0f, SNOW_SIZE, SNOW_SIZE);
|
||||
|
||||
__int16 roomNumber = Camera.pos.roomNumber;
|
||||
|
@ -5675,7 +5738,7 @@ void Renderer::DrawBubbles()
|
|||
|
||||
if (bubble->size)
|
||||
{
|
||||
AddSprite(m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + 13],
|
||||
AddSpriteBillboard(m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + 13],
|
||||
bubble->pos.x, bubble->pos.y, bubble->pos.z,
|
||||
bubble->shade * 255, bubble->shade * 255, bubble->shade * 255,
|
||||
0.0f, 1.0f, bubble->size * 0.5f, bubble->size * 0.5f);
|
||||
|
@ -5684,6 +5747,133 @@ void Renderer::DrawBubbles()
|
|||
}
|
||||
|
||||
bool Renderer::IsRoomUnderwater(__int16 roomNumber)
|
||||
{
|
||||
{
|
||||
return (m_rooms[roomNumber]->Room->flags & 1);
|
||||
}
|
||||
|
||||
bool Renderer::IsInRoom(__int32 x, __int32 y, __int32 z, __int16 roomNumber)
|
||||
{
|
||||
RendererRoom* room = m_rooms[roomNumber];
|
||||
ROOM_INFO* r = room->Room;
|
||||
|
||||
return (x >= r->x && x <= r->x + r->xSize * 1024.0f &&
|
||||
y >= r->maxceiling && y <= r->minfloor &&
|
||||
z >= r->z && z <= r->z + r->ySize * 1024.0f);
|
||||
}
|
||||
|
||||
void Renderer::DrawSplahes()
|
||||
{
|
||||
for (__int32 i = 0; i < 4; i++)
|
||||
{
|
||||
SPLASH_STRUCT* splash = &Splashes[i];
|
||||
|
||||
int x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::AddSprite3D(RendererSprite* sprite, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4, byte r, byte g, byte b, float rotation, float scale, float width, float height)
|
||||
{
|
||||
scale = 1.0f;
|
||||
|
||||
width *= scale;
|
||||
height *= scale;
|
||||
|
||||
RendererSpriteToDraw* spr = new RendererSpriteToDraw();
|
||||
spr->Type = RENDERER_SPRITE_TYPE::SPRITE_TYPE_3D;
|
||||
spr->Sprite = sprite;
|
||||
spr->X1 = x1;
|
||||
spr->Y1 = y1;
|
||||
spr->Z1 = z1;
|
||||
spr->X2 = x2;
|
||||
spr->Y2 = y2;
|
||||
spr->Z2 = z2;
|
||||
spr->X3 = x3;
|
||||
spr->Y3 = y3;
|
||||
spr->Z3 = z3;
|
||||
spr->X4 = x4;
|
||||
spr->Y4 = y4;
|
||||
spr->Z4 = z4;
|
||||
spr->R = r;
|
||||
spr->G = g;
|
||||
spr->B = b;
|
||||
spr->Rotation = rotation;
|
||||
spr->Scale = scale;
|
||||
spr->Width = width;
|
||||
spr->Height = height;
|
||||
|
||||
m_spritesToDraw.push_back(spr);
|
||||
}
|
||||
|
||||
void Renderer::DrawRipples()
|
||||
{
|
||||
for (__int32 i = 0; i < 32; i++)
|
||||
{
|
||||
RIPPLE_STRUCT* ripple = &Ripples[i];
|
||||
|
||||
if (ripple->flags & 1)
|
||||
{
|
||||
float x1 = ripple->x - ripple->size;
|
||||
float z1 = ripple->z - ripple->size;
|
||||
float x2 = ripple->x + ripple->size;
|
||||
float z2 = ripple->z + ripple->size;
|
||||
float y = ripple->y;
|
||||
|
||||
byte color = (ripple->init ? ripple->init << 1 : ripple->life << 1);
|
||||
|
||||
AddSprite3D(m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + 9],
|
||||
x1, y, z2, x2, y, z2, x2, y, z1, x1, y, z1, color, color, color, 0.0f, 1.0f, ripple->size, ripple->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::DrawUnderwaterDust()
|
||||
{
|
||||
if (!IsRoomUnderwater(Camera.pos.roomNumber))
|
||||
return;
|
||||
|
||||
if (m_firstUnderwaterDustParticles)
|
||||
{
|
||||
for (__int32 i = 0; i < NUM_UNDERWATER_DUST_PARTICLES; i++)
|
||||
m_underwaterDustParticles[i].Reset = true;
|
||||
}
|
||||
|
||||
for (__int32 i = 0; i < NUM_UNDERWATER_DUST_PARTICLES; i++)
|
||||
{
|
||||
RendererUnderwaterDustParticle* dust = &m_underwaterDustParticles[i];
|
||||
|
||||
if (dust->Reset)
|
||||
{
|
||||
dust->X = LaraItem->pos.xPos + rand() % UNDERWATER_DUST_PARTICLES_RADIUS - UNDERWATER_DUST_PARTICLES_RADIUS / 2.0f;
|
||||
dust->Y = LaraItem->pos.yPos + rand() % UNDERWATER_DUST_PARTICLES_RADIUS - UNDERWATER_DUST_PARTICLES_RADIUS / 2.0f;
|
||||
dust->Z = LaraItem->pos.zPos + rand() % UNDERWATER_DUST_PARTICLES_RADIUS - UNDERWATER_DUST_PARTICLES_RADIUS / 2.0f;
|
||||
|
||||
// Check if water room
|
||||
__int16 roomNumber = Camera.pos.roomNumber;
|
||||
FLOOR_INFO* floor = GetFloor(dust->X, dust->Y, dust->Z, &roomNumber);
|
||||
if (!IsRoomUnderwater(roomNumber))
|
||||
continue;
|
||||
|
||||
if (!IsInRoom(dust->X, dust->Y, dust->Z, roomNumber))
|
||||
{
|
||||
dust->Reset = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
dust->Life = 0;
|
||||
dust->Reset = false;
|
||||
}
|
||||
|
||||
dust->Life++;
|
||||
byte color = (dust->Life > 16 ? 32 - dust->Life : dust->Life) * 4;
|
||||
|
||||
AddSpriteBillboard(m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + 14], dust->X, dust->Y, dust->Z, color, color, color,
|
||||
0.0f, 1.0f, UNDERWATER_DUST_PARTICLES_SIZE, UNDERWATER_DUST_PARTICLES_SIZE);
|
||||
|
||||
if (dust->Life >= 32)
|
||||
dust->Reset = true;
|
||||
}
|
||||
|
||||
m_firstUnderwaterDustParticles = false;
|
||||
|
||||
return;
|
||||
}
|
|
@ -362,12 +362,15 @@ typedef struct RendererSpriteSequence {
|
|||
};
|
||||
|
||||
typedef struct RendererSpriteToDraw {
|
||||
RENDERER_SPRITE_TYPE Type;
|
||||
RendererSprite* Sprite;
|
||||
float Distance;
|
||||
float Scale;
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
float X, Y, Z;
|
||||
float X1, Y1, Z1;
|
||||
float X2, Y2, Z2;
|
||||
float X3, Y3, Z3;
|
||||
float X4, Y4, Z4;
|
||||
byte R;
|
||||
byte G;
|
||||
byte B;
|
||||
|
@ -383,9 +386,7 @@ typedef struct RendererTempVertex {
|
|||
};
|
||||
|
||||
typedef struct RendererWeatherParticle {
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
float X, Y, Z;
|
||||
float AngleH;
|
||||
float AngleV;
|
||||
float Size;
|
||||
|
@ -393,6 +394,13 @@ typedef struct RendererWeatherParticle {
|
|||
bool Reset;
|
||||
};
|
||||
|
||||
typedef struct RendererUnderwaterDustParticle {
|
||||
float X, Y, Z;
|
||||
__int16 Life;
|
||||
__int16 Room;
|
||||
bool Reset;
|
||||
};
|
||||
|
||||
typedef struct RendererLine3DToDraw {
|
||||
float X1;
|
||||
float Y1;
|
||||
|
@ -412,6 +420,7 @@ class Renderer
|
|||
LPDIRECT3DTEXTURE9 m_textureAtlas;
|
||||
LPDIRECT3DTEXTURE9 m_fontAndMiscTexture;
|
||||
LPDIRECT3DTEXTURE9 m_titleScreen;
|
||||
LPDIRECT3DTEXTURE9 m_caustics[NUM_CAUSTICS_TEXTURES];
|
||||
LPD3DXFONT m_debugFont;
|
||||
LPD3DXFONT m_gameFont;
|
||||
LPD3DXSPRITE m_sprite;
|
||||
|
@ -475,7 +484,8 @@ class Renderer
|
|||
|
||||
RENDERER_CULLMODE m_cullMode;
|
||||
RENDERER_BLENDSTATE m_blendState;
|
||||
bool m_youngLara = true;
|
||||
RendererUnderwaterDustParticle m_underwaterDustParticles[NUM_UNDERWATER_DUST_PARTICLES];
|
||||
bool m_firstUnderwaterDustParticles = true;
|
||||
|
||||
// New light pre-pass renderer
|
||||
RenderTarget2D* m_depthBuffer;
|
||||
|
@ -528,6 +538,7 @@ class Renderer
|
|||
vector<RendererVertex> m_lines3DVertices;
|
||||
bool m_enableZwrite;
|
||||
bool m_enableZtest;
|
||||
__int32 m_currentCausticsFrame = 0;
|
||||
|
||||
public:
|
||||
D3DXMATRIX ViewMatrix;
|
||||
|
@ -598,7 +609,8 @@ public:
|
|||
void UpdateFires();
|
||||
void AddDynamicLight(__int32 x, __int32 y, __int32 z, __int16 falloff, byte r, byte g, byte b);
|
||||
void ClearDynamicLights();
|
||||
void AddSprite(RendererSprite* sprite, __int32 x, __int32 y, __int32 z, byte r, byte g, byte b, float rotation, float scale, float width, float height);
|
||||
void AddSpriteBillboard(RendererSprite* sprite, float x, float y, float z, byte r, byte g, byte b, float rotation, float scale, float width, float height);
|
||||
void AddSprite3D(RendererSprite* sprite, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4, byte r, byte g, byte b, float rotation, float scale, float width, float height);
|
||||
void AddLine3D(__int32 x1, __int32 y1, __int32 z1, __int32 x2, __int32 y2, __int32 z2, byte r, byte g, byte b);
|
||||
void DrawFires();
|
||||
void DrawSparks();
|
||||
|
@ -606,6 +618,9 @@ public:
|
|||
void DrawBlood();
|
||||
void DrawDrips();
|
||||
void DrawBubbles();
|
||||
void DrawSplahes();
|
||||
void DrawRipples();
|
||||
void DrawUnderwaterDust();
|
||||
bool DrawGunshells(RENDERER_BUCKETS bucketIndex, RENDERER_PASSES pass);
|
||||
void CreateBillboardMatrix(D3DXMATRIX* out, D3DXVECTOR3* particlePos, D3DXVECTOR3* cameraPos);
|
||||
|
||||
|
@ -629,4 +644,5 @@ public:
|
|||
void SetGpuStateForBucket(RENDERER_BUCKETS bucket);
|
||||
bool DrawScene(RENDERER_PASSES pass);
|
||||
bool IsRoomUnderwater(__int16 roomNumber);
|
||||
bool IsInRoom(__int32 x, __int32 y, __int32 z, __int16 roomNumber);
|
||||
};
|
|
@ -16,7 +16,7 @@ Shader::~Shader()
|
|||
bool Shader::Compile()
|
||||
{
|
||||
printf("Compiling shader %s ...\n", m_fileName);
|
||||
|
||||
|
||||
__int64 flags = D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY;
|
||||
LPD3DXBUFFER errors = NULL;
|
||||
|
||||
|
@ -24,9 +24,9 @@ bool Shader::Compile()
|
|||
|
||||
if (res != S_OK)
|
||||
{
|
||||
//char* message = (char*)errors->GetBufferPointer();
|
||||
//printf("%s\n", message);
|
||||
//errors->Release();
|
||||
char* message = (char*)errors->GetBufferPointer();
|
||||
printf("%s\n", message);
|
||||
errors->Release();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#define MODELTYPE_PICKUP 5
|
||||
#define MODELTYPE_LARA 6
|
||||
#define MODELTYPE_SKY 7
|
||||
#define MODELTYPE_WATER_SURFACE 8
|
||||
#define MODELTYPE_ROOM_UNDERWATER 9
|
||||
|
||||
#define DEPTH_BIAS 0.0f
|
||||
#define TEXEL_SIZE 1.0f / 2048.0f
|
||||
|
@ -42,7 +44,7 @@ sampler VertexColorSampler = sampler_state
|
|||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
|
||||
/*texture2D ShadowMap;
|
||||
sampler ShadowSampler = sampler_state
|
||||
{
|
||||
|
@ -136,9 +138,14 @@ float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
|||
float3 diffuseColor = tex2D(ColorSampler, input.TextureCoordinate).rgb;
|
||||
float3 ambientColor = tex2D(VertexColorSampler, input.TextureCoordinate).rgb;
|
||||
float4 light = tex2D(LightSampler, input.TextureCoordinate);
|
||||
int pixelFlags = tex2D(NormalSampler, input.TextureCoordinate).w * 64.0f;
|
||||
/*int pixelFlags = tex2D(NormalSampler, input.TextureCoordinate).w * 64.0f;
|
||||
int modelType = pixelFlags % 32;
|
||||
bool underwater = (pixelFlags / 32 == 1);
|
||||
int pixelFlags = normalData.w * 64.0f;
|
||||
bool underwater = ((pixelFlags / 32) == 1);
|
||||
if (pixelFlags >= 32) pixelFlags -= 32;
|
||||
int modelType = pixelFlags;*/
|
||||
int modelType = round(tex2D(NormalSampler, input.TextureCoordinate).w * 16.0f);
|
||||
//if (underwater)
|
||||
// return float4(0, 0, 1, 1);
|
||||
|
||||
|
@ -150,7 +157,7 @@ float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
|||
|
||||
float shadowOcclusion = 1.0f;
|
||||
|
||||
if (modelType == MODELTYPE_ROOM)
|
||||
if (modelType == MODELTYPE_ROOM || modelType == MODELTYPE_ROOM_UNDERWATER)
|
||||
{
|
||||
if (CastShadows)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#define MODELTYPE_PICKUP 5
|
||||
#define MODELTYPE_LARA 6
|
||||
#define MODELTYPE_SKY 7
|
||||
#define MODELTYPE_WATER_SURFACE 8
|
||||
#define MODELTYPE_ROOM_UNDERWATER 9
|
||||
|
||||
#define BLENDMODE_OPAQUE 0
|
||||
#define BLENDMODE_ALPHATEST 1
|
||||
|
@ -57,6 +59,7 @@ int ModelType;
|
|||
int BlendMode;
|
||||
bool UseSkinning;
|
||||
bool Underwater;
|
||||
float4 AmbientLight;
|
||||
|
||||
texture TextureAtlas;
|
||||
sampler2D TextureAtlasSampler = sampler_state {
|
||||
|
@ -67,6 +70,17 @@ sampler2D TextureAtlasSampler = sampler_state {
|
|||
AddressV = Wrap;
|
||||
};
|
||||
|
||||
texture2D CausticsMap;
|
||||
sampler CausticsSampler = sampler_state
|
||||
{
|
||||
Texture = (CausticsMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
|
@ -77,18 +91,18 @@ VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
|
|||
if (UseSkinning)
|
||||
{
|
||||
worldPosition = mul(float4(input.Position, 1), mul(Bones[input.Bone], World));
|
||||
normal = mul(float4(input.Normal, 1), mul(Bones[input.Bone], World));
|
||||
normal = mul(float4(input.Normal, 1), Bones[input.Bone]);
|
||||
}
|
||||
else
|
||||
{
|
||||
worldPosition = mul(float4(input.Position, 1), World);
|
||||
normal = mul(float4(input.Normal, 1), World);
|
||||
normal = float4(input.Normal, 1.0f); // mul(float4(input.Normal, 1), World);
|
||||
}
|
||||
|
||||
float4 viewPosition = mul(worldPosition, View);
|
||||
|
||||
output.Position = mul(viewPosition, Projection);
|
||||
output.Normal = normalize(input.Normal);
|
||||
output.Normal = normalize(normal.xyz);
|
||||
output.TextureCoordinate = input.TextureCoordinate;
|
||||
output.Color = input.Color;
|
||||
output.WorldPosition = worldPosition;
|
||||
|
@ -103,7 +117,7 @@ PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
|
|||
PixelShaderOutput output;
|
||||
|
||||
float4 vertexColors = float4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if (ModelType == MODELTYPE_ROOM)
|
||||
if (ModelType == MODELTYPE_ROOM || ModelType == MODELTYPE_ROOM_UNDERWATER)
|
||||
{
|
||||
float3 colorMul = min(input.Color.xyz * 2.0f, 1.0f);
|
||||
vertexColors = float4(colorMul, 1.0f);
|
||||
|
@ -118,17 +132,42 @@ PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
|
|||
output.Color.a = 0.1f;
|
||||
|
||||
output.Normal.xyz = 0.5f * (input.Normal.xyz + 1.0f);
|
||||
float pixelFlags = ModelType;
|
||||
if (Underwater) pixelFlags += 32.0f;
|
||||
output.Normal.w = pixelFlags / 64.0f;
|
||||
output.Normal.w = ModelType / 16.0f;
|
||||
//float pixelFlags = ModelType;
|
||||
//if (Underwater) pixelFlags += 32.0f;
|
||||
//output.Normal.w = pixelFlags / 64.0f;
|
||||
//output.Normal.w = 1.0f;
|
||||
|
||||
output.Depth = input.PositionCopy.z / input.PositionCopy.w; // , 0.0f, 0.0f, 1.0f); // float4(d, 0.0f, 0.0f, 1.0f);
|
||||
output.Depth = input.PositionCopy.z / input.PositionCopy.w;
|
||||
|
||||
if (ModelType == MODELTYPE_ROOM)
|
||||
if (ModelType == MODELTYPE_ROOM_UNDERWATER)
|
||||
{
|
||||
float3 position = input.WorldPosition.xyz;
|
||||
float3 normal = input.Normal.xyz;
|
||||
|
||||
float fracX = position.x - floor(position.x / 2048.0f) * 2048.0f;
|
||||
float fracY = position.y - floor(position.y / 2048.0f) * 2048.0f;
|
||||
float fracZ = position.z - floor(position.z / 2048.0f) * 2048.0f;
|
||||
|
||||
float attenuation = saturate(dot(float3(0.0f, -1.0f, 0.0f), normal));
|
||||
|
||||
float3 blending = abs(normal);
|
||||
blending = normalize(max(blending, 0.00001f));
|
||||
float b = (blending.x + blending.y + blending.z);
|
||||
blending /= float3(b, b, b);
|
||||
|
||||
float3 p = float3(fracX, fracY, fracZ) / 2048.0f;
|
||||
float3 xaxis = tex2D(CausticsSampler, p.yz).rgb;
|
||||
float3 yaxis = tex2D(CausticsSampler, p.xz).rgb;
|
||||
float3 zaxis = tex2D(CausticsSampler, p.xy).rgb;
|
||||
|
||||
vertexColors += float4((xaxis * blending.x + yaxis * blending.y + zaxis * blending.z).xyz, 0.0f) * attenuation;
|
||||
}
|
||||
|
||||
if (ModelType == MODELTYPE_ROOM || ModelType == MODELTYPE_ROOM_UNDERWATER)
|
||||
output.VertexColor = vertexColors;
|
||||
else
|
||||
output.VertexColor = float4(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
output.VertexColor = float4(AmbientLight.rgb, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -1,250 +1,296 @@
|
|||
#define LIGHTTYPE_SUN 0
|
||||
#define LIGHTTYPE_POINT 1
|
||||
#define LIGHTTYPE_SPOT 2
|
||||
#define LIGHTTYPE_SHADOW 3
|
||||
|
||||
#define MODELTYPE_HORIZON 0
|
||||
#define MODELTYPE_ROOM 1
|
||||
#define MODELTYPE_MOVEABLE 2
|
||||
#define MODELTYPE_STATIC 3
|
||||
#define MODELTYPE_INVENTORY 4
|
||||
#define MODELTYPE_PICKUP 5
|
||||
#define MODELTYPE_LARA 6
|
||||
#define MODELTYPE_SKY 7
|
||||
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float3 Position : POSITION0;
|
||||
float2 TextureCoordinate : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : POSITION0;
|
||||
float2 TextureCoordinate : TEXCOORD0;
|
||||
float4 ScreenPosition : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct PixelShaderOutput
|
||||
{
|
||||
float4 Light : COLOR0;
|
||||
float4 Shadow : COLOR1;
|
||||
};
|
||||
|
||||
float4 LightPosition;
|
||||
float4 LightDirection;
|
||||
float4 LightColor;
|
||||
int LightType;
|
||||
float LightIn;
|
||||
float LightOut;
|
||||
float LightIntensity;
|
||||
float LightRange;
|
||||
bool LightDynamic;
|
||||
bool CastShadows;
|
||||
|
||||
float3 CameraPosition;
|
||||
|
||||
float4x4 World;
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjectionInverse;
|
||||
float4x4 LightView;
|
||||
float4x4 LightProjection;
|
||||
|
||||
bool AmbientPass;
|
||||
|
||||
float HalfPixelX = 1.0f / 800.0f;
|
||||
float HalfPixelY = 1.0f / 600.0f;
|
||||
|
||||
texture2D ColorMap;
|
||||
sampler ColorSampler = sampler_state
|
||||
{
|
||||
Texture = (ColorMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
texture2D DepthMap;
|
||||
sampler DepthSampler = sampler_state
|
||||
{
|
||||
Texture = (DepthMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
Mipfilter = POINT;
|
||||
};
|
||||
|
||||
texture2D NormalMap;
|
||||
sampler NormalSampler = sampler_state
|
||||
{
|
||||
Texture = (NormalMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
Mipfilter = POINT;
|
||||
};
|
||||
|
||||
texture2D VertexColorMap;
|
||||
sampler VertexColorSampler = sampler_state
|
||||
{
|
||||
Texture = (VertexColorMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
/*textureCUBE ShadowMapCube;
|
||||
samplerCUBE ShadowMapCubeSampler = sampler_state {
|
||||
texture = (ShadowMapCube);
|
||||
MinFilter = Point;
|
||||
MagFilter = Point;
|
||||
MipFilter = None;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};*/
|
||||
|
||||
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
|
||||
if (LightType == LIGHTTYPE_SUN)
|
||||
output.Position = float4(input.Position, 1.0f);
|
||||
else
|
||||
{
|
||||
float4 worldPosition = mul(float4(input.Position, 1.0f), World);
|
||||
float4 viewPosition = mul(worldPosition, View);
|
||||
output.Position = mul(viewPosition, Projection);
|
||||
}
|
||||
|
||||
output.TextureCoordinate = input.TextureCoordinate - float2(HalfPixelX, HalfPixelY);
|
||||
output.ScreenPosition = output.Position;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
||||
{
|
||||
float4 output;
|
||||
output = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
float2 texCoord = input.TextureCoordinate;
|
||||
if (LightType != LIGHTTYPE_SUN)
|
||||
{
|
||||
input.ScreenPosition.xy /= input.ScreenPosition.w;
|
||||
texCoord = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1);
|
||||
texCoord -= float2(0.5f / 800.0f, 0.5f / 600.0f);
|
||||
}
|
||||
|
||||
// Get the normal and transform back to -1 ... 1
|
||||
float4 normalData = tex2D(NormalSampler, texCoord);
|
||||
float3 normal = 2.0f * normalData - 1.0f;
|
||||
|
||||
//normal.z = sqrt(1.0f - normal.x * normal.x - normal.y * normal.y);
|
||||
|
||||
int modelType = (int)(normalData.w * 16.0f);
|
||||
float specularPower = 1.0f; // normalData.w;
|
||||
|
||||
// Get the depth value
|
||||
float depthVal = tex2D(DepthSampler, texCoord).r;
|
||||
|
||||
// We lit room geometry only in the case of dynamic lights
|
||||
if (modelType == MODELTYPE_ROOM && !LightDynamic)
|
||||
{
|
||||
// Is this light dynamic? In not, then I don't do any further calculations
|
||||
return output;
|
||||
}
|
||||
|
||||
// Get specular intensity
|
||||
float specularIntensity = tex2D(ColorSampler, texCoord).a;
|
||||
|
||||
// Now the shader is different according to light type
|
||||
if (LightType == LIGHTTYPE_SUN)
|
||||
{
|
||||
// Compute screen-space position
|
||||
float4 position;
|
||||
position.x = input.TextureCoordinate.x * 2.0f - 1.0f;
|
||||
position.y = -(input.TextureCoordinate.y * 2.0f - 1.0f);
|
||||
position.z = depthVal;
|
||||
position.w = 1.0f;
|
||||
|
||||
// Transform to world space
|
||||
position = mul(position, ViewProjectionInverse);
|
||||
position /= position.w;
|
||||
|
||||
// Surface-to-light vector
|
||||
float3 lightVector = -normalize(LightDirection);
|
||||
|
||||
// Compute diffuse light
|
||||
float NdL = max(0, dot(normal, lightVector));
|
||||
float3 diffuseLight = NdL * LightColor.rgb;
|
||||
|
||||
// Reflection vector
|
||||
float3 reflectionVector = normalize(reflect(lightVector, normal));
|
||||
|
||||
// Camera-to-surface vector
|
||||
float3 directionToCamera = normalize(CameraPosition - position);
|
||||
|
||||
// Compute specular light
|
||||
float specularLight = specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);
|
||||
|
||||
// Output the two lights
|
||||
output = float4(diffuseLight.rgb, specularLight);
|
||||
}
|
||||
else if (LightType == LIGHTTYPE_POINT)
|
||||
{
|
||||
// Compute screen-space position
|
||||
float4 position;
|
||||
position.xy = input.ScreenPosition.xy;
|
||||
position.z = depthVal;
|
||||
position.w = 1.0f;
|
||||
|
||||
// Transform to world space
|
||||
position = mul(position, ViewProjectionInverse);
|
||||
position /= position.w;
|
||||
|
||||
// Surface-to-light vector
|
||||
float3 lightVector = LightPosition - position;
|
||||
|
||||
// Compute attenuation based on distance - linear attenuation
|
||||
float attenuation = saturate(1.0f - length(lightVector) / LightOut);
|
||||
|
||||
// Normalize light vector
|
||||
lightVector = normalize(lightVector);
|
||||
|
||||
// Compute diffuse light
|
||||
float NdL = pow((dot(normal, lightVector) * 0.5f) + 0.5f, 2); //max(0, dot(normal, lightVector));
|
||||
float3 diffuseLight = NdL * LightColor.rgb;
|
||||
|
||||
// Reflection vector
|
||||
float3 reflectionVector = normalize(reflect(-lightVector, normal));
|
||||
|
||||
// Camera-to-surface vector
|
||||
float3 directionToCamera = normalize(CameraPosition - position);
|
||||
|
||||
// Compute specular light
|
||||
float specularLight = specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);
|
||||
|
||||
// Take into account attenuation and lightIntensity.
|
||||
output = attenuation * LightIntensity * float4(diffuseLight.rgb, specularLight) * 0.75f;
|
||||
}
|
||||
|
||||
//output.a = 0.5f;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
technique Light
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
VertexShader = compile vs_3_0 VertexShaderFunction();
|
||||
PixelShader = compile ps_3_0 PixelShaderFunction();
|
||||
}
|
||||
#define LIGHTTYPE_SUN 0
|
||||
#define LIGHTTYPE_POINT 1
|
||||
#define LIGHTTYPE_SPOT 2
|
||||
#define LIGHTTYPE_SHADOW 3
|
||||
|
||||
#define MODELTYPE_HORIZON 0
|
||||
#define MODELTYPE_ROOM 1
|
||||
#define MODELTYPE_MOVEABLE 2
|
||||
#define MODELTYPE_STATIC 3
|
||||
#define MODELTYPE_INVENTORY 4
|
||||
#define MODELTYPE_PICKUP 5
|
||||
#define MODELTYPE_LARA 6
|
||||
#define MODELTYPE_SKY 7
|
||||
#define MODELTYPE_WATER_SURFACE 8
|
||||
#define MODELTYPE_ROOM_UNDERWATER 9
|
||||
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float3 Position : POSITION0;
|
||||
float2 TextureCoordinate : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : POSITION0;
|
||||
float2 TextureCoordinate : TEXCOORD0;
|
||||
float4 ScreenPosition : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct PixelShaderOutput
|
||||
{
|
||||
float4 Light : COLOR0;
|
||||
float4 Shadow : COLOR1;
|
||||
};
|
||||
|
||||
float4 LightPosition;
|
||||
float4 LightDirection;
|
||||
float4 LightColor;
|
||||
int LightType;
|
||||
float LightIn;
|
||||
float LightOut;
|
||||
float LightIntensity;
|
||||
float LightRange;
|
||||
bool LightDynamic;
|
||||
bool CastShadows;
|
||||
|
||||
float3 CameraPosition;
|
||||
|
||||
float4x4 World;
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjectionInverse;
|
||||
float4x4 LightView;
|
||||
float4x4 LightProjection;
|
||||
|
||||
bool AmbientPass;
|
||||
|
||||
float HalfPixelX = 1.0f / 800.0f;
|
||||
float HalfPixelY = 1.0f / 600.0f;
|
||||
|
||||
texture2D ColorMap;
|
||||
sampler ColorSampler = sampler_state
|
||||
{
|
||||
Texture = (ColorMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
texture2D DepthMap;
|
||||
sampler DepthSampler = sampler_state
|
||||
{
|
||||
Texture = (DepthMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
Mipfilter = POINT;
|
||||
};
|
||||
|
||||
texture2D NormalMap;
|
||||
sampler NormalSampler = sampler_state
|
||||
{
|
||||
Texture = (NormalMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
Mipfilter = POINT;
|
||||
};
|
||||
|
||||
texture2D VertexColorMap;
|
||||
sampler VertexColorSampler = sampler_state
|
||||
{
|
||||
Texture = (VertexColorMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};
|
||||
|
||||
/*texture2D CausticsMap;
|
||||
sampler CausticsSampler = sampler_state
|
||||
{
|
||||
Texture = (CausticsMap);
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
MagFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
Mipfilter = LINEAR;
|
||||
};*/
|
||||
|
||||
/*textureCUBE ShadowMapCube;
|
||||
samplerCUBE ShadowMapCubeSampler = sampler_state {
|
||||
texture = (ShadowMapCube);
|
||||
MinFilter = Point;
|
||||
MagFilter = Point;
|
||||
MipFilter = None;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};*/
|
||||
|
||||
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
|
||||
if (LightType == LIGHTTYPE_SUN)
|
||||
output.Position = float4(input.Position, 1.0f);
|
||||
else
|
||||
{
|
||||
float4 worldPosition = mul(float4(input.Position, 1.0f), World);
|
||||
float4 viewPosition = mul(worldPosition, View);
|
||||
output.Position = mul(viewPosition, Projection);
|
||||
}
|
||||
|
||||
output.TextureCoordinate = input.TextureCoordinate - float2(HalfPixelX, HalfPixelY);
|
||||
output.ScreenPosition = output.Position;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
||||
{
|
||||
float4 output;
|
||||
output = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
float2 texCoord = input.TextureCoordinate;
|
||||
if (LightType != LIGHTTYPE_SUN)
|
||||
{
|
||||
input.ScreenPosition.xy /= input.ScreenPosition.w;
|
||||
texCoord = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1);
|
||||
texCoord -= float2(0.5f / 800.0f, 0.5f / 600.0f);
|
||||
}
|
||||
|
||||
// Get the normal and transform back to -1 ... 1
|
||||
float4 normalData = tex2D(NormalSampler, texCoord);
|
||||
int modelType = round(normalData.w * 16.0f);
|
||||
float3 normal = normalize(2.0f * normalData.xyz - 1.0f);
|
||||
|
||||
//normal.z = sqrt(1.0f - normal.x * normal.x - normal.y * normal.y);
|
||||
|
||||
float specularPower = 1.0f; // normalData.w;
|
||||
|
||||
// Get the depth value
|
||||
float depthVal = tex2D(DepthSampler, texCoord).r;
|
||||
|
||||
// Sample caustics if needed
|
||||
/*float4 caustics = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
if (modelType == MODELTYPE_ROOM_UNDERWATER)
|
||||
{
|
||||
//return float4(1, 0, 0, 1);
|
||||
|
||||
// Compute screen-space position
|
||||
float4 position;
|
||||
position.xy = input.ScreenPosition.xy;
|
||||
position.z = depthVal;
|
||||
position.w = 1.0f;
|
||||
|
||||
// Transform to world space
|
||||
position = mul(position, ViewProjectionInverse);
|
||||
position /= position.w;
|
||||
|
||||
float fracX = position.x - floor(position.x / 2048.0f) * 2048.0f;
|
||||
float fracY = position.y - floor(position.y / 2048.0f) * 2048.0f;
|
||||
float fracZ = position.z - floor(position.z / 2048.0f) * 2048.0f;
|
||||
float attenuation = saturate(dot(float3(0.0f, -1.0f, 0.0f), normal));
|
||||
|
||||
float3 blending = abs(normal);
|
||||
blending = normalize(max(blending, 0.00001f));
|
||||
float b = (blending.x + blending.y + blending.z);
|
||||
blending /= float3(b, b, b);
|
||||
|
||||
float3 p = float3(fracX, fracY, fracZ) / 2048.0f;
|
||||
float3 xaxis = tex2D(CausticsSampler, p.yz).rgb;
|
||||
float3 yaxis = tex2D(CausticsSampler, p.xz).rgb;
|
||||
float3 zaxis = tex2D(CausticsSampler, p.xy).rgb;
|
||||
output += float4((xaxis * blending.x + yaxis * blending.y + zaxis * blending.z).xyz, 0.0f) * 0.10f * attenuation;
|
||||
}*/
|
||||
|
||||
// We lit room geometry only in the case of dynamic lights
|
||||
if ((modelType == MODELTYPE_ROOM || modelType == MODELTYPE_ROOM_UNDERWATER) && !LightDynamic)
|
||||
{
|
||||
// Is this light dynamic? In not, then I don't do any further calculations
|
||||
return (output);
|
||||
}
|
||||
|
||||
// Get specular intensity
|
||||
float specularIntensity = tex2D(ColorSampler, texCoord).a;
|
||||
|
||||
// Now the shader is different according to light type
|
||||
if (LightType == LIGHTTYPE_SUN)
|
||||
{
|
||||
// Compute screen-space position
|
||||
float4 position;
|
||||
position.x = input.TextureCoordinate.x * 2.0f - 1.0f;
|
||||
position.y = -(input.TextureCoordinate.y * 2.0f - 1.0f);
|
||||
position.z = depthVal;
|
||||
position.w = 1.0f;
|
||||
|
||||
// Transform to world space
|
||||
position = mul(position, ViewProjectionInverse);
|
||||
position /= position.w;
|
||||
|
||||
// Surface-to-light vector
|
||||
float3 lightVector = -normalize(LightDirection);
|
||||
|
||||
// Compute diffuse light
|
||||
float NdL = max(0, dot(normal, lightVector));
|
||||
float3 diffuseLight = NdL * LightColor.rgb;
|
||||
|
||||
// Reflection vector
|
||||
float3 reflectionVector = normalize(reflect(lightVector, normal));
|
||||
|
||||
// Camera-to-surface vector
|
||||
float3 directionToCamera = normalize(CameraPosition - position);
|
||||
|
||||
// Compute specular light
|
||||
float specularLight = specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);
|
||||
|
||||
// Output the two lights
|
||||
output = float4(diffuseLight.rgb, specularLight);
|
||||
}
|
||||
else if (LightType == LIGHTTYPE_POINT)
|
||||
{
|
||||
// Compute screen-space position
|
||||
float4 position;
|
||||
position.xy = input.ScreenPosition.xy;
|
||||
position.z = depthVal;
|
||||
position.w = 1.0f;
|
||||
|
||||
// Transform to world space
|
||||
position = mul(position, ViewProjectionInverse);
|
||||
position /= position.w;
|
||||
|
||||
// Surface-to-light vector
|
||||
float3 lightVector = LightPosition - position;
|
||||
|
||||
// Compute attenuation based on distance - linear attenuation
|
||||
float attenuation = saturate(1.0f - length(lightVector) / LightOut);
|
||||
|
||||
// Normalize light vector
|
||||
lightVector = normalize(lightVector);
|
||||
|
||||
// Compute diffuse light
|
||||
float NdL = pow((dot(normal, lightVector) * 0.5f) + 0.5f, 2); //max(0, dot(normal, lightVector));
|
||||
float3 diffuseLight = NdL * LightColor.rgb;
|
||||
|
||||
// Reflection vector
|
||||
float3 reflectionVector = normalize(reflect(-lightVector, normal));
|
||||
|
||||
// Camera-to-surface vector
|
||||
float3 directionToCamera = normalize(CameraPosition - position);
|
||||
|
||||
// Compute specular light
|
||||
float specularLight = specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);
|
||||
|
||||
// Take into account attenuation and lightIntensity.
|
||||
output = attenuation * LightIntensity * float4(diffuseLight.rgb, specularLight) * 0.75f;
|
||||
}
|
||||
|
||||
//output.a = 0.5f;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
technique Light
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
VertexShader = compile vs_3_0 VertexShaderFunction();
|
||||
PixelShader = compile ps_3_0 PixelShaderFunction();
|
||||
}
|
||||
}
|
|
@ -88,6 +88,13 @@ __int32 __cdecl LoadItems()
|
|||
item->pos.zPos = 21162;
|
||||
item->roomNumber = 0;
|
||||
}*/
|
||||
if (item->objectNumber == ID_LARA)
|
||||
{
|
||||
item->pos.xPos = 58*1024;
|
||||
item->pos.yPos = 0;
|
||||
item->pos.zPos = 39*1024;
|
||||
item->roomNumber = 144;
|
||||
}
|
||||
}
|
||||
|
||||
for (__int32 i = 0; i < NumItems; i++)
|
||||
|
|