Puuh auf den letzten Metern machen mir die Shader echt zu schaffen :-(.
Es will nicht funktionieren sobald die Shared Texture mehr als zwei Slots hat. Allerdings finde ich den Fehler nicht und mich wundert dass es erst ab zwei Slots nicht mehr geht.
Leider sind Shader nicht meine Stärke, aber meiner amateurhaften Meinung nach müssten ComputeShader und Surface-Shader passen.
Mit
zwei Slots (16x32 für zwei 16x16 Texturen) sieht alles soweit OK aus.
Mit
vier Slots (16x64 für vier 16x16 Texturen) fängt er scheinbar an in der Textur ins Leere zu greifen, die Normalen sehen wie (0,0,0)-Vektoren aus.
Dabei ist meines Erachtens alles OK. Folgende Shared Texture Slots werden erzeugt. Sieht soweit alles OK aus, Scale-Faktor (Größenverhältnis eines Slots im Vergleich zur gesamten Textur), UVOffset bzw. PixelOffset haben gute Werte. Habt ihr irgendeine Idee was das Problem sein könnte? Ich habe den ComputeShader irgendwie im Verdacht, ich interpretiere die schwarzen Flächen so dass der ComputeShader nicht die korrekten Bereiche mit normalen belegt und dort deswegen noch (0,0,0)-vektoren sind.
SharedTextureManager::No free slot in existing textures in sharedTextureList found. Adding new SharedTexture.
SharedTexture::Initialized with constructor. Overall texture dimension=16x64. Slots=4
SpaceObjectProcedural::Received new shared texture. Slot=0, Scale+Offset=(1.0, 0.25, 0.0, 0.0), PixelOffset=(0.0, 0.0)
SpaceObjectProcedural::Received new shared texture. Slot=1, Scale+Offset=(1.0, 0.25, 0.0, 0.25), PixelOffset=(0.0, 16.0)
SpaceObjectProcedural::Received new shared texture. Slot=2, Scale+Offset=(1.0, 0.25, 0.0, 0.5), PixelOffset=(0.0, 32.0)
SpaceObjectProcedural::Received new shared texture. Slot=3, Scale+Offset=(1.0, 0.25, 0.0, 0.75), PixelOffset=(0.0, 48.0)
SharedTextureManager::No free slot in existing textures in sharedTextureList found. Adding new SharedTexture.
SharedTexture::Initialized with constructor. Overall texture dimension=16x64. Slots=4
SpaceObjectProcedural::Received new shared texture. Slot=0, Scale+Offset=(1.0, 0.25, 0.0, 0.0), PixelOffset=(0.0, 0.0)
SpaceObjectProcedural::Received new shared texture. Slot=1, Scale+Offset=(1.0, 0.25, 0.0, 0.25), PixelOffset=(0.0, 16.0)
SpaceObjectProcedural::Received new shared texture. Slot=2, Scale+Offset=(1.0, 0.25, 0.0, 0.5), PixelOffset=(0.0, 32.0)
SpaceObjectProcedural::Received new shared texture. Slot=3, Scale+Offset=(1.0, 0.25, 0.0, 0.75), PixelOffset=(0.0, 48.0)
SharedTextureManager::No free slot in existing textures in sharedTextureList found. Adding new SharedTexture.
SharedTexture::Initialized with constructor. Overall texture dimension=16x64. Slots=4
SpaceObjectProcedural::Received new shared texture. Slot=0, Scale+Offset=(1.0, 0.25, 0.0, 0.0), PixelOffset=(0.0, 0.0)
SpaceObjectProcedural::Received new shared texture. Slot=1, Scale+Offset=(1.0, 0.25, 0.0, 0.25), PixelOffset=(0.0, 16.0)
SpaceObjectProcedural::Received new shared texture. Slot=2, Scale+Offset=(1.0, 0.25, 0.0, 0.5), PixelOffset=(0.0, 32.0)
SpaceObjectProcedural::Received new shared texture. Slot=3, Scale+Offset=(1.0, 0.25, 0.0, 0.75), PixelOffset=(0.0, 48.0)
SharedTextureManager::No free slot in existing textures in sharedTextureList found. Adding new SharedTexture.
SharedTexture::Initialized with constructor. Overall texture dimension=16x64. Slots=4
SpaceObjectProcedural::Received new shared texture. Slot=0, Scale+Offset=(1.0, 0.25, 0.0, 0.0), PixelOffset=(0.0, 0.0)
SpaceObjectProcedural::Received new shared texture. Slot=1, Scale+Offset=(1.0, 0.25, 0.0, 0.25), PixelOffset=(0.0, 16.0)
SpaceObjectProcedural::Received new shared texture. Slot=2, Scale+Offset=(1.0, 0.25, 0.0, 0.5), PixelOffset=(0.0, 32.0)
SpaceObjectProcedural::Received new shared texture. Slot=3, Scale+Offset=(1.0, 0.25, 0.0, 0.75), PixelOffset=(0.0, 48.0)
SharedTextureManager::No free slot in existing textures in sharedTextureList found. Adding new SharedTexture.
SharedTexture::Initialized with constructor. Overall texture dimension=16x64. Slots=4
SpaceObjectProcedural::Received new shared texture. Slot=0, Scale+Offset=(1.0, 0.25, 0.0, 0.0), PixelOffset=(0.0, 0.0)
SpaceObjectProcedural::Received new shared texture. Slot=1, Scale+Offset=(1.0, 0.25, 0.0, 0.25), PixelOffset=(0.0, 16.0)
SpaceObjectProcedural::Received new shared texture. Slot=2, Scale+Offset=(1.0, 0.25, 0.0, 0.5), PixelOffset=(0.0, 32.0)
SpaceObjectProcedural::Received new shared texture. Slot=3, Scale+Offset=(1.0, 0.25, 0.0, 0.75), PixelOffset=(0.0, 48.0)
SharedTextureManager::No free slot in existing textures in sharedTextureList found. Adding new SharedTexture.
SharedTexture::Initialized with constructor. Overall texture dimension=16x64. Slots=4
SpaceObjectProcedural::Received new shared texture. Slot=0, Scale+Offset=(1.0, 0.25, 0.0, 0.0), PixelOffset=(0.0, 0.0)
SpaceObjectProcedural::Received new shared texture. Slot=1, Scale+Offset=(1.0, 0.25, 0.0, 0.25), PixelOffset=(0.0, 16.0)
SpaceObjectProcedural::Received new shared texture. Slot=2, Scale+Offset=(1.0, 0.25, 0.0, 0.5), PixelOffset=(0.0, 32.0)
SpaceObjectProcedural::Received new shared texture. Slot=3, Scale+Offset=(1.0, 0.25, 0.0, 0.75), PixelOffset=(0.0, 48.0)
SharedTextureManager::No free slot in existing textures in sharedTextureList found. Adding new SharedTexture.
SharedTexture::Initialized with constructor. Overall texture dimension=16x64. Slots=4
SpaceObjectProcedural::Received new shared texture. Slot=0, Scale+Offset=(1.0, 0.25, 0.0, 0.0), PixelOffset=(0.0, 0.0)
SpaceObjectProcedural::Received new shared texture. Slot=1, Scale+Offset=(1.0, 0.25, 0.0, 0.25), PixelOffset=(0.0, 16.0)
Der ComputeShader erhält die PixelOffset-Informationen über einen ComputeBuffer, individual pro Oberflächen-Plane. Diese werden zum Thread-Index (16x16x1 Dispatch) des ComputeShaders ergänzt, wenn die Normalen-Vektoren in die Textur geschrieben werden.
Code: Alles auswählen
RWTexture2D<float4> patchGeneratedNormalMapTexture;
// Do normal calculation and create NormalMap and SurfaceTexture
void CSMain2 (uint2 id : SV_DispatchThreadID)
{
// Get the constants
GenerationConstantsStruct constants = generationConstantsBuffer[0];
... calulcate normal....
// Prepare Texture ID
//uint2 textureID = uint2(id.y,id.x);
uint2 textureID = uint2(id.y+constants.sharedNormalMapTextureSlotPixelOffset.x,id.x+constants.sharedNormalMapTextureSlotPixelOffset.y);
// Create the ObjectSpace NormalMap
....
float3 normalRGB = normal.xyz /2;
patchGeneratedNormalMapTexture[textureID] = float4(normalRGB,1);
}
Der Surface Shader bekommt die Scale- und UVOffset-Information über ein uniform float4.
Zuweisung über Unity:
Code: Alles auswählen
quadtreeTerrain.material.SetVector("_NormalMapOffset", quadtreeTerrain.sharedNormalMapTextureSlot.Offset());
Im Shader über "fixed3 normal = tex2D(_NormalMap, IN.uv_NormalMap * _NormalMapOffset.xy + _NormalMapOffset.zw);"
Code: Alles auswählen
Shader "Custom/ProceduralPatch" {
Properties{
_MaterialTex("Albedo (RGB)", 2D) = "white" {}
_SurfaceMap("Albedo (RGB)", 2D) = "white" {}
_NormalMap("Albedo (RGB)", 2D) = "bump" {}
}
SubShader{
Tags{ "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
#include "UnityCG.cginc"
#pragma surface surf Standard fullforwardshadows
#pragma vertex vert
struct appdata_full_compute {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
float4 texcoord2 : TEXCOORD2;
float4 texcoord3 : TEXCOORD3;
#if defined(SHADER_API_XBOX360)
half4 texcoord4 : TEXCOORD4;
half4 texcoord5 : TEXCOORD5;
#endif
fixed4 color : COLOR;
#ifdef SHADER_API_D3D11
uint id: SV_VertexID;
#endif
};
struct OutputStruct {
float4 position;
float3 patchCenter;
};
float globalNoise;
#pragma target 5.0
sampler2D _MaterialTex;
sampler2D _SurfaceMap;
sampler2D _NormalMap;
#ifdef SHADER_API_D3D11
StructuredBuffer<OutputStruct> patchGeneratedFinalDataBuffer;
#endif
struct Input {
float2 uv_MaterialTex;
float2 uv_SurfaceMap;
float2 uv_NormalMap;
float3 worldPos;
float3 objPos;
};
uniform float4 _NormalMapOffset; // E.g. (1.0,0.25,0.0,0.5) for the third 64x64 texture slot in a 64x265 texture
void vert(inout appdata_full_compute v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input, o);
#ifdef SHADER_API_D3D11
// Read Data from buffer
float4 position = patchGeneratedFinalDataBuffer[v.id].position;
float3 patchCenter = patchGeneratedFinalDataBuffer[v.id].patchCenter;
// Perform changes to the data
// Translate the patch to its 'planet-space' center:
position.xyz += patchCenter;
// Apply data
v.vertex = float4(position);
o.uv_MaterialTex = v.texcoord.xy;
o.uv_SurfaceMap = v.texcoord.xy;
o.uv_NormalMap = v.texcoord.xy;
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.objPos = v.vertex;
#endif
}
void surf(Input IN, inout SurfaceOutputStandard o)
{
// Apply normalmap
fixed3 normal = tex2D(_NormalMap, IN.uv_NormalMap * _NormalMapOffset.xy + _NormalMapOffset.zw);
o.Normal = normal;
// Apply materialtexture
fixed3 crgb = tex2D(_MaterialTex, IN.uv_MaterialTex).rgb;
fixed4 c = fixed4(crgb, 1);
o.Albedo = c;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Mal schauen ich denke im Notfall werde ich nochmal den ComputeShader Code vereinfachen und nur einen Cube rendern, und mit den Shared Textures mal eine normale Farbtexturierung machen anstelle von normalen.
Dann kann man ggf. besser erkennen was genau passiert.