Redo of render paths
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
import Common;
|
||||
|
||||
interface IBRDF
|
||||
{
|
||||
float3 evaluate(float3 view, float3 light, float3 normal, float3 tangent, float3 biTangent, float3 lightColor);
|
||||
};
|
||||
|
||||
struct BlinnPhong : IBRDF
|
||||
{
|
||||
float3 baseColor;
|
||||
float metallic = 0;
|
||||
float3 normal = float3(0, 1, 0);
|
||||
float subsurface = 0;
|
||||
float specular = 0.5;
|
||||
float roughness = 0.5;
|
||||
float specularTint = 0;
|
||||
float anisotropic = 0;
|
||||
float sheen = 0;
|
||||
float sheenTint = 0.5f;
|
||||
float clearCoat = 0;
|
||||
float clearCoatGloss = 1;
|
||||
|
||||
float3 evaluate(float3 view, float3 light, float3 surfaceNormal, float3 tangent, float3 biTangent, float3 lightColor)
|
||||
{
|
||||
float nDotL = saturate(dot(normal, light));
|
||||
float3 h = normalize(light + view);
|
||||
float nDotH = saturate(dot(normal, h));
|
||||
|
||||
return baseColor * nDotL + lightColor * specular * pow(nDotH, sheen);
|
||||
}
|
||||
};
|
||||
|
||||
struct DisneyBRDF : IBRDF
|
||||
{
|
||||
float3 baseColor;
|
||||
float metallic = 0;
|
||||
float3 normal = float3(0, 1, 0);
|
||||
float subsurface = 0;
|
||||
float specular = 0.5;
|
||||
float roughness = 0.5;
|
||||
float specularTint = 0;
|
||||
float anisotropic = 0;
|
||||
float sheen = 0;
|
||||
float sheenTint = 0.5f;
|
||||
float clearCoat = 0;
|
||||
float clearCoatGloss = 1;
|
||||
|
||||
float sqr(float x)
|
||||
{
|
||||
return x * x;
|
||||
}
|
||||
|
||||
float SchlickFresnel(float u)
|
||||
{
|
||||
float m = clamp(1 - u, 0, 1);
|
||||
float m2 = m * m;
|
||||
return m2 * m2 * m; // pow(m,5)
|
||||
}
|
||||
|
||||
float GTR1(float NdotH, float a)
|
||||
{
|
||||
if (a >= 1)
|
||||
return 1 / PI;
|
||||
float a2 = a * a;
|
||||
float t = 1 + (a2 - 1) * NdotH * NdotH;
|
||||
return (a2 - 1) / (PI * log(a2) * t);
|
||||
}
|
||||
|
||||
float GTR2(float NdotH, float a)
|
||||
{
|
||||
float a2 = a * a;
|
||||
float t = 1 + (a2 - 1) * NdotH * NdotH;
|
||||
return a2 / (PI * t * t);
|
||||
}
|
||||
|
||||
float GTR2_aniso(float NdotH, float HdotX, float HdotY, float ax, float ay)
|
||||
{
|
||||
return 1 / (PI * ax * ay * sqr(sqr(HdotX / ax) + sqr(HdotY / ay) + NdotH * NdotH));
|
||||
}
|
||||
|
||||
float smithG_GGX(float NdotV, float alphaG)
|
||||
{
|
||||
float a = alphaG * alphaG;
|
||||
float b = NdotV * NdotV;
|
||||
return 1 / (NdotV + sqrt(a + b - a * b));
|
||||
}
|
||||
|
||||
float smithG_GGX_aniso(float NdotV, float VdotX, float VdotY, float ax, float ay)
|
||||
{
|
||||
return 1 / (NdotV + sqrt(sqr(VdotX * ax) + sqr(VdotY * ay) + sqr(NdotV)));
|
||||
}
|
||||
|
||||
float3 mon2lin(float3 x)
|
||||
{
|
||||
return float3(pow(x[0], 2.2), pow(x[1], 2.2), pow(x[2], 2.2));
|
||||
}
|
||||
|
||||
|
||||
float3 evaluate(float3 V, float3 L, float3 surfaceNormal, float3 X, float3 Y, float3 lightColor)
|
||||
{
|
||||
float3 N = normal;
|
||||
float NdotL = dot(N, L);
|
||||
float NdotV = dot(N, V);
|
||||
if (NdotL < 0 || NdotV < 0)
|
||||
return float3(0);
|
||||
float3 H = normalize(L + V);
|
||||
|
||||
float NdotH = dot(N, H);
|
||||
float LdotH = dot(L, H);
|
||||
float3 Cdlin = mon2lin(baseColor);
|
||||
float Cdlum = .3 * Cdlin[0] + .6 * Cdlin[1] + .1 * Cdlin[2]; // luminance approx.
|
||||
float3 Ctint = Cdlum > 0 ? Cdlin / Cdlum : float3(1); // normalize lum. to isolate hue+sat
|
||||
float3 Cspec0 = lerp(specular * .08 * lerp(float3(1), Ctint, specularTint), Cdlin, metallic);
|
||||
float3 Csheen = lerp(float3(1), Ctint, sheenTint);
|
||||
|
||||
// Diffuse fresnel - go from 1 at normal incidence to .5 at grazing
|
||||
// and mix in diffuse retro-reflection based on roughness
|
||||
float FL = SchlickFresnel(NdotL), FV = SchlickFresnel(NdotV);
|
||||
float Fd90 = 0.5 + 2 * LdotH * LdotH * roughness;
|
||||
float Fd = lerp(1.0, Fd90, FL) * lerp(1.0, Fd90, FV);
|
||||
|
||||
// Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf
|
||||
// 1.25 scale is used to (roughly) preserve albedo
|
||||
// Fss90 used to "flatten" retroreflection based on roughness
|
||||
float Fss90 = LdotH * LdotH * roughness;
|
||||
float Fss = lerp(1.0, Fss90, FL) * lerp(1.0, Fss90, FV);
|
||||
float ss = 1.25 * (Fss * (1 / (NdotL + NdotV) - .5) + .5);
|
||||
|
||||
// specular
|
||||
float aspect = sqrt(1 - anisotropic * .9);
|
||||
float ax = max(.001, sqr(roughness) / aspect);
|
||||
float ay = max(.001, sqr(roughness) * aspect);
|
||||
float Ds = GTR2_aniso(NdotH, dot(H, X), dot(H, Y), ax, ay);
|
||||
float FH = SchlickFresnel(LdotH);
|
||||
float3 Fs = lerp(Cspec0, float3(1), FH);
|
||||
float Gs;
|
||||
Gs = smithG_GGX_aniso(NdotL, dot(L, X), dot(L, Y), ax, ay);
|
||||
Gs *= smithG_GGX_aniso(NdotV, dot(V, X), dot(V, Y), ax, ay);
|
||||
|
||||
// sheen
|
||||
float3 Fsheen = FH * sheen * Csheen;
|
||||
|
||||
// clearcoat (ior = 1.5 -> F0 = 0.04)
|
||||
float Dr = GTR1(NdotH, lerp(.1, .001, clearCoatGloss));
|
||||
float Fr = lerp(.04, 1.0, FH);
|
||||
float Gr = smithG_GGX(NdotL, .25) * smithG_GGX(NdotV, .25);
|
||||
|
||||
return ((1 / PI) * lerp(Fd, ss, subsurface) * Cdlin + Fsheen)
|
||||
* (1 - metallic)
|
||||
+ Gs * Fs * Ds + .25 * clearCoat * Gr * Fr * Dr;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
const static float PI = 3.1415926535897932f;
|
||||
const static uint MAX_PARTICLES = 65536;
|
||||
const static uint BLOCK_SIZE = 8;
|
||||
|
||||
cbuffer ScreenToViewParams
|
||||
{
|
||||
float4x4 inverseProjection;
|
||||
float2 screenDimensions;
|
||||
}
|
||||
|
||||
// Convert clip space coordinates to view space
|
||||
float4 clipToView( float4 clip )
|
||||
{
|
||||
// View space position.
|
||||
float4 view = mul( inverseProjection, clip );
|
||||
// Perspective projection.
|
||||
view = view / view.w;
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
// Convert screen space coordinates to view space.
|
||||
float4 screenToView( float4 screen )
|
||||
{
|
||||
// Convert to normalized texture coordinates
|
||||
float2 texCoord = screen.xy / screenDimensions;
|
||||
|
||||
// Convert to clip space
|
||||
float4 clip = float4( float2( texCoord.x, -texCoord.y ) * 2.0f - 1.0f, screen.z, screen.w );
|
||||
|
||||
return clipToView( clip );
|
||||
}
|
||||
|
||||
struct Plane
|
||||
{
|
||||
float3 n;
|
||||
float d;
|
||||
float3 p0;
|
||||
float3 p1;
|
||||
float3 p2;
|
||||
};
|
||||
|
||||
struct Frustum
|
||||
{
|
||||
Plane planes[4];
|
||||
};
|
||||
Plane computePlane(float3 p0, float3 p1, float3 p2)
|
||||
{
|
||||
Plane plane;
|
||||
|
||||
float3 v0 = p2 - p0;
|
||||
float3 v2 = p1 - p0;
|
||||
|
||||
plane.n = normalize(cross(v0, v2));
|
||||
|
||||
plane.d = dot(plane.n, p0);
|
||||
plane.p0 = p0;
|
||||
plane.p1 = p1;
|
||||
plane.p2 = p2;
|
||||
|
||||
return plane;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import LightEnv;
|
||||
import Material;
|
||||
import BRDF;
|
||||
import InputGeometry;
|
||||
|
||||
struct FlatColorMaterial : IMaterial
|
||||
{
|
||||
float3 diffuseColor;
|
||||
float specularity;
|
||||
|
||||
typedef BlinnPhong BRDF;
|
||||
BlinnPhong prepare(MaterialPixelParameter input)
|
||||
{
|
||||
BlinnPhong result;
|
||||
result.baseColor = diffuseColor;
|
||||
result.specular = specularity;
|
||||
result.normal = normalize(input.normal);
|
||||
result.roughness = 0.5;
|
||||
result.specularTint = 0;
|
||||
result.anisotropic = 1;
|
||||
result.sheen = 1;
|
||||
result.sheenTint = 0.5;
|
||||
result.clearCoat = 0;
|
||||
result.clearCoatGloss = 0;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
interface IVertexShaderInput
|
||||
{
|
||||
//internally, the vertex layout is stored in vec4 for faster access,
|
||||
//but here we unwrap them for convenience
|
||||
float3 getVertexPosition();
|
||||
float2 getTexCoords();
|
||||
float3 getNormal();
|
||||
float3 getTangent();
|
||||
float3 getBiTangent();
|
||||
};
|
||||
|
||||
struct PositionOnlyVertexInput : IVertexShaderInput
|
||||
{
|
||||
float4 position;
|
||||
|
||||
float3 getVertexPosition() { return position.xyz; }
|
||||
float2 getTexCoords() { return float2(0, 0); }
|
||||
float3 getNormal() { return float3(0, 1, 0); }
|
||||
float3 getTangent() { return float3(1, 0, 0); }
|
||||
float3 getBiTangent() { return float3(0, 0, 1); }
|
||||
};
|
||||
|
||||
struct PositionAndNormalVertexInput : IVertexShaderInput
|
||||
{
|
||||
float4 position;
|
||||
float4 normal;
|
||||
|
||||
float3 getVertexPosition() { return position.xyz; }
|
||||
float2 getTexCoords() { return float2(0, 0); }
|
||||
float3 getNormal() { return normal.xyz; }
|
||||
float3 getTangent() { return float3(1, 0, 0); }
|
||||
float3 getBiTangent() { return float3(0, 0, 1); }
|
||||
};
|
||||
|
||||
struct InputGeometry : IVertexShaderInput
|
||||
{
|
||||
float4 position;
|
||||
float2 texCoord;
|
||||
float4 normal;
|
||||
float4 tangent;
|
||||
float4 bitangent;
|
||||
|
||||
float3 getVertexPosition() { return position.xyz; }
|
||||
float2 getTexCoords() { return texCoord; }
|
||||
float3 getNormal() { return normal.xyz; }
|
||||
float3 getTangent() { return tangent.xyz; }
|
||||
float3 getBiTangent() { return bitangent.xyz; }
|
||||
};
|
||||
|
||||
struct MaterialPixelParameter
|
||||
{
|
||||
float3 position;
|
||||
float2 texCoord;
|
||||
float3 viewDir;
|
||||
float3 normal;
|
||||
float3 tangent;
|
||||
float3 biTangent;
|
||||
float4 clipPosition;
|
||||
float3 transformLocalToWorld(float3 input)
|
||||
{
|
||||
float3 unitNormal = normalize(normal);
|
||||
float3 unitTangent = normalize(tangent);
|
||||
unitTangent = normalize(unitTangent - dot(unitTangent, unitNormal) * unitNormal);
|
||||
float3 unitBitangent = cross(unitTangent, unitNormal);
|
||||
float3x3 tbn = float3x3(unitTangent, unitBitangent, unitNormal);
|
||||
float3 result = mul(tbn, input);
|
||||
result = normalize(result);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
import InputGeometry;
|
||||
import BRDF;
|
||||
import Common;
|
||||
|
||||
interface ILightEnv
|
||||
{
|
||||
float3 illuminate<B:IBRDF>(InputGeometry input, B brdf, float3 wo);
|
||||
};
|
||||
|
||||
struct DirectionalLight : ILightEnv
|
||||
{
|
||||
float4 color;
|
||||
float4 direction;
|
||||
float4 intensity;
|
||||
|
||||
float3 illuminate<B:IBRDF>(MaterialPixelParameter input, B brdf, float3 wo)
|
||||
{
|
||||
return intensity.xyz * brdf.evaluate(wo, direction.xyz, input.normal, input.tangent, input.biTangent, color.xyz);
|
||||
}
|
||||
};
|
||||
|
||||
struct PointLight : ILightEnv
|
||||
{
|
||||
float4 positionWS;
|
||||
float4 positionVS;
|
||||
float3 color;
|
||||
float range;
|
||||
|
||||
float3 illuminate<B:IBRDF>(MaterialPixelParameter input, B brdf, float3 viewDir)
|
||||
{
|
||||
float3 lightVec = positionWS.xyz - input.position;
|
||||
float d = length(lightVec);
|
||||
float3 direction = normalize(lightVec);
|
||||
float illuminance = max(1 - d / range, 0);
|
||||
return illuminance * brdf.evaluate(viewDir, direction, input.normal, input.tangent, input.biTangent, color);
|
||||
}
|
||||
|
||||
bool insidePlane(Plane plane)
|
||||
{
|
||||
return dot(plane.n, positionVS.xyz) - plane.d < -range;
|
||||
}
|
||||
|
||||
bool insideFrustum(Frustum frustum, float zNear, float zFar)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
//if(positionVS.z - range > zNear || positionVS.z + range < zFar)
|
||||
{
|
||||
// result = false;
|
||||
}
|
||||
for(int i = 0; i < 4 && result; ++i)
|
||||
{
|
||||
if(insidePlane(frustum.planes[i]))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
#define MAX_DIRECTIONAL_LIGHTS 4
|
||||
#define MAX_POINT_LIGHTS 256
|
||||
struct Lights
|
||||
{
|
||||
DirectionalLight directionalLights[MAX_DIRECTIONAL_LIGHTS];
|
||||
PointLight pointLights[MAX_POINT_LIGHTS];
|
||||
uint numDirectionalLights;
|
||||
uint numPointLights;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
import Common;
|
||||
import BRDF;
|
||||
import InputGeometry;
|
||||
|
||||
interface IMaterial
|
||||
{
|
||||
associatedtype BRDF : IBRDF;
|
||||
BRDF prepare(MaterialPixelParameter geometry);
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
import Material;
|
||||
import InputGeometry;
|
||||
|
||||
struct ParallaxMaterial : IMaterial
|
||||
{
|
||||
Texture2D<float4> diffuseTexture;
|
||||
Texture2D<float4> specularTexture;
|
||||
Texture2D<float4> displacementTexture;
|
||||
SamplerState textureSampler;
|
||||
float specularity;
|
||||
|
||||
typedef BlinnPhong BRDF;
|
||||
BlinnPhong prepare(InputGeometry geometry)
|
||||
{
|
||||
BlinnPhong blinn;
|
||||
blinn.baseColor = diffuseTexture.Sample(textureSampler, geometry.getTexCoords()).xyz;
|
||||
blinn.specularColor = specularTexture.Sample(textureSampler, geometry.getTexCoords()).xyz;
|
||||
blinn.specular = specularity;
|
||||
return blinn;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
struct Particle
|
||||
{
|
||||
float3 position;
|
||||
float mass;
|
||||
float3 velocity;
|
||||
float age;
|
||||
float3 forceAccumulator;
|
||||
float life;
|
||||
float color;
|
||||
float3 pad;
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
import LightEnv;
|
||||
import Material;
|
||||
import BRDF;
|
||||
import InputGeometry;
|
||||
|
||||
struct TexturedMaterial : IMaterial
|
||||
{
|
||||
Texture2D diffuseTexture;
|
||||
Texture2D specularTexture;
|
||||
Texture2D normalTexture;
|
||||
float uvScale;
|
||||
float metallic = 0;
|
||||
float subsurface = 0;
|
||||
float roughness = 0.5;
|
||||
float specularTint = 0;
|
||||
float anisotropic = 0;
|
||||
float sheen = 0;
|
||||
float sheenTint = 0.5f;
|
||||
float clearCoat = 0;
|
||||
float clearCoatGloss = 1;
|
||||
SamplerState textureSampler;
|
||||
|
||||
typedef BlinnPhong BRDF;
|
||||
BlinnPhong prepare(MaterialPixelParameter geometry)
|
||||
{
|
||||
BlinnPhong result;
|
||||
result.baseColor = diffuseTexture.Sample(textureSampler, geometry.texCoord * uvScale).xyz;
|
||||
result.metallic = 0;
|
||||
float3 bumpMapNormal = normalTexture.Sample(textureSampler, geometry.texCoord * uvScale).xyz;
|
||||
bumpMapNormal = 2.0 * bumpMapNormal - float3(1.0, 1.0, 1.0);
|
||||
result.normal = geometry.transformLocalToWorld(bumpMapNormal);
|
||||
result.specular = specularTexture.Sample(textureSampler, geometry.texCoord * uvScale).x;
|
||||
result.roughness = roughness;
|
||||
result.specularTint = specularTint;
|
||||
result.anisotropic = anisotropic;
|
||||
result.sheen = sheen;
|
||||
result.sheenTint = sheenTint;
|
||||
result.clearCoat = clearCoat;
|
||||
result.clearCoatGloss = clearCoatGloss;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user