Add Instanced Rendering / 2 more scenes
This commit is contained in:
194
project/resources/InstancedSimpleDiffuse.fx
Normal file
194
project/resources/InstancedSimpleDiffuse.fx
Normal file
@@ -0,0 +1,194 @@
|
||||
SamplerState gSampleState : SampleState;
|
||||
RasterizerState gRasterizerState : RastState;
|
||||
|
||||
float4x4 gWorldViewProj : WorldViewProjection;
|
||||
float4x4 gWorldMatrix : WorldMatrix;
|
||||
|
||||
texture2D gDiffuseMap : DiffuseMap;
|
||||
texture2D gNormalMap : Normal;
|
||||
texture2D gSpecularMap : Specular;
|
||||
texture2D gGlossMap : Gloss;
|
||||
|
||||
float3 gLightDirection : LightDirection;
|
||||
float3 gLightColor : LightColor;
|
||||
float3 gCameraPosition : CameraPosition;
|
||||
bool gUseNormal : UseNormal;
|
||||
|
||||
|
||||
static const float3 gAmbient = float3(.03f, .03f, .03f);
|
||||
static const float gLightIntensity = 7.f;
|
||||
static const float PI = 3.14159f;
|
||||
static const float gSpecularReflectance = 1.f;
|
||||
static const float gShininess = 25.f;
|
||||
|
||||
//Input output
|
||||
struct VS_INPUT {
|
||||
float3 Position : POSITION;
|
||||
float2 TexCoord : TEXCOORD;
|
||||
float3 Normal : NORMAL;
|
||||
float3 Tangent : TANGENT;
|
||||
float4 InstanceWorld0 : INSTANCEWORLD0;
|
||||
float4 InstanceWorld1 : INSTANCEWORLD1;
|
||||
float4 InstanceWorld2 : INSTANCEWORLD2;
|
||||
float4 InstanceWorld3 : INSTANCEWORLD3;
|
||||
float4 InstanceColor : INSTANCECOLOR;
|
||||
};
|
||||
struct VS_OUTPUT {
|
||||
float4 Position : SV_POSITION;
|
||||
float4 WorldPosition : WORLDPOSITION;
|
||||
float2 TexCoord : TEXCOORD;
|
||||
float3 Normal : NORMAL;
|
||||
float3 Tangent : TANGENT;
|
||||
float4 Color : COLOR; // Pass instance color to the pixel shader
|
||||
};
|
||||
|
||||
|
||||
//----------------------
|
||||
// Rasterizer state
|
||||
//----------------------
|
||||
// RasterizerState gRasterizerState
|
||||
// {
|
||||
// CullMode = none;
|
||||
// FrontCounterClockwise = false; //default
|
||||
// };
|
||||
|
||||
|
||||
//Vertex shader
|
||||
VS_OUTPUT VS(VS_INPUT input) {
|
||||
|
||||
VS_OUTPUT output;
|
||||
|
||||
// Reconstruct the world matrix from instance data
|
||||
float4x4 instanceWorld = float4x4(
|
||||
input.InstanceWorld0,
|
||||
input.InstanceWorld1,
|
||||
input.InstanceWorld2,
|
||||
input.InstanceWorld3
|
||||
);
|
||||
|
||||
// Transform the position to world space and then to clip space
|
||||
float4 worldPosition = mul(float4(input.Position, 1.0f), instanceWorld);
|
||||
output.Position = mul(worldPosition, gWorldViewProj); // Transform to clip space using gViewProjMatrix
|
||||
output.WorldPosition = worldPosition; // Pass through the
|
||||
//
|
||||
// Extract the 3x3 upper portion of the world matrix for normal and tangent transformations
|
||||
float3x3 instanceWorld3x3 = (float3x3)instanceWorld; // Extract upper 3x3 matrix
|
||||
output.Normal = normalize(mul(input.Normal, instanceWorld3x3)); // Transform and normalize the normal
|
||||
output.Tangent = normalize(mul(input.Tangent, instanceWorld3x3)); // Transform and normalize the tangent
|
||||
|
||||
// Pass through texture coordinates
|
||||
output.TexCoord = input.TexCoord;
|
||||
|
||||
// Pass through the instance color
|
||||
output.Color = input.InstanceColor;
|
||||
|
||||
return output;
|
||||
}
|
||||
float3 Phong(float ks, float exp, float3 l, float3 v, float3 n)
|
||||
{
|
||||
float3 reflected = reflect(l, n);
|
||||
float cosAngle = dot(reflected, v);
|
||||
return ks * pow(max(0.f, cosAngle), exp) * gLightColor;
|
||||
}
|
||||
float3 Lambert(float kd, float3 cd)
|
||||
{
|
||||
return (kd * cd) / PI;
|
||||
}
|
||||
|
||||
|
||||
float3 Shade(VS_OUTPUT input)
|
||||
{
|
||||
// Sample diffuse, specular, and gloss maps
|
||||
float3 diffuseSample = gDiffuseMap.Sample(gSampleState, input.TexCoord).rgb;
|
||||
float3 specularSample = gSpecularMap.Sample(gSampleState, input.TexCoord).rgb;
|
||||
float glossSample = gGlossMap.Sample(gSampleState, input.TexCoord).x;
|
||||
float3 normalSample = gNormalMap.Sample(gSampleState, input.TexCoord).rgb;
|
||||
|
||||
// Compute inversed view and light directions
|
||||
float3 invViewDirection = normalize(gCameraPosition - input.WorldPosition.xyz);
|
||||
float3 invLightDirection = -gLightDirection;
|
||||
|
||||
// Compute tangent space axes if normal mapping is used
|
||||
float3 normal = input.Normal;
|
||||
if (gUseNormal) {
|
||||
float3 binormal = cross(input.Normal, input.Tangent);
|
||||
float3x3 tangentSpaceAxis = float3x3(input.Tangent, binormal, input.Normal);
|
||||
|
||||
// Sample and transform normal map
|
||||
normal = float3(2.f * normalSample.x - 1.f,
|
||||
2.f * normalSample.y - 1.f,
|
||||
2.f * normalSample.z - 1.f);
|
||||
normal = mul(normal, tangentSpaceAxis);
|
||||
}
|
||||
|
||||
// Compute Lambert diffuse lighting
|
||||
float3 diffuse = Lambert(gLightIntensity, diffuseSample);
|
||||
|
||||
// Compute Phong specular lighting
|
||||
float ks = (specularSample.x + specularSample.y + specularSample.z) / 3.f;
|
||||
float3 specular = Phong(ks, glossSample * gShininess, invLightDirection, invViewDirection, normal);
|
||||
|
||||
// Compute observed area based on the cosine of the light angle
|
||||
float cosAngle = dot(invLightDirection, normal);
|
||||
float3 observedArea = float3(cosAngle, cosAngle, cosAngle);
|
||||
|
||||
// Combine lighting components
|
||||
float3 color = saturate(diffuse * observedArea + specular + gAmbient * cosAngle);
|
||||
|
||||
return color;
|
||||
}
|
||||
float4 PS(VS_OUTPUT input) : SV_TARGET {
|
||||
// Normalize vectors
|
||||
float3 norm = normalize(input.Normal);
|
||||
float3 lightDir = normalize(gLightDirection);
|
||||
float3 viewDir = normalize(gCameraPosition - input.WorldPosition.xyz);
|
||||
|
||||
// Compute ambient lighting
|
||||
float3 ambient = gAmbient * gLightColor;
|
||||
|
||||
// Compute diffuse lighting
|
||||
float diff = max(dot(norm, lightDir), 0.0f); // Ensure clamping to non-negative values
|
||||
float3 diffuse = diff * gLightColor;
|
||||
|
||||
// Compute specular lighting
|
||||
float3 reflectDir = reflect(-lightDir, norm); // Reflect light direction around normal
|
||||
float spec = pow(max(dot(reflectDir, viewDir), 0.0f), gShininess); // Apply shininess exponent
|
||||
float3 specular = gSpecularReflectance * spec * gLightColor;
|
||||
|
||||
// Combine the lighting components with input color
|
||||
float3 finalColor = ambient + diffuse + specular;
|
||||
// return float4(finalColor * input.Color.rgb, input.Color.a); // Multiply by vertex color
|
||||
return gDiffuseMap.Sample(gSampleState, input.TexCoord);
|
||||
}
|
||||
|
||||
float4 PSNormal(VS_OUTPUT input) : SV_TARGET {
|
||||
// Normalize the input normal
|
||||
float3 norm = normalize(input.Normal);
|
||||
|
||||
// Map the normal from [-1, 1] to [0, 1]
|
||||
float3 normalColor = 0.5f * (norm + 1.0f);
|
||||
|
||||
// Output the normal as RGB color
|
||||
return float4(normalColor, 1.0f); // Alpha is set to 1 for full opacity
|
||||
}
|
||||
|
||||
DepthStencilState gDepthStencilState
|
||||
{
|
||||
//enable
|
||||
DepthEnable = true;
|
||||
DepthWriteMask = ALL;
|
||||
DepthFunc = LESS;
|
||||
//stencil
|
||||
StencilEnable = true;
|
||||
};
|
||||
|
||||
|
||||
technique11 DefaultTechnique {
|
||||
pass P0 {
|
||||
SetDepthStencilState(gDepthStencilState, 0);
|
||||
SetRasterizerState(gRasterizerState);
|
||||
SetVertexShader(CompileShader(vs_5_0, VS()));
|
||||
SetGeometryShader(NULL);
|
||||
SetPixelShader(CompileShader(ps_5_0, PS()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user