先在此感谢大家帮助了QWQ,3天方法试遍了,也没有解决
下面是一个IFFT海生成频谱部分的代码,出现问题的具体表现是 计算着色器中
OceanInput[id.xy] = highSpectrumTex;效果为纯黑
OceanInput[id.xy] = highSpectrumTex + float4(1,1,0,0);效果为纯黑
OceanInput[id.xy] = float4(1,1,0,0);效果正常为黄色,
将OffsetSpectrum内核的代码挪动到Start内核,并改成每一帧调用Start内核,显示正常
在OffsetSpectrum中首行添加HighSpectrumTex[id.xy] = float4(1,1,0,0),两个网格全部变为纯黄;
推测可能是缓存区在内核间共享出了问题
using UnityEngine;
using System.Collections.Generic;
public class Ocean : MonoBehaviour
{
//Debug
public List<int> KernelIDs = new List<int>();
public ComputeShader OceanCompute;
public int texSize = 256;
public int gridSize = 32;
public float OceanA = 10;
public float WindSP = 10;
public Vector2 Wind;
public float time;
public Renderer HighSpectrumRenderer;
public Renderer OffsetSpectrumRenderer;
private RenderTexture HighSpectrum;
private RenderTexture OffsetSpectrum;
private ComputeBuffer reBitBuffer;
void Start()
{
KernelIDs.Add(OceanCompute.FindKernel("Start"));
KernelIDs.Add(OceanCompute.FindKernel("OffsetSpectrum"));
InitializeReBitBuffer();
InitializeRenderTexture();
InitializeCompute();
StartComputShader();
}
private void Update()
{
time += Time.deltaTime;
SetComputeParameters();
UpdateComputShader();
}
void SetComputeParameters()
{
OceanCompute.SetFloat("OceanA", OceanA);
OceanCompute.SetVector("Wind", Wind);
OceanCompute.SetFloat("WindSP", WindSP);
OceanCompute.SetFloat("Time", time);
}
void InitializeCompute()
{
HighSpectrumRenderer.material.mainTexture = HighSpectrum;
OffsetSpectrumRenderer.material.mainTexture = OffsetSpectrum;
}
void InitializeReBitBuffer()
{
int[] reBitData = new int[texSize];
int Bitleng = (int)Mathf.Log(texSize, 2);
for (int i = 0; i < texSize; i++)
{
int Invindex = 0;
int k = i;
for (int j = 0; j < Bitleng; j++)
{
Invindex = (Invindex << 1) | (k & 1);
k >>= 1;
}
reBitData[i] = Invindex;
}
reBitBuffer = new ComputeBuffer(texSize, sizeof(int));
reBitBuffer.SetData(reBitData);
}
void InitializeRenderTexture()
{
HighSpectrum = new RenderTexture(texSize, texSize, 0, RenderTextureFormat.ARGB32)
{
enableRandomWrite = true,
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Point
};
HighSpectrum.Create();
OffsetSpectrum = new RenderTexture(texSize, texSize, 0, RenderTextureFormat.ARGB32)
{
enableRandomWrite = true,
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Point
};
OffsetSpectrum.Create();
}
void StartComputShader()
{
OceanCompute.SetFloat("TexSize", texSize);
OceanCompute.SetInt("GridSize", gridSize);
OceanCompute.SetTexture(KernelIDs[0], "HighSpectrumTex", HighSpectrum);
OceanCompute.Dispatch(KernelIDs[0], texSize / 8, texSize / 8, 1);
OceanCompute.SetTexture(KernelIDs[1], "HighSpectrumTex", HighSpectrum);
OceanCompute.SetTexture(KernelIDs[1], "OceanInput", OffsetSpectrum);
}
void UpdateComputShader()
{
OceanCompute.Dispatch(KernelIDs[1], texSize / 8, texSize / 8, 1);
}
void OnDestroy()
{
if (HighSpectrum != null)
{
if (HighSpectrum.IsCreated())
HighSpectrum.Release();
DestroyImmediate(HighSpectrum);
}
if (OffsetSpectrum != null)
{
if (OffsetSpectrum.IsCreated())
OffsetSpectrum.Release();
DestroyImmediate(OffsetSpectrum);
}
reBitBuffer?.Release();
}
}
#pragma kernel Start
#pragma kernel OffsetSpectrum
#define PI 3.14159265358979323846f
#define G 9.81
StructuredBuffer<int> ReBit;
int GridSize;
float TexSize;
float OceanA;
float2 Wind;
float WindSP;
float Time;
RWTexture2D<float4> HighSpectrumTex;
RWTexture2D<float4> OceanInput;
uint getHash(uint seed)
{
seed = (seed ^ 61) ^ (seed >> 16);
seed *= 9;
seed = seed ^ (seed >> 4);
seed *= 0x27d4eb2d;
seed = seed ^ (seed >> 15);
return seed;
}
float2 getRand(uint seed)
{
seed ^= (seed << 13);
seed ^= (seed >> 17);
seed ^= (seed << 5);
float rand1 = seed / 4294967296.0f;
seed ^= (seed << 13);
seed ^= (seed >> 17);
seed ^= (seed << 5);
float rand2 = seed / 4294967296.0f;
return float2(rand1, rand2);
}
float2 Gaussian(uint2 id)
{
uint seed = getHash(id.y * GridSize + id.x);
float2 randValues = getRand(seed);
float x1 = max(1e-6f, randValues.x);
float x2 = max(1e-6f, randValues.y);
float g1 = sqrt(-2.0f * log(x1)) * cos(2.0f * PI * x2);
float g2 = sqrt(-2.0f * log(x1)) * sin(2.0f * PI * x2);
return float2(g1, g2);
}
float Phillips(float2 k)
{
float norK = max(0.001f, length(k));
float norK2 = norK * norK;
float norK4 = norK2 * norK2;
float L = WindSP * WindSP / G;
float L2 = L * L;
float dwad = dot(k, normalize(Wind));
dwad *= WindSP;
float damping = 0.001f;
float La2 = L2 * damping * damping;
return OceanA * dwad * dwad * exp(-1.0f / (norK2 * L2)) / norK4 * exp(-norK2 * La2);
}
float2 HighSpectrum(int2 id)
{
float2 k = float2(2.0f * PI * id.x / TexSize - PI, 2.0f * PI * id.y / TexSize - PI);
float2 gaussian = Gaussian(id);
float phillips = Phillips(k);
return gaussian * sqrt(phillips * 0.5f);
}
[numthreads(8,8,1)]
void Start (uint3 id : SV_DispatchThreadID)
{
float2 posFreq = HighSpectrum((int2)id.xy);
float2 negFreq = HighSpectrum(-(int2)id.xy) * float2(1, -1);
HighSpectrumTex[id.xy] = float4(posFreq, negFreq);
}
[numthreads(8,8,1)]
void OffsetSpectrum (uint3 id : SV_DispatchThreadID)
{
float4 highSpectrumTex = HighSpectrumTex[id.xy];
float2 xy = highSpectrumTex.xy;
float2 zw = highSpectrumTex.zw;
float2 k = float2(2.0f * PI * id.x / TexSize - PI, 2.0f * PI * id.y / TexSize - PI);
float wt = sqrt(length(k) * G) * Time;
float cosWT = cos(wt);
float sinWT = sin(wt);
float2 a = float2(cosWT * xy.x - sinWT * xy.y, cosWT * xy.y + sinWT * xy.x);
float2 b = float2(cosWT * zw.x - sinWT * zw.y, cosWT * zw.y + sinWT * zw.x);
OceanInput[id.xy] = highSpectrumTex + float4(1,1,0,0);
}