Weiter gearbeitet
|
Before Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 257 KiB |
|
Before Width: | Height: | Size: 257 KiB |
|
Before Width: | Height: | Size: 257 KiB |
|
Before Width: | Height: | Size: 257 KiB |
|
Before Width: | Height: | Size: 257 KiB |
|
Before Width: | Height: | Size: 257 KiB |
|
Before Width: | Height: | Size: 257 KiB |
|
Before Width: | Height: | Size: 205 KiB |
|
Before Width: | Height: | Size: 257 KiB |
|
Before Width: | Height: | Size: 223 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 272 KiB |
|
Before Width: | Height: | Size: 262 KiB |
|
Before Width: | Height: | Size: 257 KiB |
|
Before Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 205 KiB |
|
Before Width: | Height: | Size: 205 KiB |
|
Before Width: | Height: | Size: 209 KiB |
|
Before Width: | Height: | Size: 205 KiB |
|
Before Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 506 KiB |
|
Before Width: | Height: | Size: 695 KiB |
|
Before Width: | Height: | Size: 535 KiB |
|
Before Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 252 KiB |
|
After Width: | Height: | Size: 247 KiB |
|
Before Width: | Height: | Size: 213 KiB |
|
Before Width: | Height: | Size: 211 KiB |
|
Before Width: | Height: | Size: 278 KiB |
|
Before Width: | Height: | Size: 206 KiB |
|
Before Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 277 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
@@ -3,8 +3,11 @@ MaterialDef Grass {
|
||||
MaterialParameters {
|
||||
Color Color (Color) : 1.0 1.0 1.0 1.0
|
||||
Texture2D ColorMap
|
||||
Texture2D NormalMap
|
||||
Float WindSpeed : 0.5
|
||||
Float WindStrength : 0.12
|
||||
Vector3 SunDir : 0.55 0.80 0.35
|
||||
Color SunColor : 1.0 1.0 0.95 1.0
|
||||
}
|
||||
|
||||
Technique {
|
||||
@@ -15,6 +18,7 @@ MaterialDef Grass {
|
||||
WorldViewProjectionMatrix
|
||||
WorldMatrix
|
||||
Time
|
||||
AmbientLightColor
|
||||
}
|
||||
|
||||
RenderState {
|
||||
@@ -23,6 +27,7 @@ MaterialDef Grass {
|
||||
|
||||
Defines {
|
||||
HAS_COLORMAP : ColorMap
|
||||
HAS_NORMALMAP : NormalMap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
40
blight-assets/src/main/resources/MatDefs/TerrainArray.j3md
Normal file
@@ -0,0 +1,40 @@
|
||||
MaterialDef TerrainArray {
|
||||
|
||||
MaterialParameters {
|
||||
TextureArray DiffuseArray
|
||||
FloatArray DiffuseScales
|
||||
TextureArray NormalArray
|
||||
Float Shininess : 32.0
|
||||
Vector3 LightDir
|
||||
Vector3 SunColor
|
||||
Vector3 AmbientColor
|
||||
Boolean DebugNoLight
|
||||
Boolean DebugSlot0Only
|
||||
Texture2D DebugDirectTex
|
||||
Texture2D AlphaMap
|
||||
Texture2D AlphaMap_1
|
||||
Texture2D AlphaMap_2
|
||||
}
|
||||
|
||||
Technique {
|
||||
VertexShader GLSL150 : Shaders/TerrainArray.vert
|
||||
FragmentShader GLSL150 : Shaders/TerrainArray.frag
|
||||
|
||||
WorldParameters {
|
||||
WorldViewProjectionMatrix
|
||||
WorldMatrix
|
||||
ViewProjectionMatrix
|
||||
}
|
||||
|
||||
Defines {
|
||||
HAS_NORMAL_ARRAY : NormalArray
|
||||
HAS_ALPHA_1 : AlphaMap_1
|
||||
HAS_ALPHA_2 : AlphaMap_2
|
||||
HAS_LIGHTDIR : LightDir
|
||||
HAS_SCENE_LIGHT : SunColor
|
||||
DEBUG_NO_LIGHT : DebugNoLight
|
||||
DEBUG_SLOT0_ONLY : DebugSlot0Only
|
||||
DEBUG_DIRECT_TEX : DebugDirectTex
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@ MaterialDef Tree {
|
||||
Float WindSpeed : 0.5
|
||||
Texture2D BarkMap
|
||||
Boolean HasBarkMap : false
|
||||
Vector3 LightDir
|
||||
Vector3 SunColor
|
||||
Vector3 AmbientColor
|
||||
}
|
||||
|
||||
Technique {
|
||||
@@ -17,5 +20,9 @@ MaterialDef Tree {
|
||||
WorldMatrix
|
||||
Time
|
||||
}
|
||||
|
||||
Defines {
|
||||
HAS_SCENE_LIGHT : SunColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ MaterialDef TreeLeaf {
|
||||
Matrix4 LightViewProjectionMatrix5
|
||||
Vector3 LightPos
|
||||
Vector3 LightDir
|
||||
Vector3 SunColor
|
||||
Vector3 AmbientColor
|
||||
Float PCFEdge
|
||||
Float ShadowMapSize
|
||||
Boolean BackfaceShadows : false
|
||||
@@ -46,6 +48,10 @@ MaterialDef TreeLeaf {
|
||||
RenderState {
|
||||
FaceCull Off
|
||||
}
|
||||
|
||||
Defines {
|
||||
HAS_SCENE_LIGHT : SunColor
|
||||
}
|
||||
}
|
||||
|
||||
Technique PostShadow {
|
||||
|
||||
@@ -1,21 +1,71 @@
|
||||
MaterialDef Voxel {
|
||||
|
||||
MaterialParameters {
|
||||
Texture2D Tex0
|
||||
Texture2D Tex1
|
||||
Texture2D Tex2
|
||||
Texture2D Tex3
|
||||
Float TexScale : 4.0
|
||||
Texture2D TexFlat
|
||||
Texture2D TexSteep
|
||||
Texture2D TexCeil
|
||||
Texture2D NormalMapFlat
|
||||
Texture2D NormalMapSteep
|
||||
Texture2D NormalMapCeil
|
||||
Texture2D DisplacementMapFlat
|
||||
Texture2D DisplacementMapSteep
|
||||
Texture2D DisplacementMapCeil
|
||||
Float TexScale : 8.0
|
||||
Float DisplacementScale : 0.3
|
||||
Float TessellationLevel : 4.0
|
||||
Vector3 LightDir
|
||||
Vector3 SunColor
|
||||
Vector3 AmbientColor
|
||||
Boolean DebugNoLight
|
||||
}
|
||||
|
||||
Technique {
|
||||
|
||||
VertexShader GLSL150 : Shaders/Voxel.vert
|
||||
FragmentShader GLSL150 : Shaders/Voxel.frag
|
||||
|
||||
WorldParameters {
|
||||
WorldViewProjectionMatrix
|
||||
WorldMatrix
|
||||
NormalMatrix
|
||||
}
|
||||
|
||||
Defines {
|
||||
HAS_NM_FLAT : NormalMapFlat
|
||||
HAS_NM_STEEP : NormalMapSteep
|
||||
HAS_NM_CEIL : NormalMapCeil
|
||||
HAS_LIGHTDIR : LightDir
|
||||
HAS_SCENE_LIGHT : SunColor
|
||||
DEBUG_NO_LIGHT : DebugNoLight
|
||||
}
|
||||
|
||||
RenderState {
|
||||
FaceCull Off
|
||||
}
|
||||
}
|
||||
|
||||
Technique Tessellation {
|
||||
|
||||
VertexShader GLSL400 : Shaders/VoxelTess.vert
|
||||
TessellationControlShader GLSL400 : Shaders/Voxel.tsctrl
|
||||
TessellationEvaluationShader GLSL400 : Shaders/Voxel.tseval
|
||||
FragmentShader GLSL400 : Shaders/Voxel.frag
|
||||
|
||||
WorldParameters {
|
||||
WorldViewProjectionMatrix
|
||||
WorldMatrix
|
||||
ViewProjectionMatrix
|
||||
CameraPosition
|
||||
}
|
||||
|
||||
Defines {
|
||||
HAS_NM_FLAT : NormalMapFlat
|
||||
HAS_NM_STEEP : NormalMapSteep
|
||||
HAS_NM_CEIL : NormalMapCeil
|
||||
HAS_DISP_FLAT : DisplacementMapFlat
|
||||
HAS_DISP_STEEP : DisplacementMapSteep
|
||||
HAS_DISP_CEIL : DisplacementMapCeil
|
||||
HAS_LIGHTDIR : LightDir
|
||||
HAS_SCENE_LIGHT : SunColor
|
||||
}
|
||||
|
||||
RenderState {
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# Blender 4.0.2 MTL File: 'Campfire.blend'
|
||||
# www.blender.org
|
||||
|
||||
newmtl Campfire_MAT
|
||||
Ka 0.500000 0.500000 0.500000
|
||||
Ks 0.222727 0.222727 0.222727
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.450000
|
||||
d 1.000000
|
||||
illum 3
|
||||
map_Kd Campfire_MAT_BaseColor_01.jpg
|
||||
map_Ns Campfire_MAT_Roughness.jpg
|
||||
map_refl Campfire_MAT_Metallic.jpg
|
||||
map_Bump -bm 1.000000 Campfire_MAT_Normal_JL.jpg
|
||||
|
||||
newmtl Campfire_fire_MAT
|
||||
Ns 1000.000000
|
||||
Ka 0.500000 0.500000 0.500000
|
||||
Ks 1.000000 1.000000 1.000000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.450000
|
||||
illum 3
|
||||
map_Kd Campfire_fire_MAT_BaseColor_Alpha.png
|
||||
map_d Campfire_fire_MAT_BaseColor_Alpha.png
|
||||
@@ -1,15 +0,0 @@
|
||||
#Mon Jun 08 11:09:04 CEST 2026
|
||||
castShadow=true
|
||||
category=
|
||||
name=FernPlantV2
|
||||
pivotOffsetY=0.0
|
||||
placementOffsetY=0.0
|
||||
randomScaleMax=1.0
|
||||
randomScaleMin=1.0
|
||||
receiveShadow=true
|
||||
scaleX=0.002
|
||||
scaleY=0.002
|
||||
scaleZ=0.002
|
||||
solid=false
|
||||
tags=
|
||||
uniformScale=true
|
||||
@@ -1 +0,0 @@
|
||||
{"IDLE":"stand_up"}
|
||||
@@ -1,20 +0,0 @@
|
||||
#Tue Jun 09 21:42:20 CEST 2026
|
||||
castShadow=true
|
||||
category=
|
||||
cullDistance=120.0
|
||||
lod1Distance=30.0
|
||||
lod1Path=
|
||||
lod2Distance=80.0
|
||||
lod2Path=
|
||||
name=manatrank
|
||||
pivotOffsetY=0.0
|
||||
placementOffsetY=0.0
|
||||
randomScaleMax=1.0
|
||||
randomScaleMin=1.0
|
||||
receiveShadow=true
|
||||
scaleX=0.2
|
||||
scaleY=0.2
|
||||
scaleZ=0.2
|
||||
solid=false
|
||||
tags=
|
||||
uniformScale=true
|
||||
@@ -1,10 +1,20 @@
|
||||
uniform vec4 m_Color;
|
||||
uniform vec3 m_SunDir;
|
||||
uniform vec4 m_SunColor;
|
||||
uniform vec4 g_AmbientLightColor;
|
||||
|
||||
#ifdef HAS_COLORMAP
|
||||
uniform sampler2D m_ColorMap;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_NORMALMAP
|
||||
uniform sampler2D m_NormalMap;
|
||||
in vec3 wTangent;
|
||||
in vec3 wBitangent;
|
||||
#endif
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec3 wNormal;
|
||||
out vec4 outFragColor;
|
||||
|
||||
void main() {
|
||||
@@ -12,7 +22,20 @@ void main() {
|
||||
#ifdef HAS_COLORMAP
|
||||
color *= texture(m_ColorMap, texCoord);
|
||||
#endif
|
||||
// Alpha-Discard: transparente Pixel sofort verwerfen, Z-Buffer bleibt sauber
|
||||
if (color.a < 0.5) discard;
|
||||
|
||||
vec3 n = normalize(wNormal);
|
||||
|
||||
#ifdef HAS_NORMALMAP
|
||||
vec3 nm = texture(m_NormalMap, texCoord).rgb * 2.0 - 1.0;
|
||||
mat3 tbn = mat3(normalize(wTangent), normalize(wBitangent), n);
|
||||
n = normalize(tbn * nm);
|
||||
#endif
|
||||
|
||||
// Beleuchtung: Sonne (two-sided via abs für Grashalme) + Ambient
|
||||
float diffuse = abs(dot(n, normalize(m_SunDir)));
|
||||
vec3 lit = g_AmbientLightColor.rgb + m_SunColor.rgb * diffuse;
|
||||
color.rgb *= lit;
|
||||
|
||||
outFragColor = color;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,16 @@ uniform float m_WindStrength;
|
||||
|
||||
in vec3 inPosition;
|
||||
in vec2 inTexCoord;
|
||||
in vec3 inNormal;
|
||||
in vec4 inTangent;
|
||||
|
||||
out vec2 texCoord;
|
||||
out vec3 wNormal;
|
||||
|
||||
#ifdef HAS_NORMALMAP
|
||||
out vec3 wTangent;
|
||||
out vec3 wBitangent;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec4 pos = vec4(inPosition, 1.0);
|
||||
@@ -29,5 +37,14 @@ void main() {
|
||||
}
|
||||
|
||||
texCoord = inTexCoord;
|
||||
|
||||
mat3 rot = mat3(g_WorldMatrix);
|
||||
wNormal = normalize(rot * inNormal);
|
||||
|
||||
#ifdef HAS_NORMALMAP
|
||||
wTangent = normalize(rot * inTangent.xyz);
|
||||
wBitangent = cross(wNormal, wTangent) * inTangent.w;
|
||||
#endif
|
||||
|
||||
gl_Position = g_WorldViewProjectionMatrix * pos;
|
||||
}
|
||||
|
||||
133
blight-assets/src/main/resources/Shaders/TerrainArray.frag
Normal file
@@ -0,0 +1,133 @@
|
||||
uniform sampler2DArray m_DiffuseArray;
|
||||
#ifdef DEBUG_DIRECT_TEX
|
||||
uniform sampler2D m_DebugDirectTex;
|
||||
#endif
|
||||
uniform float m_DiffuseScales[12];
|
||||
uniform sampler2D m_AlphaMap;
|
||||
|
||||
#ifdef HAS_ALPHA_1
|
||||
uniform sampler2D m_AlphaMap_1;
|
||||
#endif
|
||||
#ifdef HAS_ALPHA_2
|
||||
uniform sampler2D m_AlphaMap_2;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_NORMAL_ARRAY
|
||||
uniform sampler2DArray m_NormalArray;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LIGHTDIR
|
||||
uniform vec3 m_LightDir;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SCENE_LIGHT
|
||||
uniform vec3 m_SunColor;
|
||||
uniform vec3 m_AmbientColor;
|
||||
#endif
|
||||
|
||||
in vec2 vSplatUV;
|
||||
in vec3 vWorldPos;
|
||||
in vec3 vNormal;
|
||||
in vec4 vTangent;
|
||||
|
||||
out vec4 outColor;
|
||||
|
||||
void main() {
|
||||
vec4 a0 = texture(m_AlphaMap, vSplatUV);
|
||||
vec4 a1 = vec4(0.0);
|
||||
vec4 a2 = vec4(0.0);
|
||||
#ifdef HAS_ALPHA_1
|
||||
a1 = texture(m_AlphaMap_1, vSplatUV);
|
||||
#endif
|
||||
#ifdef HAS_ALPHA_2
|
||||
a2 = texture(m_AlphaMap_2, vSplatUV);
|
||||
#endif
|
||||
|
||||
// Slot-Mapping:
|
||||
// Array[0] = Editor-Slot 1 (Basis, immer sichtbar — a0.r ist hardcoded 1.0)
|
||||
// Array[1] = Editor-Slot 2, alpha = a0.g
|
||||
// Array[2] = Editor-Slot 3, alpha = a0.b
|
||||
// Array[3] = Editor-Slot 4, alpha = a0.a
|
||||
// Array[4] = Editor-Slot 5, alpha = a1.r
|
||||
// Array[5] = Editor-Slot 6, alpha = a1.g
|
||||
// Array[6] = Editor-Slot 7, alpha = a1.b
|
||||
// Array[7] = Editor-Slot 8, alpha = a1.a
|
||||
// Array[8] = Editor-Slot 9, alpha = a2.r
|
||||
// Array[9] = Editor-Slot 10, alpha = a2.g
|
||||
// Array[10] = Editor-Slot 11, alpha = a2.b
|
||||
// Array[11] = Editor-Slot 12, alpha = a2.a
|
||||
//
|
||||
// Blending: sequential mix — jeder Overlay ersetzt den Basis-Layer schrittweise.
|
||||
// a0.r (Slot 1) wird vom Painting-Tool immer auf 1.0 gesetzt und dient nur als
|
||||
// "Basis ist belegt"-Marker; er ist kein echter Alpha-Wert.
|
||||
|
||||
float overlays[11] = float[](a0.g, a0.b, a0.a,
|
||||
a1.r, a1.g, a1.b, a1.a,
|
||||
a2.r, a2.g, a2.b, a2.a);
|
||||
|
||||
#ifdef DEBUG_DIRECT_TEX
|
||||
vec4 directCol = texture(m_DebugDirectTex, vWorldPos.xz / m_DiffuseScales[0]);
|
||||
outColor = vec4(directCol.rgb, directCol.a);
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Basis (Slot 1)
|
||||
vec4 col = texture(m_DiffuseArray, vec3(vWorldPos.xz / m_DiffuseScales[0], 0.0));
|
||||
|
||||
#ifdef DEBUG_SLOT0_ONLY
|
||||
// Debug: nur Slot 0 anzeigen, keine Alpha-Blending-Schleife
|
||||
outColor = vec4(col.rgb, col.a);
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Overlays (Slots 2-12) sequentiell darüber mischen
|
||||
for (int i = 0; i < 11; i++) {
|
||||
if (overlays[i] > 0.001) {
|
||||
vec2 uv = vWorldPos.xz / m_DiffuseScales[i + 1];
|
||||
col = mix(col, texture(m_DiffuseArray, vec3(uv, float(i + 1))), overlays[i]);
|
||||
}
|
||||
}
|
||||
|
||||
vec3 N = normalize(vNormal);
|
||||
|
||||
#ifdef HAS_NORMAL_ARRAY
|
||||
vec3 T = normalize(vTangent.xyz);
|
||||
vec3 B = cross(N, T) * vTangent.w;
|
||||
mat3 TBN = mat3(T, B, N);
|
||||
|
||||
// Normal-Map Basis (Slot 1)
|
||||
vec2 uv0 = vWorldPos.xz / m_DiffuseScales[0];
|
||||
vec3 nm0 = texture(m_NormalArray, vec3(uv0, 0.0)).rgb * 2.0 - 1.0;
|
||||
vec3 pertN = TBN * nm0;
|
||||
|
||||
// Normal-Maps Overlays (Slots 2-12) sequentiell mischen
|
||||
for (int i = 0; i < 11; i++) {
|
||||
if (overlays[i] > 0.001) {
|
||||
vec2 uv = vWorldPos.xz / m_DiffuseScales[i + 1];
|
||||
vec3 nm = texture(m_NormalArray, vec3(uv, float(i + 1))).rgb * 2.0 - 1.0;
|
||||
pertN = mix(pertN, TBN * nm, overlays[i]);
|
||||
}
|
||||
}
|
||||
N = normalize(pertN);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LIGHTDIR
|
||||
vec3 lightDir = normalize(m_LightDir);
|
||||
#else
|
||||
vec3 lightDir = normalize(vec3(0.6, 1.0, 0.4));
|
||||
#endif
|
||||
float diff = max(dot(N, lightDir), 0.0);
|
||||
|
||||
#ifdef HAS_SCENE_LIGHT
|
||||
vec3 light = m_AmbientColor + m_SunColor * diff;
|
||||
#else
|
||||
vec3 light = vec3(diff * 0.65 + 0.35);
|
||||
#endif
|
||||
|
||||
const float BRIGHTNESS = 0.80;
|
||||
#ifdef DEBUG_NO_LIGHT
|
||||
outColor = vec4(col.rgb * BRIGHTNESS, col.a);
|
||||
#else
|
||||
outColor = vec4(col.rgb * light * BRIGHTNESS, col.a);
|
||||
#endif
|
||||
}
|
||||
27
blight-assets/src/main/resources/Shaders/TerrainArray.vert
Normal file
@@ -0,0 +1,27 @@
|
||||
uniform mat4 g_WorldViewProjectionMatrix;
|
||||
uniform mat4 g_WorldMatrix;
|
||||
uniform mat4 g_ViewProjectionMatrix;
|
||||
|
||||
in vec3 inPosition;
|
||||
in vec3 inNormal;
|
||||
in vec2 inTexCoord;
|
||||
in vec4 inTangent;
|
||||
|
||||
out vec2 vSplatUV;
|
||||
out vec3 vWorldPos;
|
||||
out vec3 vNormal;
|
||||
out vec4 vTangent;
|
||||
|
||||
void main() {
|
||||
vec4 worldPos4 = g_WorldMatrix * vec4(inPosition, 1.0);
|
||||
mat3 worldMat3 = mat3(g_WorldMatrix);
|
||||
vec3 worldPos = worldPos4.xyz;
|
||||
vec3 worldNorm = normalize(worldMat3 * inNormal);
|
||||
|
||||
vSplatUV = inTexCoord;
|
||||
vWorldPos = worldPos;
|
||||
vNormal = worldNorm;
|
||||
vTangent = vec4(normalize(worldMat3 * inTangent.xyz), inTangent.w);
|
||||
|
||||
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
|
||||
}
|
||||
@@ -4,26 +4,35 @@ uniform vec4 m_Diffuse;
|
||||
uniform sampler2D m_BarkMap;
|
||||
uniform bool m_HasBarkMap;
|
||||
|
||||
#ifdef HAS_SCENE_LIGHT
|
||||
uniform vec3 m_LightDir;
|
||||
uniform vec3 m_SunColor;
|
||||
uniform vec3 m_AmbientColor;
|
||||
#endif
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec3 worldNormal;
|
||||
|
||||
void main() {
|
||||
vec3 n = normalize(worldNormal);
|
||||
|
||||
// Sun at ~45° elevation from SE — good contrast on vertical cylinders
|
||||
vec3 sunDir = normalize(vec3(0.6, 0.7, 0.4));
|
||||
vec3 fillDir = normalize(vec3(-0.5, 0.3, -0.4));
|
||||
vec3 rimDir = normalize(vec3(-0.3, 0.5, 0.7));
|
||||
|
||||
float sun = max(dot(n, sunDir), 0.0);
|
||||
float fill = max(dot(n, fillDir), 0.0) * 0.22;
|
||||
float rim = max(dot(n, rimDir), 0.0) * 0.14;
|
||||
float sky = dot(n, vec3(0.0, 1.0, 0.0)) * 0.4 + 0.4; // [0.0, 0.8]
|
||||
float light = sun * 0.75 + fill + rim + sky * 0.09 + 0.05;
|
||||
|
||||
vec3 baseColor = m_HasBarkMap
|
||||
? texture2D(m_BarkMap, texCoord).rgb * m_Diffuse.rgb
|
||||
: m_Diffuse.rgb;
|
||||
|
||||
gl_FragColor = vec4(baseColor * clamp(light, 0.0, 1.0), m_Diffuse.a);
|
||||
#ifdef HAS_SCENE_LIGHT
|
||||
float diff = max(dot(n, normalize(m_LightDir)), 0.0);
|
||||
vec3 light = clamp(m_AmbientColor + m_SunColor * diff, 0.0, 1.0);
|
||||
#else
|
||||
vec3 sunDir = normalize(vec3(0.6, 0.7, 0.4));
|
||||
vec3 fillDir = normalize(vec3(-0.5, 0.3, -0.4));
|
||||
vec3 rimDir = normalize(vec3(-0.3, 0.5, 0.7));
|
||||
float sun = max(dot(n, sunDir), 0.0);
|
||||
float fill = max(dot(n, fillDir), 0.0) * 0.22;
|
||||
float rim = max(dot(n, rimDir), 0.0) * 0.14;
|
||||
float sky = dot(n, vec3(0.0, 1.0, 0.0)) * 0.4 + 0.4;
|
||||
vec3 light = vec3(clamp(sun * 0.75 + fill + rim + sky * 0.09 + 0.05, 0.0, 1.0));
|
||||
#endif
|
||||
|
||||
gl_FragColor = vec4(baseColor * light, m_Diffuse.a);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,12 @@ uniform vec4 m_Diffuse;
|
||||
uniform sampler2D m_LeafMap;
|
||||
uniform bool m_HasLeafMap;
|
||||
|
||||
#ifdef HAS_SCENE_LIGHT
|
||||
uniform vec3 m_LightDir;
|
||||
uniform vec3 m_SunColor;
|
||||
uniform vec3 m_AmbientColor;
|
||||
#endif
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec3 worldNormal;
|
||||
|
||||
@@ -15,13 +21,18 @@ void main() {
|
||||
if (tex.a < 0.5) discard;
|
||||
baseColor = tex.rgb * m_Diffuse.rgb;
|
||||
} else {
|
||||
// Fallback: kreisförmiger Clip
|
||||
vec2 uv = texCoord * 2.0 - 1.0;
|
||||
if (dot(uv, uv) > 0.95) discard;
|
||||
float edge = 1.0 - dot(uv, uv);
|
||||
baseColor = m_Diffuse.rgb * (0.7 + 0.3 * edge);
|
||||
}
|
||||
|
||||
// Leaves transmit light — no directional shading, uniform brightness
|
||||
gl_FragColor = vec4(baseColor, 1.0);
|
||||
#ifdef HAS_SCENE_LIGHT
|
||||
// Blätter transmittieren Licht — abs() für doppelseitige Beleuchtung
|
||||
float diff = abs(dot(normalize(worldNormal), normalize(m_LightDir)));
|
||||
vec3 light = clamp(m_AmbientColor + m_SunColor * diff * 0.6, 0.0, 1.0);
|
||||
gl_FragColor = vec4(baseColor * light, 1.0);
|
||||
#else
|
||||
gl_FragColor = vec4(baseColor * 0.8, 1.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,54 +1,125 @@
|
||||
uniform sampler2D m_Tex0;
|
||||
uniform sampler2D m_Tex1;
|
||||
uniform sampler2D m_Tex2;
|
||||
uniform sampler2D m_Tex3;
|
||||
uniform sampler2D m_TexFlat;
|
||||
uniform sampler2D m_TexSteep;
|
||||
uniform sampler2D m_TexCeil;
|
||||
uniform float m_TexScale;
|
||||
|
||||
#ifdef HAS_NM_FLAT
|
||||
uniform sampler2D m_NormalMapFlat;
|
||||
#endif
|
||||
#ifdef HAS_NM_STEEP
|
||||
uniform sampler2D m_NormalMapSteep;
|
||||
#endif
|
||||
#ifdef HAS_NM_CEIL
|
||||
uniform sampler2D m_NormalMapCeil;
|
||||
#endif
|
||||
|
||||
in vec3 vWorldPos;
|
||||
in vec3 vNormal;
|
||||
in vec4 vMatWeights;
|
||||
|
||||
out vec4 outColor;
|
||||
|
||||
#ifdef HAS_LIGHTDIR
|
||||
uniform vec3 m_LightDir;
|
||||
#endif
|
||||
#ifdef HAS_SCENE_LIGHT
|
||||
uniform vec3 m_SunColor;
|
||||
uniform vec3 m_AmbientColor;
|
||||
#endif
|
||||
|
||||
vec4 triplanar(sampler2D tex, vec2 uvX, vec2 uvY, vec2 uvZ, vec3 bw) {
|
||||
return texture(tex, uvX) * bw.x
|
||||
+ texture(tex, uvY) * bw.y
|
||||
+ texture(tex, uvZ) * bw.z;
|
||||
}
|
||||
|
||||
// Triplanare Normal-Map-Mischung (Whiteout-Blending, world-space Ausgabe).
|
||||
// N = geometrische Weltoberflächen-Normale, bw = triplanare Gewichte.
|
||||
vec3 triplanarNormal(sampler2D nmap, vec2 uvX, vec2 uvY, vec2 uvZ, vec3 bw, vec3 N) {
|
||||
vec3 tnX = texture(nmap, uvX).rgb * 2.0 - 1.0;
|
||||
vec3 tnY = texture(nmap, uvY).rgb * 2.0 - 1.0;
|
||||
vec3 tnZ = texture(nmap, uvZ).rgb * 2.0 - 1.0;
|
||||
|
||||
// Reorientiertes Normal-Mapping (RNM / Whiteout): Tangent → World
|
||||
tnX = vec3(tnX.xy + N.zy, abs(tnX.z) * N.x);
|
||||
tnY = vec3(tnY.xy + N.xz, abs(tnY.z) * N.y);
|
||||
tnZ = vec3(tnZ.xy + N.xy, abs(tnZ.z) * N.z);
|
||||
|
||||
return normalize(tnX.zyx * bw.x + tnY.xzy * bw.y + tnZ.xyz * bw.z);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 blendWeights = abs(vNormal);
|
||||
blendWeights = max(blendWeights - 0.2, 0.0);
|
||||
blendWeights /= (blendWeights.x + blendWeights.y + blendWeights.z + 0.001);
|
||||
vec3 bw = pow(abs(vNormal), vec3(4.0));
|
||||
bw /= (bw.x + bw.y + bw.z + 0.001);
|
||||
|
||||
vec2 uvX = vWorldPos.yz / m_TexScale;
|
||||
vec2 uvY = vWorldPos.xz / m_TexScale;
|
||||
vec2 uvZ = vWorldPos.xy / m_TexScale;
|
||||
|
||||
vec4 col = vec4(0.0);
|
||||
// Flach ab ~11° Gefälle (20% grade, normal.y≈0.98); Fels darunter.
|
||||
float flatBlend = smoothstep(0.94, 0.99, vNormal.y);
|
||||
float ceilBlend = 1.0 - smoothstep(-0.6, -0.3, vNormal.y);
|
||||
float steepBlend = max(0.0, 1.0 - flatBlend - ceilBlend);
|
||||
|
||||
float w0 = vMatWeights.r;
|
||||
if (w0 > 0.001) {
|
||||
col += w0 * (texture(m_Tex0, uvX) * blendWeights.x
|
||||
+ texture(m_Tex0, uvY) * blendWeights.y
|
||||
+ texture(m_Tex0, uvZ) * blendWeights.z);
|
||||
}
|
||||
float w1 = vMatWeights.g;
|
||||
if (w1 > 0.001) {
|
||||
col += w1 * (texture(m_Tex1, uvX) * blendWeights.x
|
||||
+ texture(m_Tex1, uvY) * blendWeights.y
|
||||
+ texture(m_Tex1, uvZ) * blendWeights.z);
|
||||
}
|
||||
float w2 = vMatWeights.b;
|
||||
if (w2 > 0.001) {
|
||||
col += w2 * (texture(m_Tex2, uvX) * blendWeights.x
|
||||
+ texture(m_Tex2, uvY) * blendWeights.y
|
||||
+ texture(m_Tex2, uvZ) * blendWeights.z);
|
||||
}
|
||||
float w3 = vMatWeights.a;
|
||||
if (w3 > 0.001) {
|
||||
col += w3 * (texture(m_Tex3, uvX) * blendWeights.x
|
||||
+ texture(m_Tex3, uvY) * blendWeights.y
|
||||
+ texture(m_Tex3, uvZ) * blendWeights.z);
|
||||
}
|
||||
// Flat: reines XZ-UV wie das Terrain (uvY = worldPos.xz / texScale), kein Triplanar.
|
||||
// Steep/Ceil: Triplanar bleibt, da es dort keine eindeutige Projektion gibt.
|
||||
vec4 col = texture(m_TexFlat, uvY) * flatBlend
|
||||
+ triplanar(m_TexSteep, uvX, uvY, uvZ, bw) * steepBlend
|
||||
+ triplanar(m_TexCeil, uvX, uvY, uvZ, bw) * ceilBlend;
|
||||
|
||||
vec3 lightDir = normalize(vec3(0.5, 1.0, 0.3));
|
||||
float diff = max(dot(vNormal, lightDir), 0.0) * 0.7 + 0.3;
|
||||
// Geometrie-Normale für Beleuchtung, ggf. durch Normal-Map ersetzt.
|
||||
vec3 N = normalize(vNormal);
|
||||
|
||||
outColor = vec4(col.rgb * diff, col.a);
|
||||
#if defined(HAS_NM_FLAT) || defined(HAS_NM_STEEP) || defined(HAS_NM_CEIL)
|
||||
vec3 pertN = vec3(0.0);
|
||||
float totalBlend = 0.0;
|
||||
#ifdef HAS_NM_FLAT
|
||||
if (flatBlend > 0.001) {
|
||||
vec3 nmFlat = texture(m_NormalMapFlat, uvY).rgb * 2.0 - 1.0;
|
||||
// Y-Projektion RNM (identisch mit triplanarNormal Y-Achse bei bw.y=1)
|
||||
nmFlat = vec3(nmFlat.xy + N.xz, abs(nmFlat.z) * N.y);
|
||||
pertN += normalize(nmFlat.xzy) * flatBlend;
|
||||
totalBlend += flatBlend;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_NM_STEEP
|
||||
if (steepBlend > 0.001) {
|
||||
pertN += triplanarNormal(m_NormalMapSteep, uvX, uvY, uvZ, bw, N) * steepBlend;
|
||||
totalBlend += steepBlend;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_NM_CEIL
|
||||
if (ceilBlend > 0.001) {
|
||||
pertN += triplanarNormal(m_NormalMapCeil, uvX, uvY, uvZ, bw, N) * ceilBlend;
|
||||
totalBlend += ceilBlend;
|
||||
}
|
||||
#endif
|
||||
if (totalBlend > 0.001) {
|
||||
N = normalize(pertN / totalBlend);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Flache Voxel-Flächen Richtung (0,1,0) korrigieren, um Abweichungen der
|
||||
// Marching-Cubes-Normalen auszugleichen und das Terrain-Lighting zu matchen.
|
||||
N = normalize(mix(N, vec3(0.0, 1.0, 0.0), flatBlend));
|
||||
|
||||
#ifdef HAS_LIGHTDIR
|
||||
vec3 lightDir = normalize(m_LightDir);
|
||||
#else
|
||||
vec3 lightDir = normalize(vec3(0.6, 1.0, 0.4));
|
||||
#endif
|
||||
float diff = max(dot(N, lightDir), 0.0);
|
||||
|
||||
#ifdef HAS_SCENE_LIGHT
|
||||
vec3 light = m_AmbientColor + m_SunColor * diff;
|
||||
#else
|
||||
vec3 light = vec3(diff * 0.65 + 0.35);
|
||||
#endif
|
||||
|
||||
const float BRIGHTNESS = 0.80;
|
||||
#ifdef DEBUG_NO_LIGHT
|
||||
outColor = vec4(col.rgb * BRIGHTNESS, col.a);
|
||||
#else
|
||||
outColor = vec4(col.rgb * light * BRIGHTNESS, col.a);
|
||||
#endif
|
||||
if (outColor.a < 0.1) discard;
|
||||
}
|
||||
|
||||
29
blight-assets/src/main/resources/Shaders/Voxel.tsctrl
Normal file
@@ -0,0 +1,29 @@
|
||||
layout(vertices = 3) out;
|
||||
|
||||
in vec3 vWorldPos[];
|
||||
in vec3 vNormal[];
|
||||
|
||||
out vec3 tcWorldPos[];
|
||||
out vec3 tcNormal[];
|
||||
|
||||
uniform float m_TessellationLevel;
|
||||
uniform vec3 g_CameraPosition;
|
||||
|
||||
void main() {
|
||||
tcWorldPos[gl_InvocationID] = vWorldPos[gl_InvocationID];
|
||||
tcNormal[gl_InvocationID] = vNormal[gl_InvocationID];
|
||||
|
||||
if (gl_InvocationID == 0) {
|
||||
vec3 center = (vWorldPos[0] + vWorldPos[1] + vWorldPos[2]) / 3.0;
|
||||
float dist = distance(g_CameraPosition, center);
|
||||
|
||||
// Maximum subdivision close-up, falls to 1 at 64 m
|
||||
float level = mix(m_TessellationLevel, 1.0, clamp(dist / 64.0, 0.0, 1.0));
|
||||
level = max(1.0, level);
|
||||
|
||||
gl_TessLevelOuter[0] = level;
|
||||
gl_TessLevelOuter[1] = level;
|
||||
gl_TessLevelOuter[2] = level;
|
||||
gl_TessLevelInner[0] = level;
|
||||
}
|
||||
}
|
||||
82
blight-assets/src/main/resources/Shaders/Voxel.tseval
Normal file
@@ -0,0 +1,82 @@
|
||||
layout(triangles, equal_spacing, ccw) in;
|
||||
|
||||
in vec3 tcWorldPos[];
|
||||
in vec3 tcNormal[];
|
||||
|
||||
out vec3 vWorldPos;
|
||||
out vec3 vNormal;
|
||||
|
||||
uniform mat4 g_ViewProjectionMatrix;
|
||||
uniform float m_TexScale;
|
||||
uniform float m_DisplacementScale;
|
||||
|
||||
#ifdef HAS_DISP_FLAT
|
||||
uniform sampler2D m_DisplacementMapFlat;
|
||||
#endif
|
||||
#ifdef HAS_DISP_STEEP
|
||||
uniform sampler2D m_DisplacementMapSteep;
|
||||
#endif
|
||||
#ifdef HAS_DISP_CEIL
|
||||
uniform sampler2D m_DisplacementMapCeil;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec3 bc = gl_TessCoord;
|
||||
|
||||
// Interpolate position and normal from patch vertices
|
||||
vec3 pos = bc.x * tcWorldPos[0] + bc.y * tcWorldPos[1] + bc.z * tcWorldPos[2];
|
||||
vec3 nor = normalize(bc.x * tcNormal[0] + bc.y * tcNormal[1] + bc.z * tcNormal[2]);
|
||||
|
||||
// Triplanar blend weights (same as fragment shader)
|
||||
vec3 bw = pow(abs(nor), vec3(4.0));
|
||||
bw /= (bw.x + bw.y + bw.z + 0.001);
|
||||
vec2 uvX = pos.yz / m_TexScale;
|
||||
vec2 uvY = pos.xz / m_TexScale;
|
||||
vec2 uvZ = pos.xy / m_TexScale;
|
||||
|
||||
float flatBlend = smoothstep(0.94, 0.99, nor.y);
|
||||
float ceilBlend = 1.0 - smoothstep(-0.6, -0.3, nor.y);
|
||||
float steepBlend = max(0.0, 1.0 - flatBlend - ceilBlend);
|
||||
|
||||
#if defined(HAS_DISP_FLAT) || defined(HAS_DISP_STEEP) || defined(HAS_DISP_CEIL)
|
||||
float disp = 0.0;
|
||||
float totalW = 0.0;
|
||||
|
||||
#ifdef HAS_DISP_FLAT
|
||||
if (flatBlend > 0.001) {
|
||||
float d = texture(m_DisplacementMapFlat, uvX).r * bw.x
|
||||
+ texture(m_DisplacementMapFlat, uvY).r * bw.y
|
||||
+ texture(m_DisplacementMapFlat, uvZ).r * bw.z;
|
||||
disp += d * flatBlend;
|
||||
totalW += flatBlend;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_DISP_STEEP
|
||||
if (steepBlend > 0.001) {
|
||||
float d = texture(m_DisplacementMapSteep, uvX).r * bw.x
|
||||
+ texture(m_DisplacementMapSteep, uvY).r * bw.y
|
||||
+ texture(m_DisplacementMapSteep, uvZ).r * bw.z;
|
||||
disp += d * steepBlend;
|
||||
totalW += steepBlend;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_DISP_CEIL
|
||||
if (ceilBlend > 0.001) {
|
||||
float d = texture(m_DisplacementMapCeil, uvX).r * bw.x
|
||||
+ texture(m_DisplacementMapCeil, uvY).r * bw.y
|
||||
+ texture(m_DisplacementMapCeil, uvZ).r * bw.z;
|
||||
disp += d * ceilBlend;
|
||||
totalW += ceilBlend;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (totalW > 0.001) disp /= totalW;
|
||||
|
||||
// 0.5 = neutral (no displacement), 0 = sink, 1 = raise
|
||||
pos += nor * ((disp - 0.5) * m_DisplacementScale);
|
||||
#endif
|
||||
|
||||
vWorldPos = pos;
|
||||
vNormal = nor;
|
||||
gl_Position = g_ViewProjectionMatrix * vec4(pos, 1.0);
|
||||
}
|
||||
@@ -1,19 +1,15 @@
|
||||
uniform mat4 g_WorldViewProjectionMatrix;
|
||||
uniform mat4 g_WorldMatrix;
|
||||
uniform mat3 g_NormalMatrix;
|
||||
|
||||
in vec3 inPosition;
|
||||
in vec3 inNormal;
|
||||
in vec4 inColor; // material blend weights (r=tex0, g=tex1, b=tex2, a=tex3)
|
||||
|
||||
out vec3 vWorldPos;
|
||||
out vec3 vNormal;
|
||||
out vec4 vMatWeights;
|
||||
|
||||
void main() {
|
||||
vec4 worldPos = g_WorldMatrix * vec4(inPosition, 1.0);
|
||||
vWorldPos = worldPos.xyz;
|
||||
vNormal = normalize(g_NormalMatrix * inNormal);
|
||||
vMatWeights = inColor;
|
||||
vNormal = normalize(mat3(g_WorldMatrix) * inNormal);
|
||||
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
|
||||
}
|
||||
|
||||
15
blight-assets/src/main/resources/Shaders/VoxelTess.vert
Normal file
@@ -0,0 +1,15 @@
|
||||
uniform mat4 g_WorldViewProjectionMatrix;
|
||||
uniform mat4 g_WorldMatrix;
|
||||
|
||||
in vec3 inPosition;
|
||||
in vec3 inNormal;
|
||||
|
||||
out vec3 vWorldPos;
|
||||
out vec3 vNormal;
|
||||
|
||||
void main() {
|
||||
vec4 wpos = g_WorldMatrix * vec4(inPosition, 1.0);
|
||||
vWorldPos = wpos.xyz;
|
||||
vNormal = normalize(mat3(g_WorldMatrix) * inNormal);
|
||||
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/gravel1/Gravel040_1K-PNG_NormalGL.png","displacementMap":"Textures/gravel1/Gravel040_1K-PNG_Displacement.png","roughnessMap":"Textures/gravel1/Gravel040_1K-PNG_Roughness.png","aoMap":"Textures/gravel1/Gravel040_1K-PNG_AmbientOcclusion.png"}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/gras2/Ground003_1K-PNG_NormalGL.png","displacementMap":"Textures/gras2/Ground003_1K-PNG_Displacement.png","roughnessMap":"Textures/gras2/Ground003_1K-PNG_Roughness.png","aoMap":""}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/leaves2/Ground019_1K-PNG_NormalGL.png","displacementMap":"Textures/leaves2/Ground019_1K-PNG_Displacement.png","roughnessMap":"Textures/leaves2/Ground019_1K-PNG_Roughness.png","aoMap":"Textures/leaves2/Ground019_1K-PNG_AmbientOcclusion.png"}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/leaves1/Ground023_1K-PNG_NormalGL.png","displacementMap":"Textures/leaves1/Ground023_1K-PNG_Displacement.png","roughnessMap":"Textures/leaves1/Ground023_1K-PNG_Roughness.png","aoMap":"Textures/leaves1/Ground023_1K-PNG_AmbientOcclusion.png"}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/gras1/Ground037_1K-PNG_NormalGL.png","displacementMap":"Textures/gras1/Ground037_1K-PNG_Displacement.png","roughnessMap":"Textures/gras1/Ground037_1K-PNG_Roughness.png","aoMap":"Textures/gras1/Ground037_1K-PNG_AmbientOcclusion.png"}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/dirt1/Ground048_1K-PNG_NormalGL.png","displacementMap":"Textures/dirt1/Ground048_1K-PNG_Displacement.png","roughnessMap":"Textures/dirt1/Ground048_1K-PNG_Roughness.png","aoMap":"Textures/dirt1/Ground048_1K-PNG_AmbientOcclusion.png"}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/sand1/Ground054_1K-PNG_NormalGL.png","displacementMap":"Textures/sand1/Ground054_1K-PNG_Displacement.png","roughnessMap":"Textures/sand1/Ground054_1K-PNG_Roughness.png","aoMap":"Textures/sand1/Ground054_1K-PNG_AmbientOcclusion.png"}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/sand2/Ground060_1K-PNG_NormalGL.png","displacementMap":"Textures/sand2/Ground060_1K-PNG_Displacement.png","roughnessMap":"Textures/sand2/Ground060_1K-PNG_Roughness.png","aoMap":"Textures/sand2/Ground060_1K-PNG_AmbientOcclusion.png"}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/gras3/Ground068_1K-PNG_NormalGL.png","displacementMap":"Textures/gras3/Ground068_1K-PNG_Displacement.png","roughnessMap":"Textures/gras3/Ground068_1K-PNG_Roughness.png","aoMap":"Textures/gras3/Ground068_1K-PNG_AmbientOcclusion.png"}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/dirt2/Ground079S_1K-PNG_NormalGL.png","displacementMap":"Textures/dirt2/Ground079S_1K-PNG_Displacement.png","roughnessMap":"Textures/dirt2/Ground079S_1K-PNG_Roughness.png","aoMap":"Textures/dirt2/Ground079S_1K-PNG_AmbientOcclusion.png"}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/rock2/Rock030_1K-PNG_NormalGL.png","displacementMap":"Textures/rock2/Rock030_1K-PNG_Displacement.png","roughnessMap":"Textures/rock2/Rock030_1K-PNG_Roughness.png","aoMap":"Textures/rock2/Rock030_1K-PNG_AmbientOcclusion.png"}
|
||||
@@ -0,0 +1 @@
|
||||
{"normalMap":"Textures/rock1/Rock033_1K-PNG_NormalGL.png","displacementMap":"Textures/rock1/Rock033_1K-PNG_Displacement.png","roughnessMap":"Textures/rock1/Rock033_1K-PNG_Roughness.png","aoMap":"Textures/rock1/Rock033_1K-PNG_AmbientOcclusion.png"}
|
||||