You're breathtaking!

This commit is contained in:
Wojtek Figat
2020-12-07 23:40:54 +01:00
commit 6fb9eee74c
5143 changed files with 1153594 additions and 0 deletions

44
.gitattributes vendored Normal file
View File

@@ -0,0 +1,44 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted to native line endings on checkout.
*.c text diff=cpp
*.h text diff=cpp
*.cpp text diff=cpp
*.hpp text diff=cpp
*.txt text
*.cs text diff=csharp
# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf
*.props text eol=crlf
*.csproj text eol=crlf
*.vcxproj text eol=crlf
*.vcxproj.filters text eol=crlf
# Git LFS for binaries
*.flax filter=lfs diff=lfs merge=lfs -text
*.bin filter=lfs diff=lfs merge=lfs -text
*.dat filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text
*.lib filter=lfs diff=lfs merge=lfs -text
*.so filter=lfs diff=lfs merge=lfs -text
*.pdb filter=lfs diff=lfs merge=lfs -text
*.exe filter=lfs diff=lfs merge=lfs -text
*.a filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.ai filter=lfs diff=lfs merge=lfs -text
*.mp3 filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text
*.ogg filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.mov filter=lfs diff=lfs merge=lfs -text
*.FBX filter=lfs diff=lfs merge=lfs -text
*.fbx filter=lfs diff=lfs merge=lfs -text
*.blend filter=lfs diff=lfs merge=lfs -text
*.obj filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text

187
.gitignore vendored Normal file
View File

@@ -0,0 +1,187 @@
# Flax stuff
*.sln
[Dd]ebug/
[Rr]elease/
obj/
Cache/
Binaries/
Logs/
Source/*.csproj
!Source/Engine/Debug
# User-specific files
*.suo
*.user
*.sln.docstates
*.idb
*.tlog
*.lastbuilddate
*.opendb
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# NuGet Packages Directory
packages/**/*
!packages/repositories.config
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Enable "build/" folder in the NuGet Packages folder since
# NuGet packages use it for MSBuild targets.
# This line needs to be after the ignore of the build folder
# (and the packages folder if the line above has been uncommented)
!packages/build/
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project files
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# IDE files
*.VC.db
enc_temp_folder/
*.stackdump
.vs/
bin/
obj/
*.vcxproj.filters
.vscode/
*.code-workspace

0
.gitmodules vendored Normal file
View File

46
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@flaxengine.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

BIN
Content/Editor/Camera/M_Camera.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Camera/O_Camera.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Camera/T_Camera.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/CubeTexturePreviewMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/DefaultFontMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/EditorIcon.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Fonts/Inconsolata-Regular.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Fonts/Roboto-Regular.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Fonts/SegMDL2.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Fonts/Segoe Media Center Regular.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/Axis.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/Material.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/MaterialAxisFocus.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/MaterialAxisX.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/MaterialAxisY.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/MaterialAxisZ.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/MaterialWire.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/MaterialWireFocus.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/ScaleAxis.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/TranslateAxis.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/WireBox.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/WireCircle.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Highlight Material.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/AudioListener.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/AudioSource.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Decal.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/DirectionalLight.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/EnvironmentProbe.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/IconsMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/ParticleEffect.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/PointLight.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/SceneAnimationPlayer.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Skybox.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Skylight.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Textures/AudioListner.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Textures/AudioSource.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Textures/Decal.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Textures/DirectionalLight.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Textures/EnvironmentProbe.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Textures/ParticleEffect.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Textures/PointLight.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Textures/SceneAnimationPlayer.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Textures/SkyLight.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Icons/Textures/Skybox.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/IconsAtlas.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/IesProfilePreviewMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -0,0 +1,23 @@
<DockPanelLayout Version="4">
<MainWindow IsMaximized="True">
<Bounds X="0" Y="23" Width="1920" Height="1017" />
</MainWindow>
<MasterPanel SelectedTab="0">
<Window Typename="::FlaxEditor.Windows.EditGameWindow" />
<Window Typename="::FlaxEditor.Windows.GameWindow" />
<Panel DockState="10" SplitterValue="0.24" SelectedTab="0">
<Window Typename="::FlaxEditor.Windows.PropertiesWindow" />
<Panel DockState="7" SplitterValue="0.25" SelectedTab="0">
<Window Typename="::FlaxEditor.Windows.ToolboxWindow" />
</Panel>
</Panel>
<Panel DockState="9" SplitterValue="0.37" SelectedTab="0">
<Window Typename="::FlaxEditor.Windows.ContentWindow" />
<Window Typename="::FlaxEditor.Windows.DebugLogWindow" />
<Window Typename="::FlaxEditor.Windows.OutputLogWindow" />
</Panel>
<Panel DockState="8" SplitterValue="0.25" SelectedTab="0">
<Window Typename="::FlaxEditor.Windows.SceneTreeWindow" />
</Panel>
</MasterPanel>
</DockPanelLayout>

View File

@@ -0,0 +1,217 @@
// File generated by Flax Materials Editor
// Version: @0
#define MATERIAL 1
@3
#include "./Flax/Common.hlsl"
#include "./Flax/MaterialCommon.hlsl"
#include "./Flax/GBufferCommon.hlsl"
@7
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 WorldMatrix;
float4x4 ViewMatrix;
float4x4 InvWorld;
float4x4 SVPositionToWorld;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
@1META_CB_END
// Use depth buffer for per-pixel decal layering
Texture2D DepthBuffer : register(t0);
// Material shader resources
@2
// Material properties generation input
struct MaterialInput
{
float3 WorldPosition;
float TwoSidedSign;
float2 TexCoord;
float3x3 TBN;
float4 SvPosition;
float3 PreSkinnedPosition;
float3 PreSkinnedNormal;
};
// Transforms a vector from tangent space to world space
float3 TransformTangentVectorToWorld(MaterialInput input, float3 tangentVector)
{
return mul(tangentVector, input.TBN);
}
// Transforms a vector from world space to tangent space
float3 TransformWorldVectorToTangent(MaterialInput input, float3 worldVector)
{
return mul(input.TBN, worldVector);
}
// Transforms a vector from world space to view space
float3 TransformWorldVectorToView(MaterialInput input, float3 worldVector)
{
return mul(worldVector, (float3x3)ViewMatrix);
}
// Transforms a vector from view space to world space
float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
{
return mul((float3x3)ViewMatrix, viewVector);
}
// Transforms a vector from local space to world space
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
{
float3x3 localToWorld = (float3x3)WorldMatrix;
return mul(localVector, localToWorld);
}
// Transforms a vector from local space to world space
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
{
float3x3 localToWorld = (float3x3)WorldMatrix;
return mul(localToWorld, worldVector);
}
// Gets the current object position (supports instancing)
float3 GetObjectPosition(MaterialInput input)
{
return WorldMatrix[3].xyz;
}
// Gets the current object size
float3 GetObjectSize(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{
return 0;
}
// Get the current object LOD transition dither factor (supports instancing)
float GetLODDitherFactor(MaterialInput input)
{
return 0;
}
// Gets the interpolated vertex color (in linear space)
float4 GetVertexColor(MaterialInput input)
{
return 1;
}
// Get material properties function (for pixel shader)
Material GetMaterialPS(MaterialInput input)
{
@4
}
// Programmatically set the line number after all the material inputs which have a variable number of line endings
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
#line 1000
// Input macro specified by the material: DECAL_BLEND_MODE
#define DECAL_BLEND_MODE_TRANSLUCENT 0
#define DECAL_BLEND_MODE_STAIN 1
#define DECAL_BLEND_MODE_NORMAL 2
#define DECAL_BLEND_MODE_EMISSIVE 3
// Vertex Shader function for decals rendering
META_VS(true, FEATURE_LEVEL_ES2)
META_VS_IN_ELEMENT(POSITION, 0, R32G32B32_FLOAT, 0, 0, PER_VERTEX, 0, true)
void VS_Decal(in float3 Position : POSITION0, out float4 SvPosition : SV_Position)
{
// Compute world space vertex position
float3 worldPosition = mul(float4(Position.xyz, 1), WorldMatrix).xyz;
// Compute clip space position
SvPosition = mul(float4(worldPosition.xyz, 1), ViewProjectionMatrix);
}
// Pixel Shader function for decals rendering
META_PS(true, FEATURE_LEVEL_ES2)
void PS_Decal(
in float4 SvPosition : SV_Position
, out float4 Out0 : SV_Target0
#if DECAL_BLEND_MODE == DECAL_BLEND_MODE_TRANSLUCENT
, out float4 Out1 : SV_Target1
#if USE_NORMAL || USE_EMISSIVE
, out float4 Out2 : SV_Target2
#endif
#if USE_NORMAL && USE_EMISSIVE
, out float4 Out3 : SV_Target3
#endif
#endif
)
{
float2 screenUV = SvPosition.xy * ScreenSize.zw;
SvPosition.z = SAMPLE_RT(DepthBuffer, screenUV).r;
float4 positionHS = mul(float4(SvPosition.xyz, 1), SVPositionToWorld);
float3 positionWS = positionHS.xyz / positionHS.w;
float3 positionOS = mul(float4(positionWS, 1), InvWorld).xyz;
// Clip content outside the decal
clip(0.5 - abs(positionOS.xyz));
// By default, map textures using the vectors perpendicular to the projection direction
float2 decalUVs = positionOS.xz + 0.5f;
// Setup material input
MaterialInput materialInput = (MaterialInput)0;
materialInput.WorldPosition = positionWS;
materialInput.TexCoord = decalUVs;
materialInput.TwoSidedSign = 1;
materialInput.SvPosition = SvPosition;
// Build tangent to world transformation matrix
float3 ddxWp = ddx(positionWS);
float3 ddyWp = ddy(positionWS);
materialInput.TBN[0] = normalize(ddyWp);
materialInput.TBN[1] = normalize(ddxWp);
materialInput.TBN[2] = normalize(cross(ddxWp, ddyWp));
// Sample material
Material material = GetMaterialPS(materialInput);
// Masking
#if MATERIAL_MASKED
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
#endif
// Set the output
#if DECAL_BLEND_MODE == DECAL_BLEND_MODE_TRANSLUCENT
// GBuffer0
Out0 = float4(material.Color, material.Opacity);
// GBuffer2
Out1 = float4(material.Roughness, material.Metalness, material.Specular, material.Opacity);
#if USE_EMISSIVE
// Light Buffer
Out2 = float4(material.Emissive, material.Opacity);
#if USE_NORMAL
// GBuffer1
Out3 = float4(material.WorldNormal * 0.5f + 0.5f, 1);
#endif
#elif USE_NORMAL
// GBuffer1
Out2 = float4(material.WorldNormal * 0.5f + 0.5f, 1);
#endif
#elif DECAL_BLEND_MODE == DECAL_BLEND_MODE_STAIN
Out0 = float4(material.Color, material.Opacity);
#elif DECAL_BLEND_MODE == DECAL_BLEND_MODE_NORMAL
Out0 = float4(material.WorldNormal * 0.5f + 0.5f, 1);
#elif DECAL_BLEND_MODE == DECAL_BLEND_MODE_EMISSIVE
Out0 = float4(material.Emissive * material.Opacity, material.Opacity);
#else
#error "Invalid decal blending mode"
#endif
}

View File

@@ -0,0 +1,239 @@
// File generated by Flax Editor
// Version: @0
@3
#include "./Flax/Common.hlsl"
#include "./Flax/GBufferCommon.hlsl"
#include "./Flax/Matrix.hlsl"
@7
// Primary constant buffer
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 InvViewProjectionMatrix;
float4x4 InvViewMatrix;
float4x4 ViewMatrix;
float4x4 WorldMatrix;
float4x4 InvWorldMatrix;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float Time;
float4 ViewInfo;
float4 ScreenSize;
float3 EffectPosition;
float DeltaTime;
float4 EffectRotation;
float3 EffectScale;
uint ParticleCounterOffset;
float3 Dummy0;
uint SpawnCount;
@1META_CB_END
// Particles data buffers
ByteAddressBuffer SrcParticlesData : register(t0);
RWByteAddressBuffer DstParticlesData : register(u0);
// The GPU particles simulation context data
struct Context
{
uint ParticleIndex;
uint ParticlesCount;
uint Seed;
};
@6
// Seed generation function
uint WangHash(uint seed)
{
seed = (seed ^ 61) ^ (seed >> 16);
seed += (seed << 3);
seed = seed ^ (seed >> 4);
seed *= 0x27d4eb2d;
seed = seed ^ (seed >> 15);
return seed;
}
// Random number generation function
float Rand(inout uint seed)
{
const uint multiplier = 0x0019660d;
const uint increment = 0x3c6ef35f;
seed = multiplier * seed + increment;
return asfloat((seed >> 9) | 0x3f800000) - 1.0f;
}
float4 Mod289(float4 x)
{
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
float4 Perm(float4 x)
{
return Mod289(((x * 34.0) + 1.0) * x);
}
float Noise(float3 p)
{
float3 a = floor(p);
float3 d = p - a;
d = d * d * (3.0 - 2.0 * d);
float4 b = a.xxyy + float4(0.0, 1.0, 0.0, 1.0);
float4 k1 = Perm(b.xyxy);
float4 k2 = Perm(k1.xyxy + b.zzww);
float4 c = k2 + a.zzzz;
float4 k3 = Perm(c);
float4 k4 = Perm(c + 1.0);
float4 o1 = frac(k3 * (1.0 / 41.0));
float4 o2 = frac(k4 * (1.0 / 41.0));
float4 o3 = o2 * d.z + o1 * (1.0 - d.z);
float2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);
return o4.y * d.y + o4.x * (1.0 - d.y);
}
float3 Noise3D(float3 p)
{
float o = Noise(p);
float a = Noise(p + float3(0.0001f, 0.0f, 0.0f));
float b = Noise(p + float3(0.0f, 0.0001f, 0.0f));
float c = Noise(p + float3(0.0f, 0.0f, 0.0001f));
float3 grad = float3(o - a, o - b, o - c);
float3 other = abs(grad.zxy);
return normalize(cross(grad,other));
}
float3 Noise3D(float3 position, int octaves, float roughness)
{
float weight = 0.0f;
float3 noise = float3(0.0, 0.0, 0.0);
float scale = 1.0f;
for (int i = 0; i < octaves; i++)
{
float curWeight = pow((1.0-((float)i / octaves)), lerp(2.0, 0.2, roughness));
noise += Noise3D(position * scale) * curWeight;
weight += curWeight;
scale *= 1.72531;
}
return noise / weight;
}
// Reprojects the world space position from the given UV and raw device depth
float3 ReprojectPosition(float2 uv, float rawDepth)
{
uv = uv * float2(2.0, -2.0) + float2(-1.0, 1.0);
float4 pos = mul(float4(uv.x, uv.y, rawDepth, 1.0f), InvViewProjectionMatrix);
return pos.xyz / pos.w;
}
// Random values generation wrapper macros
#define RAND Rand(context.Seed)
#define RAND2 float2(RAND, RAND)
#define RAND3 float3(RAND, RAND, RAND)
#define RAND4 float4(RAND, RAND, RAND, RAND)
@2uint GetParticleUint(uint particleIndex, int offset)
{
return SrcParticlesData.Load(particleIndex * PARTICLE_STRIDE + offset);
}
int GetParticleInt(uint particleIndex, int offset)
{
return asint(SrcParticlesData.Load(particleIndex * PARTICLE_STRIDE + offset));
}
float GetParticleFloat(uint particleIndex, int offset)
{
return asfloat(SrcParticlesData.Load(particleIndex * PARTICLE_STRIDE + offset));
}
float2 GetParticleVec2(uint particleIndex, int offset)
{
return asfloat(SrcParticlesData.Load2(particleIndex * PARTICLE_STRIDE + offset));
}
float3 GetParticleVec3(uint particleIndex, int offset)
{
return asfloat(SrcParticlesData.Load3(particleIndex * PARTICLE_STRIDE + offset));
}
float4 GetParticleVec4(uint particleIndex, int offset)
{
return asfloat(SrcParticlesData.Load4(particleIndex * PARTICLE_STRIDE + offset));
}
void SetParticleUint(uint particleIndex, int offset, uint value)
{
DstParticlesData.Store(particleIndex * PARTICLE_STRIDE + offset, value);
}
void SetParticleInt(uint particleIndex, int offset, int value)
{
DstParticlesData.Store(particleIndex * PARTICLE_STRIDE + offset, asuint(value));
}
void SetParticleFloat(uint particleIndex, int offset, float value)
{
DstParticlesData.Store(particleIndex * PARTICLE_STRIDE + offset, asuint(value));
}
void SetParticleVec2(uint particleIndex, int offset, float2 value)
{
DstParticlesData.Store2(particleIndex * PARTICLE_STRIDE + offset, asuint(value));
}
void SetParticleVec3(uint particleIndex, int offset, float3 value)
{
DstParticlesData.Store3(particleIndex * PARTICLE_STRIDE + offset, asuint(value));
}
void SetParticleVec4(uint particleIndex, int offset, float4 value)
{
DstParticlesData.Store4(particleIndex * PARTICLE_STRIDE + offset, asuint(value));
}
bool AddParticle(out uint dstIndex)
{
// Acquire the particle index in the destination buffer
DstParticlesData.InterlockedAdd(ParticleCounterOffset, 1, dstIndex);
// Prevent overflow
return dstIndex >= PARTICLE_CAPACITY;
}
void UpdateParticle(Context context)
{
@5}
void SpawnParticle(Context context)
{
if (AddParticle(context.ParticleIndex))
return;
@4}
// Main entry point for the particles simulation and spawning
META_CS(true, FEATURE_LEVEL_SM5)
[numthreads(THREAD_GROUP_SIZE, 1, 1)]
void CS_Main(uint3 dispatchThreadId : SV_DispatchThreadID)
{
Context context;
context.ParticleIndex = dispatchThreadId.x;
context.ParticlesCount = min(SrcParticlesData.Load(ParticleCounterOffset), PARTICLE_CAPACITY);
context.Seed = WangHash(context.ParticleIndex ^ asuint(Time));
if (context.ParticleIndex < context.ParticlesCount)
{
UpdateParticle(context);
}
else if (context.ParticleIndex < context.ParticlesCount + SpawnCount)
{
SpawnParticle(context);
}
}

View File

@@ -0,0 +1,260 @@
// File generated by Flax Materials Editor
// Version: @0
#define MATERIAL 1
@3
#include "./Flax/Common.hlsl"
#include "./Flax/MaterialCommon.hlsl"
#include "./Flax/GBufferCommon.hlsl"
#include "./Flax/GUICommon.hlsl"
@7
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 WorldMatrix;
float4x4 ViewMatrix;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
@1META_CB_END
// Material shader resources
@2
// Interpolants passed from the vertex shader
struct VertexOutput
{
float4 Position : SV_Position;
float3 WorldPosition : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
float2 WindowPos : TEXCOORD2;
#if USE_VERTEX_COLOR
half4 VertexColor : COLOR;
#endif
float4 ClipExtents : TEXCOORD3;
float2 ClipOrigin : TEXCOORD4;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
};
// Interpolants passed to the pixel shader
struct PixelInput
{
float4 Position : SV_Position;
float3 WorldPosition : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
float2 WindowPos : TEXCOORD2;
#if USE_VERTEX_COLOR
half4 VertexColor : COLOR;
#endif
float4 ClipExtents : TEXCOORD3;
float2 ClipOrigin : TEXCOORD4;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
bool IsFrontFace : SV_IsFrontFace;
};
// Material properties generation input
struct MaterialInput
{
float3 WorldPosition;
float TwoSidedSign;
float2 TexCoord;
#if USE_VERTEX_COLOR
half4 VertexColor;
#endif
float3x3 TBN;
float4 SvPosition;
float3 PreSkinnedPosition;
float3 PreSkinnedNormal;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT];
#endif
};
MaterialInput GetMaterialInput(Render2DVertex input, VertexOutput output)
{
MaterialInput result;
result.WorldPosition = output.WorldPosition;
result.TexCoord = output.TexCoord;
#if USE_VERTEX_COLOR
result.VertexColor = output.VertexColor;
#endif
result.TBN[0] = float3(1, 0, 0);
result.TBN[1] = float3(0, 1, 0);
result.TBN[2] = float3(0, 0, 1);
result.TwoSidedSign = 1.0;
result.SvPosition = output.Position;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
result.CustomVSToPS = output.CustomVSToPS;
#endif
return result;
}
MaterialInput GetMaterialInput(PixelInput input)
{
MaterialInput result;
result.WorldPosition = input.WorldPosition;
result.TexCoord = input.TexCoord;
#if USE_VERTEX_COLOR
result.VertexColor = input.VertexColor;
#endif
result.TBN[0] = float3(1, 0, 0);
result.TBN[1] = float3(0, 1, 0);
result.TBN[2] = float3(0, 0, 1);
result.TwoSidedSign = input.IsFrontFace ? 1.0 : -1.0;
result.SvPosition = input.Position;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
result.CustomVSToPS = input.CustomVSToPS;
#endif
return result;
}
// Transforms a vector from tangent space to world space
float3 TransformTangentVectorToWorld(MaterialInput input, float3 tangentVector)
{
return mul(tangentVector, input.TBN);
}
// Transforms a vector from world space to tangent space
float3 TransformWorldVectorToTangent(MaterialInput input, float3 worldVector)
{
return mul(input.TBN, worldVector);
}
// Transforms a vector from world space to view space
float3 TransformWorldVectorToView(MaterialInput input, float3 worldVector)
{
return mul(worldVector, (float3x3)ViewMatrix);
}
// Transforms a vector from view space to world space
float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
{
return mul((float3x3)ViewMatrix, viewVector);
}
// Transforms a vector from local space to world space
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
{
return localVector;
}
// Transforms a vector from local space to world space
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
{
return worldVector;
}
// Gets the current object position (supports instancing)
float3 GetObjectPosition(MaterialInput input)
{
return float3(0, 0, 0);
}
// Gets the current object size
float3 GetObjectSize(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{
return 0;
}
// Get the current object LOD transition dither factor (supports instancing)
float GetLODDitherFactor(MaterialInput input)
{
return 0;
}
// Gets the interpolated vertex color (in linear space)
float4 GetVertexColor(MaterialInput input)
{
#if USE_VERTEX_COLOR
return input.VertexColor;
#else
return 1;
#endif
}
// Get material properties function (for vertex shader)
Material GetMaterialVS(MaterialInput input)
{
@5
}
// Get material properties function (for pixel shader)
Material GetMaterialPS(MaterialInput input)
{
@4
}
// Programmatically set the line number after all the material inputs which have a variable number of line endings
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
#line 1000
// Vertex Shader function for GUI materials rendering
META_VS(true, FEATURE_LEVEL_ES2)
META_VS_IN_ELEMENT(POSITION, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 0, R16G16_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(COLOR, 0, R32G32B32A32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 1, R32G32B32A32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 2, R32G32B32A32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
VertexOutput VS_GUI(Render2DVertex input)
{
VertexOutput output;
// Render2D::RenderingFeatures::VertexSnapping
if ((int)input.CustomDataAndClipOrigin.y & 1)
input.Position = (int2)input.Position;
output.Position = mul(float4(input.Position, 0, 1), ViewProjectionMatrix);
output.WorldPosition = mul(float4(input.Position, 0, 1), WorldMatrix).xyz;
output.TexCoord = input.TexCoord;
output.WindowPos = input.Position;
#if USE_VERTEX_COLOR
output.VertexColor = input.Color;
#endif
output.ClipOrigin = input.CustomDataAndClipOrigin.zw;
output.ClipExtents = input.ClipExtents;
// Get material input params if need to evaluate any material property
#if USE_CUSTOM_VERTEX_INTERPOLATORS
MaterialInput materialInput = GetMaterialInput(input, output);
Material material = GetMaterialVS(materialInput);
#endif
// Copy interpolants for other shader stages
#if USE_CUSTOM_VERTEX_INTERPOLATORS
output.CustomVSToPS = material.CustomVSToPS;
#endif
return output;
}
// Pixel Shader function for GUI materials rendering
META_PS(true, FEATURE_LEVEL_ES2)
float4 PS_GUI(PixelInput input) : SV_Target0
{
// 2D per pixel clipping
PerformClipping(input.ClipOrigin, input.WindowPos, input.ClipExtents);
// Get material parameters
MaterialInput materialInput = GetMaterialInput(input);
Material material = GetMaterialPS(materialInput);
// Masking
#if MATERIAL_MASKED
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
#endif
return float4(material.Emissive, material.Opacity);
}

View File

@@ -0,0 +1,868 @@
// File generated by Flax Materials Editor
// Version: @0
#define MATERIAL 1
#define MAX_LOCAL_LIGHTS 4
@3
#include "./Flax/Common.hlsl"
#include "./Flax/MaterialCommon.hlsl"
#include "./Flax/GBufferCommon.hlsl"
#include "./Flax/LightingCommon.hlsl"
#if USE_REFLECTIONS
#include "./Flax/ReflectionsCommon.hlsl"
#endif
#include "./Flax/Lighting.hlsl"
#include "./Flax/ShadowsSampling.hlsl"
#include "./Flax/ExponentialHeightFog.hlsl"
#include "./Flax/Matrix.hlsl"
@7
struct SpriteInput
{
float2 Position : POSITION;
float2 TexCoord : TEXCOORD;
};
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 WorldMatrix;
float4x4 ViewMatrix;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
uint SortedIndicesOffset;
float PerInstanceRandom;
int ParticleStride;
int PositionOffset;
int SpriteSizeOffset;
int SpriteFacingModeOffset;
int SpriteFacingVectorOffset;
int VelocityOffset;
int RotationOffset;
int ScaleOffset;
int ModelFacingModeOffset;
float RibbonUVTilingDistance;
float2 RibbonUVScale;
float2 RibbonUVOffset;
int RibbonWidthOffset;
int RibbonTwistOffset;
int RibbonFacingVectorOffset;
uint RibbonSegmentCount;
float4x4 WorldMatrixInverseTransposed;
@1META_CB_END
// Secondary constantant buffer (for lighting)
META_CB_BEGIN(1, LightingData)
LightData DirectionalLight;
LightShadowData DirectionalLightShadow;
LightData SkyLight;
ProbeData EnvironmentProbe;
ExponentialHeightFogData ExponentialHeightFog;
float3 Dummy1;
uint LocalLightsCount;
LightData LocalLights[MAX_LOCAL_LIGHTS];
META_CB_END
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
// Particles attributes buffer
ByteAddressBuffer ParticlesData : register(t0);
// Ribbons don't use sorted indices so overlap the segment distances buffer on the slot
#define HAS_SORTED_INDICES (!defined(_VS_Ribbon))
#if HAS_SORTED_INDICES
// Sorted particles indices
Buffer<uint> SortedIndices : register(t1);
#else
// Ribbon particles segments distances buffer
Buffer<float> SegmentDistances : register(t1);
#endif
// Shader resources
TextureCube EnvProbe : register(t2);
TextureCube SkyLightTexture : register(t3);
Texture2DArray DirectionalLightShadowMap : register(t4);
@2
// Interpolants passed from the vertex shader
struct VertexOutput
{
float4 Position : SV_Position;
float3 WorldPosition : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
uint ParticleIndex : TEXCOORD2;
#if USE_VERTEX_COLOR
half4 VertexColor : COLOR;
#endif
float3x3 TBN : TEXCOORD3;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
float3 InstanceOrigin : TEXCOORD6;
float InstanceParams : TEXCOORD7; // x-PerInstanceRandom
};
// Interpolants passed to the pixel shader
struct PixelInput
{
float4 Position : SV_Position;
float3 WorldPosition : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
uint ParticleIndex : TEXCOORD2;
#if USE_VERTEX_COLOR
half4 VertexColor : COLOR;
#endif
float3x3 TBN : TEXCOORD3;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
float3 InstanceOrigin : TEXCOORD6;
float InstanceParams : TEXCOORD7; // x-PerInstanceRandom
bool IsFrontFace : SV_IsFrontFace;
};
// Material properties generation input
struct MaterialInput
{
float3 WorldPosition;
float TwoSidedSign;
float2 TexCoord;
uint ParticleIndex;
#if USE_VERTEX_COLOR
half4 VertexColor;
#endif
float3x3 TBN;
float4 SvPosition;
float3 PreSkinnedPosition;
float3 PreSkinnedNormal;
float3 InstanceOrigin;
float InstanceParams;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT];
#endif
};
MaterialInput GetMaterialInput(PixelInput input)
{
MaterialInput result = (MaterialInput)0;
result.WorldPosition = input.WorldPosition;
result.TexCoord = input.TexCoord;
result.ParticleIndex = input.ParticleIndex;
#if USE_VERTEX_COLOR
result.VertexColor = input.VertexColor;
#endif
result.TBN = input.TBN;
result.TwoSidedSign = input.IsFrontFace ? 1.0 : -1.0;
result.InstanceOrigin = input.InstanceOrigin;
result.InstanceParams = input.InstanceParams;
result.SvPosition = input.Position;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
result.CustomVSToPS = input.CustomVSToPS;
#endif
return result;
}
// Gets the local to world transform matrix (supports instancing)
float4x4 GetInstanceTransform(ModelInput input)
{
return WorldMatrix;
}
float4x4 GetInstanceTransform(MaterialInput input)
{
return WorldMatrix;
}
// Removes the scale vector from the local to world transformation matrix (supports instancing)
float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld)
{
// Extract per axis scales from localToWorld transform
float scaleX = length(localToWorld[0]);
float scaleY = length(localToWorld[1]);
float scaleZ = length(localToWorld[2]);
float3 invScale = float3(
scaleX > 0.00001f ? 1.0f / scaleX : 0.0f,
scaleY > 0.00001f ? 1.0f / scaleY : 0.0f,
scaleZ > 0.00001f ? 1.0f / scaleZ : 0.0f);
localToWorld[0] *= invScale.x;
localToWorld[1] *= invScale.y;
localToWorld[2] *= invScale.z;
return localToWorld;
}
// Transforms a vector from tangent space to world space
float3 TransformTangentVectorToWorld(MaterialInput input, float3 tangentVector)
{
return mul(tangentVector, input.TBN);
}
// Transforms a vector from world space to tangent space
float3 TransformWorldVectorToTangent(MaterialInput input, float3 worldVector)
{
return mul(input.TBN, worldVector);
}
// Transforms a vector from world space to view space
float3 TransformWorldVectorToView(MaterialInput input, float3 worldVector)
{
return mul(worldVector, (float3x3)ViewMatrix);
}
// Transforms a vector from view space to world space
float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
{
return mul((float3x3)ViewMatrix, viewVector);
}
// Transforms a vector from local space to world space
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
{
float3x3 localToWorld = (float3x3)GetInstanceTransform(input);
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
return mul(localVector, localToWorld);
}
// Transforms a vector from local space to world space
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
{
float3x3 localToWorld = (float3x3)GetInstanceTransform(input);
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
return mul(localToWorld, worldVector);
}
// Gets the current object position (supports instancing)
float3 GetObjectPosition(MaterialInput input)
{
return input.InstanceOrigin.xyz;
}
// Gets the current object size
float3 GetObjectSize(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value (supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{
return input.InstanceParams;
}
// Get the current object LOD transition dither factor (supports instancing)
float GetLODDitherFactor(MaterialInput input)
{
return 0;
}
// Gets the interpolated vertex color (in linear space)
float4 GetVertexColor(MaterialInput input)
{
#if USE_VERTEX_COLOR
return input.VertexColor;
#else
return 1;
#endif
}
uint GetParticleUint(uint particleIndex, int offset)
{
return ParticlesData.Load(particleIndex * ParticleStride + offset);
}
int GetParticleInt(uint particleIndex, int offset)
{
return asint(ParticlesData.Load(particleIndex * ParticleStride + offset));
}
float GetParticleFloat(uint particleIndex, int offset)
{
return asfloat(ParticlesData.Load(particleIndex * ParticleStride + offset));
}
float2 GetParticleVec2(uint particleIndex, int offset)
{
return asfloat(ParticlesData.Load2(particleIndex * ParticleStride + offset));
}
float3 GetParticleVec3(uint particleIndex, int offset)
{
return asfloat(ParticlesData.Load3(particleIndex * ParticleStride + offset));
}
float4 GetParticleVec4(uint particleIndex, int offset)
{
return asfloat(ParticlesData.Load4(particleIndex * ParticleStride + offset));
}
float3 TransformParticlePosition(float3 input)
{
return mul(float4(input, 1.0f), WorldMatrix).xyz;
}
float3 TransformParticleVector(float3 input)
{
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
}
// Get material properties function (for vertex shader)
Material GetMaterialVS(MaterialInput input)
{
@5
}
// Get material properties function (for domain shader)
Material GetMaterialDS(MaterialInput input)
{
@6
}
// Get material properties function (for pixel shader)
Material GetMaterialPS(MaterialInput input)
{
@4
}
// Programmatically set the line number after all the material inputs which have a variable number of line endings
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
#line 1000
// Calculates the transform matrix from mesh tangent space to local space
half3x3 CalcTangentToLocal(ModelInput input)
{
float bitangentSign = input.Tangent.w ? -1.0f : +1.0f;
float3 normal = input.Normal.xyz * 2.0 - 1.0;
float3 tangent = input.Tangent.xyz * 2.0 - 1.0;
float3 bitangent = cross(normal, tangent) * bitangentSign;
return float3x3(tangent, bitangent, normal);
}
half3x3 CalcTangentToWorld(in float4x4 world, in half3x3 tangentToLocal)
{
half3x3 localToWorld = RemoveScaleFromLocalToWorld((float3x3)world);
return mul(tangentToLocal, localToWorld);
}
float3 GetParticlePosition(uint ParticleIndex)
{
return TransformParticlePosition(GetParticleVec3(ParticleIndex, PositionOffset));
}
// Vertex Shader function for Sprite Rendering
META_VS(true, FEATURE_LEVEL_ES2)
META_VS_IN_ELEMENT(POSITION, 0, R32G32_FLOAT, 0, 0, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
{
VertexOutput output;
#if HAS_SORTED_INDICES
// Sorted particles mapping
if (SortedIndicesOffset != 0xFFFFFFFF)
{
particleIndex = SortedIndices[SortedIndicesOffset + particleIndex];
}
#endif
// Read particle data
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset);
float2 spriteSize = GetParticleVec2(particleIndex, SpriteSizeOffset);
int spriteFacingMode = SpriteFacingModeOffset != -1 ? GetParticleInt(particleIndex, SpriteFacingModeOffset) : -1;
float4x4 world = WorldMatrix;
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
float3x3 viewRot = transpose((float3x3)ViewMatrix);
float3 position = mul(float4(particlePosition, 1), world).xyz;
// Orient sprite
float3 axisX, axisY, axisZ;
if (spriteFacingMode == 0)
{
// Face Camera Position
axisZ = normalize(ViewPos - position);
axisX = -normalize(cross(viewRot[1].xyz, axisZ));
axisY = cross(axisZ, axisX);
}
else if (spriteFacingMode == 1)
{
// Face Camera Plane
axisX = viewRot[0].xyz;
axisY = -viewRot[1].xyz;
axisZ = viewRot[2].xyz;
}
else if (spriteFacingMode == 2)
{
// Along Velocity
float3 velocity = GetParticleVec3(particleIndex, VelocityOffset);
axisY = normalize(velocity);
axisZ = ViewPos - position;
axisX = normalize(cross(axisY, axisZ));
axisZ = cross(axisX, axisY);
}
else if (spriteFacingMode == 3)
{
// Custom Facing Vector
float3 spriteFacingVector = GetParticleVec3(particleIndex, SpriteFacingVectorOffset);
axisZ = spriteFacingVector;
axisX = normalize(cross(viewRot[1].xyz, axisZ));
axisY = cross(axisZ, axisX);
}
else if (spriteFacingMode == 4)
{
// Fixed Axis
float3 spriteFacingVector = GetParticleVec3(particleIndex, SpriteFacingVectorOffset);
axisY = spriteFacingVector;
axisZ = ViewPos - position;
axisX = normalize(cross(axisY, axisZ));
axisZ = cross(axisX, axisY);
}
else
{
// Default
axisX = float3(1, 0, 0);
axisY = float3(0, 1, 0);
axisZ = float3(0, 0, 1);
}
// Compute world space vertex position
float3 spriteVertexPosition = float3(input.Position.xy * spriteSize, 0);
spriteVertexPosition = mul(spriteVertexPosition, eulerMatrix);
spriteVertexPosition = mul(spriteVertexPosition, float3x3(axisX, axisY, axisZ));
output.WorldPosition = position + spriteVertexPosition;
// Compute clip space position
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.TexCoord = input.TexCoord;
output.ParticleIndex = particleIndex;
#if USE_VERTEX_COLOR
output.VertexColor = 1;
#endif
output.InstanceOrigin = world[3].xyz;
output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = float3x3(axisX, axisY, axisZ);
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
output.TBN = tangentToWorld;
// Get material input params if need to evaluate any material property
#if USE_POSITION_OFFSET || USE_CUSTOM_VERTEX_INTERPOLATORS
MaterialInput materialInput = (MaterialInput)0;
materialInput.WorldPosition = output.WorldPosition;
materialInput.TexCoord = output.TexCoord;
materialInput.ParticleIndex = output.ParticleIndex;
#if USE_VERTEX_COLOR
materialInput.VertexColor = output.VertexColor;
#endif
materialInput.TBN = output.TBN;
materialInput.TwoSidedSign = 1;
materialInput.SvPosition = output.Position;
materialInput.PreSkinnedPosition = float3(input.Position.xy, 0);
materialInput.PreSkinnedNormal = tangentToLocal[2].xyz;
materialInput.InstanceOrigin = output.InstanceOrigin;
materialInput.InstanceParams = output.InstanceParams;
Material material = GetMaterialVS(materialInput);
#endif
// Apply world position offset per-vertex
#if USE_POSITION_OFFSET
output.WorldPosition += material.PositionOffset;
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
#endif
// Copy interpolants for other shader stages
#if USE_CUSTOM_VERTEX_INTERPOLATORS
output.CustomVSToPS = material.CustomVSToPS;
#endif
return output;
}
// Vertex Shader function for Model Rendering
META_VS(true, FEATURE_LEVEL_ES2)
META_VS_IN_ELEMENT(POSITION, 0, R32G32B32_FLOAT, 0, 0, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 0, R16G16_FLOAT, 1, 0, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(NORMAL, 0, R10G10B10A2_UNORM, 1, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TANGENT, 0, R10G10B10A2_UNORM, 1, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 1, R16G16_FLOAT, 1, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(COLOR, 0, R8G8B8A8_UNORM, 2, 0, PER_VERTEX, 0, USE_VERTEX_COLOR)
VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
{
VertexOutput output;
#if HAS_SORTED_INDICES
// Sorted particles mapping
if (SortedIndicesOffset != 0xFFFFFFFF)
{
particleIndex = SortedIndices[SortedIndicesOffset + particleIndex];
}
#endif
// Read particle data
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
float3 particleScale = GetParticleVec3(particleIndex, ScaleOffset);
float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset);
int modelFacingMode = ModelFacingModeOffset != -1 ? GetParticleInt(particleIndex, ModelFacingModeOffset) : -1;
float3 position = mul(float4(particlePosition, 1), WorldMatrix).xyz;
// Compute final vertex position in the world
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
float4 transform0 = float4(eulerMatrix[0], particlePosition.x);
float4 transform1 = float4(eulerMatrix[1], particlePosition.y);
float4 transform2 = float4(eulerMatrix[2], particlePosition.z);
float4x4 scaleMatrix = float4x4(float4(particleScale.x, 0.0f, 0.0f, 0.0f), float4(0.0f, particleScale.y, 0.0f, 0.0f), float4(0.0f, 0.0f, particleScale.z, 0.0f), float4(0.0f, 0.0f, 0.0f, 1.0f));
float4x4 world = float4x4(transform0, transform1, transform2, float4(0.0f, 0.0f, 0.0f, 1.0f));
if (modelFacingMode == 0)
{
// Face Camera Position
float3 direction = normalize(ViewPos - position);
float4 alignmentQuat = FindQuatBetween(float3(1.0f, 0.0f, 0.0f), direction);
float4x4 alignmentMat = QuaternionToMatrix(alignmentQuat);
world = mul(world, mul(alignmentMat, scaleMatrix));
}
else if (modelFacingMode == 1)
{
// Face Camera Plane
float3 direction = -ViewDir;
float4 alignmentQuat = FindQuatBetween(float3(1.0f, 0.0f, 0.0f), direction);
float4x4 alignmentMat = QuaternionToMatrix(alignmentQuat);
world = mul(world, mul(alignmentMat, scaleMatrix));
}
else if (modelFacingMode == 2)
{
// Along Velocity
float3 direction = GetParticleVec3(particleIndex, VelocityOffset);
float4 alignmentQuat = FindQuatBetween(float3(1.0f, 0.0f, 0.0f), normalize(direction));
float4x4 alignmentMat = QuaternionToMatrix(alignmentQuat);
world = mul(world, mul(alignmentMat, scaleMatrix));
}
else
{
// Default
world = mul(world, scaleMatrix);
}
world = transpose(world);
world = mul(world, WorldMatrix);
// Calculate the vertex position in world space
output.WorldPosition = mul(float4(input.Position, 1), world).xyz;
// Compute clip space position
output.Position = mul(float4(output.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.TexCoord = input.TexCoord;
output.ParticleIndex = particleIndex;
#if USE_VERTEX_COLOR
output.VertexColor = input.Color;
#endif
output.InstanceOrigin = WorldMatrix[3].xyz;
output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = CalcTangentToLocal(input);
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
output.TBN = tangentToWorld;
// Get material input params if need to evaluate any material property
#if USE_POSITION_OFFSET || USE_CUSTOM_VERTEX_INTERPOLATORS
MaterialInput materialInput = (MaterialInput)0;
materialInput.WorldPosition = output.WorldPosition;
materialInput.TexCoord = output.TexCoord;
materialInput.ParticleIndex = output.ParticleIndex;
#if USE_VERTEX_COLOR
materialInput.VertexColor = output.VertexColor;
#endif
materialInput.TBN = output.TBN;
materialInput.TwoSidedSign = 1;
materialInput.SvPosition = output.Position;
materialInput.PreSkinnedPosition = input.Position.xyz;
materialInput.PreSkinnedNormal = tangentToLocal[2].xyz;
materialInput.InstanceOrigin = output.InstanceOrigin;
materialInput.InstanceParams = output.InstanceParams;
Material material = GetMaterialVS(materialInput);
#endif
// Apply world position offset per-vertex
#if USE_POSITION_OFFSET
output.WorldPosition += material.PositionOffset;
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
#endif
// Copy interpolants for other shader stages
#if USE_CUSTOM_VERTEX_INTERPOLATORS
output.CustomVSToPS = material.CustomVSToPS;
#endif
return output;
}
// Vertex Shader function for Ribbon Rendering
META_VS(true, FEATURE_LEVEL_ES2)
VertexOutput VS_Ribbon(uint vertexIndex : SV_VertexID)
{
VertexOutput output;
// Get particle data
uint particleIndex = vertexIndex / 2;
int vertexSign = (((int)vertexIndex & 0x1) * 2) - 1;
float3 position = GetParticlePosition(particleIndex);
float ribbonWidth = RibbonWidthOffset != -1 ? GetParticleFloat(particleIndex, RibbonWidthOffset) : 20.0f;
float ribbonTwist = RibbonTwistOffset != -1 ? GetParticleFloat(particleIndex, RibbonTwistOffset) : 0.0f;
// Calculate ribbon direction
float3 direction;
if (particleIndex == 0)
{
float3 nextParticlePos = GetParticlePosition(particleIndex + 1);
direction = nextParticlePos - position;
}
else
{
float3 previousParticlePos = GetParticlePosition(particleIndex - 1);
direction = position - previousParticlePos;
}
// Calculate particle orientation (tangent vectors)
float3 cameraDirection = SafeNormalize(ViewPos - position);
float3 tangentUp = SafeNormalize(direction);
float3 facing = RibbonFacingVectorOffset != -1 ? GetParticleVec3(particleIndex, RibbonFacingVectorOffset) : cameraDirection;
float twistSine, twistCosine;
sincos(radians(ribbonTwist), twistSine, twistCosine);
facing = facing * twistCosine + cross(facing, tangentUp) * twistSine + tangentUp * dot(tangentUp, facing) * (1 - twistCosine);
float3 tangentRight = SafeNormalize(cross(tangentUp, facing));
if (!any(tangentRight))
{
tangentRight = SafeNormalize(cross(tangentUp, float3(0.0f, 0.0f, 1.0f)));
}
// Calculate texture coordinates
float texCoordU;
#ifdef _VS_Ribbon
if (RibbonUVTilingDistance != 0.0f)
{
texCoordU = SegmentDistances[particleIndex] / RibbonUVTilingDistance;
}
else
#endif
{
texCoordU = (float)particleIndex / RibbonSegmentCount;
}
float texCoordV = (vertexIndex + 1) & 0x1;
output.TexCoord = float2(texCoordU, texCoordV) * RibbonUVScale + RibbonUVOffset;
// Compute world space vertex position
output.WorldPosition = position + tangentRight * vertexSign * (ribbonWidth.xxx * 0.5f);
// Compute clip space position
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.ParticleIndex = particleIndex;
#if USE_VERTEX_COLOR
output.VertexColor = 1;
#endif
output.InstanceOrigin = WorldMatrix[3].xyz;
output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
output.TBN = tangentToWorld;
// Get material input params if need to evaluate any material property
#if USE_POSITION_OFFSET || USE_CUSTOM_VERTEX_INTERPOLATORS
MaterialInput materialInput = (MaterialInput)0;
materialInput.WorldPosition = output.WorldPosition;
materialInput.TexCoord = output.TexCoord;
materialInput.ParticleIndex = output.ParticleIndex;
#if USE_VERTEX_COLOR
materialInput.VertexColor = output.VertexColor;
#endif
materialInput.TBN = output.TBN;
materialInput.TwoSidedSign = 1;
materialInput.SvPosition = output.Position;
materialInput.PreSkinnedPosition = Position;
materialInput.PreSkinnedNormal = tangentToLocal[2].xyz;
materialInput.InstanceOrigin = output.InstanceOrigin;
materialInput.InstanceParams = output.InstanceParams;
Material material = GetMaterialVS(materialInput);
#endif
// Apply world position offset per-vertex
#if USE_POSITION_OFFSET
output.WorldPosition += material.PositionOffset;
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
#endif
// Copy interpolants for other shader stages
#if USE_CUSTOM_VERTEX_INTERPOLATORS
output.CustomVSToPS = material.CustomVSToPS;
#endif
return output;
}
// Pixel Shader function for Forward Pass
META_PS(USE_FORWARD, FEATURE_LEVEL_ES2)
float4 PS_Forward(PixelInput input) : SV_Target0
{
float4 output = 0;
// Get material parameters
MaterialInput materialInput = GetMaterialInput(input);
Material material = GetMaterialPS(materialInput);
// Masking
#if MATERIAL_MASKED
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
#endif
// Add emissive light
output = float4(material.Emissive, material.Opacity);
#if MATERIAL_SHADING_MODEL != SHADING_MODEL_UNLIT
// Setup GBuffer data as proxy for lighting
GBufferSample gBuffer;
gBuffer.Normal = material.WorldNormal;
gBuffer.Roughness = material.Roughness;
gBuffer.Metalness = material.Metalness;
gBuffer.Color = material.Color;
gBuffer.Specular = material.Specular;
gBuffer.AO = material.AO;
gBuffer.ViewPos = mul(float4(materialInput.WorldPosition, 1), ViewMatrix).xyz;
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE
gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity);
#elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity);
#else
gBuffer.CustomData = float4(0, 0, 0, 0);
#endif
gBuffer.WorldPos = materialInput.WorldPosition;
gBuffer.ShadingModel = MATERIAL_SHADING_MODEL;
// Calculate lighting from a single directional light
float4 shadowMask = 1.0f;
if (DirectionalLight.CastShadows > 0)
{
LightShadowData directionalLightShadowData = GetDirectionalLightShadowData();
shadowMask.r = SampleShadow(DirectionalLight, directionalLightShadowData, DirectionalLightShadowMap, gBuffer, shadowMask.g);
}
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
// Calculate lighting from sky light
light += GetSkyLightLighting(SkyLight, gBuffer, SkyLightTexture);
// Calculate lighting from local lights
LOOP
for (uint localLightIndex = 0; localLightIndex < LocalLightsCount; localLightIndex++)
{
const LightData localLight = LocalLights[localLightIndex];
bool isSpotLight = localLight.SpotAngles.x > -2.0f;
shadowMask = 1.0f;
light += GetLighting(ViewPos, localLight, gBuffer, shadowMask, true, isSpotLight);
}
#if USE_REFLECTIONS
// Calculate reflections
light.rgb += GetEnvProbeLighting(ViewPos, EnvProbe, EnvironmentProbe, gBuffer) * light.a;
#endif
// Add lighting (apply ambient occlusion)
output.rgb += light.rgb * gBuffer.AO;
#if USE_FOG
// Calculate exponential height fog
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, 0);
// Apply fog to the output color
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
output = float4(output.rgb * fog.a + fog.rgb, output.a);
#elif MATERIAL_BLEND == MATERIAL_BLEND_TRANSPARENT
output = float4(output.rgb * fog.a + fog.rgb, output.a);
#elif MATERIAL_BLEND == MATERIAL_BLEND_ADDITIVE
output = float4(output.rgb * fog.a + fog.rgb, output.a * fog.a);
#elif MATERIAL_BLEND == MATERIAL_BLEND_MULTIPLY
output = float4(lerp(float3(1, 1, 1), output.rgb, fog.aaa * fog.aaa), output.a);
#endif
#endif
#endif
return output;
}
#if USE_DISTORTION
// Pixel Shader function for Distortion Pass
META_PS(USE_DISTORTION, FEATURE_LEVEL_ES2)
float4 PS_Distortion(PixelInput input) : SV_Target0
{
// Get material parameters
MaterialInput materialInput = GetMaterialInput(input);
Material material = GetMaterialPS(materialInput);
// Masking
#if MATERIAL_MASKED
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
#endif
float3 viewNormal = normalize(TransformWorldVectorToView(materialInput, material.WorldNormal));
float airIOR = 1.0f;
#if USE_PIXEL_NORMAL_OFFSET_REFRACTION
float3 viewVertexNormal = TransformWorldVectorToView(materialInput, TransformTangentVectorToWorld(materialInput, float3(0, 0, 1)));
float2 distortion = (viewVertexNormal.xy - viewNormal.xy) * (material.Refraction - airIOR);
#else
float2 distortion = viewNormal.xy * (material.Refraction - airIOR);
#endif
// Clip if the distortion distance (squared) is too small to be noticed
clip(dot(distortion, distortion) - 0.00001);
// Scale up for better precision in low/subtle refractions at the expense of artefacts at higher refraction
distortion *= 4.0f;
// Store positive and negative offsets separately
float2 addOffset = max(distortion, 0);
float2 subOffset = abs(min(distortion, 0));
return float4(addOffset.x, addOffset.y, subOffset.x, subOffset.y);
}
#endif
// Pixel Shader function for Depth Pass
META_PS(true, FEATURE_LEVEL_ES2)
void PS_Depth(PixelInput input
#if GLSL
, out float4 OutColor : SV_Target0
#endif
)
{
// Get material parameters
MaterialInput materialInput = GetMaterialInput(input);
Material material = GetMaterialPS(materialInput);
// Perform per pixel clipping
#if MATERIAL_MASKED
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
#endif
#if MATERIAL_BLEND == MATERIAL_BLEND_TRANSPARENT
clip(material.Opacity - MATERIAL_OPACITY_THRESHOLD);
#endif
#if GLSL
OutColor = 0;
#endif
}

View File

@@ -0,0 +1,150 @@
// File generated by Flax Materials Editor
// Version: @0
#define MATERIAL 1
@3
#include "./Flax/Common.hlsl"
#include "./Flax/MaterialCommon.hlsl"
#include "./Flax/GBufferCommon.hlsl"
@7
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewMatrix;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
float4 TemporalAAJitter;
@1META_CB_END
// Material shader resources
@2
// Interpolants passed to the pixel shader
struct PixelInput
{
float4 Position : SV_Position;
float3 WorldPosition : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
bool IsFrontFace : SV_IsFrontFace;
};
// Material properties generation input
struct MaterialInput
{
float3 WorldPosition;
float TwoSidedSign;
float2 TexCoord;
#if USE_VERTEX_COLOR
half4 VertexColor;
#endif
float3x3 TBN;
float4 SvPosition;
float3 PreSkinnedPosition;
float3 PreSkinnedNormal;
};
MaterialInput GetMaterialInput(PixelInput input)
{
MaterialInput result = (MaterialInput)0;
result.WorldPosition = input.WorldPosition;
result.TexCoord = input.TexCoord;
#if USE_VERTEX_COLOR
result.VertexColor = float4(0, 0, 0, 1);
#endif
result.TBN[0] = float3(1, 0, 0);
result.TBN[1] = float3(0, 1, 0);
result.TBN[2] = float3(0, 0, 1);
result.TwoSidedSign = input.IsFrontFace ? 1.0 : -1.0;
result.SvPosition = input.Position;
return result;
}
// Transforms a vector from tangent space to world space
float3 TransformTangentVectorToWorld(MaterialInput input, float3 tangentVector)
{
return mul(tangentVector, input.TBN);
}
// Transforms a vector from world space to tangent space
float3 TransformWorldVectorToTangent(MaterialInput input, float3 worldVector)
{
return mul(input.TBN, worldVector);
}
// Transforms a vector from world space to view space
float3 TransformWorldVectorToView(MaterialInput input, float3 worldVector)
{
return mul(worldVector, (float3x3)ViewMatrix);
}
// Transforms a vector from view space to world space
float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
{
return mul((float3x3)ViewMatrix, viewVector);
}
// Transforms a vector from local space to world space
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
{
return localVector;
}
// Transforms a vector from local space to world space
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
{
return worldVector;
}
// Gets the current object position (supports instancing)
float3 GetObjectPosition(MaterialInput input)
{
return float3(0, 0, 0);
}
// Gets the current object size
float3 GetObjectSize(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{
return 0;
}
// Get the current object LOD transition dither factor (supports instancing)
float GetLODDitherFactor(MaterialInput input)
{
return 0;
}
// Gets the interpolated vertex color (in linear space)
float4 GetVertexColor(MaterialInput input)
{
return 1;
}
// Get material properties function (for pixel shader)
Material GetMaterialPS(MaterialInput input)
{
@4
}
// Programmatically set the line number after all the material inputs which have a variable number of line endings
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
#line 1000
// Pixel Shader function for PostFx materials rendering
META_PS(true, FEATURE_LEVEL_ES2)
float4 PS_PostFx(PixelInput input) : SV_Target0
{
// Get material parameters
MaterialInput materialInput = GetMaterialInput(input);
Material material = GetMaterialPS(materialInput);
return float4(material.Emissive, material.Opacity);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,785 @@
// File generated by Flax Materials Editor
// Version: @0
#define MATERIAL 1
@3
// Enables/disables smooth terrain chunks LOD transitions (with morphing higher LOD near edges to the lower LOD in the neighbour)
#define USE_SMOOTH_LOD_TRANSITION 1
// Switches between using 0, 4 or 8 heightmap layers (values: 0, 1, 2)
#define TERRAIN_LAYERS_DATA_SIZE 2
#define USE_TERRAIN_LAYERS (TERRAIN_LAYERS_DATA_SIZE > 0)
#include "./Flax/Common.hlsl"
#include "./Flax/MaterialCommon.hlsl"
#include "./Flax/GBufferCommon.hlsl"
@7
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 WorldMatrix;
float4x4 ViewMatrix;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
float4 LightmapArea;
float3 WorldInvScale;
float WorldDeterminantSign;
float PerInstanceRandom;
float CurrentLOD;
float ChunkSizeNextLOD;
float TerrainChunkSizeLOD0;
float4 HeightmapUVScaleBias;
float4 NeighborLOD;
float2 OffsetUV;
float2 Dummy0;
@1META_CB_END
#if CAN_USE_LIGHTMAP
// Irradiance and directionality prebaked lightmaps
Texture2D Lightmap0 : register(t0);
Texture2D Lightmap1 : register(t1);
Texture2D Lightmap2 : register(t2);
#endif
// Terrain data
Texture2D Heightmap : register(t3);
Texture2D Splatmap0 : register(t4);
Texture2D Splatmap1 : register(t5);
// Material shader resources
@2
// Interpolants passed from the vertex shader
struct VertexOutput
{
float4 Position : SV_Position;
float3 WorldPosition : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
float2 LightmapUV : TEXCOORD2;
float3 WorldNormal : TEXCOORD3;
float HolesMask : TEXCOORD4;
#if USE_TERRAIN_LAYERS
float4 Layers[TERRAIN_LAYERS_DATA_SIZE] : TEXCOORD5;
#endif
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
#if USE_TESSELLATION
float TessellationMultiplier : TESS;
#endif
};
// Interpolants passed to the pixel shader
struct PixelInput
{
float4 Position : SV_Position;
float3 WorldPosition : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
float2 LightmapUV : TEXCOORD2;
float3 WorldNormal : TEXCOORD3;
float HolesMask : TEXCOORD4;
#if USE_TERRAIN_LAYERS
float4 Layers[TERRAIN_LAYERS_DATA_SIZE] : TEXCOORD5;
#endif
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
bool IsFrontFace : SV_IsFrontFace;
};
// Material properties generation input
struct MaterialInput
{
float3 WorldPosition;
float TwoSidedSign;
float2 TexCoord;
#if USE_LIGHTMAP
float2 LightmapUV;
#endif
float3x3 TBN;
float4 SvPosition;
float3 PreSkinnedPosition;
float3 PreSkinnedNormal;
float HolesMask;
#if USE_TERRAIN_LAYERS
float4 Layers[TERRAIN_LAYERS_DATA_SIZE];
#endif
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT];
#endif
};
MaterialInput GetMaterialInput(PixelInput input)
{
MaterialInput result = (MaterialInput)0;
result.WorldPosition = input.WorldPosition;
result.TexCoord = input.TexCoord;
#if USE_LIGHTMAP
result.LightmapUV = input.LightmapUV;
#endif
result.TBN = CalcTangentBasisFromWorldNormal(input.WorldNormal);
result.TwoSidedSign = WorldDeterminantSign * (input.IsFrontFace ? 1.0 : -1.0);
result.SvPosition = input.Position;
result.HolesMask = input.HolesMask;
#if USE_TERRAIN_LAYERS
result.Layers = input.Layers;
#endif
#if USE_CUSTOM_VERTEX_INTERPOLATORS
result.CustomVSToPS = input.CustomVSToPS;
#endif
return result;
}
// Removes the scale vector from the local to world transformation matrix
float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld)
{
localToWorld[0] *= WorldInvScale.x;
localToWorld[1] *= WorldInvScale.y;
localToWorld[2] *= WorldInvScale.z;
return localToWorld;
}
// Transforms a vector from tangent space to world space
float3 TransformTangentVectorToWorld(MaterialInput input, float3 tangentVector)
{
return mul(tangentVector, input.TBN);
}
// Transforms a vector from world space to tangent space
float3 TransformWorldVectorToTangent(MaterialInput input, float3 worldVector)
{
return mul(input.TBN, worldVector);
}
// Transforms a vector from world space to view space
float3 TransformWorldVectorToView(MaterialInput input, float3 worldVector)
{
return mul(worldVector, (float3x3)ViewMatrix);
}
// Transforms a vector from view space to world space
float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
{
return mul((float3x3)ViewMatrix, viewVector);
}
// Transforms a vector from local space to world space
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
{
float3x3 localToWorld = (float3x3)WorldMatrix;
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
return mul(localVector, localToWorld);
}
// Transforms a vector from local space to world space
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
{
float3x3 localToWorld = (float3x3)WorldMatrix;
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
return mul(localToWorld, worldVector);
}
// Gets the current object position
float3 GetObjectPosition(MaterialInput input)
{
return WorldMatrix[3].xyz;
}
// Gets the current object size
float3 GetObjectSize(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value
float GetPerInstanceRandom(MaterialInput input)
{
return PerInstanceRandom;
}
// Get the current object LOD transition dither factor
float GetLODDitherFactor(MaterialInput input)
{
return 0;
}
// Gets the interpolated vertex color (in linear space)
float4 GetVertexColor(MaterialInput input)
{
return 1;
}
// Get material properties function (for vertex shader)
Material GetMaterialVS(MaterialInput input)
{
@5
}
// Get material properties function (for domain shader)
Material GetMaterialDS(MaterialInput input)
{
@6
}
// Get material properties function (for pixel shader)
Material GetMaterialPS(MaterialInput input)
{
@4
}
// Programmatically set the line number after all the material inputs which have a variable number of line endings
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
#line 1000
// Calculates LOD value (with fractional part for blending)
float CalcLOD(float2 xy, float4 morph)
{
#if USE_SMOOTH_LOD_TRANSITION
// Use LOD value based on Barycentric coordinates to morph to the lower LOD near chunk edges
float4 lodCalculated = morph * CurrentLOD + NeighborLOD * (float4(1, 1, 1, 1) - morph);
// Pick a quadrant (top, left, right or bottom)
float lod;
if ((xy.x + xy.y) > 1)
{
if (xy.x < xy.y)
{
lod = lodCalculated.w;
}
else
{
lod = lodCalculated.z;
}
}
else
{
if (xy.x < xy.y)
{
lod = lodCalculated.y;
}
else
{
lod = lodCalculated.x;
}
}
return lod;
#else
return CurrentLOD;
#endif
}
float3x3 CalcTangentToWorld(float4x4 world, float3x3 tangentToLocal)
{
float3x3 localToWorld = RemoveScaleFromLocalToWorld((float3x3)world);
return mul(tangentToLocal, localToWorld);
}
// Must match structure defined in TerrainManager.cpp
struct TerrainVertexInput
{
float2 TexCoord : TEXCOORD0;
float4 Morph : TEXCOORD1;
};
// Vertex Shader function for terrain rendering
META_VS(true, FEATURE_LEVEL_ES2)
META_VS_IN_ELEMENT(TEXCOORD, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 1, R8G8B8A8_UNORM, 0, ALIGN, PER_VERTEX, 0, true)
VertexOutput VS(TerrainVertexInput input)
{
VertexOutput output;
// Calculate terrain LOD for this chunk
float lodCalculated = CalcLOD(input.TexCoord, input.Morph);
float lodValue = CurrentLOD;
float morphAlpha = lodCalculated - CurrentLOD;
// Sample heightmap
float2 heightmapUVs = input.TexCoord * HeightmapUVScaleBias.xy + HeightmapUVScaleBias.zw;
#if USE_SMOOTH_LOD_TRANSITION
float4 heightmapValueThisLOD = Heightmap.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
float2 nextLODPos = round(input.TexCoord * ChunkSizeNextLOD) / ChunkSizeNextLOD;
float2 heightmapUVsNextLOD = nextLODPos * HeightmapUVScaleBias.xy + HeightmapUVScaleBias.zw;
float4 heightmapValueNextLOD = Heightmap.SampleLevel(SamplerPointClamp, heightmapUVsNextLOD, lodValue + 1);
float4 heightmapValue = lerp(heightmapValueThisLOD, heightmapValueNextLOD, morphAlpha);
bool isHole = max(heightmapValueThisLOD.b + heightmapValueThisLOD.a, heightmapValueNextLOD.b + heightmapValueNextLOD.a) >= 1.9f;
#if USE_TERRAIN_LAYERS
float4 splatmapValueThisLOD = Splatmap0.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
float4 splatmapValueNextLOD = Splatmap0.SampleLevel(SamplerPointClamp, heightmapUVsNextLOD, lodValue + 1);
float4 splatmap0Value = lerp(splatmapValueThisLOD, splatmapValueNextLOD, morphAlpha);
#if TERRAIN_LAYERS_DATA_SIZE > 1
splatmapValueThisLOD = Splatmap1.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
splatmapValueNextLOD = Splatmap1.SampleLevel(SamplerPointClamp, heightmapUVsNextLOD, lodValue + 1);
float4 splatmap1Value = lerp(splatmapValueThisLOD, splatmapValueNextLOD, morphAlpha);
#endif
#endif
#else
float4 heightmapValue = Heightmap.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
bool isHole = (heightmapValue.b + heightmapValue.a) >= 1.9f;
#if USE_TERRAIN_LAYERS
float4 splatmap0Value = Splatmap0.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
#if TERRAIN_LAYERS_DATA_SIZE > 1
float4 splatmap1Value = Splatmap1.SampleLevel(SamplerPointClamp, heightmapUVs, lodValue);
#endif
#endif
#endif
float height = (float)((int)(heightmapValue.x * 255.0) + ((int)(heightmapValue.y * 255) << 8)) / 65535.0;
// Extract normal and the holes mask
float2 normalTemp = float2(heightmapValue.b, heightmapValue.a) * 2.0f - 1.0f;
float3 normal = float3(normalTemp.x, sqrt(1.0 - saturate(dot(normalTemp, normalTemp))), normalTemp.y);
normal = normalize(normal);
output.HolesMask = isHole ? 0 : 1;
if (isHole)
{
normal = float3(0, 1, 0);
}
// Construct vertex position
#if USE_SMOOTH_LOD_TRANSITION
float2 positionXZThisLOD = input.TexCoord * TerrainChunkSizeLOD0;
float2 positionXZNextLOD = nextLODPos * TerrainChunkSizeLOD0;
float2 positionXZ = lerp(positionXZThisLOD, positionXZNextLOD, morphAlpha);
#else
float2 positionXZ = input.TexCoord * TerrainChunkSizeLOD0;
#endif
float3 position = float3(positionXZ.x, height, positionXZ.y);
// Compute world space vertex position
output.WorldPosition = mul(float4(position, 1), WorldMatrix).xyz;
// Compute clip space position
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
// Pass vertex attributes
#if USE_SMOOTH_LOD_TRANSITION
float2 texCoord = lerp(input.TexCoord, nextLODPos, morphAlpha);
#else
float2 texCoord = input.TexCoord;
#endif
output.TexCoord = positionXZ * (1.0f / TerrainChunkSizeLOD0) + OffsetUV;
output.LightmapUV = texCoord * LightmapArea.zw + LightmapArea.xy;
// Extract terrain layers weights from the splatmap
#if USE_TERRAIN_LAYERS
output.Layers[0] = splatmap0Value;
#if TERRAIN_LAYERS_DATA_SIZE > 1
output.Layers[1] = splatmap1Value;
#endif
#endif
// Compute world space normal vector
float3x3 tangentToLocal = CalcTangentBasisFromWorldNormal(normal);
float3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
output.WorldNormal = tangentToWorld[2];
// Get material input params if need to evaluate any material property
#if USE_POSITION_OFFSET || USE_TESSELLATION || USE_CUSTOM_VERTEX_INTERPOLATORS
MaterialInput materialInput = (MaterialInput)0;
materialInput.WorldPosition = output.WorldPosition;
materialInput.TexCoord = output.TexCoord;
#if USE_LIGHTMAP
materialInput.LightmapUV = output.LightmapUV;
#endif
materialInput.TBN = CalcTangentBasisFromWorldNormal(output.WorldNormal);
materialInput.TwoSidedSign = WorldDeterminantSign;
materialInput.SvPosition = output.Position;
materialInput.PreSkinnedPosition = position;
materialInput.PreSkinnedNormal = normal;
materialInput.HolesMask = output.HolesMask;
#if USE_TERRAIN_LAYERS
materialInput.Layers = output.Layers;
#endif
Material material = GetMaterialVS(materialInput);
#endif
// Apply world position offset per-vertex
#if USE_POSITION_OFFSET
output.WorldPosition += material.PositionOffset;
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
#endif
// Get tessalation multiplier (per vertex)
#if USE_TESSELLATION
output.TessellationMultiplier = material.TessellationMultiplier;
#endif
// Copy interpolants for other shader stages
#if USE_CUSTOM_VERTEX_INTERPOLATORS
output.CustomVSToPS = material.CustomVSToPS;
#endif
return output;
}
#if USE_TESSELLATION
// Interpolants passed from the hull shader to the domain shader
struct TessalationHSToDS
{
float4 Position : SV_Position;
float3 WorldPosition : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
float2 LightmapUV : TEXCOORD2;
float3 WorldNormal : TEXCOORD3;
float HolesMask : TEXCOORD4;
#if USE_TERRAIN_LAYERS
float4 Layers[TERRAIN_LAYERS_DATA_SIZE] : TEXCOORD5;
#endif
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
float TessellationMultiplier : TESS;
};
// Interpolants passed from the domain shader and to the pixel shader
struct TessalationDSToPS
{
float4 Position : SV_Position;
float3 WorldPosition : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
float2 LightmapUV : TEXCOORD2;
float3 WorldNormal : TEXCOORD3;
float HolesMask : TEXCOORD4;
#if USE_TERRAIN_LAYERS
float4 Layers[TERRAIN_LAYERS_DATA_SIZE] : TEXCOORD5;
#endif
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
};
MaterialInput GetMaterialInput(TessalationDSToPS input)
{
MaterialInput result = (MaterialInput)0;
result.WorldPosition = input.WorldPosition;
result.TexCoord = input.TexCoord;
#if USE_LIGHTMAP
result.LightmapUV = input.LightmapUV;
#endif
result.TBN = CalcTangentBasisFromWorldNormal(input.WorldNormal);
result.TwoSidedSign = WorldDeterminantSign;
result.SvPosition = input.Position;
result.HolesMask = input.HolesMask;
#if USE_TERRAIN_LAYERS
result.Layers = input.Layers;
#endif
#if USE_CUSTOM_VERTEX_INTERPOLATORS
result.CustomVSToPS = input.CustomVSToPS;
#endif
return result;
}
struct TessalationPatch
{
float EdgeTessFactor[3] : SV_TessFactor;
float InsideTessFactor : SV_InsideTessFactor;
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
float3 B210 : POSITION4;
float3 B120 : POSITION5;
float3 B021 : POSITION6;
float3 B012 : POSITION7;
float3 B102 : POSITION8;
float3 B201 : POSITION9;
float3 B111 : CENTER;
#endif
};
TessalationPatch HS_PatchConstant(InputPatch<VertexOutput, 3> input)
{
TessalationPatch output;
// Average tess factors along edges, and pick an edge tess factor for the interior tessellation
float4 TessellationMultipliers;
TessellationMultipliers.x = 0.5f * (input[1].TessellationMultiplier + input[2].TessellationMultiplier);
TessellationMultipliers.y = 0.5f * (input[2].TessellationMultiplier + input[0].TessellationMultiplier);
TessellationMultipliers.z = 0.5f * (input[0].TessellationMultiplier + input[1].TessellationMultiplier);
TessellationMultipliers.w = 0.333f * (input[0].TessellationMultiplier + input[1].TessellationMultiplier + input[2].TessellationMultiplier);
TessellationMultipliers = clamp(TessellationMultipliers, 1, MAX_TESSELLATION_FACTOR);
output.EdgeTessFactor[0] = TessellationMultipliers.x; // 1->2 edge
output.EdgeTessFactor[1] = TessellationMultipliers.y; // 2->0 edge
output.EdgeTessFactor[2] = TessellationMultipliers.z; // 0->1 edge
output.InsideTessFactor = TessellationMultipliers.w;
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
// Calculate PN-Triangle coefficients
// Refer to Vlachos 2001 for the original formula
float3 p1 = input[0].WorldPosition;
float3 p2 = input[1].WorldPosition;
float3 p3 = input[2].WorldPosition;
float3 n1 = input[0].WorldNormal;
float3 n2 = input[1].WorldNormal;
float3 n3 = input[2].WorldNormal;
// Calculate control points
output.B210 = (2.0f * p1 + p2 - dot((p2 - p1), n1) * n1) / 3.0f;
output.B120 = (2.0f * p2 + p1 - dot((p1 - p2), n2) * n2) / 3.0f;
output.B021 = (2.0f * p2 + p3 - dot((p3 - p2), n2) * n2) / 3.0f;
output.B012 = (2.0f * p3 + p2 - dot((p2 - p3), n3) * n3) / 3.0f;
output.B102 = (2.0f * p3 + p1 - dot((p1 - p3), n3) * n3) / 3.0f;
output.B201 = (2.0f * p1 + p3 - dot((p3 - p1), n1) * n1) / 3.0f;
float3 e = (output.B210 + output.B120 + output.B021 +
output.B012 + output.B102 + output.B201) / 6.0f;
float3 v = (p1 + p2 + p3) / 3.0f;
output.B111 = e + ((e - v) / 2.0f);
#endif
return output;
}
META_HS(USE_TESSELLATION, FEATURE_LEVEL_SM5)
META_HS_PATCH(TESSELLATION_IN_CONTROL_POINTS)
[domain("tri")]
[partitioning("fractional_odd")]
[outputtopology("triangle_cw")]
[maxtessfactor(MAX_TESSELLATION_FACTOR)]
[outputcontrolpoints(3)]
[patchconstantfunc("HS_PatchConstant")]
TessalationHSToDS HS(InputPatch<VertexOutput, TESSELLATION_IN_CONTROL_POINTS> input, uint ControlPointID : SV_OutputControlPointID)
{
TessalationHSToDS output;
// Pass through shader
#define COPY(thing) output.thing = input[ControlPointID].thing;
COPY(Position);
COPY(WorldPosition);
COPY(TexCoord);
COPY(LightmapUV);
COPY(WorldNormal);
COPY(HolesMask);
COPY(TessellationMultiplier);
#if USE_TERRAIN_LAYERS
COPY(Layers);
#endif
#if USE_CUSTOM_VERTEX_INTERPOLATORS
COPY(CustomVSToPS);
#endif
#undef COPY
return output;
}
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PHONG
// Orthogonal projection on to plane
float3 ProjectOntoPlane(float3 planeNormal, float3 planePoint, float3 pointToProject)
{
return pointToProject - dot(pointToProject-planePoint, planeNormal) * planeNormal;
}
#endif
META_DS(USE_TESSELLATION, FEATURE_LEVEL_SM5)
[domain("tri")]
TessalationDSToPS DS(TessalationPatch constantData, float3 barycentricCoords : SV_DomainLocation, const OutputPatch<TessalationHSToDS, 3> input)
{
TessalationDSToPS output;
// Get the barycentric coords
float U = barycentricCoords.x;
float V = barycentricCoords.y;
float W = barycentricCoords.z;
// Interpolate patch attributes to generated vertices
#define INTERPOLATE(thing) output.thing = U * input[0].thing + V * input[1].thing + W * input[2].thing
#define COPY(thing) output.thing = input[0].thing
INTERPOLATE(Position);
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
// Precompute squares and squares * 3
float UU = U * U;
float VV = V * V;
float WW = W * W;
float UU3 = UU * 3.0f;
float VV3 = VV * 3.0f;
float WW3 = WW * 3.0f;
// Interpolate using barycentric coordinates and PN Triangle control points
output.WorldPosition =
input[0].WorldPosition * UU * U +
input[1].WorldPosition * VV * V +
input[2].WorldPosition * WW * W +
constantData.B210 * UU3 * V +
constantData.B120 * VV3 * U +
constantData.B021 * VV3 * W +
constantData.B012 * WW3 * V +
constantData.B102 * WW3 * U +
constantData.B201 * UU3 * W +
constantData.B111 * 6.0f * W * U * V;
#else
INTERPOLATE(WorldPosition);
#endif
INTERPOLATE(TexCoord);
INTERPOLATE(LightmapUV);
INTERPOLATE(WorldNormal);
INTERPOLATE(HolesMask);
#if USE_TERRAIN_LAYERS
UNROLL
for (int i = 0; i < TERRAIN_LAYERS_DATA_SIZE; i++)
{
INTERPOLATE(Layers[i]);
}
#endif
#if USE_CUSTOM_VERTEX_INTERPOLATORS
UNROLL
for (int i = 0; i < CUSTOM_VERTEX_INTERPOLATORS_COUNT; i++)
{
INTERPOLATE(CustomVSToPS[i]);
}
#endif
#undef INTERPOLATE
#undef COPY
// Interpolating normal can unnormalize it, so normalize it
output.WorldNormal = normalize(output.WorldNormal);
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PHONG
// Orthogonal projection in the tangent planes
float3 posProjectedU = ProjectOntoPlane(input[0].WorldNormal, input[0].WorldPosition, output.WorldPosition);
float3 posProjectedV = ProjectOntoPlane(input[1].WorldNormal, input[1].WorldPosition, output.WorldPosition);
float3 posProjectedW = ProjectOntoPlane(input[2].WorldNormal, input[2].WorldPosition, output.WorldPosition);
// Interpolate the projected points
output.WorldPosition = U * posProjectedU + V * posProjectedV + W * posProjectedW;
#endif
// Perform displacement mapping
#if USE_DISPLACEMENT
MaterialInput materialInput = GetMaterialInput(output);
Material material = GetMaterialDS(materialInput);
output.WorldPosition += material.WorldDisplacement;
#endif
// Recalculate the clip space position
output.Position = mul(float4(output.WorldPosition, 1), ViewProjectionMatrix);
return output;
}
#endif
#if USE_LIGHTMAP
float3 SampleLightmap(Material material, MaterialInput materialInput)
{
// Sample lightmaps
float4 lightmap0 = Lightmap0.Sample(SamplerLinearClamp, materialInput.LightmapUV);
float4 lightmap1 = Lightmap1.Sample(SamplerLinearClamp, materialInput.LightmapUV);
float4 lightmap2 = Lightmap2.Sample(SamplerLinearClamp, materialInput.LightmapUV);
// Unpack H-basis
float3 h0 = float3(lightmap0.x, lightmap1.x, lightmap2.x);
float3 h1 = float3(lightmap0.y, lightmap1.y, lightmap2.y);
float3 h2 = float3(lightmap0.z, lightmap1.z, lightmap2.z);
float3 h3 = float3(lightmap0.w, lightmap1.w, lightmap2.w);
// Sample baked diffuse irradiance from the H-basis coefficients
float3 normal = material.TangentNormal;
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
normal *= material.TangentNormal;
#endif
return GetHBasisIrradiance(normal, h0, h1, h2, h3) / PI;
}
#endif
// Pixel Shader function for GBuffer Pass
META_PS(true, FEATURE_LEVEL_ES2)
META_PERMUTATION_1(USE_LIGHTMAP=0)
META_PERMUTATION_1(USE_LIGHTMAP=1)
void PS_GBuffer(
in PixelInput input
,out float4 Light : SV_Target0
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
,out float4 RT0 : SV_Target1
,out float4 RT1 : SV_Target2
,out float4 RT2 : SV_Target3
#if USE_GBUFFER_CUSTOM_DATA
,out float4 RT3 : SV_Target4
#endif
#endif
)
{
Light = 0;
// Get material parameters
MaterialInput materialInput = GetMaterialInput(input);
Material material = GetMaterialPS(materialInput);
// Masking
#if MATERIAL_MASKED
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
#endif
#if USE_LIGHTMAP
float3 diffuseColor = GetDiffuseColor(material.Color, material.Metalness);
float3 specularColor = GetSpecularColor(material.Color, material.Specular, material.Metalness);
// Sample lightmap
float3 diffuseIndirectLighting = SampleLightmap(material, materialInput);
// Apply static indirect light
Light.rgb = diffuseColor * diffuseIndirectLighting * AOMultiBounce(material.AO, diffuseColor);
#endif
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
// Pack material properties to GBuffer
RT0 = float4(material.Color, material.AO);
RT1 = float4(material.WorldNormal * 0.5 + 0.5, MATERIAL_SHADING_MODEL * (1.0 / 3.0));
RT2 = float4(material.Roughness, material.Metalness, material.Specular, 0);
// Custom data
#if USE_GBUFFER_CUSTOM_DATA
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE
RT3 = float4(material.SubsurfaceColor, material.Opacity);
#elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
RT3 = float4(material.SubsurfaceColor, material.Opacity);
#else
RT3 = float4(0, 0, 0, 0);
#endif
#endif
// Add light emission
#if USE_EMISSIVE
Light.rgb += material.Emissive;
#endif
#else
// Handle blending as faked forward pass (use Light buffer and skip GBuffer modification)
Light = float4(material.Emissive, material.Opacity);
#endif
}
// Pixel Shader function for Depth Pass
META_PS(true, FEATURE_LEVEL_ES2)
void PS_Depth(PixelInput input
#if GLSL
, out float4 OutColor : SV_Target0
#endif
)
{
#if MATERIAL_MASKED
// Perform per pixel clipping if material requries it
MaterialInput materialInput = GetMaterialInput(input);
Material material = GetMaterialPS(materialInput);
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
#endif
#if GLSL
OutColor = 0;
#endif
}

BIN
Content/Editor/Particles/Constant Burst.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Particles/Particle Material Color.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Particles/Particle Material Preview.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Particles/Periodic Burst.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Particles/Ribbon Spiral.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Particles/Smoke Atlas Normal.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Particles/Smoke Atlas.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Particles/Smoke Material.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Particles/Smoke.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Particles/Sparks.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Primitives/Capsule.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Primitives/Cone.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Primitives/Cube.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Primitives/Cylinder.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Primitives/Plane.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Primitives/Sphere.flax (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -0,0 +1,24 @@
%copyright%
#include "%filename%.h"
%class%::%class%(const SpawnParams& params)
: Script(params)
{
// Enable ticking OnUpdate function
_tickUpdate = true;
}
void %class%::OnEnable()
{
// Here you can add code that needs to be called when script is enabled (eg. register for events)
}
void %class%::OnDisable()
{
// Here you can add code that needs to be called when script is disabled (eg. unregister from events)
}
void %class%::OnUpdate()
{
// Here you can add code that needs to be called every frame
}

View File

@@ -0,0 +1,29 @@
%copyright%using System;
using System.Collections.Generic;
using FlaxEngine;
namespace %namespace%
{
public class %class% : Script
{
public override void OnStart()
{
// Here you can add code that needs to be called when script is created, just before the first game update
}
public override void OnEnable()
{
// Here you can add code that needs to be called when script is enabled (eg. register for events)
}
public override void OnDisable()
{
// Here you can add code that needs to be called when script is disabled (eg. unregister from events)
}
public override void OnUpdate()
{
// Here you can add code that needs to be called every frame
}
}
}

View File

@@ -0,0 +1,14 @@
%copyright%
#pragma once
#include "Engine/Scripting/Script.h"
API_CLASS() class %module%%class% : public Script
{
DECLARE_SCRIPTING_TYPE(%class%);
// [Script]
void OnEnable() override;
void OnDisable() override;
void OnUpdate() override;
};

View File

@@ -0,0 +1,12 @@
%copyright%#include "./Flax/Common.hlsl"
META_CB_BEGIN(0, Data)
float4 Color;
META_CB_END
META_PS(true, FEATURE_LEVEL_ES2)
float4 PS_Fullscreen(Quad_VS2PS input) : SV_Target
{
// Solid color fill from the constant buffer passed from code
return Color;
}

BIN
Content/Editor/SimplySky.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Terrain/Circle Brush Material.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Terrain/Highlight Terrain Material.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/TexturePreviewMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/VisjectSurface.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Wires Debug Material.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/DefaultMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/DefaultTerrainMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/Models/Box.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/Models/Quad.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/Models/SimpleBox.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/Models/Sphere.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/Models/SphereLowPoly.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/SingleColorMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/SkyboxMaterial.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/Textures/BlackTexture.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/Textures/Bokeh/Circle.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Engine/Textures/Bokeh/Cross.flax (Stored with Git LFS) Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More