990 lines
46 KiB
C#
990 lines
46 KiB
C#
using Godot;
|
||
using Godot.NativeInterop;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
|
||
[Tool]
|
||
[GlobalClass]
|
||
public partial class SunshineClouds : CompositorEffect
|
||
{
|
||
[ExportGroup("Basic Settings")]
|
||
[Export(PropertyHint.Range, "0,1")] public float CloudsCoverage { get { return _cloudsCoverage; } set { _cloudsCoverage = value; } }
|
||
private float _cloudsCoverage = 0.6f;
|
||
[Export(PropertyHint.Range, "0,20")] public float CloudsDensity { get { return _cloudsDensity; } set { _cloudsDensity = value; } }
|
||
private float _cloudsDensity = 1.0f;
|
||
[Export(PropertyHint.Range, "0,1")] public float AtmosphericDensity { get { return _atmosphericDensity; } set { _atmosphericDensity = value; } }
|
||
private float _atmosphericDensity = 0.5f;
|
||
|
||
[ExportSubgroup("Colors")]
|
||
[Export(PropertyHint.Range, "0,0.5")] public float CloudsAnisotropy { get { return _cloudsAnisotropy; } set { _cloudsAnisotropy = value; } }
|
||
private float _cloudsAnisotropy = 0.3f;
|
||
[Export] public Color CloudAmbientColor { get; set; } = new Color(0.352f, 0.624f, 0.784f, 1.0f);
|
||
[Export] public Color CloudAmbientTint { get; set; } = new Color(1.0f, 1.0f, 1.0f, 1.0f);
|
||
[Export] public Color AtmosphereColor { get; set; } = new Color(0.801f, 0.893f, 0.962f, 1.0f);
|
||
[Export] public Color AmbientOcclusionColor { get; set; } = new Color(0.17f, 0.044f, 0.027f, 0.549f);
|
||
|
||
[ExportSubgroup("Structure")]
|
||
[Export(PropertyHint.Range, "0,1")] public float AccumilationDecay { get { return _accumilationDecay; } set { _accumilationDecay = value; } }
|
||
private float _accumilationDecay = 0.5f;
|
||
[Export(PropertyHint.Range, "100,1000000")] public float ExtraLargeNoiseScale { get { return _extraLargeNoiseScale; } set { _extraLargeNoiseScale = value; } }
|
||
private float _extraLargeNoiseScale = 320000.0f;
|
||
[Export(PropertyHint.Range, "100,500000")] public float LargeNoiseScale { get { return _largeNoiseScale; } set { _largeNoiseScale = value; } }
|
||
private float _largeNoiseScale = 50000.0f;
|
||
[Export(PropertyHint.Range, "100,100000")] public float MediumNoiseScale { get { return _mediumNoiseScale; } set { _mediumNoiseScale = value; } }
|
||
private float _mediumNoiseScale = 6000.0f;
|
||
[Export(PropertyHint.Range, "100,10000")] public float SmallNoiseScale { get { return _smallNoiseScale; } set { _smallNoiseScale = value; } }
|
||
private float _smallNoiseScale = 2500.0f;
|
||
|
||
[Export(PropertyHint.Range, "0.001,1.0")] public float CloudsSharpness { get { return _cloudsSharpness; } set { _cloudsSharpness = value; } }
|
||
private float _cloudsSharpness = 1.0f;
|
||
[Export(PropertyHint.Range, "0,3")] public float CloudsDetailPower { get { return _cloudsDetailPower; } set { _cloudsDetailPower = value; } }
|
||
private float _cloudsDetailPower = 0.9f;
|
||
[Export(PropertyHint.Range, "0,50000")] public float CurlNoiseStrength { get { return _curlNoiseStrength; } set { _curlNoiseStrength = value; } }
|
||
private float _curlNoiseStrength = 5000.0f;
|
||
|
||
[Export(PropertyHint.Range, "0,2")] public float LightingSharpness { get { return _lightingSharpness; } set { _lightingSharpness = value; } }
|
||
private float _lightingSharpness = 0.05f;
|
||
[Export(PropertyHint.Range, "0,10")] public float LightingDensity { get { return _lightingDensity; } set { _lightingDensity = value; } }
|
||
private float _lightingDensity = 0.55f;
|
||
|
||
[Export] public float CloudFloor { get { return _cloudFloor; } set { _cloudFloor = value; } }
|
||
private float _cloudFloor = 1500.0f;
|
||
[Export] public float CloudCeiling { get { return _cloudCeiling; } set { _cloudCeiling = value; } }
|
||
private float _cloudCeiling = 25000.0f;
|
||
|
||
|
||
|
||
[ExportSubgroup("Performance")]
|
||
[Export] public int MaxStepCount { get { return _maxStepCount; } set { _maxStepCount = value; } }
|
||
private int _maxStepCount = 50;
|
||
[Export] public int MaxLightingSteps { get { return _maxLightingSteps; } set { _maxLightingSteps = value; } }
|
||
private int _maxLightingSteps = 32;
|
||
|
||
[Export(PropertyHint.Enum, "Native,Quarter,Eighth,Sixteenth")] public int ResolutionScale { get { return _resolutionScale; } set { _resolutionScale = value; _lastSize = Vector2I.Zero; } }
|
||
private int _resolutionScale = 0;
|
||
|
||
[Export(PropertyHint.Range, "0,2")] public float LODBias { get { return _LODBias; } set { _LODBias = value; } }
|
||
private float _LODBias = 1.0f;
|
||
|
||
[ExportSubgroup("Noise Textures")]
|
||
[Export] public Texture3D DitherNoise { get { return _DitherNoise; } set { _DitherNoise = value; } }
|
||
private Texture3D _DitherNoise;
|
||
[Export] public Texture2D HeightGradient { get { return _HeightGradient; } set { _HeightGradient = value; } }
|
||
private Texture2D _HeightGradient;
|
||
[Export] public Texture2D ExtraLargeNoisePatterns { get { return _ExtraLargeNoisePatterns; } set { _ExtraLargeNoisePatterns = value; } }
|
||
private Texture2D _ExtraLargeNoisePatterns;
|
||
[Export] public Texture3D LargeScaleNoise { get { return _LargeScaleNoise; } set { _LargeScaleNoise = value; } }
|
||
private Texture3D _LargeScaleNoise;
|
||
[Export] public Texture3D MediumScaleNoise { get { return _MediumScaleNoise; } set { _MediumScaleNoise = value; } }
|
||
private Texture3D _MediumScaleNoise;
|
||
[Export] public Texture3D SmallScaleNoise { get { return _SmallScaleNoise; } set { _SmallScaleNoise = value; } }
|
||
private Texture3D _SmallScaleNoise;
|
||
[Export] public Texture3D CurlNoise { get { return _CurlNoise; } set { _CurlNoise = value; } }
|
||
private Texture3D _CurlNoise;
|
||
|
||
|
||
[ExportGroup("Advanced Settings")]
|
||
[ExportSubgroup("Visuals")]
|
||
[Export(PropertyHint.Range, "0,1000")] public float DitherSpeed { get { return _ditherSpeed; } set { _ditherSpeed = value; } }
|
||
private float _ditherSpeed = 100.8254f;
|
||
[Export(PropertyHint.Range, "0,20")] public float BlurPower { get { return _blurPower; } set { _blurPower = value; } }
|
||
private float _blurPower = 2.0f;
|
||
[Export(PropertyHint.Range, "0,6")] public float BlurQuality { get { return _blurQuality; } set { _blurQuality = value; } }
|
||
private float _blurQuality = 1.0f;
|
||
|
||
[ExportSubgroup("Performance")]
|
||
[Export] public float MinStepDistance { get { return _minStepDistance; } set { _minStepDistance = value; } }
|
||
private float _minStepDistance = 100.0f;
|
||
[Export] public float MaxStepDistance { get { return _maxStepDistance; } set { _maxStepDistance = value; } }
|
||
private float _maxStepDistance = 600.0f;
|
||
|
||
[Export] public float LightingTravelDistance { get { return _lightingTravelDistance; } set { _lightingTravelDistance = value; } }
|
||
private float _lightingTravelDistance = 5000.0f;
|
||
|
||
[ExportGroup("Compute Shaders")]
|
||
[Export(PropertyHint.File, "*.glsl")] public RDShaderFile PrePassComputeShader;
|
||
[Export(PropertyHint.File, "*.glsl")] public RDShaderFile ComputeShader;
|
||
[Export(PropertyHint.File, "*.glsl")] public RDShaderFile PostPassComputeShader;
|
||
|
||
[ExportGroup("Internal Use")]
|
||
[ExportSubgroup("Positions")]
|
||
[Export] public Vector3 WindDirection { get; set; } = Vector3.Zero;
|
||
[Export] public Vector3 ExtraLargeScaleCloudsPosition { get; set; } = Vector3.Zero;
|
||
[Export] public Vector3 LargeScaleCloudsPosition { get; set; } = Vector3.Zero;
|
||
[Export] public Vector3 MediumScaleCloudsPosition { get; set; } = Vector3.Zero;
|
||
[Export] public Vector3 DetailCloudsPosition { get; set; } = Vector3.Zero;
|
||
[Export] public float CurrentTime { get; set; } = 0.0f;
|
||
[ExportSubgroup("Light Data")]
|
||
[Export] public Godot.Collections.Array<Vector4> DirectionalLightsData { get; set; } = new Godot.Collections.Array<Vector4>();
|
||
[Export] public Godot.Collections.Array<Vector4> PointLightsData { get; set; } = new Godot.Collections.Array<Vector4>();
|
||
|
||
public bool LightsUpdated { get; set; } = false;
|
||
|
||
private RenderingDevice _rd;
|
||
private Rid _shader = new Rid();
|
||
private Rid _pipeline = new Rid();
|
||
|
||
private Rid _prepass_shader = new Rid();
|
||
private Rid _prepass_pipeline = new Rid();
|
||
|
||
private Rid _postpass_shader = new Rid();
|
||
private Rid _postpass_pipeline = new Rid();
|
||
|
||
private Rid _nearestSampler = new Rid();
|
||
private Rid _linearSampler = new Rid();
|
||
private Rid _linearSamplerNoRepeat = new Rid();
|
||
|
||
private Rid _generalDataBuffer = new Rid();
|
||
private Rid _lightDataBuffer = new Rid();
|
||
private Rid[] _accumulationTextures;
|
||
private Rid _resizedDepth = new Rid();
|
||
private byte[] _pushConstants;
|
||
private byte[] _prepasspushConstants;
|
||
private byte[] _postpasspushConstants;
|
||
private Vector2I _lastSize = new Vector2I(0,0);
|
||
|
||
private RenderSceneBuffersRD _buffers;
|
||
|
||
|
||
private Rid[] _uniformSets;
|
||
private float[] _generalDataFloats = new float[112];
|
||
private byte[] _generalData = new byte[448];
|
||
|
||
private float[] _lightDataFloats = new float[96];
|
||
private byte[] _lightData = new byte[384];
|
||
|
||
private bool _accumulationisA = false;
|
||
|
||
private Transform3D? _lastViewMat;
|
||
private Projection? _lastProjectionMat;
|
||
|
||
private int _filterIndex = 0;
|
||
|
||
public SunshineClouds()
|
||
{
|
||
EffectCallbackType = EffectCallbackTypeEnum.PostSky;
|
||
AccessResolvedDepth = true;
|
||
AccessResolvedColor = true;
|
||
NeedsMotionVectors = true;
|
||
|
||
RenderingServer.CallOnRenderThread(Callable.From(InitializeCompute));
|
||
}
|
||
|
||
|
||
public override void _Notification(int what)
|
||
{
|
||
if (what == NotificationPredelete)
|
||
{
|
||
RenderingServer.CallOnRenderThread(Callable.From(ClearCompute));
|
||
}
|
||
}
|
||
|
||
private void ClearCompute()
|
||
{
|
||
//GD.Print("clearing compute");
|
||
if (_rd != null)
|
||
{
|
||
if (_shader.IsValid) _rd.FreeRid(_shader);
|
||
_shader = new Rid();
|
||
|
||
if (_prepass_shader.IsValid) _rd.FreeRid(_prepass_shader);
|
||
_prepass_shader = new Rid();
|
||
|
||
if (_postpass_shader.IsValid) _rd.FreeRid(_postpass_shader);
|
||
_postpass_shader = new Rid();
|
||
|
||
if (_nearestSampler.IsValid) _rd.FreeRid(_nearestSampler);
|
||
_nearestSampler = new Rid();
|
||
|
||
if (_linearSampler.IsValid) _rd.FreeRid(_linearSampler);
|
||
_linearSampler = new Rid();
|
||
|
||
if (_linearSamplerNoRepeat.IsValid) _rd.FreeRid(_linearSamplerNoRepeat);
|
||
_linearSamplerNoRepeat = new Rid();
|
||
|
||
if (_generalDataBuffer.IsValid) _rd.FreeRid(_generalDataBuffer);
|
||
_generalDataBuffer = new Rid();
|
||
|
||
if (_lightDataBuffer.IsValid) _rd.FreeRid(_lightDataBuffer);
|
||
_lightDataBuffer = new Rid();
|
||
|
||
if (_resizedDepth.IsValid) _rd.FreeRid(_resizedDepth);
|
||
_resizedDepth = new Rid();
|
||
|
||
|
||
|
||
if (_accumulationTextures != null)
|
||
{
|
||
foreach (var item in _accumulationTextures)
|
||
{
|
||
if (item.IsValid)
|
||
{
|
||
_rd.FreeRid(item);
|
||
}
|
||
}
|
||
_accumulationTextures = null;
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
|
||
public void InitializeCompute()
|
||
{
|
||
if (_rd == null)
|
||
{
|
||
_rd = RenderingServer.GetRenderingDevice();
|
||
|
||
if (_rd == null)
|
||
{
|
||
Enabled = false;
|
||
GD.PrintErr("No rendering device on load.");
|
||
return;
|
||
}
|
||
}
|
||
|
||
ClearCompute();
|
||
|
||
RDSamplerState samplerState = new RDSamplerState();
|
||
samplerState.MinFilter = RenderingDevice.SamplerFilter.Nearest;
|
||
samplerState.MagFilter = RenderingDevice.SamplerFilter.Nearest;
|
||
samplerState.RepeatU = RenderingDevice.SamplerRepeatMode.Repeat;
|
||
samplerState.RepeatV = RenderingDevice.SamplerRepeatMode.Repeat;
|
||
samplerState.RepeatW = RenderingDevice.SamplerRepeatMode.Repeat;
|
||
_nearestSampler = _rd.SamplerCreate(samplerState);
|
||
|
||
RDSamplerState linearsamplerState = new RDSamplerState();
|
||
linearsamplerState.MinFilter = RenderingDevice.SamplerFilter.Linear;
|
||
linearsamplerState.MagFilter = RenderingDevice.SamplerFilter.Linear;
|
||
linearsamplerState.RepeatU = RenderingDevice.SamplerRepeatMode.Repeat;
|
||
linearsamplerState.RepeatV = RenderingDevice.SamplerRepeatMode.Repeat;
|
||
linearsamplerState.RepeatW = RenderingDevice.SamplerRepeatMode.Repeat;
|
||
_linearSampler = _rd.SamplerCreate(linearsamplerState);
|
||
|
||
|
||
RDSamplerState linearsamplerStateNoRepeat = new RDSamplerState();
|
||
linearsamplerStateNoRepeat.MinFilter = RenderingDevice.SamplerFilter.Linear;
|
||
linearsamplerStateNoRepeat.MagFilter = RenderingDevice.SamplerFilter.Linear;
|
||
linearsamplerStateNoRepeat.RepeatU = RenderingDevice.SamplerRepeatMode.ClampToEdge;
|
||
linearsamplerStateNoRepeat.RepeatV = RenderingDevice.SamplerRepeatMode.ClampToEdge;
|
||
linearsamplerStateNoRepeat.RepeatW = RenderingDevice.SamplerRepeatMode.ClampToEdge;
|
||
_linearSamplerNoRepeat = _rd.SamplerCreate(linearsamplerStateNoRepeat);
|
||
|
||
if (DitherNoise == null) {
|
||
DitherNoise = ResourceLoader.Load("res://addons/SunshineClouds2/NoiseTextures/bluenoise_Dither.png") as Texture3D;
|
||
}
|
||
if (HeightGradient == null){
|
||
HeightGradient = ResourceLoader.Load("res://addons/SunshineClouds2/NoiseTextures/HeightGradient.tres") as Texture2D;
|
||
}
|
||
if (ExtraLargeNoisePatterns == null){
|
||
ExtraLargeNoisePatterns = ResourceLoader.Load("res://addons/SunshineClouds2/NoiseTextures/ExtraLargeScaleNoise.tres") as Texture2D;
|
||
}
|
||
if (LargeScaleNoise == null){
|
||
LargeScaleNoise = ResourceLoader.Load("res://addons/SunshineClouds2/NoiseTextures/LargeScaleNoise.tres") as Texture3D;
|
||
}
|
||
if (MediumScaleNoise == null){
|
||
MediumScaleNoise = ResourceLoader.Load("res://addons/SunshineClouds2/NoiseTextures/MediumScaleNoise.tres") as Texture3D;
|
||
}
|
||
if (SmallScaleNoise == null){
|
||
SmallScaleNoise = ResourceLoader.Load("res://addons/SunshineClouds2/NoiseTextures/SmallScaleNoise.tres") as Texture3D;
|
||
}
|
||
if (CurlNoise == null){
|
||
CurlNoise = ResourceLoader.Load("res://addons/SunshineClouds2/NoiseTextures/curl_noise_varied.tga") as Texture3D;
|
||
}
|
||
|
||
|
||
if (ComputeShader == null)
|
||
{
|
||
ComputeShader = ResourceLoader.Load<RDShaderFile>("res://addons/SunshineClouds2/SunshineCloudsCompute.glsl");
|
||
}
|
||
if (PrePassComputeShader == null)
|
||
{
|
||
PrePassComputeShader = ResourceLoader.Load<RDShaderFile>("res://addons/SunshineClouds2/SunshineCloudsPreCompute.glsl");
|
||
}
|
||
|
||
if (PostPassComputeShader == null)
|
||
{
|
||
PostPassComputeShader = ResourceLoader.Load<RDShaderFile>("res://addons/SunshineClouds2/SunshineCloudsPostCompute.glsl");
|
||
}
|
||
|
||
if (ComputeShader == null || PrePassComputeShader == null || PostPassComputeShader == null)
|
||
{
|
||
Enabled = false;
|
||
GD.PrintErr("No Shader found on load.");
|
||
ClearCompute();
|
||
return;
|
||
}
|
||
|
||
var prepassshaderSpirv = PrePassComputeShader.GetSpirV();
|
||
_prepass_shader = _rd.ShaderCreateFromSpirV(prepassshaderSpirv);
|
||
if (_prepass_shader.IsValid)
|
||
{
|
||
_prepass_pipeline = _rd.ComputePipelineCreate(_prepass_shader);
|
||
}
|
||
else
|
||
{
|
||
Enabled = false;
|
||
GD.PrintErr("Prepass Shader failed to compile.");
|
||
ClearCompute();
|
||
return;
|
||
}
|
||
|
||
var shaderSpirv = ComputeShader.GetSpirV();
|
||
_shader = _rd.ShaderCreateFromSpirV(shaderSpirv);
|
||
if (_shader.IsValid)
|
||
{
|
||
_pipeline = _rd.ComputePipelineCreate(_shader);
|
||
}
|
||
else
|
||
{
|
||
Enabled = false;
|
||
GD.PrintErr("Shader failed to compile.");
|
||
ClearCompute();
|
||
return;
|
||
}
|
||
|
||
var postpassshaderSpirv = PostPassComputeShader.GetSpirV();
|
||
_postpass_shader = _rd.ShaderCreateFromSpirV(postpassshaderSpirv);
|
||
if (_postpass_shader.IsValid)
|
||
{
|
||
_postpass_pipeline = _rd.ComputePipelineCreate(_postpass_shader);
|
||
}
|
||
else
|
||
{
|
||
Enabled = false;
|
||
GD.PrintErr("Post pass Shader failed to compile.");
|
||
ClearCompute();
|
||
return;
|
||
}
|
||
}
|
||
|
||
public override void _RenderCallback(int effectCallbackType, RenderData renderData)
|
||
{
|
||
if (_rd == null)
|
||
{
|
||
InitializeCompute();
|
||
}
|
||
else if (_pipeline.IsValid && HeightGradient != null && ExtraLargeNoisePatterns != null && LargeScaleNoise != null && MediumScaleNoise != null && SmallScaleNoise != null && DitherNoise != null && CurlNoise != null)
|
||
{
|
||
_buffers = renderData.GetRenderSceneBuffers() as RenderSceneBuffersRD;
|
||
if (_buffers != null)
|
||
{
|
||
Vector2I size = _buffers.GetInternalSize();
|
||
if (size.X == 0 && size.Y == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
uint resscale = 1;
|
||
|
||
switch (ResolutionScale)
|
||
{
|
||
case 0: //1:1
|
||
resscale = 1;
|
||
break;
|
||
case 1: //4:1
|
||
resscale = 2;
|
||
break;
|
||
case 2: //8:1
|
||
resscale = 4;
|
||
break;
|
||
case 3: //16:1
|
||
resscale = 8;
|
||
break;
|
||
}
|
||
|
||
Vector2I newSize = size;
|
||
newSize.X = newSize.X / (int)resscale;
|
||
newSize.Y = newSize.Y / (int)resscale;
|
||
|
||
uint viewCount = _buffers.GetViewCount();
|
||
|
||
if (size != _lastSize || _uniformSets == null || _uniformSets.Length != viewCount * 3)
|
||
{
|
||
InitializeCompute();
|
||
|
||
_accumulationTextures = new Rid[viewCount * 6];
|
||
_uniformSets = new Rid[viewCount * 3];
|
||
|
||
//prepass push constants:
|
||
float[] prepassData = new float[4];
|
||
_prepasspushConstants = new byte[16];
|
||
|
||
prepassData[0] = size.X;
|
||
prepassData[1] = size.Y;
|
||
prepassData[2] = resscale;
|
||
prepassData[3] = 0.0f;
|
||
|
||
Buffer.BlockCopy(prepassData, 0, _prepasspushConstants, 0, 16);
|
||
|
||
float[] postpassData = new float[4];
|
||
_postpasspushConstants = new byte[16];
|
||
|
||
postpassData[0] = newSize.X;
|
||
postpassData[1] = newSize.Y;
|
||
postpassData[2] = resscale;
|
||
postpassData[3] = 0.0f;
|
||
|
||
Buffer.BlockCopy(postpassData, 0, _postpasspushConstants, 0, 16);
|
||
|
||
|
||
for (uint view = 0; view < viewCount; view++)
|
||
{
|
||
Rid colorImage = _buffers.GetColorLayer(view);
|
||
Rid depthImage = _buffers.GetDepthLayer(view);
|
||
|
||
var baseColorformat = _rd.TextureGetFormat(colorImage);
|
||
baseColorformat.Format = RenderingDevice.DataFormat.R32G32B32A32Sfloat;
|
||
baseColorformat.Width = (uint)newSize.X;
|
||
baseColorformat.Height = (uint)newSize.Y;
|
||
|
||
//then make my data accumilation images.
|
||
_accumulationTextures[view * 3] = _rd.TextureCreate(baseColorformat, new RDTextureView(), null);
|
||
_accumulationTextures[view * 3 + 1] = _rd.TextureCreate(baseColorformat, new RDTextureView(), null);
|
||
_accumulationTextures[view * 3 + 2] = _rd.TextureCreate(baseColorformat, new RDTextureView(), null);
|
||
_accumulationTextures[view * 3 + 3] = _rd.TextureCreate(baseColorformat, new RDTextureView(), null);
|
||
_accumulationTextures[view * 3 + 4] = _rd.TextureCreate(baseColorformat, new RDTextureView(), null);
|
||
_accumulationTextures[view * 3 + 5] = _rd.TextureCreate(baseColorformat, new RDTextureView(), null);
|
||
|
||
|
||
var depthformat = _rd.TextureGetFormat(depthImage);
|
||
depthformat.Width = (uint)newSize.X;
|
||
depthformat.Height = (uint)newSize.Y;
|
||
depthformat.Format = RenderingDevice.DataFormat.R32Sfloat;
|
||
depthformat.UsageBits = RenderingDevice.TextureUsageBits.StorageBit | RenderingDevice.TextureUsageBits.SamplingBit;
|
||
_resizedDepth = _rd.TextureCreate(depthformat, new RDTextureView(), null);
|
||
|
||
|
||
var _prepassuniformsArray = new Godot.Collections.Array<RDUniform>();
|
||
var prepassDepthUniform = new RDUniform();
|
||
prepassDepthUniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
prepassDepthUniform.Binding = 0;
|
||
prepassDepthUniform.AddId(_nearestSampler);
|
||
prepassDepthUniform.AddId(depthImage);
|
||
_prepassuniformsArray.Add(prepassDepthUniform);
|
||
|
||
var prepassDepthOutputUniform = new RDUniform();
|
||
prepassDepthOutputUniform.UniformType = RenderingDevice.UniformType.Image;
|
||
prepassDepthOutputUniform.Binding = 1;
|
||
prepassDepthOutputUniform.AddId(_resizedDepth);
|
||
_prepassuniformsArray.Add(prepassDepthOutputUniform);
|
||
|
||
_uniformSets[view * 3] = _rd.UniformSetCreate(_prepassuniformsArray, _prepass_shader, 0);
|
||
|
||
|
||
var _uniformsArray = new Godot.Collections.Array<RDUniform>();
|
||
|
||
var outputDataUniform = new RDUniform();
|
||
outputDataUniform.UniformType = RenderingDevice.UniformType.Image;
|
||
outputDataUniform.Binding = 0;
|
||
outputDataUniform.AddId(_accumulationTextures[view * 3]);
|
||
_uniformsArray.Add(outputDataUniform);
|
||
|
||
var outputColorUniform = new RDUniform();
|
||
outputColorUniform.UniformType = RenderingDevice.UniformType.Image;
|
||
outputColorUniform.Binding = 1;
|
||
outputColorUniform.AddId(_accumulationTextures[view * 3 + 1]);
|
||
_uniformsArray.Add(outputColorUniform);
|
||
|
||
|
||
var accum1Auniform = new RDUniform();
|
||
accum1Auniform.UniformType = RenderingDevice.UniformType.Image;
|
||
accum1Auniform.Binding = 2;
|
||
accum1Auniform.AddId(_accumulationTextures[view * 3 + 2]);
|
||
_uniformsArray.Add(accum1Auniform);
|
||
|
||
var accum1Buniform = new RDUniform();
|
||
accum1Buniform.UniformType = RenderingDevice.UniformType.Image;
|
||
accum1Buniform.Binding = 3;
|
||
accum1Buniform.AddId(_accumulationTextures[view * 3 + 3]);
|
||
_uniformsArray.Add(accum1Buniform);
|
||
|
||
var accum2Auniform = new RDUniform();
|
||
accum2Auniform.UniformType = RenderingDevice.UniformType.Image;
|
||
accum2Auniform.Binding = 4;
|
||
accum2Auniform.AddId(_accumulationTextures[view * 3 + 4]);
|
||
_uniformsArray.Add(accum2Auniform);
|
||
|
||
var accum2Buniform = new RDUniform();
|
||
accum2Buniform.UniformType = RenderingDevice.UniformType.Image;
|
||
accum2Buniform.Binding = 5;
|
||
accum2Buniform.AddId(_accumulationTextures[view * 3 + 5]);
|
||
_uniformsArray.Add(accum2Buniform);
|
||
|
||
|
||
|
||
var depthuniform = new RDUniform();
|
||
depthuniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
depthuniform.Binding = 6;
|
||
depthuniform.AddId(_nearestSampler);
|
||
depthuniform.AddId(_resizedDepth);
|
||
_uniformsArray.Add(depthuniform);
|
||
|
||
|
||
var extraNoiseuniform = new RDUniform();
|
||
extraNoiseuniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
extraNoiseuniform.Binding = 7;
|
||
extraNoiseuniform.AddId(_linearSampler);
|
||
extraNoiseuniform.AddId(RenderingServer.TextureGetRdTexture(ExtraLargeNoisePatterns.GetRid()));
|
||
_uniformsArray.Add(extraNoiseuniform);
|
||
|
||
var noiseuniform = new RDUniform();
|
||
noiseuniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
noiseuniform.Binding = 8;
|
||
noiseuniform.AddId(_linearSampler);
|
||
noiseuniform.AddId(RenderingServer.TextureGetRdTexture(LargeScaleNoise.GetRid()));
|
||
_uniformsArray.Add(noiseuniform);
|
||
|
||
var mediumnoiseuniform = new RDUniform();
|
||
mediumnoiseuniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
mediumnoiseuniform.Binding = 9;
|
||
mediumnoiseuniform.AddId(_linearSampler);
|
||
mediumnoiseuniform.AddId(RenderingServer.TextureGetRdTexture(MediumScaleNoise.GetRid()));
|
||
_uniformsArray.Add(mediumnoiseuniform);
|
||
|
||
var smallnoiseuniform = new RDUniform();
|
||
smallnoiseuniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
smallnoiseuniform.Binding = 10;
|
||
smallnoiseuniform.AddId(_linearSampler);
|
||
smallnoiseuniform.AddId(RenderingServer.TextureGetRdTexture(SmallScaleNoise.GetRid()));
|
||
_uniformsArray.Add(smallnoiseuniform);
|
||
|
||
var curlnoiseuniform = new RDUniform();
|
||
curlnoiseuniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
curlnoiseuniform.Binding = 11;
|
||
curlnoiseuniform.AddId(_linearSampler);
|
||
curlnoiseuniform.AddId(RenderingServer.TextureGetRdTexture(CurlNoise.GetRid()));
|
||
_uniformsArray.Add(curlnoiseuniform);
|
||
|
||
var dithernoiseuniform = new RDUniform();
|
||
dithernoiseuniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
dithernoiseuniform.Binding = 12;
|
||
dithernoiseuniform.AddId(_nearestSampler);
|
||
dithernoiseuniform.AddId(RenderingServer.TextureGetRdTexture(DitherNoise.GetRid()));
|
||
_uniformsArray.Add(dithernoiseuniform);
|
||
|
||
|
||
var heightgradientuniform = new RDUniform();
|
||
heightgradientuniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
heightgradientuniform.Binding = 13;
|
||
heightgradientuniform.AddId(_linearSamplerNoRepeat);
|
||
heightgradientuniform.AddId(RenderingServer.TextureGetRdTexture(HeightGradient.GetRid()));
|
||
_uniformsArray.Add(heightgradientuniform);
|
||
|
||
|
||
_generalDataBuffer = _rd.UniformBufferCreate(448);
|
||
var camerauniform = new RDUniform();
|
||
camerauniform.UniformType = RenderingDevice.UniformType.UniformBuffer;
|
||
camerauniform.Binding = 14;
|
||
camerauniform.AddId(_generalDataBuffer);
|
||
_uniformsArray.Add(camerauniform);
|
||
|
||
_lightDataBuffer = _rd.UniformBufferCreate(384);
|
||
var lightdatauniform = new RDUniform();
|
||
lightdatauniform.UniformType = RenderingDevice.UniformType.UniformBuffer;
|
||
lightdatauniform.Binding = 15;
|
||
lightdatauniform.AddId(_lightDataBuffer);
|
||
_uniformsArray.Add(lightdatauniform);
|
||
|
||
_uniformSets[view * 3 + 1] = _rd.UniformSetCreate(_uniformsArray, _shader, 0);
|
||
|
||
|
||
var _postpassuniformsArray = new Godot.Collections.Array<RDUniform>();
|
||
var prepassColorDataUniform = new RDUniform();
|
||
prepassColorDataUniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
prepassColorDataUniform.Binding = 0;
|
||
prepassColorDataUniform.AddId(_linearSamplerNoRepeat);
|
||
prepassColorDataUniform.AddId(_accumulationTextures[view * 3]);
|
||
_postpassuniformsArray.Add(prepassColorDataUniform);
|
||
|
||
var prepassColorUniform = new RDUniform();
|
||
prepassColorUniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
prepassColorUniform.Binding = 1;
|
||
prepassColorUniform.AddId(_linearSamplerNoRepeat);
|
||
prepassColorUniform.AddId(_accumulationTextures[view * 3 + 1]);
|
||
_postpassuniformsArray.Add(prepassColorUniform);
|
||
|
||
var postpassColorUniform = new RDUniform();
|
||
postpassColorUniform.UniformType = RenderingDevice.UniformType.Image;
|
||
postpassColorUniform.Binding = 2;
|
||
postpassColorUniform.AddId(colorImage);
|
||
_postpassuniformsArray.Add(postpassColorUniform);
|
||
|
||
var postpassDepthUniform = new RDUniform();
|
||
postpassDepthUniform.UniformType = RenderingDevice.UniformType.SamplerWithTexture;
|
||
postpassDepthUniform.Binding = 3;
|
||
postpassDepthUniform.AddId(_nearestSampler);
|
||
postpassDepthUniform.AddId(depthImage);
|
||
_postpassuniformsArray.Add(postpassDepthUniform);
|
||
|
||
var postpasscamerauniform = new RDUniform();
|
||
postpasscamerauniform.UniformType = RenderingDevice.UniformType.UniformBuffer;
|
||
postpasscamerauniform.Binding = 4;
|
||
postpasscamerauniform.AddId(_generalDataBuffer);
|
||
_postpassuniformsArray.Add(postpasscamerauniform);
|
||
|
||
var postpasslightdatauniform = new RDUniform();
|
||
postpasslightdatauniform.UniformType = RenderingDevice.UniformType.UniformBuffer;
|
||
postpasslightdatauniform.Binding = 5;
|
||
postpasslightdatauniform.AddId(_lightDataBuffer);
|
||
_postpassuniformsArray.Add(postpasslightdatauniform);
|
||
|
||
_uniformSets[view * 3 + 2] = _rd.UniformSetCreate(_postpassuniformsArray, _postpass_shader, 0);
|
||
|
||
}
|
||
LightsUpdated = true;
|
||
}
|
||
|
||
using var ms = new System.IO.MemoryStream();
|
||
using var bw = new System.IO.BinaryWriter(ms);
|
||
|
||
bw.Write((float)newSize.X);
|
||
bw.Write((float)newSize.Y);
|
||
bw.Write(_largeNoiseScale);
|
||
bw.Write(_mediumNoiseScale);
|
||
|
||
bw.Write(CurrentTime);
|
||
bw.Write(_cloudsCoverage);
|
||
bw.Write(_cloudsDensity);
|
||
bw.Write(_cloudsDetailPower);
|
||
|
||
bw.Write(_lightingDensity);
|
||
bw.Write(_accumilationDecay);
|
||
|
||
var rendersceneData = renderData.GetRenderSceneData();
|
||
var cameraTR = rendersceneData.GetCamTransform();
|
||
var viewProj = rendersceneData.GetCamProjection();
|
||
|
||
|
||
//_accumulationisA = !_accumulationisA;
|
||
bw.Write(_accumulationisA ? 1.0f : 0.0f);
|
||
bw.Write(0.0f);
|
||
|
||
_pushConstants = ms.ToArray();
|
||
_lastSize = size;
|
||
|
||
UpdateMatricies(cameraTR, viewProj);
|
||
if (LightsUpdated || DirectionalLightsData.Count == 0)
|
||
{
|
||
UpdateLights();
|
||
}
|
||
|
||
|
||
uint prepassxGroups = ((uint)size.X - 1) / 32 + 1;
|
||
uint prepassyGroups = ((uint)size.Y - 1) / 32 + 1;
|
||
|
||
uint xGroups = ((uint)size.X - 1) / 32 / resscale + 1;
|
||
uint yGroups = ((uint)size.Y - 1) / 32 / resscale + 1;
|
||
|
||
for (uint view = 0; view < viewCount; view++)
|
||
{
|
||
//GD.Print((uint)_prepasspushConstants.Length);
|
||
var prepasscomputeList = _rd.ComputeListBegin();
|
||
_rd.ComputeListBindComputePipeline(prepasscomputeList, _prepass_pipeline);
|
||
_rd.ComputeListBindUniformSet(prepasscomputeList, _uniformSets[view * 3], 0);
|
||
_rd.ComputeListSetPushConstant(prepasscomputeList, _prepasspushConstants, (uint)_prepasspushConstants.Length);
|
||
_rd.ComputeListDispatch(prepasscomputeList, xGroups, yGroups, 1);
|
||
//_rd.ComputeListAddBarrier(prepasscomputeList);
|
||
_rd.ComputeListEnd();
|
||
|
||
|
||
|
||
var computeList = _rd.ComputeListBegin();
|
||
_rd.ComputeListBindComputePipeline(computeList, _pipeline);
|
||
_rd.ComputeListBindUniformSet(computeList, _uniformSets[view * 3 + 1], 0);
|
||
_rd.ComputeListSetPushConstant(computeList, _pushConstants, (uint)_pushConstants.Length);
|
||
_rd.ComputeListDispatch(computeList, xGroups, yGroups, 1);
|
||
//_rd.ComputeListAddBarrier(computeList);
|
||
_rd.ComputeListEnd();
|
||
|
||
|
||
var postpasscomputeList = _rd.ComputeListBegin();
|
||
_rd.ComputeListBindComputePipeline(postpasscomputeList, _postpass_pipeline);
|
||
_rd.ComputeListBindUniformSet(postpasscomputeList, _uniformSets[view * 3 + 2], 0);
|
||
_rd.ComputeListSetPushConstant(postpasscomputeList, _postpasspushConstants, (uint)_postpasspushConstants.Length);
|
||
_rd.ComputeListDispatch(postpasscomputeList, prepassxGroups, prepassyGroups, 1);
|
||
_rd.ComputeListEnd();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
private Vector2 GetRotationDifferences(Transform3D transformA, Transform3D transformB)
|
||
{
|
||
// Get the forward vectors of each transform
|
||
Vector3 forwardA = -transformA.Basis.Z;
|
||
Vector3 forwardB = -transformB.Basis.Z;
|
||
|
||
// Normalize the vectors
|
||
forwardA = forwardA.Normalized();
|
||
forwardB = forwardB.Normalized();
|
||
|
||
// Calculate the horizontal (yaw) difference
|
||
Vector3 adjustedforwardA = new Vector3(forwardA.X, 0.0f, forwardA.Z).Normalized();
|
||
Vector3 adjustedforwardB = new Vector3(forwardB.X, 0.0f, forwardB.Z).Normalized();
|
||
Vector3 perp = adjustedforwardA.Cross(adjustedforwardB);
|
||
|
||
float yawDifference = adjustedforwardA.AngleTo(adjustedforwardB);
|
||
if (perp.Dot(Vector3.Up) < 0.0f)
|
||
{
|
||
yawDifference *= -1.0f;
|
||
}
|
||
|
||
float pitchDifference = new Vector3(0.0f, forwardA.Y, 1.0f).Normalized().AngleTo(new Vector3(0.0f, forwardB.Y, 1.0f).Normalized());
|
||
|
||
if (forwardA.Y > forwardB.Y)
|
||
{
|
||
pitchDifference *= -1.0f;
|
||
}
|
||
|
||
return new Vector2(yawDifference, pitchDifference);
|
||
}
|
||
|
||
|
||
private void UpdateMatricies(Transform3D cameraTR, Projection viewProj)
|
||
{
|
||
int idx = 0;
|
||
|
||
_filterIndex += 1; //Switch to 4 if your testing the 2x2 bayer pattern.
|
||
if (_filterIndex >= 16)
|
||
{
|
||
_filterIndex = 0;
|
||
}
|
||
|
||
// Camera matrix (16 floats)
|
||
_generalDataFloats[idx++] = cameraTR.Basis.X.X;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.X.Y;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.X.Z;
|
||
_generalDataFloats[idx++] = 0;
|
||
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Y.X;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Y.Y;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Y.Z;
|
||
_generalDataFloats[idx++] = 0;
|
||
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Z.X;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Z.Y;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Z.Z;
|
||
_generalDataFloats[idx++] = 0;
|
||
|
||
_generalDataFloats[idx++] = cameraTR.Origin.X;
|
||
_generalDataFloats[idx++] = cameraTR.Origin.Y;
|
||
_generalDataFloats[idx++] = cameraTR.Origin.Z;
|
||
_generalDataFloats[idx++] = 1.0f;
|
||
|
||
// Camera matrix (previous frame or current if not available)
|
||
if (_lastViewMat.HasValue)
|
||
{
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Basis.X.X;
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Basis.X.Y;
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Basis.X.Z;
|
||
_generalDataFloats[idx++] = 0;
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Basis.Y.X;
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Basis.Y.Y;
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Basis.Y.Z;
|
||
_generalDataFloats[idx++] = 0;
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Basis.Z.X;
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Basis.Z.Y;
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Basis.Z.Z;
|
||
_generalDataFloats[idx++] = 0;
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Origin.X;
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Origin.Y;
|
||
_generalDataFloats[idx++] = _lastViewMat.Value.Origin.Z;
|
||
_generalDataFloats[idx++] = 1.0f;
|
||
}
|
||
else
|
||
{
|
||
_generalDataFloats[idx++] = cameraTR.Basis.X.X;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.X.Y;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.X.Z;
|
||
_generalDataFloats[idx++] = 0;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Y.X;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Y.Y;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Y.Z;
|
||
_generalDataFloats[idx++] = 0;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Z.X;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Z.Y;
|
||
_generalDataFloats[idx++] = cameraTR.Basis.Z.Z;
|
||
_generalDataFloats[idx++] = 0;
|
||
_generalDataFloats[idx++] = cameraTR.Origin.X;
|
||
_generalDataFloats[idx++] = cameraTR.Origin.Y;
|
||
_generalDataFloats[idx++] = cameraTR.Origin.Z;
|
||
_generalDataFloats[idx++] = 1.0f;
|
||
}
|
||
|
||
// Projection matrix (16 floats)
|
||
_generalDataFloats[idx++] = viewProj.X.X;
|
||
_generalDataFloats[idx++] = viewProj.X.Y;
|
||
_generalDataFloats[idx++] = viewProj.X.Z;
|
||
_generalDataFloats[idx++] = viewProj.X.W;
|
||
|
||
_generalDataFloats[idx++] = viewProj.Y.X;
|
||
_generalDataFloats[idx++] = viewProj.Y.Y;
|
||
_generalDataFloats[idx++] = viewProj.Y.Z;
|
||
_generalDataFloats[idx++] = viewProj.Y.W;
|
||
|
||
_generalDataFloats[idx++] = viewProj.Z.X;
|
||
_generalDataFloats[idx++] = viewProj.Z.Y;
|
||
_generalDataFloats[idx++] = viewProj.Z.Z;
|
||
_generalDataFloats[idx++] = viewProj.Z.W;
|
||
|
||
_generalDataFloats[idx++] = viewProj.W.X;
|
||
_generalDataFloats[idx++] = viewProj.W.Y;
|
||
_generalDataFloats[idx++] = viewProj.W.Z;
|
||
_generalDataFloats[idx++] = viewProj.W.W;
|
||
|
||
// Projection matrix (previous frame or current if not available)
|
||
if (_lastProjectionMat.HasValue)
|
||
{
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.X.X;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.X.Y;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.X.Z;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.X.W;
|
||
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.Y.X;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.Y.Y;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.Y.Z;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.Y.W;
|
||
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.Z.X;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.Z.Y;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.Z.Z;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.Z.W;
|
||
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.W.X;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.W.Y;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.W.Z;
|
||
_generalDataFloats[idx++] = _lastProjectionMat.Value.W.W;
|
||
}
|
||
else
|
||
{
|
||
_generalDataFloats[idx++] = viewProj.X.X;
|
||
_generalDataFloats[idx++] = viewProj.X.Y;
|
||
_generalDataFloats[idx++] = viewProj.X.Z;
|
||
_generalDataFloats[idx++] = viewProj.X.W;
|
||
|
||
_generalDataFloats[idx++] = viewProj.Y.X;
|
||
_generalDataFloats[idx++] = viewProj.Y.Y;
|
||
_generalDataFloats[idx++] = viewProj.Y.Z;
|
||
_generalDataFloats[idx++] = viewProj.Y.W;
|
||
|
||
_generalDataFloats[idx++] = viewProj.Z.X;
|
||
_generalDataFloats[idx++] = viewProj.Z.Y;
|
||
_generalDataFloats[idx++] = viewProj.Z.Z;
|
||
_generalDataFloats[idx++] = viewProj.Z.W;
|
||
|
||
_generalDataFloats[idx++] = viewProj.W.X;
|
||
_generalDataFloats[idx++] = viewProj.W.Y;
|
||
_generalDataFloats[idx++] = viewProj.W.Z;
|
||
_generalDataFloats[idx++] = viewProj.W.W;
|
||
}
|
||
|
||
_lastProjectionMat = viewProj;
|
||
_lastViewMat = cameraTR;
|
||
_accumulationisA = !_accumulationisA;
|
||
|
||
// Simple data (44 floats)
|
||
_generalDataFloats[idx++] = ExtraLargeScaleCloudsPosition.X;
|
||
_generalDataFloats[idx++] = ExtraLargeScaleCloudsPosition.Y;
|
||
_generalDataFloats[idx++] = ExtraLargeScaleCloudsPosition.Z;
|
||
_generalDataFloats[idx++] = ExtraLargeNoiseScale;
|
||
|
||
_generalDataFloats[idx++] = LargeScaleCloudsPosition.X;
|
||
_generalDataFloats[idx++] = LargeScaleCloudsPosition.Y;
|
||
_generalDataFloats[idx++] = LargeScaleCloudsPosition.Z;
|
||
_generalDataFloats[idx++] = LightingSharpness;
|
||
|
||
_generalDataFloats[idx++] = MediumScaleCloudsPosition.X;
|
||
_generalDataFloats[idx++] = MediumScaleCloudsPosition.Y;
|
||
_generalDataFloats[idx++] = MediumScaleCloudsPosition.Z;
|
||
_generalDataFloats[idx++] = LightingTravelDistance;
|
||
|
||
_generalDataFloats[idx++] = DetailCloudsPosition.X;
|
||
_generalDataFloats[idx++] = DetailCloudsPosition.Y;
|
||
_generalDataFloats[idx++] = DetailCloudsPosition.Z;
|
||
_generalDataFloats[idx++] = AtmosphericDensity;
|
||
|
||
_generalDataFloats[idx++] = CloudAmbientColor.R * CloudAmbientTint.R;
|
||
_generalDataFloats[idx++] = CloudAmbientColor.G * CloudAmbientTint.G;
|
||
_generalDataFloats[idx++] = CloudAmbientColor.B * CloudAmbientTint.B;
|
||
_generalDataFloats[idx++] = CloudAmbientColor.A * CloudAmbientTint.A;
|
||
|
||
_generalDataFloats[idx++] = AmbientOcclusionColor.R;
|
||
_generalDataFloats[idx++] = AmbientOcclusionColor.G;
|
||
_generalDataFloats[idx++] = AmbientOcclusionColor.B;
|
||
_generalDataFloats[idx++] = AmbientOcclusionColor.A;
|
||
|
||
_generalDataFloats[idx++] = AtmosphereColor.R;
|
||
_generalDataFloats[idx++] = AtmosphereColor.G;
|
||
_generalDataFloats[idx++] = AtmosphereColor.B;
|
||
_generalDataFloats[idx++] = AtmosphereColor.A;
|
||
|
||
_generalDataFloats[idx++] = _smallNoiseScale;
|
||
_generalDataFloats[idx++] = _minStepDistance;
|
||
_generalDataFloats[idx++] = _maxStepDistance;
|
||
_generalDataFloats[idx++] = _LODBias;
|
||
|
||
_generalDataFloats[idx++] = _cloudsSharpness;
|
||
_generalDataFloats[idx++] = (float)DirectionalLightsData.Count / 2;
|
||
_generalDataFloats[idx++] = (float)PointLightsData.Count / 2;
|
||
_generalDataFloats[idx++] = _cloudsAnisotropy;
|
||
|
||
_generalDataFloats[idx++] = _cloudFloor;
|
||
_generalDataFloats[idx++] = _cloudCeiling;
|
||
_generalDataFloats[idx++] = (float)_maxStepCount;
|
||
_generalDataFloats[idx++] = (float)_maxLightingSteps;
|
||
|
||
_generalDataFloats[idx++] = (float)_filterIndex;
|
||
_generalDataFloats[idx++] = (float)_blurPower;
|
||
_generalDataFloats[idx++] = (float)_blurQuality;
|
||
_generalDataFloats[idx++] = (float)_curlNoiseStrength;
|
||
|
||
_generalDataFloats[idx++] = WindDirection.X;
|
||
_generalDataFloats[idx++] = WindDirection.Z;
|
||
_generalDataFloats[idx++] = 0.0f;
|
||
_generalDataFloats[idx++] = 0.0f;
|
||
|
||
// Copy all floats to the byte buffer
|
||
Buffer.BlockCopy(_generalDataFloats, 0, _generalData, 0, _generalDataFloats.Length * 4);
|
||
|
||
_rd.BufferUpdate(_generalDataBuffer, 0, (uint)_generalData.Length, _generalData);
|
||
}
|
||
|
||
private void UpdateLights()
|
||
{
|
||
LightsUpdated = false;
|
||
|
||
if (DirectionalLightsData.Count == 0)
|
||
{
|
||
DirectionalLightsData.Add(new Vector4(0.5f, 1.0f, 0.5f, 16.0f));
|
||
DirectionalLightsData.Add(new Vector4(1.0f, 1.0f, 1.0f, 1.0f));
|
||
}
|
||
|
||
int idx = 0;
|
||
int directionalLightCount = Mathf.Min(DirectionalLightsData.Count, 8);
|
||
for (int i = 0; i < directionalLightCount; i++)
|
||
{
|
||
_lightDataFloats[idx++] = DirectionalLightsData[i].X;
|
||
_lightDataFloats[idx++] = DirectionalLightsData[i].Y;
|
||
_lightDataFloats[idx++] = DirectionalLightsData[i].Z;
|
||
_lightDataFloats[idx++] = DirectionalLightsData[i].W;
|
||
}
|
||
idx = 32;
|
||
int pointLightCount = Mathf.Min(PointLightsData.Count, 16);
|
||
for (int i = 0; i < pointLightCount; i++)
|
||
{
|
||
_lightDataFloats[idx++] = PointLightsData[i].X;
|
||
_lightDataFloats[idx++] = PointLightsData[i].Y;
|
||
_lightDataFloats[idx++] = PointLightsData[i].Z;
|
||
_lightDataFloats[idx++] = PointLightsData[i].W;
|
||
}
|
||
|
||
// Copy all floats to the byte buffer
|
||
Buffer.BlockCopy(_lightDataFloats, 0, _lightData, 0, _lightDataFloats.Length * 4);
|
||
|
||
_rd.BufferUpdate(_lightDataBuffer, 0, (uint)_lightData.Length, _lightData);
|
||
}
|
||
}
|