I wrote a volumetric fog shader that samples from a 3D texture, generated at runtime in a compute shader. In a Mac build, the 3D texture is seemingly not filled, even though in Editor Play Mode on a Mac it works perfectly fine – even though both presumably use Metal.
The texture is initialized here:
private void GenerateFogTexture() {
int worleyKernelHandle=fogComputeShader.FindKernel("CalcWorleyTexture3D");
RenderTexture worleyTexture=new RenderTexture(128,128,0,RenderTextureFormat.ARGB32); //powers of 2 <-- I actually assign only RGB, does that matter?
worleyTexture.dimension=UnityEngine.Rendering.TextureDimension.Tex3D;
worleyTexture.volumeDepth=32;
worleyTexture.enableRandomWrite=true;
worleyTexture.Create();
fogComputeShader.SetTexture(worleyKernelHandle,"worleyTexture",worleyTexture); //transfer data to GPU
fogComputeShader.Dispatch(worleyKernelHandle,128/8,128/8,32/2); //number of threads specified here times number in compute shader should match pixel count
worleyTexture.wrapMode=TextureWrapMode.Repeat;
noiseMaterial.SetTexture("_WorleyTex",worleyTexture);
int simplexKernelHandle=fogComputeShader.FindKernel("CalcSimplexTexture3D");
RenderTexture simplexTexture=new RenderTexture(48,48,0,RenderTextureFormat.R8); //multiples of 6
simplexTexture.dimension=UnityEngine.Rendering.TextureDimension.Tex3D;
simplexTexture.volumeDepth=48;
simplexTexture.enableRandomWrite=true;
simplexTexture.Create();
fogComputeShader.SetTexture(simplexKernelHandle,"simplexTexture",simplexTexture); //transfer data to GPU
fogComputeShader.Dispatch(simplexKernelHandle,48/4,48/4,48/4); //number of threads specified here times number in compute shader should match pixel count
simplexTexture.wrapMode=TextureWrapMode.Repeat;
noiseMaterial.SetTexture("_SimplexTex",simplexTexture);
} //GenerateFogTexture
And the compute shader is:
#pragma kernel CalcWorleyTexture3D
#pragma kernel CalcSimplexTexture3D
#include "Noise.cginc"
RWTexture3D<float3> worleyTexture; //rgb
RWTexture3D<float> simplexTexture; //single channel
[numthreads(8,8,2)]
void CalcWorleyTexture3D(uint3 id:SV_DispatchThreadID) {
worleyTexture[id.xyz]=float3(WorleyNoise3d(0.125*id.xyz,int3(16,16,4)),
WorleyNoise3d(0.25*id.xyz,int3(32,32,8)),
WorleyNoise3d(0.5*id.xyz,int3(64,64,16)));
} //CalcWorleyTexture3D
[numthreads(4,4,4)]
void CalcSimplexTexture3D(uint3 id:SV_DispatchThreadID) {
//simplexTexture[id.xyz]=SimplexNoise3dFbm(id.xyz);
simplexTexture[id.xyz]=PeriodicSimplexNoise3d(id.xyz);
} //CalcSimplexTexture3D
The texture is sampled in a shader (NoisyFog) through a sampler3D with tex3D. The Editor does produce a warning, but I cannot make sense of why:
Metal: Shader[CosmoDM/NoisyFog]: Incompatible texture type [MTLTextureType2D] of texture bound at index 0, expected [MTLTextureType3D]
Does anyone know what causes the error, or why it works in the editor but not in the build?