Initial commit

This commit is contained in:
2025-12-17 16:47:48 +00:00
commit 13813f3363
4964 changed files with 1079753 additions and 0 deletions

View File

@@ -0,0 +1,588 @@
#!/usr/bin/env python3
"""
Shader Packer for bgfx
Compiles all shaders from bgfx_shaders.json for multiple backends
"""
import json
import os
import subprocess
import sys
import tempfile
import struct
import hashlib
import re
from pathlib import Path
from typing import Dict, List, Optional
# Shader compiler configurations
SHADERC = "shaderc" # bgfx shaderc compiler path
# Backend configurations
BACKENDS = {
"spirv": {
"vs": ["linux", "spirv16-13"],
"fs": ["linux", "spirv16-13"],
},
"metal": {
"vs": ["osx", "metal31-14"],
"fs": ["osx", "metal31-14"],
},
"glsl": {
"vs": ["linux", "430"],
"fs": ["linux", "430"],
},
"glsles": {
"vs": ["android", "310_es"],
"fs": ["android", "310_es"],
}
}
class ShaderCompiler:
def __init__(self, source_dir: str, output_dir: str, include_dir: str):
self.source_dir = Path(source_dir)
self.output_dir = Path(output_dir)
self.include_dir = Path(include_dir)
self.varying_def = self.source_dir / "varying.def.sc"
self.compiled_shaders = {} # Track compiled shaders for packing
def get_shader_type(self, name: str) -> str:
"""Determine shader type from name"""
name_lower = name.lower()
if "vs" in name_lower or "vertex" in name_lower:
return "vertex"
elif "fs" in name_lower or "fragment" in name_lower or "ps" in name_lower or "pixel" in name_lower:
return "fragment"
elif "cs" in name_lower or "compute" in name_lower:
return "compute"
else:
# Default based on target
return "vertex" if name_lower.endswith("vs") else "fragment"
def resolve_includes(self, shader_source: str, source_path: Path, max_depth: int = 10) -> str:
"""
Recursively resolve #include directives in shader source.
Returns the shader source with all includes expanded inline.
"""
if max_depth <= 0:
print(f" Warning: max include depth reached, possible circular include")
return shader_source
# Pattern to match: #include "filename" or #include <filename>
include_pattern = re.compile(r'^\s*#\s*include\s+[<"]([^>"]+)[>"]', re.MULTILINE)
def replace_include(match):
include_file = match.group(1)
# Try to find the include file relative to the source file or in include dir
include_path = source_path.parent / include_file
if not include_path.exists():
include_path = self.include_dir / include_file
if not include_path.exists():
include_path = self.source_dir / include_file
if not include_path.exists():
# Can't find the file, leave the include directive as-is
return match.group(0)
try:
with open(include_path, 'r') as f:
included_content = f.read()
# Recursively resolve includes in the included file
resolved_content = self.resolve_includes(included_content, include_path, max_depth - 1)
# Return the included content with a comment indicating what was included
return f"// BEGIN INCLUDE: {include_file}\n{resolved_content}\n// END INCLUDE: {include_file}\n"
except Exception as e:
print(f" Warning: failed to include {include_file}: {e}")
return match.group(0)
return include_pattern.sub(replace_include, shader_source)
def prune_unused_functions(self, shader_source: str, entrypoint: str) -> str:
"""
Remove function definitions and prototypes not reachable from `entrypoint`.
Heuristic-based static analysis:
- Finds top-level function definitions (simple regex for return-type + name(...) { ... }).
- Builds a call graph by scanning function bodies for function-name( tokens.
- Performs BFS from `entrypoint` to find reachable functions.
- Removes function definitions and prototypes not in the reachable set.
This is intentionally conservative: if the entrypoint is not found or parsing fails,
it returns the original source unchanged.
"""
try:
src = shader_source
# Find function definitions using a heuristic regex; capture the function name
# Pattern: optional leading qualifiers + return type, then function name, params, then '{'
func_header_re = re.compile(r'^[ \t]*(?:[A-Za-z_][\w<>\s\*\:\&]+)\s+([A-Za-z_]\w*)\s*\([^;{]*\)\s*\{', re.MULTILINE)
funcs = {}
for m in func_header_re.finditer(src):
name = m.group(1)
# find the opening brace position for this match
brace_pos = src.find('{', m.end() - 1)
if brace_pos == -1:
continue
# find matching closing brace
depth = 0
i = brace_pos
end = None
while i < len(src):
if src[i] == '{':
depth += 1
elif src[i] == '}':
depth -= 1
if depth == 0:
end = i
break
i += 1
if end is None:
# Unbalanced braces, abort pruning
return shader_source
# find start of the function definition (walk backwards to line start)
start = src.rfind('\n', 0, m.start())
start = start + 1 if start != -1 else 0
funcs[name] = (start, end + 1, src[start:end + 1])
if not funcs:
return shader_source
# Build call graph: for each function, find calls to other function names
call_re = re.compile(r'\b([A-Za-z_]\w*)\s*\(')
graph = {name: set() for name in funcs}
for name, (_, _, body) in funcs.items():
for call in call_re.findall(body):
if call != name and call in funcs:
graph[name].add(call)
# BFS from entrypoint
if entrypoint not in funcs:
# entrypoint may be renamed with a suffix or have different case; try case-insensitive match
lower_map = {n.lower(): n for n in funcs}
if entrypoint.lower() in lower_map:
entrypoint = lower_map[entrypoint.lower()]
else:
# No entrypoint found in parsed functions — don't prune
return shader_source
reachable = set()
stack = [entrypoint]
while stack:
cur = stack.pop()
if cur in reachable:
continue
reachable.add(cur)
for nb in graph.get(cur, ()):
if nb not in reachable:
stack.append(nb)
# Determine functions to remove
# Only remove shader entry points:
# - Functions ending in VS, PS, FS, or CS (e.g., DefaultVS, AdornPS)
# - Functions starting with vs or ps followed by uppercase or nothing (e.g., vsCustom, ps, psAdd)
# Don't remove utility functions as they may be called by bgfx-generated code
entry_point_pattern = re.compile(r'^([a-zA-Z][a-zA-Z0-9_]*(VS|PS|FS|CS)|vs($|[A-Z])|ps($|[A-Z])[a-zA-Z0-9_]*)$')
to_remove = [
name for name in funcs
if name not in reachable and entry_point_pattern.match(name)
]
if not to_remove:
return shader_source
# Remove definitions in reverse order of start index
removals = sorted(((funcs[n][0], funcs[n][1], n) for n in to_remove), key=lambda x: x[0], reverse=True)
new_src = src
for s, e, n in removals:
# Remove the function definition span
new_src = new_src[:s] + new_src[e:]
# Also remove possible prototypes like: 'void name(...);' (single line)
proto_re = re.compile(r'^\s*[\w\*\s\:\<\>]+\b' + re.escape(n) + r'\s*\([^;{]*\)\s*;\s*\n?', re.MULTILINE)
new_src = proto_re.sub('', new_src)
print(f" Pruned {len(to_remove)} unused function(s): {', '.join(sorted(to_remove))}")
return new_src
except Exception as e:
# Parsing failed — be safe and return original source
print(f" Warning: pruning failed ({e}), using original source")
return shader_source
def compile_shader(
self,
shader_name: str,
source_file: str,
entrypoint: str,
backend: str,
defines: Optional[List[str]] = None,
exclude: Optional[str] = None,
target: str = "",
) -> bool:
"""Compile a single shader variant"""
# Check exclusions
if exclude and backend in exclude.split():
print(f" Skipping {shader_name} for {backend} (excluded)")
return True
# Determine shader type
shader_type = self.get_shader_type(target)
type_flag = "vertex" if shader_type == "vertex" else "fragment"
# Get backend config
backend_config = BACKENDS.get(backend)
if not backend_config:
print(f" Unknown backend: {backend}")
return False
# Determine platform and profile
platform = backend_config[type_flag[0] + "s"][0]
profile = backend_config[type_flag[0] + "s"][1]
# Prepare output directory
output_path = self.output_dir / backend / shader_type
output_path.mkdir(parents=True, exist_ok=True)
# Output file
output_file = output_path / f"{shader_name}.bin"
# Source file path
source_path = self.source_dir / source_file
if not source_path.exists():
print(f" ERROR: Source file not found: {source_path}")
return False
# Read the original shader source
with open(source_path, 'r') as f:
shader_source = f.read()
# Resolve #includes to get the full source code for pruning
resolved_source = self.resolve_includes(shader_source, source_path)
# Prune unused functions to avoid including vertex shader code in fragment shaders
pruned_source = self.prune_unused_functions(resolved_source, entrypoint)
# For fragment shaders, replace $input with the varyings from $output
if shader_type == "fragment":
# Extract $output directive to get the varying list
output_match = re.search(r'\$output\s+([^\n]+)', pruned_source)
if output_match:
# Get the varyings from $output
varyings = output_match.group(1)
# Replace $input with the varyings for fragment shaders
# This ensures fragment shaders receive varyings, not vertex attributes
pruned_source = re.sub(r'\$input\s+[^\n]+', f'$input {varyings}', pruned_source, count=1)
# Create a temporary file with the main() wrapper
# Instead of wrapping, we'll use preprocessor to rename the entry point to main
temp_source = None
try:
# Create temporary file in the same directory as source for proper include paths
temp_fd, temp_path = tempfile.mkstemp(
suffix='.sc',
prefix=f'tmp_{shader_name}_',
dir=str(self.source_dir),
text=True
)
temp_source = Path(temp_path)
# Write shader source with preprocessor macro to rename entry point to main
with os.fdopen(temp_fd, 'w') as f:
# Replace the entry point function name with 'main' using preprocessor
# This must be done BEFORE any includes so the function is named correctly
f.write(f"// Auto-generated: Renaming {entrypoint} to main for bgfx\n")
f.write(f"#define {entrypoint} main\n\n")
# Now write the pruned shader content
f.write(pruned_source)
# Build shaderc command using the temporary file
cmd = [
SHADERC,
"-f", str(temp_source),
"-o", str(output_file),
"--platform", platform,
"--type", type_flag,
"-i", str(self.include_dir),
"--varyingdef", str(self.varying_def),
"--profile", profile,
]
# Add defines
if defines:
for define in defines.split():
cmd.extend(["--define", define])
# Add verbose flag for debugging (optional)
# cmd.append("--verbose")
# Run shader compiler
result = subprocess.run(
cmd,
capture_output=True,
text=True,
check=False,
)
if result.returncode != 0:
print(f" ERROR compiling {shader_name} ({backend}):")
print(f" Command: {' '.join(cmd)}")
print(f" STDERR: {result.stderr}")
if result.stdout:
print(f" STDOUT: {result.stdout}")
return False
# Track compiled shader for packing
if backend not in self.compiled_shaders:
self.compiled_shaders[backend] = []
self.compiled_shaders[backend].append({
'name': shader_name,
'path': output_file,
})
print(f"{shader_name} ({backend}/{shader_type})")
return True
except FileNotFoundError:
print(f" ERROR: shaderc not found. Please ensure bgfx shaderc is in PATH or set SHADERC variable.")
return False
except Exception as e:
print(f" ERROR: {e}")
return False
finally:
# Clean up temporary file
if temp_source and temp_source.exists():
try:
temp_source.unlink()
except:
pass
def create_pack(self, backend: str, pack_name: str) -> bool:
"""Create a shader pack file in the RBXS format"""
if backend not in self.compiled_shaders:
print(f" No compiled shaders for backend: {backend}")
return False
shaders = self.compiled_shaders[backend]
if not shaders:
print(f" No shaders to pack for backend: {backend}")
return False
print(f"\nCreating pack: {pack_name}")
# Pack format:
# - Header: "RBXS" (4 bytes)
# - Entry count: unsigned int (4 bytes)
# - Entry table: array of PackEntryFile (92 bytes each)
# - Data: concatenated shader binaries
# PackEntryFile structure (92 bytes total):
# - name: char[64]
# - md5: char[16]
# - offset: unsigned int (4 bytes)
# - size: unsigned int (4 bytes)
# - reserved: char[8]
entries = []
data_offset = 8 + (92 * len(shaders)) # Header + count + entry table
shader_data = bytearray()
for shader in sorted(shaders, key=lambda x: x['name']):
shader_path = shader['path']
shader_name = shader['name']
# Read shader binary
if not shader_path.exists():
print(f" ERROR: Compiled shader not found: {shader_path}")
return False
with open(shader_path, 'rb') as f:
binary_data = f.read()
# Calculate MD5
md5 = hashlib.md5(binary_data).digest()
# Create entry
entry = {
'name': shader_name.encode('utf-8')[:64].ljust(64, b'\0'),
'md5': md5,
'offset': data_offset + len(shader_data),
'size': len(binary_data),
'reserved': b'\0' * 8,
}
entries.append(entry)
shader_data.extend(binary_data)
print(f" + {shader_name} ({len(binary_data)} bytes)")
# Write pack file
pack_path = self.output_dir / pack_name
try:
with open(pack_path, 'wb') as f:
# Write header
f.write(b'RBXS')
# Write entry count
f.write(struct.pack('<I', len(entries)))
# Write entry table
for entry in entries:
f.write(entry['name'])
f.write(entry['md5'])
f.write(struct.pack('<I', entry['offset']))
f.write(struct.pack('<I', entry['size']))
f.write(entry['reserved'])
# Write shader data
f.write(shader_data)
print(f"\n✓ Created pack: {pack_path} ({len(entries)} shaders, {len(shader_data)} bytes)")
return True
except Exception as e:
print(f" ERROR creating pack: {e}")
return False
def pack_all_shaders(self, backends: Optional[List[str]] = None):
"""Compile all shaders from bgfx_shaders.json"""
# Read bgfx_shaders.json
shaders_json = self.source_dir / "../bgfx_shaders.json"
if not shaders_json.exists():
print(f"ERROR: bgfx_shaders.json not found at {shaders_json}")
return False
with open(shaders_json, "r") as f:
shaders = json.load(f)
# Use all backends if none specified
if backends is None:
backends = list(BACKENDS.keys())
print(f"Compiling {len(shaders)} shader variants for backends: {', '.join(backends)}")
print(f"Source: {self.source_dir}")
print(f"Output: {self.output_dir}")
print()
total = 0
success = 0
failed = []
for shader in shaders:
name = shader["name"]
source = shader["source"]
entrypoint = shader["entrypoint"]
defines = shader.get("defines", "")
exclude = shader.get("exclude", "")
target = shader.get("target", "")
print(f"Compiling {name} from {source}::{entrypoint}")
for backend in backends:
total += 1
if self.compile_shader(name, source, entrypoint, backend, defines, exclude, target):
success += 1
else:
failed.append(f"{name} ({backend})")
print()
print(f"Compilation complete: {success}/{total} successful")
if failed:
print(f"\nFailed shaders:")
for f in failed:
print(f" - {f}")
return False
# Create pack files for each backend
print("\n" + "="*60)
print("Creating shader packs...")
print("="*60)
pack_success = True
for backend in backends:
# Map backend names to pack names
pack_name_map = {
"glsl": "shaders_glsl.pack",
"glsles": "shaders_glsles.pack",
"spirv": "shaders_spirv.pack",
"osx": "shaders_osx.pack",
"ios": "shaders_ios.pack"
}
pack_name = pack_name_map.get(backend, f"shaders_{backend}.pack")
if not self.create_pack(backend, pack_name):
pack_success = False
return pack_success
def main():
import argparse
parser = argparse.ArgumentParser(description="Compile bgfx shaders from bgfx_shaders.json")
parser.add_argument(
"--source",
default="bgfx_source",
help="Source directory containing .sc files (default: bgfx_source)",
)
parser.add_argument(
"--output",
default="compiled",
help="Output directory for compiled shaders (default: compiled)",
)
parser.add_argument(
"--include",
default="bgfx_source",
help="Include directory for shader headers (default: bgfx_source)",
)
parser.add_argument(
"--packs",
nargs="+",
choices=list(BACKENDS.keys()),
help="Backends to compile for (default: all)",
)
parser.add_argument(
"--shaderc",
default="shaderc",
help="Path to bgfx shaderc compiler (default: shaderc in PATH)",
)
args = parser.parse_args()
# Set global shaderc path
global SHADERC
SHADERC = args.shaderc
# Get script directory
script_dir = Path(__file__).parent
# Resolve paths
source_dir = script_dir / args.source
output_dir = script_dir / args.output
include_dir = script_dir / args.include
# Create compiler
compiler = ShaderCompiler(str(source_dir), str(output_dir), str(include_dir))
# Compile shaders
success = compiler.pack_all_shaders(args.packs)
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,234 @@
[
{ "name": "AdornAALineVS", "source": "adorn.sc", "target": "vs_2_0", "entrypoint": "AdornAALineVS"},
{ "name": "AdornAALineFS", "source": "adorn.sc", "target": "ps_2_0", "entrypoint": "AdornAALinePS" },
{ "name": "AdornVS", "source": "adorn.sc", "target": "vs_2_0", "entrypoint": "AdornVS" },
{ "name": "AdornSelfLitVS", "source": "adorn.sc", "target": "vs_2_0", "entrypoint": "AdornSelfLitVS" },
{ "name": "AdornSelfLitHighlightVS", "source": "adorn.sc", "target": "vs_2_0", "entrypoint": "AdornSelfLitHighlightVS" },
{ "name": "AdornLightingVS", "source": "adorn.sc", "target": "vs_2_0", "entrypoint": "AdornVS", "defines": "PIN_LIGHTING" },
{ "name": "AdornFS", "source": "adorn.sc", "target": "ps_2_0", "entrypoint": "AdornPS" },
{ "name": "AdornOutlineVS", "source": "adorn.sc", "target": "vs_2_0", "entrypoint": "AdornOutlineVS"},
{ "name": "AdornOutlineFS", "source": "adorn.sc", "target": "ps_2_0", "entrypoint": "AdornOutlinePS" },
{ "name": "GBufferResolveVS", "source" : "gbuffer.sc", "target" : "vs_2_0", "entrypoint" : "gbufferVS" },
{ "name": "GBufferResolveFS", "source" : "gbuffer.sc", "target" : "ps_2_0", "entrypoint" : "gbufferPS" },
{ "name": "DefaultNeonFS", "source": "neon.sc", "target": "ps_2_0", "entrypoint": "DefaultPS" },
{ "name": "DefaultNeonHQFS", "source": "neon.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultNeonHQGBufferFS", "source": "neon.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "ParticleVS", "source": "particle.sc", "target": "vs_1_1", "entrypoint": "vs" },
{ "name": "ParticleAddFS", "source": "particle.sc", "target": "ps_2_0", "entrypoint": "psAdd" },
{ "name": "ParticleModulateFS", "source": "particle.sc", "target": "ps_2_0", "entrypoint": "psModulate" },
{ "name": "ParticleCrazyFS", "source": "particle.sc", "target": "ps_2_0", "entrypoint": "psCrazy" },
{ "name": "ParticleCrazySparklesFS", "source": "particle.sc", "target": "ps_2_0", "entrypoint": "psCrazySparkles" },
{ "name": "ParticleCustomVS", "source": "particle.sc", "target": "vs_1_1", "entrypoint": "vsCustom" },
{ "name": "ParticleCustomFS", "source": "particle.sc", "target": "ps_2_0", "entrypoint": "psCustom" },
{ "name": "ProfilerVS", "source": "profiler.sc", "target": "vs_1_1", "entrypoint": "ProfilerVS" },
{ "name": "ProfilerFS", "source": "profiler.sc", "target": "ps_2_0", "entrypoint": "ProfilerPS" },
{ "name": "ImGuiFS", "source": "profiler.sc", "target": "ps_2_0", "entrypoint": "ImGuiPS" },
{ "name": "DefaultShadowStaticVS", "source": "shadow.sc", "target": "vs_2_0", "entrypoint": "ShadowVS" },
{ "name": "DefaultShadowSkinnedVS", "source": "shadow.sc", "target": "vs_2_0", "entrypoint": "ShadowVS", "defines": "PIN_SKINNED" },
{ "name": "DefaultShadowFS", "source": "shadow.sc", "target": "ps_2_0", "entrypoint": "ShadowPS" },
{ "name": "SkyVS", "source": "sky.sc", "target": "vs_1_1", "entrypoint": "SkyVS" },
{ "name": "SkyFS", "source": "sky.sc", "target": "ps_2_0", "entrypoint": "SkyPS" },
{ "name": "SmoothWaterVS", "source": "smoothwater.sc", "target": "vs_2_0", "entrypoint": "WaterVS" },
{ "name": "SmoothWaterHQVS", "source": "smoothwater.sc", "target": "vs_3_0", "entrypoint": "WaterVS", "defines": "PIN_HQ" },
{ "name": "SmoothWaterFS", "source": "smoothwater.sc", "target": "ps_2_0", "entrypoint": "WaterPS" },
{ "name": "SmoothWaterHQFS", "source": "smoothwater.sc", "target": "ps_3_0", "entrypoint": "WaterPS", "defines": "PIN_HQ" },
{ "name": "SmoothWaterHQGBufferFS", "source": "smoothwater.sc", "target": "ps_3_0", "entrypoint": "WaterPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "SSAOVS", "source": "screenspace.sc", "target": "vs_3_0", "entrypoint": "passThrough_vs"},
{ "name": "SSAODepthDownFS", "source": "ssao.sc", "target": "ps_3_0", "entrypoint": "SSAODepthDownPS", "exclude": "glsles" },
{ "name": "SSAOFS", "source": "ssao.sc", "target": "ps_3_0", "entrypoint": "SSAOPS", "exclude": "glsles" },
{ "name": "SSAOBlurXFS", "source": "ssao.sc", "target": "ps_3_0", "entrypoint": "SSAOBlurXPS", "exclude": "glsles" },
{ "name": "SSAOBlurYFS", "source": "ssao.sc", "target": "ps_3_0", "entrypoint": "SSAOBlurYPS", "exclude": "glsles" },
{ "name": "SSAOCompositVS", "source": "ssao.sc", "target": "vs_3_0", "entrypoint": "SSAOCompositVS", "exclude": "glsles" },
{ "name": "SSAOCompositFS", "source": "ssao.sc", "target": "ps_3_0", "entrypoint": "SSAOCompositPS", "exclude": "glsles" },
{ "name": "TexCompVS", "source": "texcomp.sc", "target": "vs_1_1", "entrypoint": "TexCompVS" },
{ "name": "TexCompFS", "source": "texcomp.sc", "target": "ps_2_0", "entrypoint": "TexCompPS" },
{ "name": "TexCompPMAFS", "source": "texcomp.sc", "target": "ps_2_0", "entrypoint": "TexCompPMAPS" },
{ "name": "UIVS", "source": "ui.sc", "target": "vs_1_1", "entrypoint": "UIVS" },
{ "name": "UIFogVS", "source": "ui.sc", "target": "vs_1_1", "entrypoint": "UIVS", "defines": "PIN_FOG" },
{ "name": "UIFS", "source": "ui.sc", "target": "ps_2_0", "entrypoint": "UIPS" },
{ "name": "UIFogFS", "source": "ui.sc", "target": "ps_2_0", "entrypoint": "UIPS", "defines": "PIN_FOG" },
{ "name": "WaterVS", "source": "water.sc", "target": "vs_2_0", "entrypoint": "water_vs" },
{ "name": "WaterHQVS", "source": "water.sc", "target": "vs_2_0", "entrypoint": "water_vs", "defines": "PIN_HQ" },
{ "name": "WaterFS", "source": "water.sc", "target": "ps_2_0", "entrypoint": "water_ps" },
{ "name": "WaterHQFS", "source": "water.sc", "target": "ps_2_a", "entrypoint": "water_ps", "defines": "PIN_HQ" },
{ "name": "PassThroughVS", "source": "screenspace.sc", "target": "vs_1_1", "entrypoint": "passThrough_vs"},
{ "name": "PassThroughFS", "source": "screenspace.sc", "target": "ps_2_0", "entrypoint": "passThrough_ps"},
{ "name": "GlowApplyFS", "source": "screenspace.sc", "target": "ps_2_a", "entrypoint": "glowApply_ps", "exclude": "glsles" },
{ "name": "DownSample4x4VS", "source": "screenspace.sc", "target": "vs_1_1", "entrypoint": "downsample4x4_vs", "exclude": "glsles" },
{ "name": "DownSample4x4GlowFS", "source": "screenspace.sc", "target": "ps_2_0", "entrypoint": "downSample4x4Glow_ps", "exclude": "glsles" },
{ "name": "ShadowBlurFS", "source": "screenspace.sc", "target": "ps_2_0", "entrypoint": "ShadowBlurPS" },
{ "name": "Blur3FS", "source": "screenspace.sc", "target": "ps_2_a", "entrypoint": "blur3_ps", "exclude": "glsles" },
{ "name": "Blur5FS", "source": "screenspace.sc", "target": "ps_2_a", "entrypoint": "blur5_ps", "exclude": "glsles" },
{ "name": "Blur7FS", "source": "screenspace.sc", "target": "ps_2_a", "entrypoint": "blur7_ps", "exclude": "glsles" },
{ "name": "FXAAFS", "source": "screenspace.sc", "target": "ps_2_a", "entrypoint": "fxaa_ps", "exclude": "glsles" },
{ "name": "ImageProcessFS", "source": "screenspace.sc", "target": "ps_2_0", "entrypoint": "imageProcess_ps", "exclude": "glsles" },
{ "name": "DefaultStaticVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS" },
{ "name": "DefaultStaticHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_HQ" },
{ "name": "DefaultSkinnedVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SKINNED" },
{ "name": "DefaultSkinnedHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SKINNED PIN_HQ" },
{ "name": "DefaultStaticDebugVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_DEBUG" },
{ "name": "DefaultSkinnedDebugVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SKINNED PIN_DEBUG" },
{ "name": "DefaultFS", "source": "default.sc", "target": "ps_2_0", "entrypoint": "DefaultPS" },
{ "name": "DefaultHQFS", "source": "default.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultHQGBufferFS", "source": "default.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultStaticReflectionVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_REFLECTION" },
{ "name": "DefaultSkinnedReflectionVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SKINNED PIN_REFLECTION" },
{ "name": "DefaultStaticSurfaceHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SURFACE PIN_HQ" },
{ "name": "DefaultSkinnedSurfaceHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SKINNED PIN_SURFACE PIN_HQ" },
{ "name": "LowQMaterialFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "PIN_LOWQMAT" },
{ "name": "LowQMaterialWangFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_LOWQMAT PIN_WANG" },
{ "name": "LowQMaterialWangFallbackFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "PIN_LOWQMAT PIN_WANG_FALLBACK" },
{ "name": "DefaultPlasticFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS" },
{ "name": "DefaultPlasticHQFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultPlasticHQGBufferFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultPlasticReflectionFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION" },
{ "name": "DefaultPlasticReflectionHQFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION PIN_HQ" },
{ "name": "DefaultPlasticReflectionHQGBufferFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultSmoothPlasticFS", "source": "smoothplastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS" },
{ "name": "DefaultSmoothPlasticHQFS", "source": "smoothplastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultSmoothPlasticHQGBufferFS", "source": "smoothplastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultSmoothPlasticReflectionFS", "source": "smoothplastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION" },
{ "name": "DefaultSmoothPlasticReflectionHQFS", "source": "smoothplastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION PIN_HQ" },
{ "name": "DefaultSmoothPlasticReflectionHQGBufferFS", "source": "smoothplastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultWoodHQFS", "source": "wood.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultWoodHQGBufferFS", "source": "wood.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultMarbleHQFS", "source": "marble.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultMarbleHQGBufferFS", "source": "marble.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultSlateHQFS", "source": "slate.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultSlateHQGBufferFS", "source": "slate.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultGraniteHQFS", "source": "granite.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultGraniteHQGBufferFS", "source": "granite.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultConcreteHQFS", "source": "concrete.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultConcreteHQGBufferFS", "source": "concrete.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultPebbleHQFS", "source": "pebble.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultPebbleHQGBufferFS", "source": "pebble.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultBrickHQFS", "source": "brick.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultBrickHQGBufferFS", "source": "brick.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultRustHQFS", "source": "rust.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultRustHQGBufferFS", "source": "rust.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultDiamondplateHQFS", "source": "diamondplate.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultDiamondplateHQGBufferFS", "source": "diamondplate.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultAluminumHQFS", "source": "aluminum.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultAluminumHQGBufferFS", "source": "aluminum.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultGrassHQFS", "source": "grass.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultGrassHQGBufferFS", "source": "grass.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultSandHQFS", "source": "sand.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultSandHQGBufferFS", "source": "sand.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultFabricHQFS", "source": "fabric.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultFabricHQGBufferFS", "source": "fabric.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultIceHQFS", "source": "ice.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultIceHQGBufferFS", "source": "ice.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultCobblestoneHQFS", "source": "cobblestone.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultCobblestoneHQGBufferFS", "source": "cobblestone.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultMetalHQFS", "source": "metal.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultMetalHQGBufferFS", "source": "metal.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultWoodPlanksHQFS", "source": "woodplanks.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultWoodPlanksHQGBufferFS", "source": "woodplanks.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "MegaClusterVS", "source": "megacluster.sc", "target": "vs_2_0", "entrypoint": "MegaClusterVS" },
{ "name": "MegaClusterHQVS", "source": "megacluster.sc", "target": "vs_2_0", "entrypoint": "MegaClusterVS", "defines": "PIN_HQ" },
{ "name": "MegaClusterFS", "source": "megacluster.sc", "target": "ps_2_0", "entrypoint": "MegaClusterPS" },
{ "name": "MegaClusterHQFS", "source": "megacluster.sc", "target": "ps_2_a", "entrypoint": "MegaClusterPS", "defines": "PIN_HQ" },
{ "name": "MegaClusterHQGBufferFS", "source": "megacluster.sc", "target": "ps_2_a", "entrypoint": "MegaClusterPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "SmoothClusterVS", "source": "smoothcluster.sc", "target": "vs_2_0", "entrypoint": "TerrainVS" },
{ "name": "SmoothClusterHQVS", "source": "smoothcluster.sc", "target": "vs_3_0", "entrypoint": "TerrainVS", "defines": "PIN_HQ" },
{ "name": "SmoothClusterFS", "source": "smoothcluster.sc", "target": "ps_2_0", "entrypoint": "TerrainPS" },
{ "name": "SmoothClusterHQFS", "source": "smoothcluster.sc", "target": "ps_3_0", "entrypoint": "TerrainPS", "defines": "PIN_HQ" },
{ "name": "SmoothClusterHQGBufferFS", "source": "smoothcluster.sc", "target": "ps_3_0", "entrypoint": "TerrainPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudLowQMaterialFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_LOWQMAT" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudLowQMaterialWangFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_LOWQMAT PIN_WANG" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudLowQMaterialWangFallbackFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_LOWQMAT PIN_WANG_FALLBACK" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticHQFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticHQGBufferFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticReflectionFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_REFLECTION" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticReflectionHQFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_REFLECTION PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticReflectionHQGBufferFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_REFLECTION PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultStaticVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultStaticHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultSkinnedVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SKINNED" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultSkinnedHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SKINNED PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultStaticDebugVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_DEBUG" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultSkinnedDebugVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SKINNED PIN_DEBUG" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultFS", "source": "default.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultHQFS", "source": "default.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultHQGBufferFS", "source": "default.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultStaticReflectionVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_REFLECTION" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultSkinnedReflectionVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SKINNED PIN_REFLECTION" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultStaticSurfaceHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SURFACE PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultSkinnedSurfaceHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SKINNED PIN_SURFACE PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultStaticVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultStaticHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSkinnedVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SKINNED" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSkinnedHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SKINNED PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultStaticDebugVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_DEBUG" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSkinnedDebugVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SKINNED PIN_DEBUG" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultFS", "source": "default.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultHQFS", "source": "default.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultHQGBufferFS", "source": "default.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultStaticReflectionVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_REFLECTION" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSkinnedReflectionVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SKINNED PIN_REFLECTION" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultStaticSurfaceHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SURFACE PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSkinnedSurfaceHQVS", "source": "default.sc", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SKINNED PIN_SURFACE PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicLowQMaterialFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_LOWQMAT" },
{ "version": 2013, "key": "Classic", "name": "ClassicLowQMaterialWangFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_LOWQMAT PIN_WANG" },
{ "version": 2013, "key": "Classic", "name": "ClassicLowQMaterialWangFallbackFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_LOWQMAT PIN_WANG_FALLBACK" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticHQFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticHQGBufferFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticReflectionFS", "source": "plastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticReflectionHQFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticReflectionHQGBufferFS", "source": "plastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticFS", "source": "smoothplastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticHQFS", "source": "smoothplastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticHQGBufferFS", "source": "smoothplastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticReflectionFS", "source": "smoothplastic.sc", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticReflectionHQFS", "source": "smoothplastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticReflectionHQGBufferFS", "source": "smoothplastic.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultWoodHQFS", "source": "wood.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultWoodHQGBufferFS", "source": "wood.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultMarbleHQFS", "source": "marble.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultMarbleHQGBufferFS", "source": "marble.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSlateHQFS", "source": "slate.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSlateHQGBufferFS", "source": "slate.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultGraniteHQFS", "source": "granite.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultGraniteHQGBufferFS", "source": "granite.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultConcreteHQFS", "source": "concrete.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultConcreteHQGBufferFS", "source": "concrete.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPebbleHQFS", "source": "pebble.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPebbleHQGBufferFS", "source": "pebble.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultBrickHQFS", "source": "brick.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultBrickHQGBufferFS", "source": "brick.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultRustHQFS", "source": "rust.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultRustHQGBufferFS", "source": "rust.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultDiamondplateHQFS", "source": "diamondplate.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultDiamondplateHQGBufferFS", "source": "diamondplate.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultAluminumHQFS", "source": "aluminum.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultAluminumHQGBufferFS", "source": "aluminum.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultGrassHQFS", "source": "grass.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultGrassHQGBufferFS", "source": "grass.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSandHQFS", "source": "sand.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSandHQGBufferFS", "source": "sand.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultFabricHQFS", "source": "fabric.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultFabricHQGBufferFS", "source": "fabric.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultIceHQFS", "source": "ice.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultIceHQGBufferFS", "source": "ice.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultCobblestoneHQFS", "source": "cobblestone.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultCobblestoneHQGBufferFS", "source": "cobblestone.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultMetalHQFS", "source": "metal.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultMetalHQGBufferFS", "source": "metal.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultWoodPlanksHQFS", "source": "woodplanks.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultWoodPlanksHQGBufferFS", "source": "woodplanks.sc", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicMegaClusterVS", "source": "megacluster.sc", "target": "vs_2_0", "entrypoint": "MegaClusterVS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicMegaClusterHQVS", "source": "megacluster.sc", "target": "vs_2_0", "entrypoint": "MegaClusterVS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicMegaClusterFS", "source": "megacluster.sc", "target": "ps_2_0", "entrypoint": "MegaClusterPS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicMegaClusterHQFS", "source": "megacluster.sc", "target": "ps_2_a", "entrypoint": "MegaClusterPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicMegaClusterHQGBufferFS", "source": "megacluster.sc", "target": "ps_2_a", "entrypoint": "MegaClusterPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicSmoothClusterVS", "source": "smoothcluster.sc", "target": "vs_2_0", "entrypoint": "TerrainVS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicSmoothClusterHQVS", "source": "smoothcluster.sc", "target": "vs_3_0", "entrypoint": "TerrainVS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicSmoothClusterFS", "source": "smoothcluster.sc", "target": "ps_2_0", "entrypoint": "TerrainPS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicSmoothClusterHQFS", "source": "smoothcluster.sc", "target": "ps_3_0", "entrypoint": "TerrainPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicSmoothClusterHQGBufferFS", "source": "smoothcluster.sc", "target": "ps_3_0", "entrypoint": "TerrainPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" }
]

View File

@@ -0,0 +1,193 @@
$input a_position, a_texcoord0, a_normal
$output v_texcoord0, v_color0, v_texcoord1, v_worldPos, v_position, v_start, v_end, v_centerRadius
#include "common.sh"
uniform vec4 u_color;
uniform vec4 u_pixelInfo; // x -> Fov * 0.5f / screenSize.y; y -> ScreenWidth; z -> ScreenWidth / ScreenHeight; w -> Line thickness
SAMPLER2D(s_diffuseMap, 0);
// Vertex Shaders
void AdornSelfLitVS()
{
vec4 worldPos = mul(u_worldMatrix, vec4(a_position, 1.0));
vec3 worldNormal = normalize(mul(u_worldMatrix, vec4(a_normal, 0.0)).xyz);
vec3 light = normalize(u_cameraPosition - worldPos.xyz);
float ndotl = saturate(dot(worldNormal, light));
float lighting = 0.5 + (1.0 - 0.5) * ndotl;
float specular = pow(ndotl, 64.0);
gl_Position = mul(u_viewProjection, worldPos);
v_texcoord0 = a_texcoord0;
v_color0 = vec4(u_color.rgb * lighting + vec3(specular), u_color.a);
v_texcoord1.x = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
}
void AdornSelfLitHighlightVS()
{
vec4 worldPos = mul(u_worldMatrix, vec4(a_position, 1.0));
vec3 worldNormal = normalize(mul(u_worldMatrix, vec4(a_normal, 0.0)).xyz);
vec3 light = normalize(u_cameraPosition - worldPos.xyz);
float ndotl = saturate(dot(worldNormal, light));
float lighting = 0.75 + (1.0 - 0.75) * ndotl;
float specular = pow(ndotl, 64.0);
gl_Position = mul(u_viewProjection, worldPos);
v_texcoord0 = a_texcoord0;
v_color0 = vec4(u_color.rgb * lighting + vec3(specular), u_color.a);
v_texcoord1.x = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
}
void AdornVS()
{
vec4 worldPos = mul(u_worldMatrix, vec4(a_position, 1.0));
#ifdef PIN_LIGHTING
vec3 worldNormal = normalize(mul(u_worldMatrix, vec4(a_normal, 0.0)).xyz);
float ndotl = dot(worldNormal, -u_lamp0Dir);
vec3 lighting = u_ambientColor + saturate(ndotl) * u_lamp0Color + saturate(-ndotl) * u_lamp1Color;
#else
vec3 lighting = vec3(1.0);
#endif
gl_Position = mul(u_viewProjection, worldPos);
v_texcoord0 = a_texcoord0;
v_color0 = vec4(u_color.rgb * lighting, u_color.a);
v_texcoord1.x = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
}
void AdornAALineVS()
{
vec4 worldPos = mul(u_worldMatrix, vec4(a_position, 1.0));
vec3 worldNormal = normalize(mul(u_worldMatrix, vec4(a_normal, 0.0)).xyz);
// line start and end position in world space
vec4 startPosW = mul(u_worldMatrix, vec4(1.0, 0.0, 0.0, 1.0));
vec4 endPosW = mul(u_worldMatrix, vec4(-1.0, 0.0, 0.0, 1.0));
// Compute view-space w
float w = dot(u_viewProjection[3], vec4(worldPos.xyz, 1.0));
// radius in pixels + constant because line has to be little bit bigger to perform anti aliasing
float radius = u_pixelInfo.w + 2.0;
// scale the way that line has same size on screen
if (length(worldPos.xyz - startPosW.xyz) < length(worldPos.xyz - endPosW.xyz))
{
float w = dot(u_viewProjection[3], vec4(startPosW.xyz, 1.0));
float pixel_radius = radius * w * u_pixelInfo.x;
worldPos.xyz = startPosW.xyz + worldNormal * pixel_radius;
}
else
{
float w = dot(u_viewProjection[3], vec4(endPosW.xyz, 1.0));
float pixel_radius = radius * w * u_pixelInfo.x;
worldPos.xyz = endPosW.xyz + worldNormal * pixel_radius;
}
// output for PS
gl_Position = mul(u_viewProjection, worldPos);
v_position = gl_Position.xyw;
v_start = mul(u_viewProjection, startPosW);
v_end = mul(u_viewProjection, endPosW);
v_texcoord1.x = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
// screen ratio
v_position.y *= u_pixelInfo.z;
v_start.y *= u_pixelInfo.z;
v_end.y *= u_pixelInfo.z;
}
void AdornOutlineVS()
{
vec4 worldPos = mul(u_worldMatrix, vec4(a_position, 1.0));
gl_Position = mul(u_viewProjection, worldPos);
v_color0 = u_color;
v_worldPos = worldPos.xyz;
v_centerRadius = vec4(mul(u_worldMatrix, vec4(0.0, 0.0, 0.0, 1.0)).xyz,
length(mul(u_worldMatrix, vec4(1.0, 0.0, 0.0, 0.0)).xyz));
}
// Pixel/Fragment Shaders
void AdornPS()
{
vec4 result = texture2D(s_diffuseMap, v_texcoord0) * v_color0;
result.rgb = mix(u_fogColor, result.rgb, saturate(v_texcoord1.x));
gl_FragColor = result;
}
void AdornAALinePS()
{
vec3 position = v_position / v_position.z;
vec4 start = v_start / v_start.w;
vec4 end = v_end / v_end.w;
vec2 lineDir = normalize(end.xy - start.xy);
vec2 fragToPoint = position.xy - start.xy;
// tips of the line are not Anti-Aliased, they are just cut
// discard as soon as we can
float startDist = dot(lineDir, fragToPoint);
float endDist = dot(lineDir, -position.xy + end.xy);
if (startDist < 0.0)
discard;
if (endDist < 0.0)
discard;
vec2 perpLineDir = vec2(lineDir.y, -lineDir.x);
float dist = abs(dot(perpLineDir, fragToPoint));
// high point serves to compute the function which is described below
float highPoint = 1.0 + (u_pixelInfo.w - 1.0) * 0.5;
// this is function that has this shape /¯¯¯\, it is symmetric, centered around 0 on X axis
// slope parts are +- 45 degree and are 1px thick. Area of the shape sums to line thickness in pixels
// function for 1px would be /\, func for 2px is /¯\ and so on...
vec4 result = vec4(1.0);
result.a = saturate(highPoint - (dist * 0.5 * u_pixelInfo.y));
result *= u_color;
// convert to sRGB, its not perfect for non-black backgrounds, but its the best we can get
result.a = pow(saturate(1.0 - result.a), 1.0/2.2);
result.a = 1.0 - result.a;
result.rgb = mix(u_fogColor, result.rgb, saturate(v_texcoord1.x));
gl_FragColor = result;
}
void AdornOutlinePS()
{
vec3 rayO = v_worldPos - v_centerRadius.xyz;
vec3 rayD = normalize(v_worldPos - u_cameraPosition);
// magnitude(rayO + t * rayD) = radius
// t^2 + bt + c = radius
float thickness = 1.0;
float r0 = v_centerRadius.w;
float r1 = max(0.0, v_centerRadius.w - thickness);
float b = 2.0 * dot(rayO, rayD);
float c0 = dot(rayO, rayO) - r0 * r0;
float c1 = dot(rayO, rayO) - r1 * r1;
if (b * b < 4.0 * c0)
discard;
if (b * b > 4.0 * c1)
discard;
gl_FragColor = v_color0;
}

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 256.0
#define CFG_REFLECTION_SCALE 0.4
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 128.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.3
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,731 @@
/*
* Copyright 2011-2025 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
*/
#ifndef BGFX_SHADER_H_HEADER_GUARD
#define BGFX_SHADER_H_HEADER_GUARD
#if !defined(BGFX_CONFIG_MAX_BONES)
# define BGFX_CONFIG_MAX_BONES 32
#endif // !defined(BGFX_CONFIG_MAX_BONES)
#ifndef __cplusplus
#if BGFX_SHADER_LANGUAGE_HLSL > 300
# define BRANCH [branch]
# define LOOP [loop]
# define UNROLL [unroll]
#else
# define BRANCH
# define LOOP
# define UNROLL
#endif // BGFX_SHADER_LANGUAGE_HLSL > 300
#if (BGFX_SHADER_LANGUAGE_HLSL > 300 || BGFX_SHADER_LANGUAGE_METAL || BGFX_SHADER_LANGUAGE_SPIRV) && BGFX_SHADER_TYPE_FRAGMENT
# define EARLY_DEPTH_STENCIL [earlydepthstencil]
#else
# define EARLY_DEPTH_STENCIL
#endif // BGFX_SHADER_LANGUAGE_HLSL > 300 && BGFX_SHADER_TYPE_FRAGMENT
#if BGFX_SHADER_LANGUAGE_GLSL
# define ARRAY_BEGIN(_type, _name, _count) _type _name[_count] = _type[](
# define ARRAY_END() )
#else
# define ARRAY_BEGIN(_type, _name, _count) _type _name[_count] = {
# define ARRAY_END() }
#endif // BGFX_SHADER_LANGUAGE_GLSL
#if BGFX_SHADER_LANGUAGE_HLSL \
|| BGFX_SHADER_LANGUAGE_PSSL \
|| BGFX_SHADER_LANGUAGE_SPIRV \
|| BGFX_SHADER_LANGUAGE_METAL
# define CONST(_x) static const _x
# define dFdx(_x) ddx(_x)
# define dFdy(_y) ddy(-(_y))
# define inversesqrt(_x) rsqrt(_x)
# define fract(_x) frac(_x)
# define bvec2 bool2
# define bvec3 bool3
# define bvec4 bool4
// To be able to patch the uav registers on the DXBC SPDB Chunk (D3D11 renderer) the whitespaces around
// '_type[_reg]' are necessary. This only affects shaders with debug info (i.e., those that have the SPDB Chunk).
# if BGFX_SHADER_LANGUAGE_HLSL > 400 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
# define REGISTER(_type, _reg) register( _type[_reg] )
# else
# define REGISTER(_type, _reg) register(_type ## _reg)
# endif // BGFX_SHADER_LANGUAGE_HLSL
# if BGFX_SHADER_LANGUAGE_HLSL > 300 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
# if BGFX_SHADER_LANGUAGE_HLSL > 400 || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
# define dFdxCoarse(_x) ddx_coarse(_x)
# define dFdxFine(_x) ddx_fine(_x)
# define dFdyCoarse(_y) ddy_coarse(-(_y))
# define dFdyFine(_y) ddy_fine(-(_y))
# endif // BGFX_SHADER_LANGUAGE_HLSL > 400
# if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
float intBitsToFloat(int _x) { return asfloat(_x); }
vec2 intBitsToFloat(uint2 _x) { return asfloat(_x); }
vec3 intBitsToFloat(uint3 _x) { return asfloat(_x); }
vec4 intBitsToFloat(uint4 _x) { return asfloat(_x); }
# endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
float uintBitsToFloat(uint _x) { return asfloat(_x); }
vec2 uintBitsToFloat(uint2 _x) { return asfloat(_x); }
vec3 uintBitsToFloat(uint3 _x) { return asfloat(_x); }
vec4 uintBitsToFloat(uint4 _x) { return asfloat(_x); }
uint floatBitsToUint(float _x) { return asuint(_x); }
uvec2 floatBitsToUint(vec2 _x) { return asuint(_x); }
uvec3 floatBitsToUint(vec3 _x) { return asuint(_x); }
uvec4 floatBitsToUint(vec4 _x) { return asuint(_x); }
int floatBitsToInt(float _x) { return asint(_x); }
ivec2 floatBitsToInt(vec2 _x) { return asint(_x); }
ivec3 floatBitsToInt(vec3 _x) { return asint(_x); }
ivec4 floatBitsToInt(vec4 _x) { return asint(_x); }
uint bitfieldReverse(uint _x) { return reversebits(_x); }
uint2 bitfieldReverse(uint2 _x) { return reversebits(_x); }
uint3 bitfieldReverse(uint3 _x) { return reversebits(_x); }
uint4 bitfieldReverse(uint4 _x) { return reversebits(_x); }
# if !BGFX_SHADER_LANGUAGE_SPIRV
uint packHalf2x16(vec2 _x)
{
return (f32tof16(_x.y)<<16) | f32tof16(_x.x);
}
vec2 unpackHalf2x16(uint _x)
{
return vec2(f16tof32(_x & 0xffff), f16tof32(_x >> 16) );
}
# endif // !BGFX_SHADER_LANGUAGE_SPIRV
struct BgfxSampler2D
{
SamplerState m_sampler;
Texture2D m_texture;
};
struct BgfxISampler2D
{
Texture2D<ivec4> m_texture;
};
struct BgfxUSampler2D
{
Texture2D<uvec4> m_texture;
};
struct BgfxSampler2DArray
{
SamplerState m_sampler;
Texture2DArray m_texture;
};
struct BgfxSampler2DShadow
{
SamplerComparisonState m_sampler;
Texture2D m_texture;
};
struct BgfxSampler2DArrayShadow
{
SamplerComparisonState m_sampler;
Texture2DArray m_texture;
};
struct BgfxSampler3D
{
SamplerState m_sampler;
Texture3D m_texture;
};
struct BgfxISampler3D
{
Texture3D<ivec4> m_texture;
};
struct BgfxUSampler3D
{
Texture3D<uvec4> m_texture;
};
struct BgfxSamplerCube
{
SamplerState m_sampler;
TextureCube m_texture;
};
struct BgfxSamplerCubeShadow
{
SamplerComparisonState m_sampler;
TextureCube m_texture;
};
struct BgfxSampler2DMS
{
Texture2DMS<vec4> m_texture;
};
vec4 bgfxTexture2D(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTexture2DBias(BgfxSampler2D _sampler, vec2 _coord, float _bias)
{
return _sampler.m_texture.SampleBias(_sampler.m_sampler, _coord, _bias);
}
vec4 bgfxTexture2DLod(BgfxSampler2D _sampler, vec2 _coord, float _level)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level);
}
vec4 bgfxTexture2DLodOffset(BgfxSampler2D _sampler, vec2 _coord, float _level, ivec2 _offset)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level, _offset);
}
vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec3 _coord)
{
vec2 coord = _coord.xy * rcp(_coord.z);
return _sampler.m_texture.Sample(_sampler.m_sampler, coord);
}
vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec4 _coord)
{
vec2 coord = _coord.xy * rcp(_coord.w);
return _sampler.m_texture.Sample(_sampler.m_sampler, coord);
}
vec4 bgfxTexture2DGrad(BgfxSampler2D _sampler, vec2 _coord, vec2 _dPdx, vec2 _dPdy)
{
return _sampler.m_texture.SampleGrad(_sampler.m_sampler, _coord, _dPdx, _dPdy);
}
vec4 bgfxTexture2DArray(BgfxSampler2DArray _sampler, vec3 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTexture2DArrayLod(BgfxSampler2DArray _sampler, vec3 _coord, float _lod)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _lod);
}
vec4 bgfxTexture2DArrayLodOffset(BgfxSampler2DArray _sampler, vec3 _coord, float _level, ivec2 _offset)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level, _offset);
}
float bgfxShadow2D(BgfxSampler2DShadow _sampler, vec3 _coord)
{
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, _coord.xy, _coord.z);
}
float bgfxShadow2DProj(BgfxSampler2DShadow _sampler, vec4 _coord)
{
vec3 coord = _coord.xyz * rcp(_coord.w);
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, coord.xy, coord.z);
}
vec2 bgfxTextureSize(BgfxSampler2DShadow _sampler, int _lod)
{
vec2 result;
float numberOfMipMapLevels;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, numberOfMipMapLevels);
return result;
}
vec4 bgfxShadow2DArray(BgfxSampler2DArrayShadow _sampler, vec4 _coord)
{
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, _coord.xyz, _coord.w);
}
vec2 bgfxTextureSize(BgfxSampler2DArrayShadow _sampler, int _lod)
{
vec2 result;
float numberOfMipMapLevels;
float numberOfElements;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, numberOfElements, numberOfMipMapLevels);
return result;
}
vec4 bgfxTexture3D(BgfxSampler3D _sampler, vec3 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTexture3DLod(BgfxSampler3D _sampler, vec3 _coord, float _level)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level);
}
ivec4 bgfxTexture3D(BgfxISampler3D _sampler, vec3 _coord)
{
uvec3 size;
_sampler.m_texture.GetDimensions(size.x, size.y, size.z);
return _sampler.m_texture.Load(ivec4(_coord * size, 0) );
}
uvec4 bgfxTexture3D(BgfxUSampler3D _sampler, vec3 _coord)
{
uvec3 size;
_sampler.m_texture.GetDimensions(size.x, size.y, size.z);
return _sampler.m_texture.Load(ivec4(_coord * size, 0) );
}
vec4 bgfxTextureCube(BgfxSamplerCube _sampler, vec3 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureCubeBias(BgfxSamplerCube _sampler, vec3 _coord, float _bias)
{
return _sampler.m_texture.SampleBias(_sampler.m_sampler, _coord, _bias);
}
vec4 bgfxTextureCubeLod(BgfxSamplerCube _sampler, vec3 _coord, float _level)
{
return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level);
}
float bgfxShadowCube(BgfxSamplerCubeShadow _sampler, vec4 _coord)
{
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, _coord.xyz, _coord.w);
}
vec4 bgfxTexelFetch(BgfxSampler2D _sampler, ivec2 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec3(_coord, _lod) );
}
vec4 bgfxTexelFetchOffset(BgfxSampler2D _sampler, ivec2 _coord, int _lod, ivec2 _offset)
{
return _sampler.m_texture.Load(ivec3(_coord, _lod), _offset );
}
vec2 bgfxTextureSize(BgfxSampler2D _sampler, int _lod)
{
vec2 result;
float numberOfMipMapLevels;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, numberOfMipMapLevels);
return result;
}
vec2 bgfxTextureSize(BgfxISampler2D _sampler, int _lod)
{
vec2 result;
float numberOfMipMapLevels;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, numberOfMipMapLevels);
return result;
}
vec2 bgfxTextureSize(BgfxUSampler2D _sampler, int _lod)
{
vec2 result;
float numberOfMipMapLevels;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, numberOfMipMapLevels);
return result;
}
vec4 bgfxTextureGather0(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather1(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.GatherGreen(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather2(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.GatherBlue(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather3(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.GatherAlpha(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGatherOffset0(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
{
return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord, _offset);
}
vec4 bgfxTextureGatherOffset1(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
{
return _sampler.m_texture.GatherGreen(_sampler.m_sampler, _coord, _offset);
}
vec4 bgfxTextureGatherOffset2(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
{
return _sampler.m_texture.GatherBlue(_sampler.m_sampler, _coord, _offset);
}
vec4 bgfxTextureGatherOffset3(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
{
return _sampler.m_texture.GatherAlpha(_sampler.m_sampler, _coord, _offset);
}
vec4 bgfxTextureGather0(BgfxSampler2DArray _sampler, vec3 _coord)
{
return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather1(BgfxSampler2DArray _sampler, vec3 _coord)
{
return _sampler.m_texture.GatherGreen(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather2(BgfxSampler2DArray _sampler, vec3 _coord)
{
return _sampler.m_texture.GatherBlue(_sampler.m_sampler, _coord);
}
vec4 bgfxTextureGather3(BgfxSampler2DArray _sampler, vec3 _coord)
{
return _sampler.m_texture.GatherAlpha(_sampler.m_sampler, _coord);
}
ivec4 bgfxTexelFetch(BgfxISampler2D _sampler, ivec2 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec3(_coord, _lod) );
}
uvec4 bgfxTexelFetch(BgfxUSampler2D _sampler, ivec2 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec3(_coord, _lod) );
}
vec4 bgfxTexelFetch(BgfxSampler2DMS _sampler, ivec2 _coord, int _sampleIdx)
{
return _sampler.m_texture.Load(_coord, _sampleIdx);
}
vec4 bgfxTexelFetch(BgfxSampler2DArray _sampler, ivec3 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec4(_coord, _lod) );
}
vec4 bgfxTexelFetch(BgfxSampler3D _sampler, ivec3 _coord, int _lod)
{
return _sampler.m_texture.Load(ivec4(_coord, _lod) );
}
vec3 bgfxTextureSize(BgfxSampler3D _sampler, int _lod)
{
vec3 result;
float numberOfMipMapLevels;
_sampler.m_texture.GetDimensions(_lod, result.x, result.y, result.z, numberOfMipMapLevels);
return result;
}
# define SAMPLER2D(_name, _reg) \
uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \
uniform Texture2D _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler2D _name = { _name ## Sampler, _name ## Texture }
# define ISAMPLER2D(_name, _reg) \
uniform Texture2D<ivec4> _name ## Texture : REGISTER(t, _reg); \
static BgfxISampler2D _name = { _name ## Texture }
# define USAMPLER2D(_name, _reg) \
uniform Texture2D<uvec4> _name ## Texture : REGISTER(t, _reg); \
static BgfxUSampler2D _name = { _name ## Texture }
# define sampler2D BgfxSampler2D
# define texture2D(_sampler, _coord) bgfxTexture2D(_sampler, _coord)
# define texture2DBias(_sampler, _coord, _bias) bgfxTexture2DBias(_sampler, _coord, _bias)
# define texture2DLod(_sampler, _coord, _level) bgfxTexture2DLod(_sampler, _coord, _level)
# define texture2DLodOffset(_sampler, _coord, _level, _offset) bgfxTexture2DLodOffset(_sampler, _coord, _level, _offset)
# define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord)
# define texture2DGrad(_sampler, _coord, _dPdx, _dPdy) bgfxTexture2DGrad(_sampler, _coord, _dPdx, _dPdy)
# define SAMPLER2DARRAY(_name, _reg) \
uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \
uniform Texture2DArray _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler2DArray _name = { _name ## Sampler, _name ## Texture }
# define sampler2DArray BgfxSampler2DArray
# define texture2DArray(_sampler, _coord) bgfxTexture2DArray(_sampler, _coord)
# define texture2DArrayLod(_sampler, _coord, _lod) bgfxTexture2DArrayLod(_sampler, _coord, _lod)
# define texture2DArrayLodOffset(_sampler, _coord, _level, _offset) bgfxTexture2DArrayLodOffset(_sampler, _coord, _level, _offset)
# define SAMPLER2DMS(_name, _reg) \
uniform Texture2DMS<vec4> _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler2DMS _name = { _name ## Texture }
# define sampler2DMS BgfxSampler2DMS
# define SAMPLER2DSHADOW(_name, _reg) \
uniform SamplerComparisonState _name ## SamplerComparison : REGISTER(s, _reg); \
uniform Texture2D _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler2DShadow _name = { _name ## SamplerComparison, _name ## Texture }
# define sampler2DShadow BgfxSampler2DShadow
# define shadow2D(_sampler, _coord) bgfxShadow2D(_sampler, _coord)
# define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord)
# define SAMPLER2DARRAYSHADOW(_name, _reg) \
uniform SamplerComparisonState _name ## SamplerComparison : REGISTER(s, _reg); \
uniform Texture2DArray _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler2DArrayShadow _name = { _name ## SamplerComparison, _name ## Texture }
# define sampler2DArrayShadow BgfxSampler2DArrayShadow
# define shadow2DArray(_sampler, _coord) bgfxShadow2DArray(_sampler, _coord)
# define SAMPLER3D(_name, _reg) \
uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \
uniform Texture3D _name ## Texture : REGISTER(t, _reg); \
static BgfxSampler3D _name = { _name ## Sampler, _name ## Texture }
# define ISAMPLER3D(_name, _reg) \
uniform Texture3D<ivec4> _name ## Texture : REGISTER(t, _reg); \
static BgfxISampler3D _name = { _name ## Texture }
# define USAMPLER3D(_name, _reg) \
uniform Texture3D<uvec4> _name ## Texture : REGISTER(t, _reg); \
static BgfxUSampler3D _name = { _name ## Texture }
# define sampler3D BgfxSampler3D
# define texture3D(_sampler, _coord) bgfxTexture3D(_sampler, _coord)
# define texture3DLod(_sampler, _coord, _level) bgfxTexture3DLod(_sampler, _coord, _level)
# define SAMPLERCUBE(_name, _reg) \
uniform SamplerState _name ## Sampler : REGISTER(s, _reg); \
uniform TextureCube _name ## Texture : REGISTER(t, _reg); \
static BgfxSamplerCube _name = { _name ## Sampler, _name ## Texture }
# define samplerCube BgfxSamplerCube
# define textureCube(_sampler, _coord) bgfxTextureCube(_sampler, _coord)
# define textureCubeBias(_sampler, _coord, _bias) bgfxTextureCubeBias(_sampler, _coord, _bias)
# define textureCubeLod(_sampler, _coord, _level) bgfxTextureCubeLod(_sampler, _coord, _level)
# define SAMPLERCUBESHADOW(_name, _reg) \
uniform SamplerComparisonState _name ## SamplerComparison : REGISTER(s, _reg); \
uniform TextureCube _name ## Texture : REGISTER(t, _reg); \
static BgfxSamplerCubeShadow _name = { _name ## SamplerComparison, _name ## Texture }
# define samplerCubeShadow BgfxSamplerCubeShadow
# define shadowCube(_sampler, _coord) bgfxShadowCube(_sampler, _coord)
# define texelFetch(_sampler, _coord, _lod) bgfxTexelFetch(_sampler, _coord, _lod)
# define texelFetchOffset(_sampler, _coord, _lod, _offset) bgfxTexelFetchOffset(_sampler, _coord, _lod, _offset)
# define textureSize(_sampler, _lod) bgfxTextureSize(_sampler, _lod)
# define textureGather(_sampler, _coord, _comp) bgfxTextureGather ## _comp(_sampler, _coord)
# define textureGatherOffset(_sampler, _coord, _offset, _comp) bgfxTextureGatherOffset ## _comp(_sampler, _coord, _offset)
# else
# define sampler2DShadow sampler2D
vec4 bgfxTexture2DProj(sampler2D _sampler, vec3 _coord)
{
return tex2Dproj(_sampler, vec4(_coord.xy, 0.0, _coord.z) );
}
vec4 bgfxTexture2DProj(sampler2D _sampler, vec4 _coord)
{
return tex2Dproj(_sampler, _coord);
}
float bgfxShadow2D(sampler2DShadow _sampler, vec3 _coord)
{
#if 0
float occluder = tex2D(_sampler, _coord.xy).x;
return step(_coord.z, occluder);
#else
return tex2Dproj(_sampler, vec4(_coord.xy, _coord.z, 1.0) ).x;
#endif // 0
}
float bgfxShadow2DProj(sampler2DShadow _sampler, vec4 _coord)
{
#if 0
vec3 coord = _coord.xyz * rcp(_coord.w);
float occluder = tex2D(_sampler, coord.xy).x;
return step(coord.z, occluder);
#else
return tex2Dproj(_sampler, _coord).x;
#endif // 0
}
# define SAMPLER2D(_name, _reg) uniform sampler2D _name : REGISTER(s, _reg)
# define SAMPLER2DMS(_name, _reg) uniform sampler2DMS _name : REGISTER(s, _reg)
# define texture2D(_sampler, _coord) tex2D(_sampler, _coord)
# define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord)
# define SAMPLER2DARRAY(_name, _reg) SAMPLER2D(_name, _reg)
# define texture2DArray(_sampler, _coord) texture2D(_sampler, (_coord).xy)
# define texture2DArrayLod(_sampler, _coord, _lod) texture2DLod(_sampler, _coord, _lod)
# define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name : REGISTER(s, _reg)
# define shadow2D(_sampler, _coord) bgfxShadow2D(_sampler, _coord)
# define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord)
# define SAMPLER3D(_name, _reg) uniform sampler3D _name : REGISTER(s, _reg)
# define texture3D(_sampler, _coord) tex3D(_sampler, _coord)
# define SAMPLERCUBE(_name, _reg) uniform samplerCUBE _name : REGISTER(s, _reg)
# define textureCube(_sampler, _coord) texCUBE(_sampler, _coord)
# define texture2DLod(_sampler, _coord, _level) tex2Dlod(_sampler, vec4( (_coord).xy, 0.0, _level) )
# define texture2DGrad(_sampler, _coord, _dPdx, _dPdy) tex2Dgrad(_sampler, _coord, _dPdx, _dPdy)
# define texture3DLod(_sampler, _coord, _level) tex3Dlod(_sampler, vec4( (_coord).xyz, _level) )
# define textureCubeLod(_sampler, _coord, _level) texCUBElod(_sampler, vec4( (_coord).xyz, _level) )
# endif // BGFX_SHADER_LANGUAGE_HLSL > 300
vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_mtx, _vec); }
vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_vec, _mtx); }
vec4 instMul(vec4 _vec, mat4 _mtx) { return mul(_mtx, _vec); }
vec4 instMul(mat4 _mtx, vec4 _vec) { return mul(_vec, _mtx); }
bvec2 lessThan(vec2 _a, vec2 _b) { return _a < _b; }
bvec3 lessThan(vec3 _a, vec3 _b) { return _a < _b; }
bvec4 lessThan(vec4 _a, vec4 _b) { return _a < _b; }
bvec2 lessThanEqual(vec2 _a, vec2 _b) { return _a <= _b; }
bvec3 lessThanEqual(vec3 _a, vec3 _b) { return _a <= _b; }
bvec4 lessThanEqual(vec4 _a, vec4 _b) { return _a <= _b; }
bvec2 greaterThan(vec2 _a, vec2 _b) { return _a > _b; }
bvec3 greaterThan(vec3 _a, vec3 _b) { return _a > _b; }
bvec4 greaterThan(vec4 _a, vec4 _b) { return _a > _b; }
bvec2 greaterThanEqual(vec2 _a, vec2 _b) { return _a >= _b; }
bvec3 greaterThanEqual(vec3 _a, vec3 _b) { return _a >= _b; }
bvec4 greaterThanEqual(vec4 _a, vec4 _b) { return _a >= _b; }
bvec2 notEqual(vec2 _a, vec2 _b) { return _a != _b; }
bvec3 notEqual(vec3 _a, vec3 _b) { return _a != _b; }
bvec4 notEqual(vec4 _a, vec4 _b) { return _a != _b; }
bvec2 equal(vec2 _a, vec2 _b) { return _a == _b; }
bvec3 equal(vec3 _a, vec3 _b) { return _a == _b; }
bvec4 equal(vec4 _a, vec4 _b) { return _a == _b; }
float mix(float _a, float _b, float _t) { return lerp(_a, _b, _t); }
vec2 mix(vec2 _a, vec2 _b, vec2 _t) { return lerp(_a, _b, _t); }
vec3 mix(vec3 _a, vec3 _b, vec3 _t) { return lerp(_a, _b, _t); }
vec4 mix(vec4 _a, vec4 _b, vec4 _t) { return lerp(_a, _b, _t); }
float mod(float _a, float _b) { return _a - _b * floor(_a / _b); }
vec2 mod(vec2 _a, vec2 _b) { return _a - _b * floor(_a / _b); }
vec3 mod(vec3 _a, vec3 _b) { return _a - _b * floor(_a / _b); }
vec4 mod(vec4 _a, vec4 _b) { return _a - _b * floor(_a / _b); }
#else
# define CONST(_x) const _x
# define atan2(_x, _y) atan(_x, _y)
# define mul(_a, _b) ( (_a) * (_b) )
# define saturate(_x) clamp(_x, 0.0, 1.0)
# define SAMPLER2D(_name, _reg) uniform sampler2D _name
# define SAMPLER2DMS(_name, _reg) uniform sampler2DMS _name
# define SAMPLER3D(_name, _reg) uniform sampler3D _name
# define SAMPLERCUBE(_name, _reg) uniform samplerCube _name
# define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name
# define SAMPLER2DARRAY(_name, _reg) uniform sampler2DArray _name
# define SAMPLER2DMSARRAY(_name, _reg) uniform sampler2DMSArray _name
# define SAMPLERCUBEARRAY(_name, _reg) uniform samplerCubeArray _name
# define SAMPLER2DARRAYSHADOW(_name, _reg) uniform sampler2DArrayShadow _name
# define ISAMPLER2D(_name, _reg) uniform isampler2D _name
# define USAMPLER2D(_name, _reg) uniform usampler2D _name
# define ISAMPLER3D(_name, _reg) uniform isampler3D _name
# define USAMPLER3D(_name, _reg) uniform usampler3D _name
# if BGFX_SHADER_LANGUAGE_GLSL >= 130
# define texture2D(_sampler, _coord) texture(_sampler, _coord)
# define texture2DArray(_sampler, _coord) texture(_sampler, _coord)
# define texture3D(_sampler, _coord) texture(_sampler, _coord)
# define textureCube(_sampler, _coord) texture(_sampler, _coord)
# define texture2DLod(_sampler, _coord, _lod) textureLod(_sampler, _coord, _lod)
# define texture2DLodOffset(_sampler, _coord, _lod, _offset) textureLodOffset(_sampler, _coord, _lod, _offset)
# define texture2DBias(_sampler, _coord, _bias) texture(_sampler, _coord, _bias)
# define textureCubeBias(_sampler, _coord, _bias) texture(_sampler, _coord, _bias)
# else
# define texture2DBias(_sampler, _coord, _bias) texture2D(_sampler, _coord, _bias)
# define textureCubeBias(_sampler, _coord, _bias) textureCube(_sampler, _coord, _bias)
# endif // BGFX_SHADER_LANGUAGE_GLSL >= 130
vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_vec, _mtx); }
vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_mtx, _vec); }
vec4 instMul(vec4 _vec, mat4 _mtx) { return mul(_vec, _mtx); }
vec4 instMul(mat4 _mtx, vec4 _vec) { return mul(_mtx, _vec); }
float rcp(float _a) { return 1.0/_a; }
vec2 rcp(vec2 _a) { return vec2(1.0)/_a; }
vec3 rcp(vec3 _a) { return vec3(1.0)/_a; }
vec4 rcp(vec4 _a) { return vec4(1.0)/_a; }
#endif // BGFX_SHADER_LANGUAGE_*
vec2 vec2_splat(float _x) { return vec2(_x, _x); }
vec3 vec3_splat(float _x) { return vec3(_x, _x, _x); }
vec4 vec4_splat(float _x) { return vec4(_x, _x, _x, _x); }
#if BGFX_SHADER_LANGUAGE_GLSL >= 130 || BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
uvec2 uvec2_splat(uint _x) { return uvec2(_x, _x); }
uvec3 uvec3_splat(uint _x) { return uvec3(_x, _x, _x); }
uvec4 uvec4_splat(uint _x) { return uvec4(_x, _x, _x, _x); }
#endif // BGFX_SHADER_LANGUAGE_GLSL >= 130 || BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_SPIRV || BGFX_SHADER_LANGUAGE_METAL
mat4 mtxFromRows(vec4 _0, vec4 _1, vec4 _2, vec4 _3)
{
#if BGFX_SHADER_LANGUAGE_GLSL
return transpose(mat4(_0, _1, _2, _3) );
#else
return mat4(_0, _1, _2, _3);
#endif // BGFX_SHADER_LANGUAGE_GLSL
}
mat4 mtxFromCols(vec4 _0, vec4 _1, vec4 _2, vec4 _3)
{
#if BGFX_SHADER_LANGUAGE_GLSL
return mat4(_0, _1, _2, _3);
#else
return transpose(mat4(_0, _1, _2, _3) );
#endif // BGFX_SHADER_LANGUAGE_GLSL
}
mat3 mtxFromRows(vec3 _0, vec3 _1, vec3 _2)
{
#if BGFX_SHADER_LANGUAGE_GLSL
return transpose(mat3(_0, _1, _2) );
#else
return mat3(_0, _1, _2);
#endif // BGFX_SHADER_LANGUAGE_GLSL
}
mat3 mtxFromCols(vec3 _0, vec3 _1, vec3 _2)
{
#if BGFX_SHADER_LANGUAGE_GLSL
return mat3(_0, _1, _2);
#else
return transpose(mat3(_0, _1, _2) );
#endif // BGFX_SHADER_LANGUAGE_GLSL
}
#if BGFX_SHADER_LANGUAGE_GLSL
#define mtxFromRows3(_0, _1, _2) transpose(mat3(_0, _1, _2) )
#define mtxFromRows4(_0, _1, _2, _3) transpose(mat4(_0, _1, _2, _3) )
#define mtxFromCols3(_0, _1, _2) mat3(_0, _1, _2)
#define mtxFromCols4(_0, _1, _2, _3) mat4(_0, _1, _2, _3)
#else
#define mtxFromRows3(_0, _1, _2) mat3(_0, _1, _2)
#define mtxFromRows4(_0, _1, _2, _3) mat4(_0, _1, _2, _3)
#define mtxFromCols3(_0, _1, _2) transpose(mat3(_0, _1, _2) )
#define mtxFromCols4(_0, _1, _2, _3) transpose(mat4(_0, _1, _2, _3) )
#endif // BGFX_SHADER_LANGUAGE_GLSL
uniform vec4 u_viewRect;
uniform vec4 u_viewTexel;
uniform mat4 u_view;
uniform mat4 u_invView;
uniform mat4 u_proj;
uniform mat4 u_invProj;
uniform mat4 u_viewProj;
uniform mat4 u_invViewProj;
uniform mat4 u_model[BGFX_CONFIG_MAX_BONES];
uniform mat4 u_modelView;
uniform mat4 u_invModelView;
uniform mat4 u_modelViewProj;
uniform vec4 u_alphaRef4;
#define u_alphaRef u_alphaRef4.x
#endif // __cplusplus
#endif // BGFX_SHADER_H_HEADER_GUARD

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 96.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 48.0
#define CFG_NORMAL_DETAIL_TILING 0.0
#define CFG_NORMAL_DETAIL_SCALE 0.0
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,15 @@
#define CFG_WANG_TILES
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 64.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 32.0
#include "material.sc"

View File

@@ -0,0 +1,223 @@
#ifndef COMMON_SH_HEADER_GUARD
#define COMMON_SH_HEADER_GUARD
#include "globals.sh"
#include <bgfx_shader.sh>
// GLSLES has limited number of vertex shader registers so we have to use less bones
#if defined(GLSLES) && !defined(GL3)
#define MAX_BONE_COUNT 32
#else
#define MAX_BONE_COUNT 72
#endif
// PowerVR saturate() is compiled to min/max pair
// These are cross-platform specialized saturates that are free on PC and only cost 1 cycle on PowerVR
float saturate0(float v)
{
return max(v, 0.0);
}
float saturate1(float v)
{
return min(v, 1.0);
}
#if defined(GLSLES) && !defined(GL3)
#define WANG_SUBSET_SCALE 2.0
#else
#define WANG_SUBSET_SCALE 1.0
#endif
#define GBUFFER_MAX_DEPTH 500.0
// Texture samplers - bgfx style
#define TEX_DECLARE2D(name, reg) SAMPLER2D(name, reg)
#define TEX_DECLARE3D(name, reg) SAMPLER3D(name, reg)
#define TEX_DECLARECUBE(name, reg) SAMPLERCUBE(name, reg)
// Unified matrix uniforms
uniform mat4 u_worldMatrix;
uniform vec4 u_worldMatrixArray[MAX_BONE_COUNT * 3];
#if defined(GLSLES) || defined(PIN_WANG_FALLBACK)
#define TEXTURE_WANG(name) 0
void getWang(sampler2D unused, vec2 uv, float tiling, out vec2 wangUv, out vec4 wangUVDerivatives)
{
wangUv = uv * WANG_SUBSET_SCALE;
wangUVDerivatives = vec4(0.0, 0.0, 0.0, 0.0); // not used in this mode
}
vec4 sampleWang(sampler2D s, vec2 uv, vec4 wangUVDerivatives)
{
return texture2D(s, uv);
}
#else
#define TEXTURE_WANG(name) name
void getWang(sampler2D s, vec2 uv, float tiling, out vec2 wangUv, out vec4 wangUVDerivatives)
{
#ifndef WIN_MOBILE
float idxTexSize = 128.0;
#else
float idxTexSize = 32.0;
#endif
vec2 wangBase = uv * tiling * 4.0;
#if defined(DX11) && !defined(WIN_MOBILE)
// compensate the precision problem of Point Sampling on some cards
vec2 wangUV = (floor(wangBase) + 0.5) / idxTexSize;
#else
vec2 wangUV = wangBase / idxTexSize;
#endif
#if defined(DX11) || defined(GL3)
vec2 wang = texture2D(s, wangUV).rg;
#else
vec2 wang = texture2D(s, wangUV).ba;
#endif
wangUVDerivatives = vec4(dFdx(wangBase * 0.25), dFdy(wangBase * 0.25));
wang *= 255.0 / 256.0;
wangUv = wang + fract(wangBase) * 0.25;
}
vec4 sampleWang(sampler2D s, vec2 uv, vec4 derivates)
{
return texture2DGrad(s, uv, derivates.xy, derivates.zw);
}
#endif
vec4 gbufferPack(float depth, vec3 diffuse, vec3 specular, float fog)
{
depth = saturate(depth / GBUFFER_MAX_DEPTH);
const vec3 lumVec = vec3(0.299, 0.587, 0.114);
vec2 comp;
comp = depth * vec2(255.0, 255.0 * 256.0);
comp = fract(comp);
comp = vec2(depth, comp.x * 256.0 / 255.0) - vec2(comp.x, comp.y) / 255.0;
vec4 result;
result.r = mix(1.0, dot(specular, lumVec), saturate(3.0 * fog));
result.g = mix(0.0, dot(diffuse, lumVec), saturate(3.0 * fog));
result.ba = comp.yx;
return result;
}
vec3 lgridOffset(vec3 v, vec3 n)
{
// cells are 4 studs in size
// offset in normal direction to prevent self-occlusion
// the offset has to be 1.5 cells in order to fully eliminate the influence of the source cell with trilinear filtering
// (i.e. 1 cell is enough for point filtering, but is not enough for trilinear filtering)
return v + n * (1.5 * 4.0);
}
vec3 lgridPrepareSample(vec3 c)
{
// yxz swizzle is necessary for GLSLES sampling to work efficiently
// (having .y as the first component allows to do the LUT lookup as a non-dependent texture fetch)
return c.yxz * u_lightConfig0.xyz + u_lightConfig1.xyz;
}
#if defined(GLSLES) && !defined(GL3)
#define LGRID_SAMPLER(name, register) TEX_DECLARE2D(name, register)
vec4 lgridSample(sampler2D t, sampler2D lut, vec3 data)
{
vec4 offsets = texture2D(lut, data.xy);
// texture is 64 pixels high
// let's compute slice lerp coeff
float slicef = fract(data.x * 64.0);
// texture has 64 slices with 8x8 atlas setup
vec2 base = clamp(data.yz, vec2(0.0), vec2(1.0)) * 0.125;
vec4 s0 = texture2D(t, base + offsets.xy);
vec4 s1 = texture2D(t, base + offsets.zw);
return mix(s0, s1, slicef);
}
#else
#define LGRID_SAMPLER(name, register) TEX_DECLARE3D(name, register)
vec4 lgridSample(sampler3D t, sampler2D lut, vec3 data)
{
vec3 edge = step(u_lightConfig3.xyz, abs(data - u_lightConfig2.xyz));
float edgef = saturate1(dot(edge, vec3(1.0)));
// replace data with 0 on edges to minimize texture cache misses
vec4 light = texture3D(t, data.yzx - data.yzx * edgef);
return mix(light, u_lightBorder, vec4(edgef));
}
#endif
vec3 nmapUnpack(vec4 value)
{
#ifdef GLSLES
return value.rgb * 2.0 - 1.0;
#else
vec2 xy = value.ag * 2.0 - 1.0;
return vec3(xy, sqrt(saturate(1.0 + dot(-xy, xy))));
#endif
}
vec3 terrainNormal(vec4 tnp0, vec4 tnp1, vec4 tnp2, vec3 w, vec3 normal, vec3 tsel)
{
// Inspired by "Voxel-Based Terrain for Real-Time Virtual Simulations" [Lengyel2010] 5.5.2
vec3 tangentTop = vec3(normal.y, -normal.x, 0.0);
vec3 tangentSide = vec3(normal.z, 0.0, -normal.x);
vec3 bitangentTop = vec3(0.0, -normal.z, normal.y);
vec3 bitangentSide = vec3(0.0, -1.0, 0.0);
// Blend pre-unpack to save cycles
vec3 tn = nmapUnpack(tnp0 * w.x + tnp1 * w.y + tnp2 * w.z);
// We blend all tangent frames together as a faster approximation to the correct world normal blend
float tselw = dot(tsel, w);
vec3 tangent = mix(tangentSide, tangentTop, tselw);
vec3 bitangent = mix(bitangentSide, bitangentTop, tselw);
return normalize(tangent * tn.x + bitangent * tn.y + normal * tn.z);
}
vec3 shadowPrepareSample(vec3 p)
{
vec4 c = vec4(p, 1.0);
return vec3(dot(u_shadowMatrix0, c), dot(u_shadowMatrix1, c), dot(u_shadowMatrix2, c));
}
float shadowDepth(vec3 lpos)
{
return lpos.z;
}
float shadowStep(float d, float z)
{
// saturate returns 1 for z in [0.1..0.9]; it fades to 0 as z approaches 0 or 1
return step(d, z) * saturate(9.0 - 20.0 * abs(z - 0.5));
}
float shadowSample(sampler2D map, vec3 lpos, float lightShadow)
{
#ifdef CLASSIC
return lightShadow;
#else
vec2 smDepth = texture2D(map, lpos.xy).rg;
float smShadow = shadowStep(smDepth.x, shadowDepth(lpos));
return (1.0 - smShadow * smDepth.y * u_outlineBrightness_ShadowInfo.w) * lightShadow;
#endif
}
#endif // COMMON_SH_HEADER_GUARD

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 32.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 20.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.3
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,425 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_color0, a_color1, a_texcoord2, a_texcoord3
$output v_pos, v_worldPos, v_texcoord0, v_texcoord1, v_color0, v_normal, v_tangent, v_lightpos_fog, v_view_depth, v_poslightspace, v_edgedist, v_reflection
#include "common.sh"
#define LQMAT_FADE_FACTOR (1.0/300.0)
#define BEVEL_WIDTH 0.06
#define PI 3.14159265359
#define BEVEL_FADE_DIST 120.0
#define BEVEL_FADE_DIST_START 0.0
#define SPEC_EXPON 81.0
#define KS 0.75
#define FADE_DIST 500.0
#define FADE_DIST_START 0.0
uniform vec4 u_worldMatrixArray[MAX_BONE_COUNT * 3];
uniform vec4 u_debugColor;
SAMPLER2D(s_studsMap, 0);
SAMPLER2D(s_lightMap, 1);
SAMPLER2D(s_lightMapLookup, 2);
SAMPLER2D(s_shadowMap, 3);
SAMPLERCUBE(s_environmentMap, 4);
SAMPLER2D(s_diffuseMap, 5);
SAMPLER2D(s_normalMap, 6);
SAMPLER2D(s_specularMap, 7);
#ifndef GLSLES
SAMPLER2D(s_normalDetailMap, 8);
#endif
uniform vec4 u_lqmatFarTilingFactor;
void Shade(vec3 albedo, vec3 nn, vec3 vn, float ks, float specExpon, vec4 light, out vec3 diffuse, out vec3 specular)
{
vec3 ln = normalize(-u_lamp0Dir);
vec3 hn = normalize(ln + vn);
float ndl = dot(nn, ln);
float ndh = dot(nn, hn);
vec2 lit0 = vec2(max(0.0, ndl), pow(max(0.0, ndh), specExpon) * step(0.0, ndl));
vec3 lampColor = u_lamp0Color;
diffuse = (light.a * (lampColor * lit0.x) + u_ambientColor + light.xyz);
diffuse *= albedo;
specular = (lampColor * lit0.y) * ks * light.a;
}
vec3 CalcBevel(vec4 edgeDistances, vec3 normal, float viewDepth)
{
vec4 bevelMultiplier = clamp((BEVEL_WIDTH - edgeDistances) / BEVEL_WIDTH, 0.0, 1.0);
float fade = clamp(1.0 - (viewDepth - BEVEL_FADE_DIST_START) / BEVEL_FADE_DIST, 0.0, 1.0);
bevelMultiplier *= fade;
normal += bevelMultiplier.x * vec3(0.5, 0.0, 0.0);
normal += bevelMultiplier.y * vec3(-0.5, 0.0, 0.0);
normal += bevelMultiplier.z * vec3(0.0, 0.5, 0.0);
normal += bevelMultiplier.w * vec3(0.0, -0.5, 0.0);
return normalize(normal);
}
vec3 DisplaceCoord(vec3 pos)
{
float cfactor = 0.980066578;
float sfactor = 0.198669331;
float cfactor2 = 0.955336489;
float sfactor2 = 0.295520207;
float cfactor3 = 0.921060994;
float sfactor3 = 0.389418342;
vec3 p = pos.xyz;
vec3 shiftPos = p;
shiftPos.x += p.x * cfactor + p.z * sfactor;
shiftPos.z += p.x * -sfactor + p.z * cfactor;
shiftPos.x += p.x * cfactor2 - p.y * sfactor2;
shiftPos.y += p.x * sfactor2 + p.y * cfactor2;
shiftPos.y += p.y * cfactor3 - p.z * sfactor3;
shiftPos.z += p.y * sfactor3 + p.z * cfactor3;
return shiftPos;
}
#ifdef CLASSIC
void DefaultVS()
{
// Transform position and normal to world space
#ifdef PIN_SKINNED
int boneIndex = int(a_color1.r);
vec4 worldRow0 = u_worldMatrixArray[boneIndex * 3];
vec4 worldRow1 = u_worldMatrixArray[boneIndex * 3 + 1];
vec4 worldRow2 = u_worldMatrixArray[boneIndex * 3 + 2];
vec3 posWorld = vec3(dot(worldRow0, vec4(a_position, 1.0)),
dot(worldRow1, vec4(a_position, 1.0)),
dot(worldRow2, vec4(a_position, 1.0)));
vec3 normalWorld = vec3(dot(worldRow0.xyz, a_normal),
dot(worldRow1.xyz, a_normal),
dot(worldRow2.xyz, a_normal));
v_tangent = vec3(dot(worldRow0.xyz, a_texcoord2),
dot(worldRow1.xyz, a_texcoord2),
dot(worldRow2.xyz, a_texcoord2));
#else
vec3 posWorld = a_position;
vec3 normalWorld = a_normal;
v_tangent = a_texcoord2;
#endif
v_pos = a_position;
v_worldPos = posWorld;
vec4 color = a_color0;
gl_Position = mul(u_viewProjection, vec4(posWorld, 1.0));
v_normal = normalWorld;
v_texcoord0 = a_texcoord0;
v_texcoord1 = a_texcoord1;
v_color0 = color;
v_lightpos_fog = vec4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)),
(u_fogParams.z - gl_Position.w) * u_fogParams.w);
v_view_depth = vec4(u_cameraPosition - posWorld, gl_Position.w);
#ifdef CLASSIC_GOURAUD
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
vec3 diffuse, specular;
Shade(vec3(1.0), normalize(v_normal), normalize(v_view_depth.xyz), 0.71, 81.0, light, diffuse, specular);
// Store in unused varyings
#endif
#if defined(PIN_HQ) || defined(PIN_REFLECTION)
v_reflection = a_color1.a / 255.0;
v_edgedist = a_texcoord3;
#endif
v_poslightspace = shadowPrepareSample(posWorld);
}
void DefaultPS()
{
float normalStrength = 0.4;
float fade = clamp(normalStrength - (v_view_depth.w - FADE_DIST_START) / FADE_DIST, 0.0, 1.0);
vec3 nn = normalize(v_normal);
vec4 edgeDistances = v_edgedist;
vec4 albedo = v_color0;
vec2 uv;
#ifndef PIN_MESH
uv = v_texcoord0;
mat3 normalMatrix = mat3(
v_tangent.xyz,
cross(nn, v_tangent.xyz),
nn
);
vec3 tn = vec3(0.0, 0.0, 0.5);
tn = mix(vec3(0.0, 0.0, 0.5), tn, fade);
tn = CalcBevel(edgeDistances, tn, v_view_depth.w);
nn = mul(tn, normalMatrix);
vec4 colorTex = texture2D(s_diffuseMap, uv);
albedo *= colorTex;
#else
uv = v_texcoord0;
vec4 colorTex = texture2D(s_diffuseMap, uv);
albedo *= colorTex;
#endif
vec3 vn = normalize(v_view_depth.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
vec3 diffusePhong, specularPhong;
vec3 diffuse, specular;
#ifdef CLASSIC_GOURAUD
// Use pre-computed lighting from vertex shader
diffuse = albedo.rgb; // Should use stored diffuse from VS
specular = vec3(0.0); // Should use stored specular from VS
#else
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffusePhong, specularPhong);
diffuse = diffusePhong;
specular = specularPhong;
#endif
vec3 result = diffuse + specular;
#ifdef PIN_REFLECTION
vec3 reflection = textureCube(s_environmentMap, reflect(-vn, nn)).rgb;
result = mix(result, reflection, v_reflection);
#endif
float fogAlpha = clamp((u_fogParams.z - length(v_view_depth.xyz)) * u_fogParams.w, 0.0, 1.0);
result = mix(u_fogColor, result, fogAlpha);
gl_FragColor = vec4(result, albedo.a);
#ifdef PIN_GBUFFER
// Output to second render target
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else // !CLASSIC - Modern rendering path
void DefaultVS()
{
// Transform position and normal to world space
#ifdef PIN_SKINNED
int boneIndex = int(a_color1.r);
vec4 worldRow0 = u_worldMatrixArray[boneIndex * 3 + 0];
vec4 worldRow1 = u_worldMatrixArray[boneIndex * 3 + 1];
vec4 worldRow2 = u_worldMatrixArray[boneIndex * 3 + 2];
vec3 posWorld = vec3(dot(worldRow0, vec4(a_position, 1.0)),
dot(worldRow1, vec4(a_position, 1.0)),
dot(worldRow2, vec4(a_position, 1.0)));
vec3 normalWorld = vec3(dot(worldRow0.xyz, a_normal),
dot(worldRow1.xyz, a_normal),
dot(worldRow2.xyz, a_normal));
#else
vec3 posWorld = a_position;
vec3 normalWorld = a_normal;
#endif
// Decode diffuse/specular parameters
#ifdef PIN_DEBUG
vec4 color = u_debugColor;
#else
vec4 color = a_color0;
#endif
float specularIntensity = a_color1.g / 255.0;
float specularPower = float(int(a_color1.b));
float ndotl = dot(normalWorld, -u_lamp0Dir);
#ifdef PIN_HQ
// We'll calculate specular in pixel shader
vec2 lt = vec2(clamp(ndotl, 0.0, 1.0), step(0.0, ndotl));
#else
// Using lit here improves performance on software vertex shader implementations
vec2 lt = vec2(max(0.0, ndotl),
pow(max(0.0, dot(normalize(-u_lamp0Dir + normalize(u_cameraPosition - posWorld)), normalWorld)), specularPower) * step(0.0, ndotl));
#endif
gl_Position = mul(u_viewProjection, vec4(posWorld, 1.0));
v_texcoord0 = a_texcoord0;
v_texcoord1 = a_texcoord1;
v_color0 = color;
v_lightpos_fog = vec4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)),
(u_fogParams.z - gl_Position.w) * u_fogParams.w);
v_view_depth = vec4(u_cameraPosition - posWorld, gl_Position.w);
#if defined(PIN_HQ) || defined(PIN_REFLECTION)
vec4 edgeDistances = a_texcoord3 * u_fadeDistance_GlowFactor.z + 0.5 * v_view_depth.w * u_fadeDistance_GlowFactor.y;
v_edgedist = edgeDistances;
v_normal = normalWorld;
// Store specular power in normal.w if needed
v_reflection = a_color1.a / 255.0;
#endif
#ifdef PIN_SURFACE
#ifdef PIN_SKINNED
vec3 tangent = vec3(dot(worldRow0.xyz, a_texcoord2),
dot(worldRow1.xyz, a_texcoord2),
dot(worldRow2.xyz, a_texcoord2));
#else
vec3 tangent = a_texcoord2;
#endif
v_tangent = tangent;
#else
vec3 diffuse = lt.x * u_lamp0Color + max(-ndotl, 0.0) * u_lamp1Color;
// Store diffuse and specular in color channels (pack into v_color0.w and other varyings)
#endif
v_poslightspace = shadowPrepareSample(posWorld);
}
vec4 sampleFar1(sampler2D s, vec2 uv, float fade, float cutoff)
{
#ifdef GLSLES
return texture2D(s, uv);
#else
if (cutoff == 0.0)
return texture2D(s, uv);
else
{
float cscale = 1.0 / (1.0 - cutoff);
return mix(texture2D(s, uv * u_lqmatFarTilingFactor.xy),
texture2D(s, uv),
saturate0(fade * cscale - cutoff * cscale));
}
#endif
}
#if defined(PIN_WANG) || defined(PIN_WANG_FALLBACK)
vec4 sampleWangSimple(sampler2D s, vec2 uv)
{
vec2 wangUv;
vec4 wangUVDerivatives;
getWang(s_normalDetailMap, uv, 1.0, wangUv, wangUVDerivatives);
return sampleWang(s, wangUv, wangUVDerivatives);
}
#endif
void DefaultPS()
{
// Compute albedo term
#ifdef PIN_SURFACE
// Surface shader path - would need surface shader implementation
vec4 albedo = v_color0;
vec3 normal = normalize(v_normal);
#elif defined(PIN_LOWQMAT)
#ifndef CFG_FAR_DIFFUSE_CUTOFF
#define CFG_FAR_DIFFUSE_CUTOFF 0.6
#endif
#if defined(PIN_WANG) || defined(PIN_WANG_FALLBACK)
vec4 albedo = sampleWangSimple(s_diffuseMap, v_texcoord0);
#else
float fade = saturate0(1.0 - v_view_depth.w * LQMAT_FADE_FACTOR);
vec4 albedo = sampleFar1(s_diffuseMap, v_texcoord0, fade, CFG_FAR_DIFFUSE_CUTOFF);
#endif
albedo.rgb = mix(vec3(1.0), v_color0.rgb, albedo.a) * albedo.rgb;
albedo.a = v_color0.a;
// Diffuse and specular from vertex shader (stored in varyings)
vec3 diffuseIntensity = vec3(1.0); // Should unpack from varyings
float specularIntensity = 0.0; // Should unpack from varyings
float reflectance = 0.0;
#else
#ifdef PIN_PLASTIC
vec4 studs = texture2D(s_studsMap, v_texcoord1);
vec4 albedo = vec4(v_color0.rgb * (studs.r * 2.0), v_color0.a);
#else
vec4 albedo = texture2D(s_diffuseMap, v_texcoord0) * v_color0;
#endif
#ifdef PIN_HQ
vec3 normal = normalize(v_normal);
float specularPower = 81.0; // Should come from varying
#elif defined(PIN_REFLECTION)
vec3 normal = v_normal;
#endif
vec3 diffuseIntensity = vec3(1.0); // Should unpack from varyings
float specularIntensity = 0.0; // Should unpack from varyings
#ifdef PIN_REFLECTION
float reflectance = v_reflection;
#endif
#endif
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
float shadow = shadowSample(s_shadowMap, v_poslightspace, light.a);
// Compute reflection term
#if defined(PIN_SURFACE) || defined(PIN_REFLECTION)
vec3 reflection = textureCube(s_environmentMap, reflect(-v_view_depth.xyz, normal)).rgb;
albedo.rgb = mix(albedo.rgb, reflection.rgb, reflectance);
#endif
// Compute diffuse term
vec3 diffuse = (u_ambientColor + diffuseIntensity * shadow + light.rgb) * albedo.rgb;
// Compute specular term
#ifdef PIN_HQ
vec3 normal = normalize(v_normal);
float specularPower = 81.0;
vec3 specular = u_lamp0Color * (specularIntensity * shadow *
pow(clamp(dot(normal, normalize(-u_lamp0Dir + normalize(v_view_depth.xyz))), 0.0, 1.0), specularPower));
#else
vec3 specular = u_lamp0Color * (specularIntensity * shadow);
#endif
// Combine
vec3 resultColor = diffuse.rgb + specular.rgb;
float resultAlpha = albedo.a;
#ifdef PIN_HQ
float ViewDepthMul = v_view_depth.w * u_fadeDistance_GlowFactor.y;
float outlineFade = saturate1(ViewDepthMul * u_outlineBrightness_ShadowInfo.x + u_outlineBrightness_ShadowInfo.y);
vec2 minIntermediate = min(v_edgedist.xy, v_edgedist.zw);
float minEdgesPlus = min(minIntermediate.x, minIntermediate.y) / ViewDepthMul;
resultColor *= saturate1(outlineFade * (1.5 - minEdgesPlus) + minEdgesPlus);
#endif
float fogAlpha = clamp(v_lightpos_fog.w, 0.0, 1.0);
#ifdef PIN_NEON
resultColor = v_color0.rgb * u_fadeDistance_GlowFactor.w;
resultAlpha = 1.0 - fogAlpha * v_color0.a;
diffuse.rgb = vec3(0.0);
specular.rgb = vec3(0.0);
#endif
resultColor = mix(u_fogColor, resultColor, fogAlpha);
gl_FragColor = vec4(resultColor, resultAlpha);
#ifdef PIN_GBUFFER
// Output to second render target
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#endif // CLASSIC

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.3
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 64.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.3
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 64.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.5
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,37 @@
$input a_position, a_texcoord0
$output v_texcoord0
#include "common.sh"
uniform vec4 u_textureSize;
SAMPLER2D(s_tex, 0);
vec4 convertPosition(vec4 p)
{
#if defined(GLSL) || defined(DX11)
return p;
#else
return p + vec4(-u_textureSize.z, u_textureSize.w, 0.0, 0.0);
#endif
}
vec2 convertUv(vec4 p)
{
#if defined(GLSL)
return p.xy * 0.5 + 0.5;
#else
return p.xy * vec2(0.5, -0.5) + 0.5;
#endif
}
void gbufferVS()
{
gl_Position = convertPosition(vec4(a_position, 1.0));
v_texcoord0 = convertUv(vec4(a_position, 1.0));
}
void gbufferPS()
{
gl_FragColor = texture2D(s_tex, v_texcoord0);
}

View File

@@ -0,0 +1,33 @@
#ifndef GLOBALS_SH_HEADER_GUARD
#define GLOBALS_SH_HEADER_GUARD
// Uniform declarations for bgfx
uniform mat4 u_viewProjection;
uniform vec4 u_viewRight;
uniform vec4 u_viewUp;
uniform vec4 u_viewDir;
uniform vec3 u_cameraPosition;
uniform vec3 u_ambientColor;
uniform vec3 u_lamp0Color;
uniform vec3 u_lamp0Dir;
uniform vec3 u_lamp1Color;
uniform vec3 u_fogColor;
uniform vec4 u_fogParams;
uniform vec4 u_lightBorder;
uniform vec4 u_lightConfig0;
uniform vec4 u_lightConfig1;
uniform vec4 u_lightConfig2;
uniform vec4 u_lightConfig3;
uniform vec4 u_fadeDistance_GlowFactor;
uniform vec4 u_outlineBrightness_ShadowInfo;
uniform vec4 u_shadowMatrix0;
uniform vec4 u_shadowMatrix1;
uniform vec4 u_shadowMatrix2;
#endif // GLOBALS_SH_HEADER_GUARD

View File

@@ -0,0 +1,23 @@
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 0.8
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.2
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.7
#define CFG_GLOSS_LOD 54.0
#define CFG_NORMAL_DETAIL_TILING 0.0
#define CFG_NORMAL_DETAIL_SCALE 0.0
#define CFG_FAR_TILING 0.0
#define CFG_FAR_DIFFUSE_CUTOFF 0.0
#define CFG_FAR_NORMAL_CUTOFF 0.0
#define CFG_FAR_SPECULAR_CUTOFF 0.0
#define CFG_OPT_NORMAL_CONST
#include "material.sc"

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 32.0
#define CFG_REFLECTION_SCALE 0.0
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 20.0
#define CFG_NORMAL_DETAIL_TILING 0.0
#define CFG_NORMAL_DETAIL_SCALE 0.0
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 256.0
#define CFG_REFLECTION_SCALE 0.4
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 128.0
#define CFG_NORMAL_DETAIL_TILING 0.0
#define CFG_NORMAL_DETAIL_SCALE 0.0
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,27 @@
#ifdef CLASSIC
#include "slate.sc"
#else
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.2
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.7
#define CFG_GLOSS_LOD 54.0
#define CFG_NORMAL_DETAIL_TILING 0.0
#define CFG_NORMAL_DETAIL_SCALE 0.0
#define CFG_FAR_TILING 0.0
#define CFG_FAR_DIFFUSE_CUTOFF 0.0
#define CFG_FAR_NORMAL_CUTOFF 0.0
#define CFG_FAR_SPECULAR_CUTOFF 0.0
#define CFG_OPT_NORMAL_CONST
#include "material.sc"
#endif

View File

@@ -0,0 +1,130 @@
#define PIN_SURFACE
#include "default.sc"
#ifndef CFG_WANG_TILES
vec4 sampleFar(sampler2D s, vec2 uv, float fade, float cutoff)
{
#ifdef GLSLES
return texture2D(s, uv);
#else
if (cutoff == 0.0)
return texture2D(s, uv);
else
{
float cscale = 1.0 / (1.0 - cutoff);
return mix(texture2D(s, uv * (CFG_FAR_TILING)),
texture2D(s, uv),
saturate0(fade * cscale - cutoff * cscale));
}
#endif
}
#endif
SAMPLER2D(s_diffuseMap, 5);
SAMPLER2D(s_normalMap, 6);
SAMPLER2D(s_specularMap, 7);
SAMPLER2D(s_studsMap, 0);
#ifndef GLSLES
SAMPLER2D(s_normalDetailMap, 8);
#endif
struct SurfaceInput
{
vec4 Color;
vec2 Uv;
vec2 UvStuds;
#ifdef PIN_REFLECTION
float Reflectance;
#endif
};
struct Surface
{
vec3 albedo;
vec3 normal;
float specular;
float gloss;
float reflectance;
};
vec3 nmapUnpack(vec4 value);
Surface surfaceShader(SurfaceInput IN, vec2 fade2)
{
#ifdef CFG_WANG_TILES
vec2 wangUv;
vec4 wangUVDerivatives;
getWang(s_normalDetailMap, IN.Uv, CFG_TEXTURE_TILING, wangUv, wangUVDerivatives);
#endif
vec2 uv = IN.Uv * (CFG_TEXTURE_TILING);
float fadeDiffuse = fade2.x;
float fade = fade2.y;
#ifdef CFG_OPT_DIFFUSE_CONST
vec4 diffuse = vec4(1.0);
#else
#ifdef CFG_WANG_TILES
vec4 diffuse = sampleWang(s_diffuseMap, wangUv, wangUVDerivatives);
#else
vec4 diffuse = sampleFar(s_diffuseMap, uv, fadeDiffuse, CFG_FAR_DIFFUSE_CUTOFF);
#endif
diffuse.rgba = diffuse.rgba * (CFG_DIFFUSE_SCALE);
#endif
#ifdef CFG_OPT_NORMAL_CONST
vec3 normal = vec3(0.0, 0.0, 1.0);
#else
#ifdef CFG_WANG_TILES
vec3 normal = nmapUnpack(sampleWang(s_normalMap, wangUv, wangUVDerivatives));
#else
vec3 normal = nmapUnpack(sampleFar(s_normalMap, uv, fade, CFG_FAR_NORMAL_CUTOFF));
#endif
#endif
#ifndef GLSLES
#ifndef CFG_WANG_TILES // normal detail unavailable when running wang tiles
vec3 normalDetail = nmapUnpack(texture2D(s_normalDetailMap, uv * (CFG_NORMAL_DETAIL_TILING)));
normal.xy += normalDetail.xy * (CFG_NORMAL_DETAIL_SCALE);
#endif
#endif
normal.xy *= fade;
float shadowFactor = 1.0 + normal.x * (CFG_NORMAL_SHADOW_SCALE);
#ifdef CFG_OPT_BLEND_COLOR
vec3 albedo = mix(vec3(1.0), IN.Color.rgb, diffuse.a) * diffuse.rgb * shadowFactor;
#else
vec3 albedo = IN.Color.rgb * diffuse.rgb * shadowFactor;
#endif
#ifndef GLSLES
vec4 studs = texture2D(s_studsMap, IN.UvStuds);
albedo *= studs.r * 2.0;
#endif
#ifdef CFG_WANG_TILES
vec2 specular = sampleWang(s_specularMap, wangUv, wangUVDerivatives).rg;
#else
vec2 specular = sampleFar(s_specularMap, uv, fade, CFG_FAR_SPECULAR_CUTOFF).rg;
#endif
// make sure glossiness is never 0 to avoid fp specials
vec2 specbase = specular * vec2(CFG_SPECULAR_SCALE, CFG_GLOSS_SCALE) + vec2(0.0, 0.01);
vec2 specfade = mix(vec2(CFG_SPECULAR_LOD, CFG_GLOSS_LOD), specbase, fade);
Surface surface;
surface.albedo = albedo;
surface.normal = normal;
surface.specular = specfade.r;
surface.gloss = specfade.g;
surface.reflectance = specular.g * fade * (CFG_REFLECTION_SCALE);
return surface;
}

View File

@@ -0,0 +1,121 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_tangent
$output v_pos, v_texcoord0, v_texcoord1, v_lightpos_fog, v_view_depth, v_normal, v_tangent, v_color0, v_poslightspace
#include "common.sh"
#include "globals.sh"
SAMPLER2D(s_diffuseHighMap, 0);
SAMPLER2D(s_diffuseLowMap, 1);
SAMPLER2D(s_normalMap, 2);
SAMPLER2D(s_specularMap, 3);
SAMPLER2D(s_lightMap, 4);
SAMPLER2D(s_lightMapLookup, 5);
SAMPLER2D(s_shadowMap, 6);
void MegaClusterVS()
{
// Decode vertex data
vec3 Normal = (a_normal.xyz - 127.0) / 127.0;
vec4 UV = a_texcoord0 / 2048.0;
// Transform position and normal to world space
// Note: world matrix does not contain rotation/scale for static geometry so we can avoid transforming normal
vec3 posWorld = mul(u_worldMatrix, vec4(a_position.xyz, 1.0)).xyz;
vec3 normalWorld = Normal;
v_pos = mul(u_viewProjection, vec4(posWorld, 1.0));
float blend = v_pos.w / 200.0;
v_lightpos_fog = vec4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)), (u_fogParams.z - v_pos.w) * u_fogParams.w);
v_texcoord0.xy = UV.xy;
v_texcoord1.xy = UV.zw;
#ifdef PIN_HQ
v_view_depth = vec4(posWorld, v_pos.w * u_fadeDistance_GlowFactor.y);
vec4 edgeDistances = a_texcoord1 * u_fadeDistance_GlowFactor.z + 0.5 * v_view_depth.w;
v_texcoord0.zw = edgeDistances.xy;
v_texcoord1.zw = edgeDistances.zw;
v_view_depth.xyz = u_cameraPosition.xyz - posWorld;
v_normal = vec4(Normal, blend);
// decode tangent
v_tangent = (a_tangent.xyz - 127.0) / 127.0;
#else
// IF LQ shading is performed in VS
float ndotl = dot(normalWorld, -u_lamp0Dir);
vec3 diffuse = saturate0(ndotl) * u_lamp0Color + max(-ndotl, 0.0) * u_lamp1Color;
v_color0 = vec4(diffuse, blend);
#endif
v_poslightspace = shadowPrepareSample(posWorld);
gl_Position = v_pos;
}
void MegaClusterPS()
{
vec4 high = texture2D(s_diffuseHighMap, v_texcoord0.xy);
vec4 low = texture2D(s_diffuseLowMap, v_texcoord1.xy);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
float shadow = shadowSample(s_shadowMap, v_poslightspace, light.a);
#ifdef PIN_HQ
vec3 albedo = mix(high.rgb, low.rgb, saturate1(v_normal.a));
// sample normal map and specular map
vec4 normalMapSample = texture2D(s_normalMap, v_texcoord0.xy);
vec4 specularMapSample = texture2D(s_specularMap, v_texcoord0.xy);
// compute bitangent and world space normal
vec3 bitangent = cross(v_normal.xyz, v_tangent.xyz);
#ifdef CLASSIC
vec3 nmap = vec3(0.0, 0.0, 0.5);
#else
vec3 nmap = nmapUnpack(normalMapSample);
#endif
vec3 normal = normalize(nmap.x * v_tangent.xyz + nmap.y * bitangent + nmap.z * v_normal.xyz);
float ndotl = dot(normal, -u_lamp0Dir);
vec3 diffuseIntensity = saturate0(ndotl) * u_lamp0Color + max(-ndotl, 0.0) * u_lamp1Color;
float specularIntensity = step(0.0, ndotl) * specularMapSample.r;
float specularPower = specularMapSample.g * 255.0 + 0.01;
// Compute diffuse and specular and combine them
vec3 diffuse = (u_ambientColor + diffuseIntensity * shadow + light.rgb) * albedo.rgb;
vec3 specular = u_lamp0Color * (specularIntensity * shadow * pow(saturate0(dot(normal, normalize(-u_lamp0Dir + normalize(v_view_depth.xyz)))), specularPower));
gl_FragColor.rgb = diffuse + specular;
// apply outlines
float outlineFade = saturate1(v_view_depth.w * u_outlineBrightness_ShadowInfo.x + u_outlineBrightness_ShadowInfo.y);
vec2 minIntermediate = min(v_texcoord0.wz, v_texcoord1.wz);
float minEdgesPlus = min(minIntermediate.x, minIntermediate.y) / v_view_depth.w;
gl_FragColor.rgb *= saturate1(outlineFade * (1.5 - minEdgesPlus) + minEdgesPlus);
gl_FragColor.a = 1.0;
#else
vec3 albedo = mix(high.rgb, low.rgb, saturate1(v_color0.a));
// Compute diffuse term
vec3 diffuse = (u_ambientColor + v_color0.rgb * shadow + light.rgb) * albedo.rgb;
// Combine
gl_FragColor.rgb = diffuse;
gl_FragColor.a = 1.0;
#endif
float fogAlpha = saturate0(v_lightpos_fog.w);
gl_FragColor.rgb = mix(u_fogColor, gl_FragColor.rgb, fogAlpha);
#ifdef CLASSIC
gl_FragColor.rgb = v_texcoord0.xyy;
gl_FragColor.rgb = u_outlineBrightness_ShadowInfo.xxx;
#endif
}

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 256.0
#define CFG_REFLECTION_SCALE 0.5
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 128.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.3
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,3 @@
#define PIN_PLASTIC
#define PIN_NEON
#include "default.sc"

View File

@@ -0,0 +1,198 @@
$input a_position, a_texcoord0, a_texcoord1, a_texcoord2, a_texcoord3
$output v_texcoord0, v_texcoord1, v_color0
#include "common.sh"
SAMPLER2D(s_tex, 0);
SAMPLER2D(s_cstrip, 1);
SAMPLER2D(s_astrip, 2);
uniform vec4 u_throttleFactor; // .x = alpha cutoff, .y = alpha boost (clamp), .w - additive/alpha ratio for Crazy shaders
uniform vec4 u_modulateColor;
uniform vec4 u_zOffset;
vec4 rotScale(vec4 scaleRotLife)
{
float cr = cos(scaleRotLife.z);
float sr = sin(scaleRotLife.z);
vec4 r;
r.x = cr * scaleRotLife.x;
r.y = -sr * scaleRotLife.x;
r.z = sr * scaleRotLife.y;
r.w = cr * scaleRotLife.y;
return r;
}
vec4 mulq(vec4 a, vec4 b)
{
vec3 i = cross(a.xyz, b.xyz) + a.w * b.xyz + b.w * a.xyz;
float r = a.w * b.w - dot(a.xyz, b.xyz);
return vec4(i, r);
}
vec4 conj(vec4 a)
{
return vec4(-a.xyz, a.w);
}
vec4 rotate(vec4 v, vec4 q)
{
return mulq(mulq(q, v), conj(q));
}
vec4 axis_angle(vec3 axis, float angle)
{
return vec4(sin(angle/2.0) * axis, cos(angle/2.0));
}
void vs()
{
vec4 pos = vec4(a_position, 1.0);
vec2 disp = a_texcoord1.xy * 2.0 - 1.0; // -1..1
vec4 scaleRotLifeFlt = a_texcoord0 * vec4(1.0/256.0, 1.0/256.0, 2.0 * 3.1415926 / 32767.0, 1.0 / 32767.0);
scaleRotLifeFlt.xy += 127.0;
vec4 rs = rotScale(scaleRotLifeFlt);
pos += u_viewRight * dot(disp, rs.xy);
pos += u_viewUp * dot(disp, rs.zw);
vec4 pos2 = pos + u_viewDir * u_zOffset.x; // Z-offset position in world space
gl_Position = mul(u_viewProjection, pos);
v_texcoord0.xy = a_texcoord1.xy;
v_texcoord0.y = 1.0 - v_texcoord0.y;
v_texcoord0.z = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
v_texcoord1.x = 1.0 - max(0.0, min(1.0, scaleRotLifeFlt.w));
v_texcoord1.y = a_texcoord2.x * (1.0 / 32767.0);
pos2 = mul(u_viewProjection, pos2); // Z-offset position in clip space
gl_Position.z = pos2.z * gl_Position.w / pos2.w; // Only need z
}
void psAdd()
{
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
vec4 vcolor = texture2D(s_cstrip, v_texcoord1.xy);
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r;
vec4 result;
result.rgb = (texcolor.rgb + vcolor.rgb) * u_modulateColor.rgb;
result.a = texcolor.a * vcolor.a;
result.rgb *= result.a;
result.rgb = mix(vec3(0.0), result.rgb, saturate(v_texcoord0.zzz));
gl_FragColor = result;
}
void psModulate()
{
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
vec4 vcolor = texture2D(s_cstrip, v_texcoord1.xy) * u_modulateColor;
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r * u_modulateColor.a;
vec4 result;
result.rgb = texcolor.rgb * vcolor.rgb;
result.a = texcolor.a * vcolor.a;
result.rgb = mix(u_fogColor.rgb, result.rgb, saturate(v_texcoord0.zzz));
gl_FragColor = result;
}
// - this shader is crazy
// - used instead of additive particles to help see bright particles (e.g. fire) on top of extremely bright backgrounds
// - requires ONE | INVSRCALPHA blend mode, useless otherwise
// - does not use color strip texture
// - outputs a blend between additive blend and alpha blend in fragment alpha
// - ratio multiplier is in throttleFactor.w
void psCrazy()
{
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
vec4 vcolor = vec4(1.0, 0.0, 0.0, 0.0);
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r;
float blendRatio = u_throttleFactor.w;
vec4 result;
result.rgb = (texcolor.rgb) * u_modulateColor.rgb * vcolor.a * texcolor.a;
result.a = blendRatio * texcolor.a * vcolor.a;
result = mix(vec4(0.0), result, saturate(v_texcoord0.zzzz));
gl_FragColor = result;
}
void psCrazySparkles()
{
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
vec4 vcolor = texture2D(s_cstrip, v_texcoord1.xy);
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r;
float blendRatio = u_throttleFactor.w;
vec4 result;
if (texcolor.a < 0.5)
{
result.rgb = vcolor.rgb * u_modulateColor.rgb * (2.0 * texcolor.a);
}
else
{
result.rgb = mix(vcolor.rgb * u_modulateColor.rgb, texcolor.rgb, 2.0 * texcolor.a - 1.0);
}
result.rgb *= vcolor.a;
result.a = blendRatio * texcolor.a * vcolor.a;
result = mix(vec4(0.0), result, saturate(v_texcoord0.zzzz));
gl_FragColor = result;
}
// Custom particle shader
void vsCustom()
{
vec4 pos = vec4(a_position, 1.0);
vec2 disp = a_texcoord1.xy * 2.0 - 1.0; // -1..1
vec4 scaleRotLifeFlt = a_texcoord0 * vec4(1.0/256.0, 1.0/256.0, 2.0 * 3.1415926 / 32767.0, 1.0 / 32767.0);
scaleRotLifeFlt.xy += 127.0;
vec4 rs = rotScale(scaleRotLifeFlt);
pos += u_viewRight * dot(disp, rs.xy);
pos += u_viewUp * dot(disp, rs.zw);
vec4 pos2 = pos + u_viewDir * u_zOffset.x; // Z-offset position in world space
gl_Position = mul(u_viewProjection, pos);
v_texcoord0.xy = a_texcoord1.xy;
v_texcoord0.y = 1.0 - v_texcoord0.y;
v_texcoord0.z = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
v_color0 = a_texcoord3 * (1.0/255.0);
pos2 = mul(u_viewProjection, pos2); // Z-offset position in clip space
gl_Position.z = pos2.z * gl_Position.w / pos2.w; // Only need z
}
void psCustom()
{
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
vec4 vcolor = v_color0;
float blendRatio = u_throttleFactor.w;
vec4 result;
result.rgb = texcolor.rgb * vcolor.rgb * vcolor.a * texcolor.a;
result.a = blendRatio * texcolor.a * vcolor.a;
result = mix(vec4(0.0), result, saturate(v_texcoord0.zzzz));
gl_FragColor = result;
}

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 32.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.15
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 20.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.5
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,208 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_color0, a_color1, a_texcoord2, a_texcoord3
$output v_pos, v_worldPos, v_texcoord0, v_texcoord1, v_color0, v_normal, v_tangent, v_lightpos_fog, v_view_depth, v_poslightspace, v_edgedist, v_reflection
#include "common.sh"
#ifdef CLASSIC
#ifdef PIN_HQ
#define PIN_SURFACE
#define ALREADY_HAS_PS
#define SPEC_EXPON 81.0
#define KS 0.75
#define FADE_DIST 500.0
#define FADE_DIST_START 0.0
#define BEVEL_WIDTH 0.06
SAMPLER2D(s_diffuseMap, 5);
SAMPLER2D(s_normalMap, 6);
SAMPLER2D(s_lightMap, 1);
SAMPLER2D(s_lightMapLookup, 2);
SAMPLERCUBE(s_environmentMap, 4);
#ifndef GLSLES
SAMPLER2D(s_normalDetailMap, 8);
#endif
uniform vec4 u_waveParams; // .x = frequency .y = phase .z = height .w = lerp
vec3 CalcBevelDir(vec4 edgeDistances)
{
vec3 dir = vec3(0.0);
vec4 bevelMultiplier = step(edgeDistances, vec4(BEVEL_WIDTH));
dir += bevelMultiplier.x * vec3(1.0, 0.0, 0.0);
dir += bevelMultiplier.y * vec3(-1.0, 0.0, 0.0);
dir += bevelMultiplier.z * vec3(0.0, 1.0, 0.0);
dir += bevelMultiplier.w * vec3(0.0, -1.0, 0.0);
return dir;
}
vec3 CalcBevel(vec4 edgeDistances, vec3 normal, float viewDepth);
void Shade(vec3 albedo, vec3 nn, vec3 vn, float ks, float specExpon, vec4 light, out vec3 diffuse, out vec3 specular);
void DefaultPS()
{
float normalStrength = 0.4;
float fade = clamp(normalStrength - (v_view_depth.w - FADE_DIST_START) / FADE_DIST, 0.0, 1.0);
vec3 nn = normalize(v_normal);
vec4 edgeDistances = v_edgedist;
vec4 albedo = v_color0;
vec2 uv;
float wt = 1.0;
#ifndef PIN_MESH
uv = v_texcoord1; // UvStuds
mat3 normalMatrix = mat3(
v_tangent.xyz,
cross(nn, v_tangent.xyz),
nn
);
vec3 tn = vec3(0.0, 0.0, 0.5);
tn = mix(vec3(0.0, 0.0, 0.5), tn, fade);
tn = CalcBevel(edgeDistances, tn, v_view_depth.w);
nn = mul(tn, normalMatrix);
wt = 1.0 - abs(length(tn.xy));
vec4 colorTex = texture2D(s_diffuseMap, uv);
#else
uv = v_texcoord0;
vec4 colorTex = texture2D(s_diffuseMap, uv);
albedo *= colorTex;
#endif
vec3 vn = normalize(v_view_depth.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
vec3 diffuse;
vec3 specular;
#ifdef CLASSIC_GOURAUD
vec3 diffusePhong;
vec3 specularPhong;
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffusePhong, specularPhong);
diffuse = mix(diffusePhong, albedo.rgb, wt); // Simplified - should use stored diffuse
specular = mix(specularPhong, vec3(0.0), wt); // Simplified - should use stored specular
#else
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
#endif
#ifndef PIN_MESH
diffuse = mix(diffuse, colorTex.xyz, colorTex.w);
#endif
vec3 result = diffuse + specular;
#ifdef PIN_REFLECTION
vec3 reflection = textureCube(s_environmentMap, reflect(-vn, nn)).rgb;
result = mix(result, reflection, v_reflection);
#endif
float fogAlpha = clamp((u_fogParams.z - length(v_view_depth.xyz)) * u_fogParams.w, 0.0, 1.0);
result = mix(u_fogColor, result, fogAlpha);
gl_FragColor = vec4(result, albedo.a);
#ifdef PIN_GBUFFER
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define PIN_PLASTIC
#include "default.sc"
#endif
#else // !CLASSIC
#if defined(PIN_HQ)
#define PIN_SURFACE
#define CFG_TEXTURE_TILING 1.0
#define CFG_BUMP_INTENSITY 0.5
#define CFG_SPECULAR 0.4
#define CFG_GLOSS 9.0
#define CFG_NORMAL_SHADOW_SCALE 0.1
struct SurfaceInput
{
vec4 Color;
vec2 Uv;
vec2 UvStuds;
#ifdef PIN_REFLECTION
float Reflectance;
#endif
};
struct Surface
{
vec3 albedo;
vec3 normal;
float specular;
float gloss;
float reflectance;
};
SAMPLER2D(s_diffuseMap, 5);
SAMPLER2D(s_normalMap, 6);
#ifndef GLSLES
SAMPLER2D(s_normalDetailMap, 8);
#endif
vec3 nmapUnpack(vec4 value);
Surface surfaceShader(SurfaceInput IN, vec2 fade2)
{
float fade = fade2.y;
vec4 studs = texture2D(s_diffuseMap, IN.UvStuds);
vec3 normal = nmapUnpack(texture2D(s_normalMap, IN.UvStuds));
#ifdef GLSLES
vec3 noise = vec3(0.0, 0.0, 1.0);
#else
vec3 noise = nmapUnpack(texture2D(s_normalDetailMap, IN.Uv * CFG_TEXTURE_TILING));
#endif
float noiseScale = saturate0(IN.Color.a * 2.0 * CFG_BUMP_INTENSITY - 1.0 * CFG_BUMP_INTENSITY);
#ifdef PIN_REFLECTION
noiseScale *= clamp(1.0 - 2.0 * IN.Reflectance, 0.0, 1.0);
#endif
normal.xy += noise.xy * noiseScale;
normal.xy *= fade;
Surface surface;
surface.albedo = IN.Color.rgb * (studs.r * 2.0);
surface.normal = normal;
surface.specular = CFG_SPECULAR;
surface.gloss = CFG_GLOSS;
#ifdef PIN_REFLECTION
surface.reflectance = IN.Reflectance;
#endif
return surface;
}
#include "default.sc"
#else
#define PIN_PLASTIC
#include "default.sc"
#endif
#endif // CLASSIC

View File

@@ -0,0 +1,31 @@
$input a_position, a_texcoord0, a_color0
$output v_texcoord0, v_color0
#include "common.sh"
SAMPLER2D(s_diffuseMap, 0);
void ProfilerVS()
{
gl_Position = mul(u_viewProjection, vec4(a_position, 1.0));
gl_Position.y = -gl_Position.y;
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}
void ProfilerPS()
{
vec4 c0 = texture2D(s_diffuseMap, v_texcoord0);
vec4 c1 = texture2D(s_diffuseMap, v_texcoord0 + vec2(0.0, 1.0 / 9.0));
gl_FragColor = c0.a < 0.5 ? vec4(0.0, 0.0, 0.0, c1.a) : c0 * v_color0;
}
void ImGuiPS()
{
vec4 texColor = texture2D(s_diffuseMap, v_texcoord0);
vec4 finalColor = texColor * v_color0;
gl_FragColor = finalColor;
}

View File

@@ -0,0 +1,15 @@
#define CFG_WANG_TILES
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 64.0
#include "material.sc"

View File

@@ -0,0 +1,21 @@
#define CFG_TEXTURE_TILING 4.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 96.0
#define CFG_REFLECTION_SCALE 0.0
#define CFG_NORMAL_SHADOW_SCALE 0.15
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 48.0
#define CFG_NORMAL_DETAIL_TILING 16.0
#define CFG_NORMAL_DETAIL_SCALE 0.5
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.5
#define CFG_FAR_NORMAL_CUTOFF 0.5
#define CFG_FAR_SPECULAR_CUTOFF 0.5
#include "material.sc"

View File

@@ -0,0 +1,343 @@
$input a_position
$output v_pos, v_texcoord0, v_texcoord1, v_texcoord2
#include "common.sh"
#include "globals.sh"
SAMPLER2D(s_texture, 0);
SAMPLER2D(s_mask, 1);
// .xy = gbuffer width/height, .zw = inverse gbuffer width/height
uniform vec4 u_textureSize;
uniform vec4 u_params1;
uniform vec4 u_params2;
vec4 convertPosition(vec4 p, float scale)
{
#if defined(GLSL) || defined(DX11)
return p;
#else
// half-pixel offset
return p + vec4(-u_textureSize.z, u_textureSize.w, 0.0, 0.0) * scale;
#endif
}
vec2 convertUv(vec4 p)
{
#ifndef GLSL
return p.xy * vec2(0.5, -0.5) + 0.5;
#else
return p.xy * 0.5 + 0.5;
#endif
}
// ===== Pass Through =====
void passThrough_vs()
{
v_pos = convertPosition(vec4(a_position.xyz, 1.0), 1.0);
v_texcoord0.xy = convertUv(vec4(a_position.xyz, 1.0));
gl_Position = v_pos;
}
void passThrough_ps()
{
gl_FragColor = texture2D(s_texture, v_texcoord0.xy);
}
// ===== Image Processing =====
void imageProcess_ps()
{
vec3 color = texture2D(s_texture, v_texcoord0.xy).rgb;
vec4 tintColor = vec4(u_params2.xyz, 1.0);
float contrast = u_params1.y;
float brightness = u_params1.x;
float grayscaleLvl = u_params1.z;
color = contrast * (color - 0.5) + 0.5 + brightness;
float grayscale = (color.r + color.g + color.g) / 3.0;
gl_FragColor = mix(vec4(color.rgb, 1.0), vec4(grayscale, grayscale, grayscale, 1.0), grayscaleLvl) * tintColor;
}
// ===== Gaussian Blur =====
vec4 gauss(float samples, vec2 uv)
{
vec2 step = u_params1.xy;
float sigma = u_params1.z;
float sigmaN1 = 1.0 / sqrt(2.0 * 3.1415926 * sigma * sigma);
float sigmaN2 = 1.0 / (2.0 * sigma * sigma);
// First sample is in the center and accounts for our pixel
vec4 result = texture2D(s_texture, uv) * sigmaN1;
float weight = sigmaN1;
// Every loop iteration computes impact of 4 pixels
// Each sample computes impact of 2 neighbor pixels, starting with the next one to the right
// Note that we sample exactly in between pixels to leverage bilinear filtering
for (int i = 0; i < int(samples); ++i)
{
float ix = 2.0 * float(i) + 1.5;
float iw = 2.0 * exp(-ix * ix * sigmaN2) * sigmaN1;
result += (texture2D(s_texture, uv + step * ix) + texture2D(s_texture, uv - step * ix)) * iw;
weight += 2.0 * iw;
}
// Since the above is an approximation of the integral with step functions, normalization compensates for the error
return (result / weight);
}
void blur3_ps()
{
gl_FragColor = gauss(3.0, v_texcoord0.xy);
}
void blur5_ps()
{
gl_FragColor = gauss(5.0, v_texcoord0.xy);
}
void blur7_ps()
{
gl_FragColor = gauss(7.0, v_texcoord0.xy);
}
// ===== FXAA =====
void fxaa_ps()
{
vec2 uv = v_texcoord0.xy;
vec2 rcpFrame = u_textureSize.zw;
// Luma conversion weights
const vec3 luma = vec3(0.299, 0.587, 0.114);
// Sample 3x3 neighborhood
vec3 rgbM = texture2D(s_texture, uv).rgb;
vec3 rgbN = texture2D(s_texture, uv + vec2(0.0, -rcpFrame.y)).rgb;
vec3 rgbS = texture2D(s_texture, uv + vec2(0.0, rcpFrame.y)).rgb;
vec3 rgbE = texture2D(s_texture, uv + vec2(rcpFrame.x, 0.0)).rgb;
vec3 rgbW = texture2D(s_texture, uv + vec2(-rcpFrame.x, 0.0)).rgb;
vec3 rgbNW = texture2D(s_texture, uv + vec2(-rcpFrame.x, -rcpFrame.y)).rgb;
vec3 rgbNE = texture2D(s_texture, uv + vec2(rcpFrame.x, -rcpFrame.y)).rgb;
vec3 rgbSW = texture2D(s_texture, uv + vec2(-rcpFrame.x, rcpFrame.y)).rgb;
vec3 rgbSE = texture2D(s_texture, uv + vec2(rcpFrame.x, rcpFrame.y)).rgb;
float lumaM = dot(rgbM, luma);
float lumaN = dot(rgbN, luma);
float lumaS = dot(rgbS, luma);
float lumaE = dot(rgbE, luma);
float lumaW = dot(rgbW, luma);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
// Find local contrast including corners
float lumaMin = min(lumaM, min(min(min(lumaN, lumaS), min(lumaE, lumaW)),
min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))));
float lumaMax = max(lumaM, max(max(max(lumaN, lumaS), max(lumaE, lumaW)),
max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))));
float range = lumaMax - lumaMin;
// Very low threshold - catch almost all edges
if (range < max(0.0156, lumaMax * 0.0625))
{
gl_FragColor = vec4(rgbM, 1.0);
return;
}
// Determine edge orientation
float edgeVert = abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) +
abs((0.50 * lumaW) + (-1.0 * lumaM) + (0.50 * lumaE)) +
abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE));
float edgeHorz = abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) +
abs((0.50 * lumaN) + (-1.0 * lumaM) + (0.50 * lumaS)) +
abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE));
bool isHorizontal = (edgeHorz >= edgeVert);
// Select samples along edge
float luma1 = isHorizontal ? lumaS : lumaE;
float luma2 = isHorizontal ? lumaN : lumaW;
float gradient1 = luma1 - lumaM;
float gradient2 = luma2 - lumaM;
// Pick steepest gradient
bool is1Steepest = abs(gradient1) >= abs(gradient2);
float gradientScaled = 0.25 * max(abs(gradient1), abs(gradient2));
float lengthSign = is1Steepest ? -1.0 : 1.0;
if (!isHorizontal)
lengthSign *= -1.0;
// Setup for edge search
vec2 posB = uv;
vec2 offNP;
offNP.x = (!isHorizontal) ? rcpFrame.x : 0.0;
offNP.y = (isHorizontal) ? rcpFrame.y : 0.0;
if (!isHorizontal)
posB.x += lengthSign * 0.5 * rcpFrame.x;
else
posB.y += lengthSign * 0.5 * rcpFrame.y;
// Extended edge search
vec2 posN = posB - offNP;
vec2 posP = posB + offNP;
float lumaEndN = dot(texture2D(s_texture, posN).rgb, luma) - lumaM * 0.5;
float lumaEndP = dot(texture2D(s_texture, posP).rgb, luma) - lumaM * 0.5;
bool doneN = abs(lumaEndN) >= gradientScaled;
bool doneP = abs(lumaEndP) >= gradientScaled;
float stepSizes[12];
stepSizes[0] = 1.0; stepSizes[1] = 1.0; stepSizes[2] = 1.5; stepSizes[3] = 1.5;
stepSizes[4] = 2.0; stepSizes[5] = 2.0; stepSizes[6] = 4.0; stepSizes[7] = 4.0;
stepSizes[8] = 8.0; stepSizes[9] = 8.0; stepSizes[10] = 16.0; stepSizes[11] = 16.0;
for (int i = 0; i < 12; ++i)
{
if (doneN && doneP) break;
if (!doneN)
{
posN -= offNP * stepSizes[i];
lumaEndN = dot(texture2D(s_texture, posN).rgb, luma) - lumaM * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
}
if (!doneP)
{
posP += offNP * stepSizes[i];
lumaEndP = dot(texture2D(s_texture, posP).rgb, luma) - lumaM * 0.5;
doneP = abs(lumaEndP) >= gradientScaled;
}
}
// Calculate span and offset
float dstN = isHorizontal ? (uv.x - posN.x) : (uv.y - posN.y);
float dstP = isHorizontal ? (posP.x - uv.x) : (posP.y - uv.y);
bool directionN = dstN < dstP;
float dst = min(dstN, dstP);
float spanLength = (dstP + dstN);
float spanLengthRcp = 1.0 / spanLength;
float pixelOffset = dst * (-spanLengthRcp) + 0.5;
// Check if we're at a good span
bool goodSpanN = (lumaEndN < 0.0) != (lumaM < lumaMin);
bool goodSpanP = (lumaEndP < 0.0) != (lumaM < lumaMin);
bool goodSpan = directionN ? goodSpanN : goodSpanP;
if (!goodSpan)
pixelOffset = 0.0;
// sub-pixel antialiasing
float lumaAverage = (1.0 / 12.0) * (2.0 * (lumaN + lumaS + lumaE + lumaW) +
lumaNW + lumaNE + lumaSW + lumaSE);
float subPixelOffset1 = saturate0(abs(lumaAverage - lumaM) / range);
subPixelOffset1 = (-2.0 * subPixelOffset1 + 3.0) * subPixelOffset1 * subPixelOffset1;
subPixelOffset1 = subPixelOffset1 * subPixelOffset1 * 0.85;
float pixelOffsetFinal = max(pixelOffset, subPixelOffset1);
// Apply offset
vec2 finalUv = uv;
if (!isHorizontal)
finalUv.x += pixelOffsetFinal * lengthSign * rcpFrame.x;
else
finalUv.y += pixelOffsetFinal * lengthSign * rcpFrame.y;
// Additional edge blending for remaining jaggies
vec3 rgbFinal = texture2D(s_texture, finalUv).rgb;
// If we're on a strong edge, do additional smart blending
if (range > 0.1)
{
float edgeBlend = saturate0(range * 2.0 - 0.2);
vec3 rgbBlur = (rgbN + rgbS + rgbE + rgbW) * 0.25;
rgbFinal = mix(rgbFinal, rgbBlur, edgeBlend * 0.15);
}
gl_FragColor = vec4(rgbFinal, 1.0);
}
// ===== Glow Apply =====
void glowApply_ps()
{
vec4 color = texture2D(s_texture, v_texcoord0.xy);
gl_FragColor = vec4(color.rgb * u_params1.x, color.a);
}
// ===== Downsample 4x4 =====
void downsample4x4_vs()
{
vec2 uv = convertUv(vec4(a_position.xyz, 1.0));
v_pos = convertPosition(vec4(a_position.xyz, 1.0), 1.0);
v_texcoord0.xy = uv;
vec2 uvOffset = u_textureSize.zw * 0.25;
v_texcoord0.zw = uv + uvOffset * vec2(-1.0, -1.0);
v_texcoord1.xy = uv + uvOffset * vec2(+1.0, -1.0);
v_texcoord1.zw = uv + uvOffset * vec2(-1.0, +1.0);
v_texcoord2.xy = uv + uvOffset * vec2(+1.0, +1.0);
gl_Position = v_pos;
}
void downSample4x4Glow_ps()
{
vec4 avgColor = texture2D(s_texture, v_texcoord0.zw);
avgColor += texture2D(s_texture, v_texcoord1.xy);
avgColor += texture2D(s_texture, v_texcoord1.zw);
avgColor += texture2D(s_texture, v_texcoord2.xy);
avgColor *= 0.25;
gl_FragColor = vec4(avgColor.rgb, 1.0) * (1.0 - avgColor.a);
}
// ===== Shadow Blur =====
void ShadowBlurPS()
{
#ifdef GLSLES
int N = 1;
float sigma = 0.5;
#else
int N = 3;
float sigma = 1.5;
#endif
vec2 step = u_params1.xy;
float sigmaN1 = 1.0 / sqrt(2.0 * 3.1415926 * sigma * sigma);
float sigmaN2 = 1.0 / (2.0 * sigma * sigma);
float depth = 1.0;
float color = 0.0;
float weight = 0.0;
for (int i = -N; i <= N; ++i)
{
float ix = float(i);
float iw = exp(-ix * ix * sigmaN2) * sigmaN1;
vec4 data = texture2D(s_texture, v_texcoord0.xy + step * ix);
depth = min(depth, data.x);
color += data.y * iw;
weight += iw;
}
float mask = texture2D(s_mask, v_texcoord0.xy).r;
// Since the above is an approximation of the integral with step functions, normalization compensates for the error
gl_FragColor = vec4(depth, color * mask * (1.0 / weight), 0.0, 0.0);
}

View File

@@ -0,0 +1,33 @@
$input a_position, a_color1
$output v_texcoord0
#include "common.sh"
void ShadowVS()
{
// Transform position to world space
#ifdef PIN_SKINNED
int boneIndex = int(a_color1.r);
vec4 worldRow0 = u_worldMatrixArray[boneIndex * 3 + 0];
vec4 worldRow1 = u_worldMatrixArray[boneIndex * 3 + 1];
vec4 worldRow2 = u_worldMatrixArray[boneIndex * 3 + 2];
vec3 posWorld = vec3(dot(worldRow0, vec4(a_position, 1.0)),
dot(worldRow1, vec4(a_position, 1.0)),
dot(worldRow2, vec4(a_position, 1.0)));
#else
vec3 posWorld = a_position;
#endif
gl_Position = mul(u_viewProjection, vec4(posWorld, 1.0));
v_texcoord0 = shadowPrepareSample(posWorld);
}
void ShadowPS()
{
float depth = shadowDepth(v_texcoord0);
gl_FragColor = vec4(depth, 1.0, 0.0, 0.0);
}

View File

@@ -0,0 +1,35 @@
$input a_position, a_texcoord0, a_color0
$output v_texcoord0, v_color0
#include "common.sh"
uniform vec4 u_color;
uniform vec4 u_color2;
SAMPLER2D(s_diffuseMap, 0);
void SkyVS()
{
vec4 wpos = mul(u_worldMatrix, vec4(a_position, 1.0));
gl_Position = mul(u_viewProjection, wpos);
#ifndef GLSLES
// snap to far plane to prevent scene-sky intersections
// small offset is needed to prevent 0/0 division in case w=0, which causes rasterization issues
// some mobile chips (hello, Vivante!) don't like it
gl_Position.z = gl_Position.w - 1.0 / 16.0;
#endif
#if BGFX_SHADER_LANGUAGE_GLSL
gl_PointSize = 2.0; // star size
#endif
v_texcoord0 = a_texcoord0;
v_color0 = a_color0 * mix(u_color2, u_color, wpos.y / 1700.0);
}
void SkyPS()
{
gl_FragColor = texture2D(s_diffuseMap, v_texcoord0) * v_color0;
}

View File

@@ -0,0 +1,98 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_color0, a_color1, a_texcoord2, a_texcoord3
$output v_pos, v_worldPos, v_texcoord0, v_texcoord1, v_color0, v_normal, v_tangent, v_lightpos_fog, v_view_depth, v_poslightspace, v_edgedist, v_reflection
#include "common.sh"
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#define SPEC_EXPON 40.0
#define KS 0.1
#define NOISE_SCALE 7.0
#define SPREAD 0.3
#define GRASS_THRESHOLD 0.95
#define FADE_DIST 290.0
#define FADE_DIST_START 0.0
SAMPLER2D(s_normalMap, 6);
SAMPLER3D(s_specularMap, 7);
SAMPLER2D(s_lightMap, 1);
SAMPLER2D(s_lightMapLookup, 2);
SAMPLER2D(s_shadowMap, 3);
vec3 CalcBevel(vec4 edgeDistances, vec3 normal, float viewDepth);
void Shade(vec3 albedo, vec3 nn, vec3 vn, float ks, float specExpon, vec4 light, out vec3 diffuse, out vec3 specular);
void DefaultPS()
{
vec3 normal = normalize(v_normal);
mat3 normalMatrix = mat3(
v_tangent.xyz,
cross(normal, v_tangent.xyz),
normal
);
float fade = clamp(1.0 - (v_view_depth.w - FADE_DIST_START) / FADE_DIST, 0.0, 1.0);
vec2 uv = v_texcoord0;
vec3 shiftPos = v_pos;
float noiseval = texture3D(s_specularMap, shiftPos.xyz / NOISE_SCALE * 0.04).x;
float noiseval2 = texture3D(s_specularMap, shiftPos.xyz / NOISE_SCALE * 0.3).x + 0.2;
noiseval *= noiseval2;
vec3 albedo = v_color0.xyz + 0.8 * fade * (noiseval * 0.5 - 0.1);
vec3 tn = texture2D(s_normalMap, uv).xyz - 0.5;
float tNormSum = 0.9 + 0.4 * (tn.x + tn.y + tn.z);
tn = mix(tn, vec3(0.0, 0.0, 0.5), 0.9);
albedo *= ((1.0 - fade) + (fade * tNormSum));
tn = CalcBevel(v_edgedist, tn, v_view_depth.w);
vec3 nn = mul(tn, normalMatrix);
vec3 vn = normalize(v_view_depth.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
light.a = shadowSample(s_shadowMap, v_poslightspace, light.a);
vec3 diffuse;
vec3 specular;
Shade(albedo, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
gl_FragColor = vec4(diffuse + specular, v_color0.w);
float fogAlpha = clamp((u_fogParams.z - length(v_view_depth.xyz)) * u_fogParams.w, 0.0, 1.0);
gl_FragColor.xyz = mix(u_fogColor, gl_FragColor.rgb, fogAlpha);
#ifdef PIN_GBUFFER
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 0.9
#define CFG_GLOSS_SCALE 128.0
#define CFG_REFLECTION_SCALE 0.0
#define CFG_NORMAL_SHADOW_SCALE 0.5
#define CFG_SPECULAR_LOD 0.14
#define CFG_GLOSS_LOD 20.0
#define CFG_NORMAL_DETAIL_TILING 5.0
#define CFG_NORMAL_DETAIL_SCALE 1.0
#define CFG_FAR_TILING 0.25
#define CFG_FAR_DIFFUSE_CUTOFF 0.75
#define CFG_FAR_NORMAL_CUTOFF 0.0
#define CFG_FAR_SPECULAR_CUTOFF 0.0
#include "material.sc"
#endif

View File

@@ -0,0 +1,149 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1
$output v_pos, v_color0, v_color1, v_texcoord0, v_texcoord1, v_texcoord2, v_lightpos_fog, v_poslightspace, v_normal, v_view_depth
#include "common.sh"
#include "globals.sh"
uniform vec4 u_layerScale;
SAMPLER2D(s_albedoMap, 0);
SAMPLER2D(s_normalMap, 1);
SAMPLER2D(s_specularMap, 2);
SAMPLERCUBE(s_envMap, 3);
SAMPLER2D(s_lightMap, 4);
SAMPLER2D(s_lightMapLookup, 5);
SAMPLER2D(s_shadowMap, 6);
vec4 getUV(vec3 position, int material, int projection, float seed)
{
vec3 u = u_worldMatrixArray[1 + projection].xyz;
vec3 v = u_worldMatrixArray[19 + projection].xyz;
vec4 m = u_worldMatrixArray[37 + material];
vec2 uv = vec2(dot(position, u), dot(position, v)) * m.x + m.y * vec2(seed, floor(seed * 2.6651441));
return vec4(uv, m.zw);
}
void TerrainVS()
{
vec3 posWorld = a_position.xyz * u_worldMatrixArray[0].w + u_worldMatrixArray[0].xyz;
vec3 normalWorld = a_normal.xyz * (1.0 / 127.0) - 1.0;
v_pos = mul(u_viewProjection, vec4(posWorld, 1.0));
v_lightpos_fog = vec4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)), (u_fogParams.z - v_pos.w) * u_fogParams.w);
v_poslightspace = shadowPrepareSample(posWorld);
v_texcoord0 = getUV(posWorld, int(a_texcoord0.x), int(a_texcoord1.x), a_normal.w / 255.0);
v_texcoord1 = getUV(posWorld, int(a_texcoord0.y), int(a_texcoord1.y), a_texcoord0.w / 255.0);
v_texcoord2 = getUV(posWorld, int(a_texcoord0.z), int(a_texcoord1.z), a_texcoord1.w / 255.0);
#if defined(GLSLES) && !defined(GL3) // iPad2 workaround
v_color0.xyz = vec3(
abs(a_position.w - 0.0) < 0.1 ? 1.0 : 0.0,
abs(a_position.w - 1.0) < 0.1 ? 1.0 : 0.0,
abs(a_position.w - 2.0) < 0.1 ? 1.0 : 0.0
);
#else
v_color0.xyz = vec3(
a_position.w == 0.0 ? 1.0 : 0.0,
a_position.w == 1.0 ? 1.0 : 0.0,
a_position.w == 2.0 ? 1.0 : 0.0
);
#endif
#ifdef PIN_HQ
v_normal = normalWorld;
v_view_depth = vec4(u_cameraPosition - posWorld, v_pos.w);
v_color1.xyz = vec3(
a_texcoord1.x > 7.5 ? 1.0 : 0.0,
a_texcoord1.y > 7.5 ? 1.0 : 0.0,
a_texcoord1.z > 7.5 ? 1.0 : 0.0
); // side vs top
#else
float ndotl = dot(normalWorld, -u_lamp0Dir);
vec3 diffuse = max(ndotl, 0.0) * u_lamp0Color + max(-ndotl, 0.0) * u_lamp1Color;
v_color1.xyz = diffuse;
#endif
gl_Position = v_pos;
}
vec4 sampleMap(sampler2D s, vec4 uv)
{
#ifdef PIN_HQ
vec2 uvs = uv.xy * u_layerScale.xy;
return texture2DGrad(s, fract(uv.xy) * u_layerScale.xy + uv.zw, dFdx(uvs), dFdy(uvs));
#else
return texture2D(s, fract(uv.xy) * u_layerScale.xy + uv.zw);
#endif
}
vec4 sampleBlend(sampler2D s, vec4 uv0, vec4 uv1, vec4 uv2, vec3 w)
{
return
sampleMap(s, uv0) * w.x +
sampleMap(s, uv1) * w.y +
sampleMap(s, uv2) * w.z;
}
vec3 sampleNormal(sampler2D s, vec4 uv0, vec4 uv1, vec4 uv2, vec3 w, vec3 normal, vec3 tsel)
{
return terrainNormal(sampleMap(s, uv0), sampleMap(s, uv1), sampleMap(s, uv2), w, normal, tsel);
}
void TerrainPS()
{
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
float shadow = shadowSample(s_shadowMap, v_poslightspace, light.a);
vec3 w = v_color0.xyz;
vec4 albedo = sampleBlend(s_albedoMap, v_texcoord0, v_texcoord1, v_texcoord2, w);
#ifdef PIN_HQ
float fade = saturate0(1.0 - v_view_depth.w * u_fadeDistance_GlowFactor.y);
#ifndef PIN_GBUFFER
vec3 normal = v_normal;
#else
vec3 normal = sampleNormal(s_normalMap, v_texcoord0, v_texcoord1, v_texcoord2, w, v_normal, v_color1.xyz);
#endif
vec4 params = sampleBlend(s_specularMap, v_texcoord0, v_texcoord1, v_texcoord2, w);
float ndotl = dot(normal, -u_lamp0Dir);
// Compute diffuse term
vec3 diffuse = (u_ambientColor + (saturate0(ndotl) * u_lamp0Color + max(-ndotl, 0.0) * u_lamp1Color) * shadow + light.rgb + params.b * 2.0) * albedo.rgb;
// Compute specular term
float specularIntensity = step(0.0, ndotl) * params.r * fade;
float specularPower = params.g * 128.0 + 0.01;
vec3 specular = u_lamp0Color * (specularIntensity * shadow * pow(saturate0(dot(normal, normalize(-u_lamp0Dir + normalize(v_view_depth.xyz)))), specularPower));
#else
// Compute diffuse term
vec3 diffuse = (u_ambientColor + v_color1.xyz * shadow + light.rgb) * albedo.rgb;
// Compute specular term
vec3 specular = vec3(0.0, 0.0, 0.0);
#endif
// Combine
gl_FragColor.rgb = diffuse + specular;
gl_FragColor.a = 1.0;
float fogAlpha = saturate0(v_lightpos_fog.w);
gl_FragColor.rgb = mix(u_fogColor, gl_FragColor.rgb, fogAlpha);
#ifdef PIN_GBUFFER
gl_FragColor = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}

View File

@@ -0,0 +1,86 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_color0, a_color1, a_texcoord2, a_texcoord3
$output v_pos, v_worldPos, v_texcoord0, v_texcoord1, v_color0, v_normal, v_tangent, v_lightpos_fog, v_view_depth, v_poslightspace, v_edgedist, v_reflection
#include "common.sh"
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#define SPEC_EXPON 81.0
#define KS 0.75
#define FADE_DIST 500.0
#define FADE_DIST_START 0.0
#define BEVEL_WIDTH 0.06
SAMPLER2D(s_lightMap, 1);
SAMPLER2D(s_lightMapLookup, 2);
SAMPLERCUBE(s_environmentMap, 4);
vec3 CalcBevel(vec4 edgeDistances, vec3 normal, float viewDepth);
void Shade(vec3 albedo, vec3 nn, vec3 vn, float ks, float specExpon, vec4 light, out vec3 diffuse, out vec3 specular);
vec3 CalcBevelDir(vec4 edgeDistances)
{
vec3 dir = vec3(0.0);
vec4 bevelMultiplier = step(edgeDistances, vec4(BEVEL_WIDTH));
dir += bevelMultiplier.x * vec3(1.0, 0.0, 0.0);
dir += bevelMultiplier.y * vec3(-1.0, 0.0, 0.0);
dir += bevelMultiplier.z * vec3(0.0, 1.0, 0.0);
dir += bevelMultiplier.w * vec3(0.0, -1.0, 0.0);
return dir;
}
void DefaultPS()
{
float normalStrength = 0.4;
float fade = clamp(normalStrength - (v_view_depth.w - FADE_DIST_START) / FADE_DIST, 0.0, 1.0);
vec3 nn = normalize(v_normal);
vec4 edgeDistances = v_edgedist;
vec4 albedo = v_color0;
// lets generate this matrix in the vertex shader and pass it in later
mat3 normalMatrix = mat3(
v_tangent.xyz,
cross(nn, v_tangent.xyz),
nn
);
vec2 uv = v_texcoord0;
vec3 tn = vec3(0.0, 0.0, 0.5);
tn = mix(vec3(0.0, 0.0, 0.5), tn, fade);
tn = CalcBevel(edgeDistances, tn, v_view_depth.w);
nn = mul(tn, normalMatrix);
vec3 vn = normalize(v_view_depth.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
vec3 diffuse;
vec3 specular;
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
vec3 result = diffuse + specular;
#ifdef PIN_REFLECTION
vec3 reflection = textureCube(s_environmentMap, reflect(-vn, nn)).rgb;
result = mix(result, reflection, v_reflection);
#endif
float fogAlpha = clamp((u_fogParams.z - length(v_view_depth.xyz)) * u_fogParams.w, 0.0, 1.0);
result = mix(u_fogColor, result, fogAlpha);
gl_FragColor = vec4(result, albedo.a);
#ifdef PIN_GBUFFER
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define PIN_PLASTIC
#include "default.sc"
#endif

View File

@@ -0,0 +1,286 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1
$output v_pos, v_color0, v_color1, v_texcoord0, v_texcoord1, v_texcoord2, v_lightpos_fog, v_normal, v_view_depth, v_poslightspace
#include "common.sh"
#include "globals.sh"
// Tunables
#define CFG_TEXTURE_TILING 0.2
#define CFG_TEXTURE_DETILING 0.1
#define CFG_SPECULAR 2.0
#define CFG_GLOSS 900.0
#define CFG_NORMAL_STRENGTH 0.25
#define CFG_REFRACTION_STRENGTH 0.05
#define CFG_FRESNEL_OFFSET 0.3
#define CFG_SSR_STEPS 8
#define CFG_SSR_START_DISTANCE 1.0
#define CFG_SSR_STEP_CLAMP 0.2
#define CFG_SSR_DEPTH_CUTOFF 10.0
uniform vec4 u_waveParams; // .x = frequency .y = phase .z = height .w = lerp
uniform vec4 u_waterColor; // deep water color
uniform vec4 u_waterParams; // .x = refraction depth scale, .y = refraction depth offset
SAMPLER2D(s_normalMap1, 0);
SAMPLER2D(s_normalMap2, 1);
SAMPLERCUBE(s_envMap, 2);
SAMPLER2D(s_lightMap, 3);
SAMPLER2D(s_lightMapLookup, 4);
SAMPLER2D(s_gbufferColor, 5);
SAMPLER2D(s_gbufferDepth, 6);
vec3 displacePosition(vec3 position, float waveFactor)
{
float x = sin((position.z - position.x) * u_waveParams.x - u_waveParams.y);
float z = sin((position.z + position.x) * u_waveParams.x + u_waveParams.y);
float p = (x + z) * u_waveParams.z;
vec3 result = position;
result.y += p * waveFactor;
return result;
}
vec4 clipToScreen(vec4 pos)
{
#ifdef GLSL
pos.xy = pos.xy * 0.5 + 0.5 * pos.w;
#else
pos.xy = pos.xy * vec2(0.5, -0.5) + 0.5 * pos.w;
#endif
return pos;
}
vec2 getUV(vec3 position, int projection, float seed)
{
vec3 u = u_worldMatrixArray[1 + projection].xyz;
vec3 v = u_worldMatrixArray[19 + projection].xyz;
vec2 uv = vec2(dot(position, u), dot(position, v)) * (0.25 * CFG_TEXTURE_TILING) + CFG_TEXTURE_DETILING * vec2(seed, floor(seed * 2.6651441));
return uv;
}
void WaterVS()
{
vec3 posWorld = a_position.xyz * u_worldMatrixArray[0].w + u_worldMatrixArray[0].xyz;
vec3 normalWorld = a_normal.xyz * (1.0 / 127.0) - 1.0;
#if defined(GLSLES) && !defined(GL3) // iPad2 workaround
vec3 weights = vec3(
abs(a_position.w - 0.0) < 0.1 ? 1.0 : 0.0,
abs(a_position.w - 1.0) < 0.1 ? 1.0 : 0.0,
abs(a_position.w - 2.0) < 0.1 ? 1.0 : 0.0
);
#else
vec3 weights = vec3(
a_position.w == 0.0 ? 1.0 : 0.0,
a_position.w == 1.0 ? 1.0 : 0.0,
a_position.w == 2.0 ? 1.0 : 0.0
);
#endif
float waveFactor = dot(weights, a_texcoord0.xyz) * (1.0 / 255.0);
#ifdef PIN_HQ
float fade = saturate0(1.0 - dot(posWorld - u_cameraPosition, -u_viewDir.xyz) * u_fadeDistance_GlowFactor.y);
posWorld = displacePosition(posWorld, waveFactor * fade);
#endif
v_pos = mul(u_viewProjection, vec4(posWorld, 1.0));
v_lightpos_fog = vec4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)), (u_fogParams.z - v_pos.w) * u_fogParams.w);
v_texcoord0.xy = getUV(posWorld, int(a_texcoord1.x), a_normal.w / 255.0);
v_texcoord1.xy = getUV(posWorld, int(a_texcoord1.y), a_texcoord0.w / 255.0);
v_texcoord2.xy = getUV(posWorld, int(a_texcoord1.z), a_texcoord1.w / 255.0);
v_color0.xyz = weights;
v_color0.w = waveFactor;
v_normal = normalWorld;
v_view_depth = vec4(u_cameraPosition - posWorld, v_pos.w);
v_color1.xyz = vec3(
a_texcoord1.x > 7.5 ? 1.0 : 0.0,
a_texcoord1.y > 7.5 ? 1.0 : 0.0,
a_texcoord1.z > 7.5 ? 1.0 : 0.0
); // side vs top
#ifdef PIN_HQ
v_poslightspace = clipToScreen(v_pos).xyz;
#endif
gl_Position = v_pos;
}
float fresnel(float ndotv)
{
return saturate0(0.78 - 2.5 * abs(ndotv)) + CFG_FRESNEL_OFFSET;
}
vec4 sampleMix(vec2 uv)
{
#ifdef PIN_HQ
return mix(texture2D(s_normalMap1, uv), texture2D(s_normalMap2, uv), u_waveParams.w);
#else
return texture2D(s_normalMap1, uv);
#endif
}
vec3 sampleNormal(vec2 uv0, vec2 uv1, vec2 uv2, vec3 w, vec3 normal, vec3 tsel)
{
return terrainNormal(sampleMix(uv0), sampleMix(uv1), sampleMix(uv2), w, normal, tsel);
}
vec3 sampleNormalSimple(vec2 uv0, vec2 uv1, vec2 uv2, vec3 w)
{
vec4 data = sampleMix(uv0) * w.x + sampleMix(uv1) * w.y + sampleMix(uv2) * w.z;
return nmapUnpack(data).xzy;
}
float unpackDepth(vec2 uv)
{
vec4 geomTex = texture2D(s_gbufferDepth, uv);
float d = geomTex.z * (1.0 / 256.0) + geomTex.w;
return d * GBUFFER_MAX_DEPTH;
}
vec3 getRefractedColor(vec4 cpos, vec3 N, vec3 waterColor)
{
vec2 refruv0 = cpos.xy / cpos.w;
vec2 refruv1 = refruv0 + N.xz * CFG_REFRACTION_STRENGTH;
vec4 refr0 = texture2D(s_gbufferColor, refruv0);
refr0.w = unpackDepth(refruv0);
vec4 refr1 = texture2D(s_gbufferColor, refruv1);
refr1.w = unpackDepth(refruv1);
vec4 result = mix(refr0, refr1, saturate0(refr1.w - cpos.w));
// Estimate water absorption by a scaled depth difference
float depthfade = saturate0((result.w - cpos.w) * u_waterParams.x + u_waterParams.y);
// Since GBuffer depth is clamped we tone the refraction down after half of the range for a smooth fadeout
float gbuffade = saturate0(cpos.w * (2.0 / GBUFFER_MAX_DEPTH) - 1.0);
float fade = saturate0(depthfade + gbuffade);
return mix(result.rgb, waterColor, fade);
}
vec3 getReflectedColor(vec4 cpos, vec3 wpos, vec3 R)
{
vec3 result = vec3(0.0, 0.0, 0.0);
float inside = 0.0;
float distance = CFG_SSR_START_DISTANCE;
float diff = 0.0;
float diffclamp = cpos.w * CFG_SSR_STEP_CLAMP;
vec4 Pproj = cpos;
vec4 Rproj = clipToScreen(mul(u_viewProjection, vec4(R, 0.0)));
for (int i = 0; i < CFG_SSR_STEPS; ++i)
{
distance += clamp(diff, -diffclamp, diffclamp);
vec4 cposi = Pproj + Rproj * distance;
vec2 uv = cposi.xy / cposi.w;
float depth = unpackDepth(uv);
diff = depth - cposi.w;
}
vec4 cposi = Pproj + Rproj * distance;
vec2 uv = cposi.xy / cposi.w;
// Ray hit has to be inside the screen bounds
float ufade = abs(uv.x - 0.5) < 0.5 ? 1.0 : 0.0;
float vfade = abs(uv.y - 0.5) < 0.5 ? 1.0 : 0.0;
// Fade reflections out with distance
float wfade = saturate0((4.0 - 0.1) - max(cpos.w, cposi.w) * (4.0 / GBUFFER_MAX_DEPTH));
// Ray hit has to be reasonably close to where we started
float dfade = abs(diff) < CFG_SSR_DEPTH_CUTOFF ? 1.0 : 0.0;
// Avoid back-projection
float Vfade = Rproj.w > 0.0 ? 1.0 : 0.0;
float fade = ufade * vfade * wfade * dfade * Vfade;
return mix(textureCube(s_envMap, R).rgb, texture2D(s_gbufferColor, uv).rgb, fade);
}
void WaterPS()
{
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
float shadow = light.a;
vec3 w = v_color0.xyz;
// Use simplified normal reconstruction for LQ mobile (assumes flat water surface)
#if defined(GLSLES) && !defined(PIN_HQ)
vec3 normal = sampleNormalSimple(v_texcoord0.xy, v_texcoord1.xy, v_texcoord2.xy, w);
#else
vec3 normal = sampleNormal(v_texcoord0.xy, v_texcoord1.xy, v_texcoord2.xy, w, v_normal, v_color1.xyz);
#endif
// Flatten the normal for Fresnel and for reflections to make them less chaotic
vec3 flatNormal = mix(v_normal, normal, CFG_NORMAL_STRENGTH);
vec3 waterColor = u_waterColor.rgb;
#ifdef PIN_HQ
float fade = saturate0(1.0 - v_view_depth.w * u_fadeDistance_GlowFactor.y);
vec3 view = normalize(v_view_depth.xyz);
float fre = fresnel(dot(flatNormal, view)) * v_color0.w;
vec3 position = u_cameraPosition - v_view_depth.xyz;
#ifdef PIN_GBUFFER
vec3 refr = getRefractedColor(vec4(v_poslightspace, v_view_depth.w), normal, waterColor);
vec3 refl = getReflectedColor(vec4(v_poslightspace, v_view_depth.w), position, reflect(-view, flatNormal));
#else
vec3 refr = waterColor;
vec3 refl = textureCube(s_envMap, reflect(-view, flatNormal)).rgb;
#endif
float specularIntensity = CFG_SPECULAR * fade;
float specularPower = CFG_GLOSS;
vec3 specular = u_lamp0Color * (specularIntensity * shadow * pow(saturate0(dot(normal, normalize(-u_lamp0Dir + view))), specularPower));
#else
vec3 view = normalize(v_view_depth.xyz);
float fre = fresnel(dot(flatNormal, view));
vec3 refr = waterColor;
vec3 refl = textureCube(s_envMap, reflect(-v_view_depth.xyz, flatNormal)).rgb;
vec3 specular = vec3(0.0, 0.0, 0.0);
#endif
// Combine
vec4 result;
result.rgb = mix(refr, refl, fre) * (u_ambientColor.rgb + u_lamp0Color.rgb * shadow + light.rgb) + specular;
result.a = 1.0;
float fogAlpha = saturate0(v_lightpos_fog.w);
result.rgb = mix(u_fogColor, result.rgb, fogAlpha);
gl_FragColor = result;
}

View File

@@ -0,0 +1,238 @@
$input a_position
$output v_pos, v_texcoord0, v_texcoord1, v_texcoord2
#include "common.sh"
#include "globals.sh"
// ao sampling
#define SSAO_NUM_PAIRS 8
#define SSAO_RADIUS 2.0
#define SSAO_MIN_PIXELS 10.0
#define SSAO_MAX_PIXELS 100.0
#define SSAO_MIP_OFFSET 2.0
// ao tuning
#define SSAO_OVERSHADOW 0.75
#define SSAO_ANGLELIMIT 0.1
#define SSAO_BOOST 1.0
// blur tuning
#define SSAO_BLUR_SAMPLES 3
#define SSAO_BLUR_STRENGTH 1.5
#define SSAO_BLUR_DEPTH_THRESHOLD 0.4
// composite tuning
#define SSAO_DEPTH_THRESHOLD_CENTER 0.02
#define SSAO_DEPTH_THRESHOLD_ESTIMATE 0.4
SAMPLER2D(s_depthBuffer, 0);
SAMPLER2D(s_randMap, 1);
SAMPLER2D(s_map, 2);
SAMPLER2D(s_geomMap, 3);
uniform vec4 u_textureSize;
uniform vec4 u_params;
vec4 convertPosition(vec4 p, float scale)
{
#if defined(GLSL) || defined(DX11)
return p;
#else
// half-pixel offset
return p + vec4(-u_textureSize.z, u_textureSize.w, 0.0, 0.0) * scale;
#endif
}
vec2 convertUv(vec4 p)
{
#ifndef GLSL
return p.xy * vec2(0.5, -0.5) + 0.5;
#else
return p.xy * 0.5 + 0.5;
#endif
}
// ===== Pass Through =====
void passThrough_vs()
{
v_pos = convertPosition(vec4(a_position.xyz, 1.0), 1.0);
v_texcoord0.xy = convertUv(vec4(a_position.xyz, 1.0));
gl_Position = v_pos;
}
// ===== SSAO Depth Downsample =====
void SSAODepthDownPS()
{
float d0 = texture2D(s_geomMap, v_texcoord0.xy + u_textureSize.zw * vec2(-0.25, -0.25)).r;
float d1 = texture2D(s_geomMap, v_texcoord0.xy + u_textureSize.zw * vec2(+0.25, -0.25)).r;
float d2 = texture2D(s_geomMap, v_texcoord0.xy + u_textureSize.zw * vec2(-0.25, +0.25)).r;
float d3 = texture2D(s_geomMap, v_texcoord0.xy + u_textureSize.zw * vec2(+0.25, +0.25)).r;
gl_FragColor = vec4(min(min(d0, d3), min(d1, d2)));
}
// ===== SSAO Calculation =====
float getSampleLength(float i)
{
return (i + 1.0) / (float(SSAO_NUM_PAIRS) + 2.0);
}
vec2 getSampleRotation(float i)
{
float pi = 3.1415926;
return vec2(cos(i / float(SSAO_NUM_PAIRS) * 2.0 * pi), sin(i / float(SSAO_NUM_PAIRS) * 2.0 * pi));
}
void SSAOPS()
{
float baseDepth = texture2DLod(s_depthBuffer, vec4(v_texcoord0.xy, 0.0, 0.0)).r;
vec4 noiseTex = texture2D(s_randMap, fract(v_texcoord0.xy * u_textureSize.xy / 4.0)) * 2.0 - 1.0;
mat2 rotation = mat2(
noiseTex.y, noiseTex.x,
-noiseTex.x, noiseTex.y
);
const float sphereRadiusZB = SSAO_RADIUS / GBUFFER_MAX_DEPTH;
vec2 radiusTex = clamp(sphereRadiusZB / baseDepth * u_params.xy, SSAO_MIN_PIXELS * u_textureSize.zw, SSAO_MAX_PIXELS * u_textureSize.zw);
float lod = log2(getSampleLength(0.0) * length(radiusTex * u_textureSize.xy)) - SSAO_MIP_OFFSET;
float result = 1.0; // center pixel
float weight = 2.0;
for (int i = 0; i < SSAO_NUM_PAIRS; i++)
{
const float offsetLength = getSampleLength(float(i));
const vec2 offsetVector = getSampleRotation(float(i)) * offsetLength;
const float segmentDiff = sphereRadiusZB * sqrt(1.0 - offsetLength * offsetLength);
const float angleLimit = offsetLength * SSAO_ANGLELIMIT;
vec2 offset = mul(rotation, offsetVector) * radiusTex;
vec2 offsetDepth;
offsetDepth.x = texture2DLod(s_depthBuffer, vec4(v_texcoord0.xy + offset, 0.0, lod)).r;
offsetDepth.y = texture2DLod(s_depthBuffer, vec4(v_texcoord0.xy - offset, 0.0, lod)).r;
vec2 diff = offsetDepth - vec2(baseDepth, baseDepth);
// 0 is the near surface of the sphere, 1 is the far surface, 0.5 is the middle
vec2 normalizedDiff = diff * (1.0 / segmentDiff * 0.5) + 0.5;
// only add sample contribution if both samples are visible - if one is invisible we estimate the twin as 1-s so sum is 1
float sampleadd = saturate0(min(normalizedDiff.x, normalizedDiff.y) + SSAO_OVERSHADOW);
result += (saturate0(normalizedDiff.x + angleLimit) + saturate0(normalizedDiff.y + angleLimit)) * sampleadd;
weight += 2.0 * sampleadd;
}
// rescale result from 0..0.5 to 0..1 and apply a power function
float finalocc = (baseDepth > 0.99) ? 1.0 : pow(saturate0(result / weight * 2.0), SSAO_BOOST);
gl_FragColor = vec4(finalocc, baseDepth, 0.0, 1.0);
}
// ===== SSAO Blur =====
vec2 ssaoBlur(vec2 uv, vec2 offset, sampler2D map)
{
float sigmaN = 1.0 / (2.0 * SSAO_BLUR_STRENGTH * SSAO_BLUR_STRENGTH);
float baseDepth = texture2D(map, uv).g;
const float sphereRadiusZB = SSAO_BLUR_DEPTH_THRESHOLD / GBUFFER_MAX_DEPTH;
float depthTolerance = clamp((baseDepth * 80.0) * sphereRadiusZB, 0.1 * sphereRadiusZB, 10.0 * sphereRadiusZB);
float result = 0.0;
float weight = 0.0;
for (int i = -SSAO_BLUR_SAMPLES; i <= SSAO_BLUR_SAMPLES; ++i)
{
const float ix = float(i);
const float iw = exp(-ix * ix * sigmaN);
vec4 data = texture2D(map, uv + offset * ix);
float w = iw * (abs(data.g - baseDepth) < depthTolerance ? 1.0 : 0.0);
result += data.r * w;
weight += w;
}
return vec2(result / weight, baseDepth);
}
void SSAOBlurXPS()
{
vec2 o = vec2(u_textureSize.z, 0.0);
vec2 ssaoTerm = ssaoBlur(v_texcoord0.xy, o, s_map);
gl_FragColor = vec4(ssaoTerm, 0.0, 1.0);
}
void SSAOBlurYPS()
{
vec2 o = vec2(0.0, u_textureSize.w);
vec2 ssaoTerm = ssaoBlur(v_texcoord0.xy, o, s_map);
gl_FragColor = vec4(ssaoTerm, 0.0, 1.0);
}
// ===== SSAO Composite =====
void SSAOCompositVS()
{
vec2 uv = convertUv(vec4(a_position.xyz, 1.0));
v_pos = convertPosition(vec4(a_position.xyz, 1.0), 1.0);
v_texcoord0.xy = uv;
vec2 uvOffset = u_textureSize.zw * 2.0;
v_texcoord0.zw = uv + vec2(uvOffset.x, 0.0);
v_texcoord1.xy = uv - vec2(uvOffset.x, 0.0);
v_texcoord1.zw = uv + vec2(0.0, uvOffset.y);
v_texcoord2.xy = uv - vec2(0.0, uvOffset.y);
gl_Position = v_pos;
}
void SSAOCompositPS()
{
vec4 geom = texture2D(s_geomMap, v_texcoord0.xy);
vec4 mapC = texture2D(s_map, v_texcoord0.xy);
vec4 map0 = texture2D(s_map, v_texcoord0.zw);
vec4 map1 = texture2D(s_map, v_texcoord1.xy);
vec4 map2 = texture2D(s_map, v_texcoord1.zw);
vec4 map3 = texture2D(s_map, v_texcoord2.xy);
float baseDepth = geom.r;
float ssaoC = mapC.r;
float depthC = mapC.g;
vec4 ssaoEst = vec4(map0.r, map1.r, map2.r, map3.r);
vec4 depthEst = vec4(map0.g, map1.g, map2.g, map3.g);
// can we trust the neighbors? 1 - yes, 0 - no
vec4 checkEst = vec4(
abs(depthEst.x - baseDepth) < SSAO_DEPTH_THRESHOLD_ESTIMATE / GBUFFER_MAX_DEPTH ? 1.0 : 0.0,
abs(depthEst.y - baseDepth) < SSAO_DEPTH_THRESHOLD_ESTIMATE / GBUFFER_MAX_DEPTH ? 1.0 : 0.0,
abs(depthEst.z - baseDepth) < SSAO_DEPTH_THRESHOLD_ESTIMATE / GBUFFER_MAX_DEPTH ? 1.0 : 0.0,
abs(depthEst.w - baseDepth) < SSAO_DEPTH_THRESHOLD_ESTIMATE / GBUFFER_MAX_DEPTH ? 1.0 : 0.0
);
float checkEstSum = dot(checkEst, vec4(1.0, 1.0, 1.0, 1.0));
float ssaoTermEst = dot(ssaoEst, checkEst) / checkEstSum;
// the final decision: pick the estimate sample if there are good neighbors and base depth is not trustworthy
float ssaoTerm = abs(depthC - baseDepth) * checkEstSum > SSAO_DEPTH_THRESHOLD_CENTER / GBUFFER_MAX_DEPTH ? ssaoTermEst : ssaoC;
// AO reduction for high specular and diffuse values. Computed in gbufferPack in common.h
float slope = geom.g;
gl_FragColor = vec4((1.0 - slope) * vec3(ssaoTerm, ssaoTerm, ssaoTerm) + slope, 1.0);
}

View File

@@ -0,0 +1,26 @@
$input a_position, a_texcoord0
$output v_texcoord0
#include "common.sh"
SAMPLER2D(s_diffuseMap, 0);
uniform vec4 u_color;
void TexCompVS()
{
gl_Position = mul(u_viewProjection, vec4(a_position, 1.0));
v_texcoord0 = a_texcoord0;
}
void TexCompPS()
{
gl_FragColor = texture2DLod(s_diffuseMap, v_texcoord0, -10.0) * u_color;
}
void TexCompPMAPS()
{
vec4 tex = texture2DLod(s_diffuseMap, v_texcoord0, -10.0);
gl_FragColor = vec4(tex.rgb * tex.a * u_color.rgb, tex.a * u_color.a);
}

View File

@@ -0,0 +1,38 @@
$input a_position, a_texcoord0, a_color0
$output v_texcoord0, v_color0, v_texcoord1
#include "common.sh"
uniform vec4 u_uiParams; // x = luminance sampling on/off, w = z offset
SAMPLER2D(s_diffuseMap, 0);
void UIVS()
{
gl_Position = mul(u_viewProjection, vec4(a_position, 1.0));
gl_Position.z -= u_uiParams.w; // against z-fighting
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
#if defined(PIN_FOG)
v_texcoord1.x = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
#endif
}
void UIPS()
{
vec4 base;
if (u_uiParams.x > 0.5)
base = vec4(1.0, 1.0, 1.0, texture2D(s_diffuseMap, v_texcoord0).r);
else
base = texture2D(s_diffuseMap, v_texcoord0);
vec4 result = v_color0 * base;
#if defined(PIN_FOG)
result.rgb = mix(u_fogColor, result.rgb, saturate(v_texcoord1.x));
#endif
gl_FragColor = result;
}

View File

@@ -0,0 +1,28 @@
vec3 v_pos : TEXCOORD0;
vec3 v_worldPos : TEXCOORD1;
vec4 v_texcoord0 : TEXCOORD2;
vec4 v_texcoord1 : TEXCOORD3;
vec4 v_color0 : COLOR0;
vec3 v_normal : NORMAL;
vec3 v_tangent : TANGENT;
vec4 v_lightpos_fog : TEXCOORD4;
vec4 v_view_depth : TEXCOORD5;
vec3 v_poslightspace : TEXCOORD6;
vec4 v_edgedist : TEXCOORD7;
float v_reflection : TEXCOORD8;
vec3 v_position : TEXCOORD9;
vec4 v_start : TEXCOORD10;
vec4 v_end : TEXCOORD11;
vec4 v_centerRadius : TEXCOORD12;
vec4 v_color1 : COLOR1;
vec2 v_texcoord2 : TEXCOORD13;
vec3 a_position : POSITION;
vec3 a_normal : NORMAL;
vec4 a_color0 : COLOR0;
vec4 a_color1 : COLOR1;
vec4 a_texcoord0 : TEXCOORD0;
vec4 a_texcoord1 : TEXCOORD1;
vec3 a_tangent : TEXCOORD2;
vec4 a_texcoord2 : TEXCOORD3;
vec4 a_texcoord3 : TEXCOORD4;

View File

@@ -0,0 +1,181 @@
$input a_position, a_normal
$output v_pos, v_texcoord0, v_worldPos, v_normal, v_lightpos_fog, v_color0
#include "common.sh"
#include "globals.sh"
//
// Water shader.
// Big, fat and ugly.
//
// All (most) things considered, I have converged to this particular way of rendering water:
//
// Vertex waves
// No transparency. Solid color for deep water.
// Fresnel law, reflects environment.
// Phong speculars.
// Ripples via animated normal map. Adjustable intensity, speed and scale. Affect reflection and speculars.
uniform vec4 u_nmAnimLerp; // ratio between normal map frames
uniform vec4 u_waveParams; // .x = frequency .y = phase .z = height
uniform vec4 u_waterColor; // deep water color
SAMPLER2D(s_normalMap1, 0);
SAMPLER2D(s_normalMap2, 1);
SAMPLERCUBE(s_envMap, 2);
SAMPLER2D(s_lightMap, 3);
SAMPLER2D(s_lightMapLookup, 4);
#ifdef PIN_HQ
# define WATER_LOD 1
#else
# define WATER_LOD 2
#endif
#define LODBIAS (-1.0)
float fadeFactor(vec3 wspos)
{
return saturate0(-0.4 + 1.4 * length(u_cameraPosition - wspos.xyz) * u_fadeDistance_GlowFactor.y);
}
float wave(vec4 wspos)
{
float x = sin((wspos.z - wspos.x - u_waveParams.y) * u_waveParams.x);
float z = sin((wspos.z + wspos.x + u_waveParams.y) * u_waveParams.x);
float p = (x + z) * u_waveParams.z;
return p - p * fadeFactor(wspos.xyz);
}
// perturbs the water mesh and vertex normals
void makeWaves(inout vec4 wspos, inout vec3 wsnrm)
{
#if WATER_LOD == 0
float gridSize = 4.0;
vec4 wspos1 = wspos;
vec4 wspos2 = wspos;
wspos1.x += gridSize;
wspos2.z += gridSize;
wspos.y += wave(wspos);
wspos1.y += wave(wspos1);
wspos2.y += wave(wspos2);
wsnrm = normalize(cross(wspos2.xyz - wspos.xyz, wspos1.xyz - wspos.xyz));
#elif WATER_LOD == 1
wspos.y += wave(wspos);
#else /* do nothing */
#endif
}
void water_vs()
{
// Decode vertex data
vec3 normal = (a_normal.xyz - 127.0) / 127.0;
normal = normalize(normal);
vec4 wspos = mul(u_worldMatrix, vec4(a_position.xyz, 1.0));
vec3 wsnrm = normal;
wspos.y -= 2.0 * u_waveParams.z;
makeWaves(wspos, wsnrm);
v_worldPos = wspos;
v_normal = wsnrm;
if (normal.y < 0.01) v_normal = normal;
// box mapping
vec2 tcselect;
vec3 wspostc = vec3(wspos.x, -wspos.y, wspos.z);
tcselect.x = dot(abs(normal.yxz), wspostc.xzx);
tcselect.y = dot(abs(normal.yxz), wspostc.zyy);
v_pos = mul(u_viewProjection, wspos);
v_texcoord0.xy = tcselect * 0.05;
v_texcoord0.z = saturate0((u_fogParams.z - v_pos.w) * u_fogParams.w);
v_texcoord0.w = LODBIAS;
v_lightpos_fog.xyz = lgridPrepareSample(lgridOffset(wspos.xyz, wsnrm.xyz));
v_color0.x = fadeFactor(wspos.xyz);
v_color0.y = (1.0 - v_color0.x) * saturate0(dot(wsnrm, -u_lamp0Dir)) * 100.0;
v_color0.z = 1.0 - 0.9 * saturate1(exp(-0.005 * length(u_cameraPosition - wspos.xyz)));
gl_Position = v_pos;
}
vec3 pixelNormal(vec4 tc0)
{
vec4 nm1 = texture2DLod(s_normalMap1, tc0.xy, tc0.w);
#if WATER_LOD <= 1
vec4 nm2 = texture2DLod(s_normalMap2, tc0.xy, tc0.w);
vec4 nm3 = mix(nm1, nm2, u_nmAnimLerp.xxxx);
#else
vec4 nm3 = nm1;
#endif
return nmapUnpack(nm3);
}
// Fresnel approximation. N1 and N2 are refractive indices.
// for above water, use n1 = 1, n2 = 1.3, for underwater use n1 = 1.3, n2 = 1
float fresnel(vec3 N, vec3 V, float n1, float n2, float p, float fade)
{
#if WATER_LOD == 0
float r0 = (n1 - n2) / (n1 + n2);
r0 *= r0;
return r0 + (1.0 - r0) * pow(1.0 - abs(dot(normalize(N), V)), p);
#else
return 0.1 + saturate0(-1.9 * abs(dot(N, V)) + 0.8); // HAXX!
#endif
}
vec4 envColor(vec3 N, vec3 V, float fade)
{
vec3 dir = reflect(V, N);
return textureCube(s_envMap, dir) * 0.91;
}
vec4 deepWaterColor(vec4 light)
{
vec4 tint = 0.8 * vec4(118.0, 143.0, 153.0, 255.0) / 255.0;
return (light + textureCubeLod(s_envMap, vec3(0.0, 1.0, 0.0), 10.0)) * tint;
}
void water_ps()
{
vec3 N2 = v_normal;
vec3 N1 = pixelNormal(v_texcoord0).xzy;
vec3 N3 = 0.5 * (N2 + N1);
N3 = mix(N3, N2, v_color0.z);
vec3 L = -u_lamp0Dir.xyz;
vec3 E = normalize(u_cameraPosition - v_worldPos.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
float fre = fresnel(N3, E, 1.0, 1.3, 5.0, v_color0.x);
vec3 diffuse = deepWaterColor(light).rgb;
vec3 env = envColor(N3, -E, v_color0.x).rgb;
vec3 R = reflect(-L, N1);
#if WATER_LOD <= 1
float specular = pow(saturate0(dot(R, E)), 1600.0) * L.y * 100.0; // baseline
# ifndef GLSLES
specular = 0.65 * saturate1(specular * saturate0(light.a - 0.4));
# endif
#else
float specular = 0.0;
#endif
vec3 result = mix(diffuse, env, fre) + vec3(specular, specular, specular);
result = mix(u_fogColor.rgb, result, v_texcoord0.z);
gl_FragColor = vec4(result, 1.0);
}

View File

@@ -0,0 +1,110 @@
$input a_position, a_normal, a_texcoord0, a_texcoord1, a_color0, a_color1, a_texcoord2, a_texcoord3
$output v_pos, v_worldPos, v_texcoord0, v_texcoord1, v_color0, v_normal, v_tangent, v_lightpos_fog, v_view_depth, v_poslightspace, v_edgedist, v_reflection
#include "common.sh"
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#define SPEC_EXPON 4.0
#define KS 0.1
#define WoodContrast vec3(0.1, 0.1, 0.1)
#define Ks1 0.32
#define Ks2 0.16
#define RingScale 4.0
#define AmpScale 1.0
#define LightRingEnd 0.4
#define DarkRingStart 0.8
#define DarkRingEnd 0.83
#define NormMapScale 0.6
#define NoiseScale 64.0
#define MixedColorRatio 0.315
#define AAFreqMultiplier 12.0
SAMPLER2D(s_normalMap, 6);
SAMPLER3D(s_specularMap, 7);
SAMPLER2D(s_lightMap, 1);
SAMPLER2D(s_lightMapLookup, 2);
SAMPLER2D(s_shadowMap, 3);
vec3 CalcBevel(vec4 edgeDistances, vec3 normal, float viewDepth);
void Shade(vec3 albedo, vec3 nn, vec3 vn, float ks, float specExpon, vec4 light, out vec3 diffuse, out vec3 specular);
void DefaultPS()
{
vec3 nn = normalize(v_normal);
mat3 normalMatrix = mat3(
v_tangent.xyz,
cross(nn, v_tangent.xyz),
nn
);
vec4 WoodPos = vec4(v_pos.xyz, mix(0.0, 0.92, abs(dot(vec3(1.0, 0.0, 0.0), nn))));
vec2 NormalUV = v_texcoord0.xy * NormMapScale * 3.0;
float singularityAttenuation = WoodPos.w;
float noiseval = texture3D(s_specularMap, WoodPos.xyz / NoiseScale).x;
vec3 tn = texture2D(s_normalMap, NormalUV).xyz - 0.5;
tn = mix(tn, vec3(0.0, 0.0, 0.5), singularityAttenuation);
vec4 edgeDistances = v_edgedist;
tn = CalcBevel(edgeDistances, tn, v_view_depth.w);
nn = mul(tn, normalMatrix);
float signalfreq = length(vec4(dFdx(WoodPos.y), dFdx(WoodPos.z), dFdy(WoodPos.y), dFdy(WoodPos.z)));
float aa_attn = clamp(signalfreq * AAFreqMultiplier - 1.0, 0.0, 1.0);
vec3 Pwood = WoodPos.xyz + (AmpScale * noiseval);
float r = RingScale * length(Pwood.yz);
r = r + texture3D(s_specularMap, vec3(r) / 32.0).x;
r = r - floor(r);
r = smoothstep(LightRingEnd, DarkRingStart, r) - smoothstep(DarkRingEnd, 1.0, r);
r = mix(r, MixedColorRatio, aa_attn);
vec3 albedo = v_color0.xyz + WoodContrast * (MixedColorRatio - r);
float Ks = mix(Ks1, Ks2, r);
vec3 vn = normalize(v_view_depth.xyz);
vec4 light = lgridSample(s_lightMap, s_lightMapLookup, v_lightpos_fog.xyz);
light.a = shadowSample(s_shadowMap, v_poslightspace, light.a);
vec3 diffuse;
vec3 specular;
Shade(albedo, nn, vn, Ks, SPEC_EXPON, light, diffuse, specular);
gl_FragColor = vec4(diffuse + specular, v_color0.w);
float fogAlpha = clamp((u_fogParams.z - length(v_view_depth.xyz)) * u_fogParams.w, 0.0, 1.0);
gl_FragColor.xyz = mix(u_fogColor, gl_FragColor.rgb, fogAlpha);
#ifdef PIN_GBUFFER
// gl_FragData[1] = gbufferPack(v_view_depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 2.0
#define CFG_GLOSS_SCALE 256.0
#define CFG_REFLECTION_SCALE 0.0
#define CFG_NORMAL_SHADOW_SCALE 0.3
#define CFG_SPECULAR_LOD 0.25
#define CFG_GLOSS_LOD 32.0
#define CFG_NORMAL_DETAIL_TILING 7.0
#define CFG_NORMAL_DETAIL_SCALE 0.6
#define CFG_FAR_TILING 0.0
#define CFG_FAR_DIFFUSE_CUTOFF 0.0
#define CFG_FAR_NORMAL_CUTOFF 0.0
#define CFG_FAR_SPECULAR_CUTOFF 0.0
#include "material.sc"
#endif

View File

@@ -0,0 +1,15 @@
#define CFG_WANG_TILES
#define CFG_TEXTURE_TILING 1.0
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 96.0
#define CFG_REFLECTION_SCALE 0.05
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 48.0
#include "material.sc"

View File

@@ -0,0 +1,80 @@
#!/usr/bin/env python3
import argparse
import os
import json
import subprocess
import platform
import re
import sys
import struct
import time
class ShaderPackBytecode:
def __init__(self, bytecode: bytes, data_size: int):
self.bytecode = bytecode
self.data_size = data_size
def main():
parser = argparse.ArgumentParser(description="Process shader packs")
parser.add_argument("--packs", nargs='+', required=True, help="Space-delimited list of shader packs")
args = parser.parse_args()
cwd = os.getcwd()
build_dir = os.path.join(cwd, "build")
os.makedirs(build_dir, exist_ok=True)
print("-- Running shader compiler")
shader_compiler = os.path.join(cwd, "shader_compiler.exe")
packs_arg = " ".join(args.packs)
command = f"{shader_compiler} /P {cwd} {packs_arg}"
if platform.system() == "Linux":
command = f"wine {command}"
# Start the timer
start_time = time.time()
try:
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, _ = process.communicate()
process.wait()
# Stop the timer and calculate the compilation time in seconds with two decimal places
end_time = time.time()
compilation_time = "{:.2f}sec".format(end_time - start_time)
if process.returncode != 0:
print(f"Error running shader compiler: {stdout.decode('utf-8')}")
sys.exit(1)
else:
# Initialize a counter for the number of packed shaders
packed_shaders_count = 0
# Parse and print the output
output_lines = stdout.decode('utf-8').splitlines()
for line in output_lines:
match = re.search(r'(\w+): updated (\d+) shaders', line)
if match:
shader_type = match.group(1)
updated_shaders = match.group(2)
packed_shaders_count += int(updated_shaders) # Update the counter
print(f"-- Updated {updated_shaders} shaders in {shader_type}")
shader_plural = "shader" if packed_shaders_count == 1 else "shaders"
print(f"-- Compiled and packed {packed_shaders_count} {shader_plural} in {compilation_time} {packed_shaders_count == 0 and '(no new changes)' or ''}")
# Move the generated files to the build directory
for pack in args.packs:
with open(os.path.join(cwd, f'shaders_{pack}.pack'), 'rb') as f:
with open(os.path.join(build_dir, f'shaders_{pack}.pack'), 'wb') as f2:
f2.write(f.read())
print(f"-- Built shader pack files available in '{build_dir}'")
except subprocess.CalledProcessError as e:
print(f"Error running shader compiler: {e}")
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,234 @@
[
{ "name": "AdornAALineVS", "source": "adorn.hlsl", "target": "vs_2_0", "entrypoint": "AdornAALineVS"},
{ "name": "AdornAALineFS", "source": "adorn.hlsl", "target": "ps_2_0", "entrypoint": "AdornAALinePS" },
{ "name": "AdornVS", "source": "adorn.hlsl", "target": "vs_2_0", "entrypoint": "AdornVS" },
{ "name": "AdornSelfLitVS", "source": "adorn.hlsl", "target": "vs_2_0", "entrypoint": "AdornSelfLitVS" },
{ "name": "AdornSelfLitHighlightVS", "source": "adorn.hlsl", "target": "vs_2_0", "entrypoint": "AdornSelfLitHighlightVS" },
{ "name": "AdornLightingVS", "source": "adorn.hlsl", "target": "vs_2_0", "entrypoint": "AdornVS", "defines": "PIN_LIGHTING" },
{ "name": "AdornFS", "source": "adorn.hlsl", "target": "ps_2_0", "entrypoint": "AdornPS" },
{ "name": "AdornOutlineVS", "source": "adorn.hlsl", "target": "vs_2_0", "entrypoint": "AdornOutlineVS"},
{ "name": "AdornOutlineFS", "source": "adorn.hlsl", "target": "ps_2_0", "entrypoint": "AdornOutlinePS" },
{ "name": "GBufferResolveVS", "source" : "gbuffer.hlsl", "target" : "vs_2_0", "entrypoint" : "gbufferVS" },
{ "name": "GBufferResolveFS", "source" : "gbuffer.hlsl", "target" : "ps_2_0", "entrypoint" : "gbufferPS" },
{ "name": "DefaultNeonFS", "source": "neon.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS" },
{ "name": "DefaultNeonHQFS", "source": "neon.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultNeonHQGBufferFS", "source": "neon.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "ParticleVS", "source": "particle.hlsl", "target": "vs_1_1", "entrypoint": "vs" },
{ "name": "ParticleAddFS", "source": "particle.hlsl", "target": "ps_2_0", "entrypoint": "psAdd" },
{ "name": "ParticleModulateFS", "source": "particle.hlsl", "target": "ps_2_0", "entrypoint": "psModulate" },
{ "name": "ParticleCrazyFS", "source": "particle.hlsl", "target": "ps_2_0", "entrypoint": "psCrazy" },
{ "name": "ParticleCrazySparklesFS", "source": "particle.hlsl", "target": "ps_2_0", "entrypoint": "psCrazySparkles" },
{ "name": "ParticleCustomVS", "source": "particle.hlsl", "target": "vs_1_1", "entrypoint": "vsCustom" },
{ "name": "ParticleCustomFS", "source": "particle.hlsl", "target": "ps_2_0", "entrypoint": "psCustom" },
{ "name": "ProfilerVS", "source": "profiler.hlsl", "target": "vs_1_1", "entrypoint": "ProfilerVS" },
{ "name": "ProfilerFS", "source": "profiler.hlsl", "target": "ps_2_0", "entrypoint": "ProfilerPS" },
{ "name": "ImGuiFS", "source": "profiler.hlsl", "target": "ps_2_0", "entrypoint": "ImGuiPS" },
{ "name": "DefaultShadowStaticVS", "source": "shadow.hlsl", "target": "vs_2_0", "entrypoint": "ShadowVS" },
{ "name": "DefaultShadowSkinnedVS", "source": "shadow.hlsl", "target": "vs_2_0", "entrypoint": "ShadowVS", "defines": "PIN_SKINNED" },
{ "name": "DefaultShadowFS", "source": "shadow.hlsl", "target": "ps_2_0", "entrypoint": "ShadowPS" },
{ "name": "SkyVS", "source": "sky.hlsl", "target": "vs_1_1", "entrypoint": "SkyVS" },
{ "name": "SkyFS", "source": "sky.hlsl", "target": "ps_2_0", "entrypoint": "SkyPS" },
{ "name": "SmoothWaterVS", "source": "smoothwater.hlsl", "target": "vs_2_0", "entrypoint": "WaterVS" },
{ "name": "SmoothWaterHQVS", "source": "smoothwater.hlsl", "target": "vs_3_0", "entrypoint": "WaterVS", "defines": "PIN_HQ" },
{ "name": "SmoothWaterFS", "source": "smoothwater.hlsl", "target": "ps_2_0", "entrypoint": "WaterPS" },
{ "name": "SmoothWaterHQFS", "source": "smoothwater.hlsl", "target": "ps_3_0", "entrypoint": "WaterPS", "defines": "PIN_HQ" },
{ "name": "SmoothWaterHQGBufferFS", "source": "smoothwater.hlsl", "target": "ps_3_0", "entrypoint": "WaterPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "SSAOVS", "source": "screenspace.hlsl", "target": "vs_3_0", "entrypoint": "passThrough_vs"},
{ "name": "SSAODepthDownFS", "source": "ssao.hlsl", "target": "ps_3_0", "entrypoint": "SSAODepthDownPS", "exclude": "glsles" },
{ "name": "SSAOFS", "source": "ssao.hlsl", "target": "ps_3_0", "entrypoint": "SSAOPS", "exclude": "glsles" },
{ "name": "SSAOBlurXFS", "source": "ssao.hlsl", "target": "ps_3_0", "entrypoint": "SSAOBlurXPS", "exclude": "glsles" },
{ "name": "SSAOBlurYFS", "source": "ssao.hlsl", "target": "ps_3_0", "entrypoint": "SSAOBlurYPS", "exclude": "glsles" },
{ "name": "SSAOCompositVS", "source": "ssao.hlsl", "target": "vs_3_0", "entrypoint": "SSAOCompositVS", "exclude": "glsles" },
{ "name": "SSAOCompositFS", "source": "ssao.hlsl", "target": "ps_3_0", "entrypoint": "SSAOCompositPS", "exclude": "glsles" },
{ "name": "TexCompVS", "source": "texcomp.hlsl", "target": "vs_1_1", "entrypoint": "TexCompVS" },
{ "name": "TexCompFS", "source": "texcomp.hlsl", "target": "ps_2_0", "entrypoint": "TexCompPS" },
{ "name": "TexCompPMAFS", "source": "texcomp.hlsl", "target": "ps_2_0", "entrypoint": "TexCompPMAPS" },
{ "name": "UIVS", "source": "ui.hlsl", "target": "vs_1_1", "entrypoint": "UIVS" },
{ "name": "UIFogVS", "source": "ui.hlsl", "target": "vs_1_1", "entrypoint": "UIVS", "defines": "PIN_FOG" },
{ "name": "UIFS", "source": "ui.hlsl", "target": "ps_2_0", "entrypoint": "UIPS" },
{ "name": "UIFogFS", "source": "ui.hlsl", "target": "ps_2_0", "entrypoint": "UIPS", "defines": "PIN_FOG" },
{ "name": "WaterVS", "source": "water.hlsl", "target": "vs_2_0", "entrypoint": "water_vs" },
{ "name": "WaterHQVS", "source": "water.hlsl", "target": "vs_2_0", "entrypoint": "water_vs", "defines": "PIN_HQ" },
{ "name": "WaterFS", "source": "water.hlsl", "target": "ps_2_0", "entrypoint": "water_ps" },
{ "name": "WaterHQFS", "source": "water.hlsl", "target": "ps_2_a", "entrypoint": "water_ps", "defines": "PIN_HQ" },
{ "name": "PassThroughVS", "source": "screenspace.hlsl", "target": "vs_1_1", "entrypoint": "passThrough_vs"},
{ "name": "PassThroughFS", "source": "screenspace.hlsl", "target": "ps_2_0", "entrypoint": "passThrough_ps"},
{ "name": "GlowApplyFS", "source": "screenspace.hlsl", "target": "ps_2_a", "entrypoint": "glowApply_ps", "exclude": "glsles" },
{ "name": "DownSample4x4VS", "source": "screenspace.hlsl", "target": "vs_1_1", "entrypoint": "downsample4x4_vs", "exclude": "glsles" },
{ "name": "DownSample4x4GlowFS", "source": "screenspace.hlsl", "target": "ps_2_0", "entrypoint": "downSample4x4Glow_ps", "exclude": "glsles" },
{ "name": "ShadowBlurFS", "source": "screenspace.hlsl", "target": "ps_2_0", "entrypoint": "ShadowBlurPS" },
{ "name": "Blur3FS", "source": "screenspace.hlsl", "target": "ps_2_a", "entrypoint": "blur3_ps", "exclude": "glsles" },
{ "name": "Blur5FS", "source": "screenspace.hlsl", "target": "ps_2_a", "entrypoint": "blur5_ps", "exclude": "glsles" },
{ "name": "Blur7FS", "source": "screenspace.hlsl", "target": "ps_2_a", "entrypoint": "blur7_ps", "exclude": "glsles" },
{ "name": "FXAAFS", "source": "screenspace.hlsl", "target": "ps_2_a", "entrypoint": "fxaa_ps", "exclude": "glsles" },
{ "name": "ImageProcessFS", "source": "screenspace.hlsl", "target": "ps_2_0", "entrypoint": "imageProcess_ps", "exclude": "glsles" },
{ "name": "DefaultStaticVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS" },
{ "name": "DefaultStaticHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_HQ" },
{ "name": "DefaultSkinnedVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SKINNED" },
{ "name": "DefaultSkinnedHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SKINNED PIN_HQ" },
{ "name": "DefaultStaticDebugVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_DEBUG" },
{ "name": "DefaultSkinnedDebugVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SKINNED PIN_DEBUG" },
{ "name": "DefaultFS", "source": "default.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS" },
{ "name": "DefaultHQFS", "source": "default.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultHQGBufferFS", "source": "default.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultStaticReflectionVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_REFLECTION" },
{ "name": "DefaultSkinnedReflectionVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SKINNED PIN_REFLECTION" },
{ "name": "DefaultStaticSurfaceHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SURFACE PIN_HQ" },
{ "name": "DefaultSkinnedSurfaceHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "PIN_SKINNED PIN_SURFACE PIN_HQ" },
{ "name": "LowQMaterialFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "PIN_LOWQMAT" },
{ "name": "LowQMaterialWangFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_LOWQMAT PIN_WANG" },
{ "name": "LowQMaterialWangFallbackFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "PIN_LOWQMAT PIN_WANG_FALLBACK" },
{ "name": "DefaultPlasticFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS" },
{ "name": "DefaultPlasticHQFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultPlasticHQGBufferFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultPlasticReflectionFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION" },
{ "name": "DefaultPlasticReflectionHQFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION PIN_HQ" },
{ "name": "DefaultPlasticReflectionHQGBufferFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultSmoothPlasticFS", "source": "smoothplastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS" },
{ "name": "DefaultSmoothPlasticHQFS", "source": "smoothplastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultSmoothPlasticHQGBufferFS", "source": "smoothplastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultSmoothPlasticReflectionFS", "source": "smoothplastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION" },
{ "name": "DefaultSmoothPlasticReflectionHQFS", "source": "smoothplastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION PIN_HQ" },
{ "name": "DefaultSmoothPlasticReflectionHQGBufferFS", "source": "smoothplastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_REFLECTION PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultWoodHQFS", "source": "wood.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultWoodHQGBufferFS", "source": "wood.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultMarbleHQFS", "source": "marble.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultMarbleHQGBufferFS", "source": "marble.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultSlateHQFS", "source": "slate.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultSlateHQGBufferFS", "source": "slate.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultGraniteHQFS", "source": "granite.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultGraniteHQGBufferFS", "source": "granite.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultConcreteHQFS", "source": "concrete.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultConcreteHQGBufferFS", "source": "concrete.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultPebbleHQFS", "source": "pebble.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultPebbleHQGBufferFS", "source": "pebble.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultBrickHQFS", "source": "brick.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultBrickHQGBufferFS", "source": "brick.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultRustHQFS", "source": "rust.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultRustHQGBufferFS", "source": "rust.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultDiamondplateHQFS", "source": "diamondplate.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultDiamondplateHQGBufferFS", "source": "diamondplate.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultAluminumHQFS", "source": "aluminum.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultAluminumHQGBufferFS", "source": "aluminum.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultGrassHQFS", "source": "grass.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultGrassHQGBufferFS", "source": "grass.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultSandHQFS", "source": "sand.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultSandHQGBufferFS", "source": "sand.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultFabricHQFS", "source": "fabric.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultFabricHQGBufferFS", "source": "fabric.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultIceHQFS", "source": "ice.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultIceHQGBufferFS", "source": "ice.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultCobblestoneHQFS", "source": "cobblestone.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultCobblestoneHQGBufferFS", "source": "cobblestone.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultMetalHQFS", "source": "metal.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultMetalHQGBufferFS", "source": "metal.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "DefaultWoodPlanksHQFS", "source": "woodplanks.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ" },
{ "name": "DefaultWoodPlanksHQGBufferFS", "source": "woodplanks.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "MegaClusterVS", "source": "megacluster.hlsl", "target": "vs_2_0", "entrypoint": "MegaClusterVS" },
{ "name": "MegaClusterHQVS", "source": "megacluster.hlsl", "target": "vs_2_0", "entrypoint": "MegaClusterVS", "defines": "PIN_HQ" },
{ "name": "MegaClusterFS", "source": "megacluster.hlsl", "target": "ps_2_0", "entrypoint": "MegaClusterPS" },
{ "name": "MegaClusterHQFS", "source": "megacluster.hlsl", "target": "ps_2_a", "entrypoint": "MegaClusterPS", "defines": "PIN_HQ" },
{ "name": "MegaClusterHQGBufferFS", "source": "megacluster.hlsl", "target": "ps_2_a", "entrypoint": "MegaClusterPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "name": "SmoothClusterVS", "source": "smoothcluster.hlsl", "target": "vs_2_0", "entrypoint": "TerrainVS" },
{ "name": "SmoothClusterHQVS", "source": "smoothcluster.hlsl", "target": "vs_3_0", "entrypoint": "TerrainVS", "defines": "PIN_HQ" },
{ "name": "SmoothClusterFS", "source": "smoothcluster.hlsl", "target": "ps_2_0", "entrypoint": "TerrainPS" },
{ "name": "SmoothClusterHQFS", "source": "smoothcluster.hlsl", "target": "ps_3_0", "entrypoint": "TerrainPS", "defines": "PIN_HQ" },
{ "name": "SmoothClusterHQGBufferFS", "source": "smoothcluster.hlsl", "target": "ps_3_0", "entrypoint": "TerrainPS", "defines": "PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudLowQMaterialFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_LOWQMAT" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudLowQMaterialWangFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_LOWQMAT PIN_WANG" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudLowQMaterialWangFallbackFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_LOWQMAT PIN_WANG_FALLBACK" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticHQFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticHQGBufferFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticReflectionFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_REFLECTION" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticReflectionHQFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_REFLECTION PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultPlasticReflectionHQGBufferFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_REFLECTION PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultStaticVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultStaticHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultSkinnedVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SKINNED" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultSkinnedHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SKINNED PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultStaticDebugVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_DEBUG" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultSkinnedDebugVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SKINNED PIN_DEBUG" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultFS", "source": "default.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultHQFS", "source": "default.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultHQGBufferFS", "source": "default.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultStaticReflectionVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_REFLECTION" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultSkinnedReflectionVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SKINNED PIN_REFLECTION" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultStaticSurfaceHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SURFACE PIN_HQ" },
{ "version": 2012, "key": "ClassicGouraud", "name": "ClassicGouraudDefaultSkinnedSurfaceHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC CLASSIC_GOURAUD PIN_SKINNED PIN_SURFACE PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultStaticVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultStaticHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSkinnedVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SKINNED" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSkinnedHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SKINNED PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultStaticDebugVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_DEBUG" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSkinnedDebugVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SKINNED PIN_DEBUG" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultFS", "source": "default.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultHQFS", "source": "default.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultHQGBufferFS", "source": "default.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultStaticReflectionVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_REFLECTION" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSkinnedReflectionVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SKINNED PIN_REFLECTION" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultStaticSurfaceHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SURFACE PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSkinnedSurfaceHQVS", "source": "default.hlsl", "target": "vs_2_0", "entrypoint": "DefaultVS", "defines": "CLASSIC PIN_SKINNED PIN_SURFACE PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicLowQMaterialFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_LOWQMAT" },
{ "version": 2013, "key": "Classic", "name": "ClassicLowQMaterialWangFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_LOWQMAT PIN_WANG" },
{ "version": 2013, "key": "Classic", "name": "ClassicLowQMaterialWangFallbackFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_LOWQMAT PIN_WANG_FALLBACK" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticHQFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticHQGBufferFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticReflectionFS", "source": "plastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticReflectionHQFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPlasticReflectionHQGBufferFS", "source": "plastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticFS", "source": "smoothplastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticHQFS", "source": "smoothplastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticHQGBufferFS", "source": "smoothplastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticReflectionFS", "source": "smoothplastic.hlsl", "target": "ps_2_0", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticReflectionHQFS", "source": "smoothplastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSmoothPlasticReflectionHQGBufferFS", "source": "smoothplastic.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_REFLECTION PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultWoodHQFS", "source": "wood.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultWoodHQGBufferFS", "source": "wood.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultMarbleHQFS", "source": "marble.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultMarbleHQGBufferFS", "source": "marble.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSlateHQFS", "source": "slate.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSlateHQGBufferFS", "source": "slate.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultGraniteHQFS", "source": "granite.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultGraniteHQGBufferFS", "source": "granite.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultConcreteHQFS", "source": "concrete.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultConcreteHQGBufferFS", "source": "concrete.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPebbleHQFS", "source": "pebble.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultPebbleHQGBufferFS", "source": "pebble.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultBrickHQFS", "source": "brick.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultBrickHQGBufferFS", "source": "brick.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultRustHQFS", "source": "rust.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultRustHQGBufferFS", "source": "rust.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultDiamondplateHQFS", "source": "diamondplate.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultDiamondplateHQGBufferFS", "source": "diamondplate.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultAluminumHQFS", "source": "aluminum.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultAluminumHQGBufferFS", "source": "aluminum.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultGrassHQFS", "source": "grass.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultGrassHQGBufferFS", "source": "grass.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSandHQFS", "source": "sand.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultSandHQGBufferFS", "source": "sand.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultFabricHQFS", "source": "fabric.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultFabricHQGBufferFS", "source": "fabric.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultIceHQFS", "source": "ice.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultIceHQGBufferFS", "source": "ice.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultCobblestoneHQFS", "source": "cobblestone.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultCobblestoneHQGBufferFS", "source": "cobblestone.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultMetalHQFS", "source": "metal.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultMetalHQGBufferFS", "source": "metal.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultWoodPlanksHQFS", "source": "woodplanks.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicDefaultWoodPlanksHQGBufferFS", "source": "woodplanks.hlsl", "target": "ps_2_a", "entrypoint": "DefaultPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicMegaClusterVS", "source": "megacluster.hlsl", "target": "vs_2_0", "entrypoint": "MegaClusterVS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicMegaClusterHQVS", "source": "megacluster.hlsl", "target": "vs_2_0", "entrypoint": "MegaClusterVS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicMegaClusterFS", "source": "megacluster.hlsl", "target": "ps_2_0", "entrypoint": "MegaClusterPS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicMegaClusterHQFS", "source": "megacluster.hlsl", "target": "ps_2_a", "entrypoint": "MegaClusterPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicMegaClusterHQGBufferFS", "source": "megacluster.hlsl", "target": "ps_2_a", "entrypoint": "MegaClusterPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" },
{ "version": 2013, "key": "Classic", "name": "ClassicSmoothClusterVS", "source": "smoothcluster.hlsl", "target": "vs_2_0", "entrypoint": "TerrainVS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicSmoothClusterHQVS", "source": "smoothcluster.hlsl", "target": "vs_3_0", "entrypoint": "TerrainVS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicSmoothClusterFS", "source": "smoothcluster.hlsl", "target": "ps_2_0", "entrypoint": "TerrainPS", "defines": "CLASSIC" },
{ "version": 2013, "key": "Classic", "name": "ClassicSmoothClusterHQFS", "source": "smoothcluster.hlsl", "target": "ps_3_0", "entrypoint": "TerrainPS", "defines": "CLASSIC PIN_HQ" },
{ "version": 2013, "key": "Classic", "name": "ClassicSmoothClusterHQGBufferFS", "source": "smoothcluster.hlsl", "target": "ps_3_0", "entrypoint": "TerrainPS", "defines": "CLASSIC PIN_HQ PIN_GBUFFER", "exclude": "glsles" }
]

Binary file not shown.

View File

@@ -0,0 +1,249 @@
#include "common.h"
struct Appdata
{
float4 Position : POSITION;
float2 Uv : TEXCOORD0;
float3 Normal : NORMAL0;
};
struct VertexOutput
{
float4 HPosition : POSITION;
float2 Uv : TEXCOORD0;
float4 Color : COLOR0;
float FogFactor : TEXCOORD1;
};
struct AALineVertexOutput
{
float4 HPosition : POSITION;
float4 Position : TEXCOORD1;
float4 Color : COLOR0;
float FogFactor : COLOR1;
float4 Start : TEXCOORD2;
float4 End : TEXCOORD3;
};
struct OutlineVertexOutput
{
float4 HPosition : POSITION;
float4 Color : COLOR0;
float4 Position : TEXCOORD0;
float4 CenterRadius : TEXCOORD1;
};
WORLD_MATRIX(WorldMatrix);
uniform float4 Color;
// pixel info is for AA line
// x -> Fov * 0.5f / screenSize.y;
// y -> ScreenWidth
// z -> ScreenWidth / ScreenHeight
// w -> Line thickness
uniform float4 PixelInfo;
VertexOutput AdornSelfLitVSGeneric(Appdata IN, float ambient)
{
VertexOutput OUT = (VertexOutput)0;
float4 position = mul(WorldMatrix, IN.Position);
float3 normal = normalize(mul((float3x3)WorldMatrix, IN.Normal));
float3 light = normalize(G(CameraPosition).xyz - position.xyz);
float ndotl = saturate(dot(normal, light));
float lighting = ambient + (1 - ambient) * ndotl;
float specular = pow(ndotl, 64.0);
OUT.HPosition = mul(G(ViewProjection), mul(WorldMatrix, IN.Position));
OUT.Uv = IN.Uv;
OUT.Color = float4(Color.rgb * lighting + specular, Color.a);
OUT.FogFactor = (G(FogParams).z - OUT.HPosition.w) * G(FogParams).w;
return OUT;
}
VertexOutput AdornSelfLitVS(Appdata IN)
{
return AdornSelfLitVSGeneric(IN, 0.5f);
}
VertexOutput AdornSelfLitHighlightVS(Appdata IN)
{
return AdornSelfLitVSGeneric(IN, 0.75f);
}
VertexOutput AdornVS(Appdata IN)
{
VertexOutput OUT = (VertexOutput)0;
float4 position = mul(WorldMatrix, IN.Position);
#ifdef PIN_LIGHTING
float3 normal = normalize(mul((float3x3)WorldMatrix, IN.Normal));
float ndotl = dot(normal, -G(Lamp0Dir));
float3 lighting = G(AmbientColor) + saturate(ndotl) * G(Lamp0Color) + saturate(-ndotl) * G(Lamp1Color);
#else
float3 lighting = 1;
#endif
OUT.HPosition = mul(G(ViewProjection), position);
OUT.Uv = IN.Uv;
OUT.Color = float4(Color.rgb * lighting, Color.a);
OUT.FogFactor = (G(FogParams).z - OUT.HPosition.w) * G(FogParams).w;
return OUT;
}
TEX_DECLARE2D(DiffuseMap, 0);
float4 AdornPS(VertexOutput IN): COLOR0
{
float4 result = tex2D(DiffuseMap, IN.Uv) * IN.Color;
result.rgb = lerp(G(FogColor), result.rgb, saturate(IN.FogFactor));
return result;
}
AALineVertexOutput AdornAALineVS(Appdata IN)
{
AALineVertexOutput OUT = (AALineVertexOutput)0;
float4 position = mul(WorldMatrix, IN.Position);
float3 normal = normalize(mul((float3x3)WorldMatrix, IN.Normal));
// line start and end position in world space
float4 startPosW = mul(WorldMatrix, float4(1, 0, 0, 1));
float4 endPosW = mul(WorldMatrix, float4(-1, 0, 0, 1));
// Compute view-space w
float w = dot(G(ViewProjection)[3], float4(position.xyz, 1.0f));
// radius in pixels + constant because line has to be little bit bigget to perform anti aliasing
float radius = PixelInfo.w + 2;
// scale the way that line has same size on screen
if (length(position - startPosW) < length(position - endPosW))
{
float w = dot(G(ViewProjection)[3], float4(startPosW.xyz, 1.0f));
float pixel_radius = radius * w * PixelInfo.x;
position.xyz = startPosW.xyz + normal * pixel_radius;
}
else
{
float w = dot(G(ViewProjection)[3], float4(endPosW.xyz, 1.0f));
float pixel_radius = radius * w * PixelInfo.x;
position.xyz = endPosW.xyz + normal * pixel_radius;
}
// output for PS
OUT.HPosition = mul(G(ViewProjection), position);
OUT.Position = OUT.HPosition;
OUT.Start = mul(G(ViewProjection), startPosW);
OUT.End = mul(G(ViewProjection), endPosW);
OUT.FogFactor = (G(FogParams).z - OUT.HPosition.w) * G(FogParams).w;
// screen ratio
OUT.Position.y *= PixelInfo.z;
OUT.Start.y *= PixelInfo.z;
OUT.End.y *= PixelInfo.z;
return OUT;
}
float4 AdornAALinePS(AALineVertexOutput IN): COLOR0
{
IN.Position /= IN.Position.w ;
IN.Start /= IN.Start.w;
IN.End /= IN.End.w;
float4 result = 1;
float2 lineDir = normalize(IN.End.xy - IN.Start.xy);
float2 fragToPoint = IN.Position.xy - IN.Start.xy;
// tips of the line are not Anti-Aliesed, they are just cut
// discard as soon as we can
float startDist = dot(lineDir, fragToPoint);
float endDist = dot(lineDir, -IN.Position.xy + IN.End.xy);
if (startDist < 0)
discard;
if (endDist < 0)
discard;
float2 perpLineDir = float2(lineDir.y, -lineDir.x);
float dist = abs(dot(perpLineDir, fragToPoint));
// high point serves to compute the function which is described bellow.
float highPoint = 1 + (PixelInfo.w - 1) * 0.5;
// this is function that has this shape /¯¯¯\, it is symetric, centered around 0 on X axis
// slope parts are +- 45 degree and are 1px thick. Area of the shape sums to line thickness in pixels
// funtion for 1px would be /\, func for 2px is /¯\ and so on...
result.a = saturate(highPoint - (dist * 0.5 * PixelInfo.y));
result *= Color;
// convert to sRGB, its not perfect for non-black backgrounds, but its the best we can get
result.a = pow( saturate(1 - result.a), 1/2.2);
result.a = 1 - result.a;
result.rgb = lerp(G(FogColor), result.rgb, saturate(IN.FogFactor));
return result;
}
OutlineVertexOutput AdornOutlineVS(Appdata IN)
{
OutlineVertexOutput OUT = (OutlineVertexOutput)0;
float4 position = mul(WorldMatrix, IN.Position);
OUT.HPosition = mul(G(ViewProjection), position);
OUT.Color = Color;
OUT.Position = position;
OUT.CenterRadius = float4(mul(WorldMatrix, float4(0, 0, 0, 1)).xyz, length(mul(WorldMatrix, float4(1, 0, 0, 0))));
return OUT;
}
float4 AdornOutlinePS(OutlineVertexOutput IN): COLOR0
{
float3 rayO = IN.Position.xyz - IN.CenterRadius.xyz;
float3 rayD = normalize(IN.Position.xyz - G(CameraPosition));
// magnitude(rayO + t * rayD) = radius
// t^2 + bt + c = radius
float thickness = 1;
float r0 = IN.CenterRadius.w;
float r1 = max(0, IN.CenterRadius.w - thickness);
float b = 2 * dot(rayO, rayD);
float c0 = dot(rayO, rayO) - r0 * r0;
float c1 = dot(rayO, rayO) - r1 * r1;
if (b * b < 4 * c0)
discard;
if (b * b > 4 * c1)
discard;
return IN.Color;
}

View File

@@ -0,0 +1,87 @@
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#include "default.hlsl"
#define SPEC_EXPON 25
#define KS .9
#define KR .42
#define FADE_DIST 250//133.33 fix!!!!!!!!!!
#define FADE_DIST_START 20
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float fade = saturate(1 - (IN.View_Depth.w - FADE_DIST_START) / FADE_DIST);
float3 nn = normalize(IN.Normal.xyz);
float3x3 normalMatrix = {
IN.Tangent.xyz,
cross(nn, IN.Tangent.xyz),
nn
};
float3 albedo = IN.Color.xyz;
float2 uv = IN.Uv.xy * 2;
float3 tn = tex2D(NormalMap, uv);
float3 tn2 = tex2D(NormalMap, uv * .4);
tn = lerp(tn, tn2, .5);
tn2 = tex2D(NormalMap, uv * .1);
tn = lerp(tn, tn2, .3) -.5;
tn = lerp(float3(0, 0, .5), tn, fade);
float tNormSum = 0.4 + 0.6 * (tn.x + tn.y + tn.z);
albedo *= ((1-fade) + (fade*tNormSum));
tn = CalcBevel(IN.EdgeDistances, tn, IN.View_Depth.w);
nn = mul(tn, normalMatrix);
float3 vn = normalize(IN.View_Depth.xyz);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
light.a = shadowSample(TEXTURE(ShadowMap), IN.PosLightSpace.xyz, light.a);
float3 diffuse;
float3 specular;
Shade(albedo, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
float3 enviroment = texCUBE(EnvironmentMap, reflect(-vn, nn)) * KR -.1;
oColor0 = float4(diffuse + specular + enviroment, IN.Color.w);
//subtract .1 because thats what dumbass roblox did for whatever reason
float fogAlpha = saturate((G(FogParams).z - length(IN.View_Depth.xyz)) * G(FogParams).w);
oColor0.xyz = lerp(G(FogColor), oColor0.rgb, fogAlpha);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 1
#define CFG_GLOSS_SCALE 256
#define CFG_REFLECTION_SCALE 0.6
#define CFG_NORMAL_SHADOW_SCALE 0
#define CFG_SPECULAR_LOD 0.94
#define CFG_GLOSS_LOD 240
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0.25
#define CFG_FAR_DIFFUSE_CUTOFF 0
#define CFG_FAR_NORMAL_CUTOFF 0.75
#define CFG_FAR_SPECULAR_CUTOFF 0
#define CFG_OPT_DIFFUSE_CONST
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,27 @@
#ifdef CLASSIC
#include "slate.hlsl"
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 1.3
#define CFG_GLOSS_SCALE 64
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.13
#define CFG_GLOSS_LOD 44
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0
#define CFG_FAR_DIFFUSE_CUTOFF 0
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#define CFG_OPT_BLEND_COLOR
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,26 @@
#ifdef CLASSIC
#include "slate.hlsl"
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 3
#define CFG_GLOSS_SCALE 256
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0.3
#define CFG_SPECULAR_LOD 0.21
#define CFG_GLOSS_LOD 22
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_OPT_BLEND_COLOR
#define CFG_WANG_TILES
#define CFG_WANG_TILES_SCALE 1
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,282 @@
#include "globals.h"
// GLSLES has limited number of vertex shader registers so we have to use less bones
#if defined(GLSLES) && !defined(GL3)
#define MAX_BONE_COUNT 32
#else
#define MAX_BONE_COUNT 72
#endif
// PowerVR saturate() is compiled to min/max pair
// These are cross-platform specialized saturates that are free on PC and only cost 1 cycle on PowerVR
#ifdef GLSLES
float saturate0(float v)
{
return max(v, 0);
}
float saturate1(float v)
{
return min(v, 1);
}
#define WANG_SUBSET_SCALE 2
#else
float saturate0(float v)
{
return saturate(v);
}
float saturate1(float v)
{
return saturate(v);
}
#define WANG_SUBSET_SCALE 1
#endif
#define GBUFFER_MAX_DEPTH 500.0f
#ifndef DX11
#define TEX_DECLARE2D(name, reg) sampler2D name : register(s##reg)
#define TEX_DECLARE3D(name, reg) sampler3D name : register(s##reg)
#define TEX_DECLARECUBE(name, reg) samplerCUBE name : register(s##reg)
#define TEXTURE(name) name
#define TEXTURE_IN_2D(name) sampler2D name
#define TEXTURE_IN_3D(name) sampler3D name
#define TEXTURE_IN_CUBE(name) samplerCUBE name
#define WORLD_MATRIX(name) uniform float4x4 name;
#define WORLD_MATRIX_ARRAY(name, count) uniform float4 name[count];
#ifdef GLSL
#define ATTR_INT4 float4
#define ATTR_INT3 float3
#define ATTR_INT2 float2
#define ATTR_INT float
#else
#define ATTR_INT4 int4
#define ATTR_INT3 int3
#define ATTR_INT2 int2
#define ATTR_INT int
#endif
#else
#define TEX_DECLARE2D(name, reg) \
SamplerState name##Sampler : register(s##reg); \
Texture2D<float4> name##Texture : register(t##reg)
#define TEX_DECLARE3D(name, reg) \
SamplerState name##Sampler : register(s##reg); \
Texture3D<float4> name##Texture : register(t##reg)
#define TEX_DECLARECUBE(name, reg) \
SamplerState name##Sampler : register(s##reg); \
TextureCube<float4> name##Texture : register(t##reg)
#define tex2D(tex, uv) tex##Texture.Sample(tex##Sampler, uv)
#define tex3D(tex, uv) tex##Texture.Sample(tex##Sampler, uv)
#define texCUBE(tex, uv) tex##Texture.Sample(tex##Sampler, uv)
#define tex2Dgrad(tex, uv, DDX, DDY) tex##Texture.SampleGrad(tex##Sampler, uv, DDX, DDY)
#define tex2Dbias(tex, uv) tex##Texture.SampleBias(tex##Sampler, uv.xy, uv.w)
#define texCUBEbias(tex, uv) tex##Texture.SampleBias(tex##Sampler, uv.xyz, uv.w)
#define TEXTURE(name) name##Sampler, name##Texture
#define TEXTURE_IN_2D(name) SamplerState name##Sampler, Texture2D name##Texture
#define TEXTURE_IN_3D(name) SamplerState name##Sampler, Texture3D name##Texture
#define TEXTURE_IN_CUBE(name) SamplerState name##Sampler, TextureCube name##Texture
#define WORLD_MATRIX(name) \
cbuffer WorldMatrixCB : register(b1) \
{ \
float4x4 name; \
}
#define WORLD_MATRIX_ARRAY(name, count) \
cbuffer WorldMatrixCB : register(b1) \
{ \
float4 name[count]; \
}
#define ATTR_INT4 int4
#define ATTR_INT3 int3
#define ATTR_INT2 int2
#define ATTR_INT int
#endif
#if defined(GLSLES) || defined(PIN_WANG_FALLBACK)
#define TEXTURE_WANG(name) 0
void getWang(float unused, float2 uv, float tiling, out float2 wangUv, out float4 wangUVDerivatives)
{
wangUv = uv * WANG_SUBSET_SCALE;
wangUVDerivatives = float4(0, 0, 0, 0); // not used in this mode
}
float4 sampleWang(TEXTURE_IN_2D(s), float2 uv, float4 wangUVDerivatives)
{
return tex2D(s, uv);
}
#else
#define TEXTURE_WANG(name) TEXTURE(name)
void getWang(TEXTURE_IN_2D(s), float2 uv, float tiling, out float2 wangUv, out float4 wangUVDerivatives)
{
#ifndef WIN_MOBILE
float idxTexSize = 128;
#else
float idxTexSize = 32;
#endif
float2 wangBase = uv * tiling * 4;
#if defined(DX11) && !defined(WIN_MOBILE)
// compensate the precision problem of Point Sampling on some cards. (We do it just at DX11 for performance reasons)
float2 wangUV = (floor(wangBase) + 0.5) / idxTexSize;
#else
float2 wangUV = wangBase / idxTexSize;
#endif
#if defined(DX11) || defined(GL3)
float2 wang = tex2D(s, wangUV).rg;
#else
float2 wang = tex2D(s, wangUV).ba;
#endif
wangUVDerivatives = float4(ddx(wangBase * 0.25), ddy(wangBase * 0.25));
wang *= 255.0 / 256.0;
wangUv = wang + frac(wangBase) * 0.25;
}
float4 sampleWang(TEXTURE_IN_2D(s), float2 uv, float4 derivates)
{
return tex2Dgrad(s, uv, derivates.xy, derivates.zw);
}
#endif
float4 gbufferPack(float depth, float3 diffuse, float3 specular, float fog)
{
depth = saturate(depth / GBUFFER_MAX_DEPTH);
const float3 bitSh = float3(255 * 255, 255, 1);
const float3 lumVec = float3(0.299, 0.587, 0.114);
float2 comp;
comp = depth * float2(255, 255 * 256);
comp = frac(comp);
comp = float2(depth, comp.x * 256 / 255) - float2(comp.x, comp.y) / 255;
float4 result;
result.r = lerp(1, dot(specular, lumVec), saturate(3 * fog));
result.g = lerp(0, dot(diffuse, lumVec), saturate(3 * fog));
result.ba = comp.yx;
return result;
}
float3 lgridOffset(float3 v, float3 n)
{
// cells are 4 studs in size
// offset in normal direction to prevent self-occlusion
// the offset has to be 1.5 cells in order to fully eliminate the influence of the source cell with trilinear filtering
// (i.e. 1 cell is enough for point filtering, but is not enough for trilinear filtering)
return v + n * (1.5f * 4.f);
}
float3 lgridPrepareSample(float3 c)
{
// yxz swizzle is necessary for GLSLES sampling to work efficiently
// (having .y as the first component allows to do the LUT lookup as a non-dependent texture fetch)
return c.yxz * G(LightConfig0).xyz + G(LightConfig1).xyz;
}
#if defined(GLSLES) && !defined(GL3)
#define LGRID_SAMPLER(name, register) TEX_DECLARE2D(name, register)
float4 lgridSample(TEXTURE_IN_2D(t), TEXTURE_IN_2D(lut), float3 data)
{
float4 offsets = tex2D(lut, data.xy);
// texture is 64 pixels high
// let's compute slice lerp coeff
float slicef = frac(data.x * 64);
// texture has 64 slices with 8x8 atlas setup
float2 base = saturate(data.yz) * 0.125;
float4 s0 = tex2D(t, base + offsets.xy);
float4 s1 = tex2D(t, base + offsets.zw);
return lerp(s0, s1, slicef);
}
#else
#define LGRID_SAMPLER(name, register) TEX_DECLARE3D(name, register)
float4 lgridSample(TEXTURE_IN_3D(t), TEXTURE_IN_2D(lut), float3 data)
{
float3 edge = step(G(LightConfig3).xyz, abs(data - G(LightConfig2).xyz));
float edgef = saturate1(dot(edge, 1));
// replace data with 0 on edges to minimize texture cache misses
float4 light = tex3D(t, data.yzx - data.yzx * edgef);
return lerp(light, G(LightBorder), edgef);
}
#endif
#ifdef GLSLES
float3 nmapUnpack(float4 value)
{
return value.rgb * 2 - 1;
}
#else
float3 nmapUnpack(float4 value)
{
float2 xy = value.ag * 2 - 1;
return float3(xy, sqrt(saturate(1 + dot(-xy, xy))));
}
#endif
float3 terrainNormal(float4 tnp0, float4 tnp1, float4 tnp2, float3 w, float3 normal, float3 tsel)
{
// Inspired by "Voxel-Based Terrain for Real-Time Virtual Simulations" [Lengyel2010] 5.5.2
float3 tangentTop = float3(normal.y, -normal.x, 0);
float3 tangentSide = float3(normal.z, 0, -normal.x);
float3 bitangentTop = float3(0, -normal.z, normal.y);
float3 bitangentSide = float3(0, -1, 0);
// Blend pre-unpack to save cycles
float3 tn = nmapUnpack(tnp0 * w.x + tnp1 * w.y + tnp2 * w.z);
// We blend all tangent frames together as a faster approximation to the correct world normal blend
float tselw = dot(tsel, w);
float3 tangent = lerp(tangentSide, tangentTop, tselw);
float3 bitangent = lerp(bitangentSide, bitangentTop, tselw);
return normalize(tangent * tn.x + bitangent * tn.y + normal * tn.z);
}
float3 shadowPrepareSample(float3 p)
{
float4 c = float4(p, 1);
return float3(dot(G(ShadowMatrix0), c), dot(G(ShadowMatrix1), c), dot(G(ShadowMatrix2), c));
}
float shadowDepth(float3 lpos)
{
return lpos.z;
}
float shadowStep(float d, float z)
{
// saturate returns 1 for z in [0.1..0.9]; it fades to 0 as z approaches 0 or 1
return step(d, z) * saturate(9 - 20 * abs(z - 0.5));
}
float shadowSample(TEXTURE_IN_2D(map), float3 lpos, float lightShadow)
{
#ifdef CLASSIC
return lightShadow;
#else
float2 smDepth = tex2D(map, lpos.xy).rg;
float smShadow = shadowStep(smDepth.x, shadowDepth(lpos));
return (1 - smShadow * smDepth.y * G(OutlineBrightness_ShadowInfo).w) * lightShadow;
#endif
}

View File

@@ -0,0 +1,73 @@
#ifdef CLASSIC
#define ALREADY_HAS_PS
#include "default.hlsl"
#define SPEC_EXPON 81
#define KS .75
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float3 nn = normalize(IN.Normal);
float3x3 normalMatrix = {
IN.Tangent.xyz,
cross(nn, IN.Tangent.xyz),
nn
};
nn = CalcBevel(IN.EdgeDistances, float3(0,0,.5), IN.View_Depth.w);
nn = mul(nn, normalMatrix);
float2 uv = IN.Uv.xy;
float3 concrete = .5 * (tex2D(DiffuseMap, uv).xyz * 2 - 1);
float3 albedo = IN.Color.xyz;
float3 vn = normalize(IN.View_Depth.xyz);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
float3 diffuse;
float3 specular;
albedo += concrete;
Shade(albedo, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
//diffuse += concrete; //this is accurate but stupid dont know if i should keep
oColor0 = float4(diffuse, IN.Color.w);
float fogAlpha = saturate((G(FogParams).z - length(IN.View_Depth.xyz)) * G(FogParams).w);
oColor0.xyz = lerp(G(FogColor), oColor0.rgb, fogAlpha);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, float3(0,0,0), fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 1.3
#define CFG_GLOSS_SCALE 128
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0
#define CFG_SPECULAR_LOD 0.07
#define CFG_GLOSS_LOD 22
#define CFG_NORMAL_DETAIL_TILING 10
#define CFG_NORMAL_DETAIL_SCALE 1
#define CFG_FAR_TILING 0.25
#define CFG_FAR_DIFFUSE_CUTOFF 0.75
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#define CFG_OPT_NORMAL_CONST
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,672 @@
#ifdef CLASSIC
#include "common.h"
#define LQMAT_FADE_FACTOR (1.0f/300.0f)
#define BEVEL_WIDTH .06
#define PI 3.14159265359
#define BEVEL_FADE_DIST 120
#define BEVEL_FADE_DIST_START 0
struct Appdata
{
float4 Position : POSITION;
float3 Normal : NORMAL;
float2 Uv : TEXCOORD0;
float2 UvStuds : TEXCOORD1;
float4 Color : COLOR0;
ATTR_INT4 Extra : COLOR1;
float3 Tangent : TEXCOORD2;
float4 EdgeDistances : TEXCOORD3;
};
struct VertexOutput
{
float2 Uv : TEXCOORD0;
float2 UvStuds : TEXCOORD1;
float4 Color : COLOR0;
float3 Normal : TEXCOORD2;
float3 Tangent : TEXCOORD3;
float3 Pos : TEXCOORD4;
float3 WorldPos : TEXCOORD5;
float4 LightPosition_Fog : TEXCOORD6;
float4 View_Depth : TEXCOORD7;
float3 PosLightSpace : TEXCOORD8;
float4 EdgeDistances : TEXCOORD9;
float Reflection : TEXCOORD10;
#ifdef CLASSIC_GOURAUD
float3 Diffuse : TEXCOORD11;
float3 Specular : TEXCOORD12;
#endif
};
#ifdef PIN_SKINNED
WORLD_MATRIX_ARRAY(WorldMatrixArray, MAX_BONE_COUNT * 3);
#endif
#ifdef PIN_DEBUG
uniform float4 DebugColor;
#endif
void Shade(float3 albedo, float3 nn, float3 vn, float ks, float specExpon, float4 light, out float3 diffuse, out float3 specular)
{
float3 ln = normalize(-G(Lamp0Dir));
float3 hn = normalize(ln + vn);
float ndl = dot(nn, ln);
float ndh = dot(nn, hn);
float2 lit0 = lit(ndl, ndh, specExpon).yz;
float3 lampColor = G(Lamp0Color);
diffuse = (light.a * (lampColor * lit0.x) + G(AmbientColor) + light.xyz);
//diffuse += light.a * max(-ndl, 0) * G(Lamp1Color); //the bitch ass light that shines on the backfacing normals remove for less ugly but less robloxeses accuracy
diffuse *= albedo;
specular = (lampColor * lit0.y) * ks * light.a;
}
float3 CalcBevel(float4 edgeDistances, float3 normal, float viewDepth)
{
float4 bevelMultiplier = saturate(BEVEL_WIDTH - edgeDistances) / BEVEL_WIDTH;
float fade = saturate(1 - (viewDepth - BEVEL_FADE_DIST_START) / BEVEL_FADE_DIST);
bevelMultiplier *= fade;
normal += bevelMultiplier.x * float3(.5,0,0);
normal += bevelMultiplier.y * float3(-.5,0,0);
normal += bevelMultiplier.z * float3(0,.5,0);
normal += bevelMultiplier.w * float3(0,-.5,0);
return normalize(normal);
}
float3 DisplaceCoord(float3 pos) //theres a fourth component but later idk
{
float cfactor = 0.980066578; //cos(0.2);
float sfactor = 0.198669331; //sin(0.2);
float cfactor2 = 0.955336489; //cos(0.3);
float sfactor2 = 0.295520207; //sin(0.3);
float cfactor3 = 0.921060994; //cos(0.4);
float sfactor3 = 0.389418342; //sin(0.4);
float3 p = pos.xyz;
float3 shiftPos = p;
shiftPos.x += p.x * cfactor + p.z * sfactor;
shiftPos.z += p.x * -sfactor + p.z * cfactor;
shiftPos.x += p.x * cfactor2 - p.y * sfactor2;
shiftPos.y += p.x * sfactor2 + p.y * cfactor2;
shiftPos.y += p.y * cfactor3 - p.z * sfactor3;
shiftPos.z += p.y * sfactor3 + p.z * cfactor3;
return shiftPos; //return float4(shiftPos,IN.TexPos3D.w);
}
TEX_DECLARE2D(StudsMap, 0);
LGRID_SAMPLER(LightMap, 1);
TEX_DECLARE2D(LightMapLookup, 2);
TEX_DECLARE2D(ShadowMap, 3);
TEX_DECLARECUBE(EnvironmentMap, 4);
TEX_DECLARE2D(DiffuseMap, 5);
TEX_DECLARE2D(NormalMap, 6);
TEX_DECLARE3D(SpecularMap, 7);
#ifndef GLSLES
TEX_DECLARE2D(NormalDetailMap, 8);
#endif
VertexOutput DefaultVS(Appdata IN, out float4 HPosition: POSITION)
{
VertexOutput OUT = (VertexOutput)0;
// Transform position and normal to world space
#ifdef PIN_SKINNED
int boneIndex = IN.Extra.r;
float4 worldRow0 = WorldMatrixArray[boneIndex * 3];
float4 worldRow1 = WorldMatrixArray[boneIndex * 3 + 1];
float4 worldRow2 = WorldMatrixArray[boneIndex * 3 + 2];
float3 posWorld = float3(dot(worldRow0, IN.Position), dot(worldRow1, IN.Position), dot(worldRow2, IN.Position));
float3 normalWorld = float3(dot(worldRow0.xyz, IN.Normal), dot(worldRow1.xyz, IN.Normal), dot(worldRow2.xyz, IN.Normal));
OUT.Tangent = float3(dot(worldRow0.xyz, IN.Tangent), dot(worldRow1.xyz, IN.Tangent), dot(worldRow2.xyz, IN.Tangent));
#else
//OUT.Pos = mul(transpose(worldMatrix), IN.Position).xyz; // IN.position
float3 posWorld = IN.Position.xyz;
float3 normalWorld = IN.Normal;
OUT.Tangent = IN.Tangent;
#endif
OUT.Pos = IN.Position.xyz;
OUT.WorldPos = posWorld;
//posWorld.xy += sin(posWorld.yx * .05) * 5;
//float scale = 6;
//posWorld.y *= 6;
//posWorld.y -= G(CameraPosition).y * (scale - 1);
float4 color = IN.Color;
HPosition = mul(G(ViewProjection), float4(posWorld, 1));
OUT.Normal = normalWorld;
OUT.Uv = IN.Uv;
OUT.UvStuds.xy = IN.UvStuds;
OUT.Color = color;
OUT.LightPosition_Fog = float4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)), (G(FogParams).z - HPosition.w) * G(FogParams).w);
OUT.View_Depth = float4(G(CameraPosition).xyz - posWorld, HPosition.w);
#ifdef CLASSIC_GOURAUD
float4 albedo = color;
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), OUT.LightPosition_Fog.xyz);
Shade(float3(1,1,1), normalize(OUT.Normal), normalize(OUT.View_Depth.xyz), .71, 81, light, OUT.Diffuse, OUT.Specular);
#endif
#if defined(PIN_HQ) || defined(PIN_REFLECTION)
//float4 edgeDistances = IN.EdgeDistances*G(FadeDistance_GlowFactor).z + 0.5 * OUT.View_Depth.w * G(FadeDistance_GlowFactor).y;
OUT.Reflection = IN.Extra.a / 255.f;
OUT.EdgeDistances = IN.EdgeDistances;
#endif
OUT.PosLightSpace.xyz = shadowPrepareSample(posWorld);
return OUT;
}
#ifdef PIN_SURFACE
struct SurfaceInput
{
float4 Color;
float2 Uv;
float2 UvStuds;
#ifdef PIN_REFLECTION
float Reflectance;
#endif
};
struct Surface
{
float3 albedo;
float3 normal;
float specular;
float gloss;
float reflectance;
};
Surface surfaceShader(SurfaceInput IN, float2 fade);
Surface surfaceShaderExec(VertexOutput IN)
{
SurfaceInput SIN;
SIN.Color = IN.Color;
SIN.Uv = IN.Uv.xy;
SIN.UvStuds = IN.UvStuds.xy;
#ifdef PIN_REFLECTION
SIN.Reflectance = IN.Reflection;
#endif
float2 fade;
fade.x = saturate0(1 - IN.View_Depth.w * LQMAT_FADE_FACTOR );
fade.y = saturate0(1 - IN.View_Depth.w * G(FadeDistance_GlowFactor).y );
return surfaceShader(SIN, fade);
}
#endif
uniform float4 LqmatFarTilingFactor; // material tiling factor for low-quality shader, must be the same as CFG_FAR_TILING
float4 sampleFar1(TEXTURE_IN_2D(s), float2 uv, float fade, float cutoff)
{
#ifdef GLSLES
return tex2D(s, uv);
#else
if (cutoff == 0)
return tex2D(s, uv);
else
{
float cscale = 1 / (1 - cutoff);
return lerp(tex2D(s, uv * (LqmatFarTilingFactor.xy) ), tex2D(s, uv ), saturate0(fade * cscale - cutoff * cscale));
}
#endif
}
//#if defined(PIN_WANG) || defined(PIN_WANG_FALLBACK)
float4 sampleWangSimple(TEXTURE_IN_2D(s), float2 uv)
{
float2 wangUv;
float4 wangUVDerivatives;
getWang(TEXTURE_WANG(NormalDetailMap), uv, 1, wangUv, wangUVDerivatives);
return sampleWang(TEXTURE(s), wangUv, wangUVDerivatives);
}
//#endif
#ifndef ALREADY_HAS_PS
#define SPEC_EXPON 81 //81
#define KS .75
#define FADE_DIST 500
#define FADE_DIST_START 0
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float normalStrength = .4;
float fade = saturate(normalStrength - (IN.View_Depth.w - FADE_DIST_START) / FADE_DIST);
float3 nn = normalize(IN.Normal);
float4 edgeDistances = IN.EdgeDistances;
float4 albedo = IN.Color;
float2 uv;
#ifndef PIN_MESH
uv = IN.Uv;
float3x3 normalMatrix = {
IN.Tangent.xyz,
cross(nn, IN.Tangent.xyz),
nn
};
//tn = tex2D(NormalMap, uv) - .5;//studs normal
float3 tn = float3(0,0,.5);
tn = lerp(float3(0, 0, .5), tn, fade);
tn = CalcBevel(edgeDistances, tn, IN.View_Depth.w);
nn = mul(tn, normalMatrix);
float4 colorTex = tex2D(DiffuseMap, uv);
albedo *= colorTex;
//albedo = lerp(albedo, colorTex.xyz, colorTex.w);//studs normal
//albedo += (colorTex.x * 2 - 1) * .07;//studs normal
#else
uv = IN.Uv;
float4 colorTex = tex2D(DiffuseMap, uv);
albedo *= colorTex;
#endif
float3 vn = normalize(IN.View_Depth.xyz);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
float3 diffusePhong;
float3 diffuse;
float3 specularPhong;
float3 specular;
#ifdef CLASSIC_GOURAUD
diffuse = lerp(diffusePhong, IN.Diffuse * albedo.rgb, 1.0);
specular = lerp(specularPhong, IN.Specular, 1.0);
#else
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffusePhong, specularPhong);
diffuse = diffusePhong;
specular = specularPhong;
#endif
#ifndef PIN_MESH
//diffuse = lerp(diffuse, colorTex.xyz, colorTex.w);
#endif
float3 result = diffuse + specular;
#ifdef PIN_REFLECTION
float3 reflection = texCUBE(EnvironmentMap, reflect(-vn, nn)).rgb;
result = lerp(result, reflection, IN.Reflection);
#endif
float fogAlpha = saturate((G(FogParams).z - length(IN.View_Depth.xyz)) * G(FogParams).w);
result = lerp(G(FogColor), result, fogAlpha);
oColor0 = float4(result, albedo.a);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#endif
#else
#include "common.h"
#define LQMAT_FADE_FACTOR (1.0f/300.0f)
struct Appdata
{
float4 Position : POSITION;
float3 Normal : NORMAL;
float2 Uv : TEXCOORD0;
float2 UvStuds : TEXCOORD1;
float4 Color : COLOR0;
ATTR_INT4 Extra : COLOR1;
#ifdef PIN_SURFACE
float3 Tangent : TEXCOORD2;
#endif
float4 EdgeDistances : TEXCOORD3;
};
struct VertexOutput
{
float4 Uv_EdgeDistance1 : TEXCOORD0;
float4 UvStuds_EdgeDistance2 : TEXCOORD1;
float4 Color : COLOR0;
float4 LightPosition_Fog : TEXCOORD2;
float4 View_Depth : TEXCOORD3;
#if defined(PIN_HQ) || defined(PIN_REFLECTION)
float4 Normal_SpecPower : TEXCOORD4;
#endif
#ifdef PIN_SURFACE
float3 Tangent : TEXCOORD5;
#else
float4 Diffuse_Specular : COLOR1;
#endif
float4 PosLightSpace_Reflectance: TEXCOORD6;
};
#ifdef PIN_SKINNED
WORLD_MATRIX_ARRAY(WorldMatrixArray, MAX_BONE_COUNT * 3);
#endif
#ifdef PIN_DEBUG
uniform float4 DebugColor;
#endif
VertexOutput DefaultVS(Appdata IN, out float4 HPosition: POSITION)
{
VertexOutput OUT = (VertexOutput)0;
// Transform position and normal to world space
#ifdef PIN_SKINNED
int boneIndex = IN.Extra.r;
float4 worldRow0 = WorldMatrixArray[boneIndex * 3 + 0];
float4 worldRow1 = WorldMatrixArray[boneIndex * 3 + 1];
float4 worldRow2 = WorldMatrixArray[boneIndex * 3 + 2];
float3 posWorld = float3(dot(worldRow0, IN.Position), dot(worldRow1, IN.Position), dot(worldRow2, IN.Position));
float3 normalWorld = float3(dot(worldRow0.xyz, IN.Normal), dot(worldRow1.xyz, IN.Normal), dot(worldRow2.xyz, IN.Normal));
#else
float3 posWorld = IN.Position.xyz;
float3 normalWorld = IN.Normal;
#endif
// Decode diffuse/specular parameters; encoding depends on the skinned flag due to vertex declaration differences
#if defined(PIN_DEBUG)
float4 color = DebugColor;
#else
float4 color = IN.Color;
#endif
float specularIntensity = IN.Extra.g / 255.f;
float specularPower = IN.Extra.b;
float ndotl = dot(normalWorld, -G(Lamp0Dir));
#ifdef PIN_HQ
// We'll calculate specular in pixel shader
float2 lt = float2(saturate(ndotl), (ndotl > 0));
#else
// Using lit here improves performance on software vertex shader implementations
float2 lt = lit(ndotl, dot(normalize(-G(Lamp0Dir) + normalize(G(CameraPosition).xyz - posWorld.xyz)), normalWorld), specularPower).yz;
#endif
HPosition = mul(G(ViewProjection), float4(posWorld, 1));
OUT.Uv_EdgeDistance1.xy = IN.Uv;
OUT.UvStuds_EdgeDistance2.xy = IN.UvStuds;
OUT.Color = color;
OUT.LightPosition_Fog = float4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)), (G(FogParams).z - HPosition.w) * G(FogParams).w);
OUT.View_Depth = float4(G(CameraPosition).xyz - posWorld, HPosition.w);
#if defined(PIN_HQ) || defined(PIN_REFLECTION)
float4 edgeDistances = IN.EdgeDistances*G(FadeDistance_GlowFactor).z + 0.5 * OUT.View_Depth.w * G(FadeDistance_GlowFactor).y;
OUT.Uv_EdgeDistance1.zw = edgeDistances.xy;
OUT.UvStuds_EdgeDistance2.zw = edgeDistances.zw;
OUT.Normal_SpecPower = float4(normalWorld, specularPower);
OUT.PosLightSpace_Reflectance.w = IN.Extra.a / 255.f;
#endif
#ifdef PIN_SURFACE
#ifdef PIN_SKINNED
float3 tangent = float3(dot(worldRow0.xyz, IN.Tangent), dot(worldRow1.xyz, IN.Tangent), dot(worldRow2.xyz, IN.Tangent));
#else
float3 tangent = IN.Tangent;
#endif
OUT.Tangent = tangent;
#else
float3 diffuse = lt.x * G(Lamp0Color) + max(-ndotl, 0) * G(Lamp1Color);
OUT.Diffuse_Specular = float4(diffuse, lt.y * specularIntensity);
#endif
OUT.PosLightSpace_Reflectance.xyz = shadowPrepareSample(posWorld);
return OUT;
}
#ifdef PIN_SURFACE
struct SurfaceInput
{
float4 Color;
float2 Uv;
float2 UvStuds;
#ifdef PIN_REFLECTION
float Reflectance;
#endif
};
struct Surface
{
float3 albedo;
float3 normal;
float specular;
float gloss;
float reflectance;
};
Surface surfaceShader(SurfaceInput IN, float2 fade);
Surface surfaceShaderExec(VertexOutput IN)
{
SurfaceInput SIN;
SIN.Color = IN.Color;
SIN.Uv = IN.Uv_EdgeDistance1.xy;
SIN.UvStuds = IN.UvStuds_EdgeDistance2.xy;
#ifdef PIN_REFLECTION
SIN.Reflectance = IN.PosLightSpace_Reflectance.w;
#endif
float2 fade;
fade.x = saturate0(1 - IN.View_Depth.w * LQMAT_FADE_FACTOR );
fade.y = saturate0(1 - IN.View_Depth.w * G(FadeDistance_GlowFactor).y );
return surfaceShader(SIN, fade);
}
#endif
TEX_DECLARE2D(StudsMap, 0);
LGRID_SAMPLER(LightMap, 1);
TEX_DECLARE2D(LightMapLookup, 2);
TEX_DECLARE2D(ShadowMap, 3);
TEX_DECLARECUBE(EnvironmentMap, 4);
TEX_DECLARE2D(DiffuseMap, 5);
TEX_DECLARE2D(NormalMap, 6);
TEX_DECLARE2D(SpecularMap, 7);
#ifndef GLSLES
TEX_DECLARE2D(NormalDetailMap, 8);
#endif
uniform float4 LqmatFarTilingFactor; // material tiling factor for low-quality shader, must be the same as CFG_FAR_TILING
float4 sampleFar1(TEXTURE_IN_2D(s), float2 uv, float fade, float cutoff)
{
#ifdef GLSLES
return tex2D(s, uv);
#else
if (cutoff == 0)
return tex2D(s, uv);
else
{
float cscale = 1 / (1 - cutoff);
return lerp(tex2D(s, uv * (LqmatFarTilingFactor.xy) ), tex2D(s, uv ), saturate0(fade * cscale - cutoff * cscale));
}
#endif
}
#if defined(PIN_WANG) || defined(PIN_WANG_FALLBACK)
float4 sampleWangSimple(TEXTURE_IN_2D(s), float2 uv)
{
float2 wangUv;
float4 wangUVDerivatives;
getWang(TEXTURE_WANG(NormalDetailMap), uv, 1, wangUv, wangUVDerivatives);
return sampleWang(TEXTURE(s), wangUv, wangUVDerivatives);
}
#endif
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
// Compute albedo term
#ifdef PIN_SURFACE
Surface surface = surfaceShaderExec(IN);
float4 albedo = float4(surface.albedo, IN.Color.a);
float3 bitangent = cross(IN.Normal_SpecPower.xyz, IN.Tangent.xyz);
float3 normal = normalize(surface.normal.x * IN.Tangent.xyz + surface.normal.y * bitangent + surface.normal.z * IN.Normal_SpecPower.xyz);
float ndotl = dot(normal, -G(Lamp0Dir));
float3 diffuseIntensity = saturate0(ndotl) * G(Lamp0Color) + max(-ndotl, 0) * G(Lamp1Color);
float specularIntensity = step(0, ndotl) * surface.specular;
float specularPower = surface.gloss;
float reflectance = surface.reflectance;
#elif PIN_LOWQMAT
#ifndef CFG_FAR_DIFFUSE_CUTOFF
#define CFG_FAR_DIFFUSE_CUTOFF (0.6f)
#endif
#if defined(PIN_WANG) || defined(PIN_WANG_FALLBACK)
float4 albedo = sampleWangSimple(TEXTURE(DiffuseMap), IN.Uv_EdgeDistance1.xy);
#else
float fade = saturate0(1 - IN.View_Depth.w * LQMAT_FADE_FACTOR);
float4 albedo = sampleFar1(TEXTURE(DiffuseMap), IN.Uv_EdgeDistance1.xy, fade, CFG_FAR_DIFFUSE_CUTOFF);
#endif
albedo.rgb = lerp(float3(1, 1, 1), IN.Color.rgb, albedo.a ) * albedo.rgb;
albedo.a = IN.Color.a;
float3 diffuseIntensity = IN.Diffuse_Specular.xyz;
float specularIntensity = IN.Diffuse_Specular.w;
float reflectance = 0;
#else
#ifdef PIN_PLASTIC
float4 studs = tex2D(StudsMap, IN.UvStuds_EdgeDistance2.xy);
float4 albedo = float4(IN.Color.rgb * (studs.r * 2), IN.Color.a);
#else
float4 albedo = tex2D(DiffuseMap, IN.Uv_EdgeDistance1.xy) * IN.Color;
#endif
#ifdef PIN_HQ
float3 normal = normalize(IN.Normal_SpecPower.xyz);
float specularPower = IN.Normal_SpecPower.w;
#elif defined(PIN_REFLECTION)
float3 normal = IN.Normal_SpecPower.xyz;
#endif
float3 diffuseIntensity = IN.Diffuse_Specular.xyz;
float specularIntensity = IN.Diffuse_Specular.w;
#ifdef PIN_REFLECTION
float reflectance = IN.PosLightSpace_Reflectance.w;
#endif
#endif
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
float shadow = shadowSample(TEXTURE(ShadowMap), IN.PosLightSpace_Reflectance.xyz, light.a);
// Compute reflection term
#if defined(PIN_SURFACE) || defined(PIN_REFLECTION)
float3 reflection = texCUBE(EnvironmentMap, reflect(-IN.View_Depth.xyz, normal)).rgb;
albedo.rgb = lerp(albedo.rgb, reflection.rgb, reflectance);
#endif
// Compute diffuse term
float3 diffuse = (G(AmbientColor) + diffuseIntensity * shadow + light.rgb) * albedo.rgb;
// Compute specular term
#ifdef PIN_HQ
float3 specular = G(Lamp0Color) * (specularIntensity * shadow * (float)(half)pow(saturate(dot(normal, normalize(-G(Lamp0Dir) + normalize(IN.View_Depth.xyz)))), specularPower));
#else
float3 specular = G(Lamp0Color) * (specularIntensity * shadow);
#endif
// Combine
oColor0.rgb = diffuse.rgb + specular.rgb;
oColor0.a = albedo.a;
#ifdef PIN_HQ
float ViewDepthMul = IN.View_Depth.w * G(FadeDistance_GlowFactor).y;
float outlineFade = saturate1( ViewDepthMul * G(OutlineBrightness_ShadowInfo).x + G(OutlineBrightness_ShadowInfo).y);
float2 minIntermediate = min(IN.Uv_EdgeDistance1.wz, IN.UvStuds_EdgeDistance2.wz);
float minEdgesPlus = min(minIntermediate.x, minIntermediate.y) / ViewDepthMul;
oColor0.rgb *= saturate1(outlineFade *(1.5 - minEdgesPlus) + minEdgesPlus);
#endif
float fogAlpha = saturate(IN.LightPosition_Fog.w);
#ifdef PIN_NEON
oColor0.rgb = IN.Color.rgb * G(FadeDistance_GlowFactor).w;
oColor0.a = 1 - fogAlpha * IN.Color.a;
diffuse.rgb = 0;
specular.rgb = 0;
#endif
oColor0.rgb = lerp(G(FogColor), oColor0.rgb, fogAlpha);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#endif

View File

@@ -0,0 +1,73 @@
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#include "default.hlsl"
#define SPEC_EXPON 25
#define KS .9
#define MIN_BACKLIGHT .9
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float3 normal = normalize(IN.Normal);
float3x3 normalMatrix = {
IN.Tangent.xyz,
cross(normal, IN.Tangent.xyz),
normal
};
float2 uv = IN.Uv.xy * 6; // * 5 * 1.2
float3 tn = tex2D(NormalMap, uv).yxz - .5;
tn = lerp(tn, float3(0,0,.5), .7);
tn = CalcBevel(IN.EdgeDistances, tn, IN.View_Depth.w);
float3 nn = normalize(mul(tn, normalMatrix));
float3 vn = normalize(IN.View_Depth.xyz);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
light.a = shadowSample(TEXTURE(ShadowMap), IN.PosLightSpace.xyz, light.a);
float3 diffuse;
float3 specular;
Shade(IN.Color.xyz, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
oColor0 = float4(diffuse + specular, IN.Color.w);
float fogAlpha = saturate((G(FogParams).z - length(IN.View_Depth.xyz)) * G(FogParams).w);
oColor0.xyz = lerp(G(FogColor), oColor0.rgb, fogAlpha);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 2.7
#define CFG_GLOSS_SCALE 256
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0.5
#define CFG_SPECULAR_LOD 0.9
#define CFG_GLOSS_LOD 160
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0
#define CFG_FAR_DIFFUSE_CUTOFF 0
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,27 @@
#ifdef CLASSIC
#include "concrete.hlsl"
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 0.2
#define CFG_GLOSS_SCALE 128
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0.2
#define CFG_SPECULAR_LOD 0.03
#define CFG_GLOSS_LOD 16
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0
#define CFG_FAR_DIFFUSE_CUTOFF 0
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#define CFG_OPT_BLEND_COLOR
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,50 @@
#include "common.h"
// .xy = gbuffer width/height, .zw = inverse gbuffer width/height
uniform float4 TextureSize;
TEX_DECLARE2D(tex, 0);
struct v2f
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
#if defined(GLSL) || defined(DX11)
float4 convertPosition(float4 p)
{
return p;
}
#else
float4 convertPosition(float4 p)
{
// half-pixel offset
return p + float4(-TextureSize.z, TextureSize.w, 0, 0);
}
#endif
#if defined(GLSL)
float2 convertUv(float4 p)
{
return p.xy * 0.5 + 0.5;
}
#else
float2 convertUv(float4 p)
{
return p.xy * float2(0.5, -0.5) + 0.5;
}
#endif
v2f gbufferVS( in float4 pos : POSITION )
{
v2f o;
o.pos = convertPosition(pos);
o.uv = convertUv(pos);
return o;
}
float4 gbufferPS( v2f i ) : COLOR0
{
return tex2D( tex, i.uv );
}

View File

@@ -0,0 +1,47 @@
#ifndef GLSL
struct Globals
{
#endif
float4x4 ViewProjection;
float4 ViewRight;
float4 ViewUp;
float4 ViewDir;
float3 CameraPosition;
float3 AmbientColor;
float3 Lamp0Color;
float3 Lamp0Dir;
float3 Lamp1Color;
float3 FogColor;
float4 FogParams;
float4 LightBorder;
float4 LightConfig0;
float4 LightConfig1;
float4 LightConfig2;
float4 LightConfig3;
float4 FadeDistance_GlowFactor;
float4 OutlineBrightness_ShadowInfo;
float4 ShadowMatrix0;
float4 ShadowMatrix1;
float4 ShadowMatrix2;
#ifndef GLSL
};
#ifdef DX11
cbuffer Globals : register(b0)
{
Globals _G;
};
#else
uniform Globals _G : register(c0);
#endif
#define G(x) _G.x
#else
#define G(x) x
#endif

View File

@@ -0,0 +1,27 @@
#ifdef CLASSIC
#include "ice.hlsl"
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 0.5
#define CFG_GLOSS_SCALE 128
#define CFG_REFLECTION_SCALE 0.2
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.19
#define CFG_GLOSS_LOD 24
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0.25
#define CFG_FAR_DIFFUSE_CUTOFF 0.6
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#define CFG_OPT_NORMAL_CONST
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,98 @@
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#include "default.hlsl"
#define SPEC_EXPON 50
#define KS .1
#define NOISE_SCALE float3(0.09, 0.02, 0.004);
#define SPREAD .3
#define GRASS_THRESHOLD .95
#define FADE_DIST 300//133.33 fix!!!!!!!!!!
#define FADE_DIST_START 20
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float3 nn = normalize(IN.Normal);
float3x3 normalMatrix = {
IN.Tangent.xyz,
cross(nn, IN.Tangent.xyz),
nn
};
float fade = saturate(1 - (IN.View_Depth.w - FADE_DIST_START) / FADE_DIST);
float2 uv = IN.Uv.xy;
float3 shiftPos = DisplaceCoord(IN.Pos.xyz);
float3 ns = NOISE_SCALE;
float noiseval2 = tex3D(SpecularMap,shiftPos.xyz*ns.x).x * 0.4;
float noiseval = tex3D(SpecularMap,shiftPos.zyx*ns.y).x * 0.6;
noiseval -= noiseval2;
float noiseval3 = tex3D(SpecularMap,shiftPos.xyz*ns.z).x * 0.3;
noiseval += noiseval3;
float interp = (noiseval - GRASS_THRESHOLD + SPREAD)/2/SPREAD+0.5;
interp = clamp(interp,0,1);
float3 grassColor = tex2D(DiffuseMap, uv).xyz;
float3 dirt = tex2D(NormalMap,uv).xyz;
float3 albedo = IN.Color.xyz;
albedo = lerp(grassColor + IN.Color.xyz - float3(0.31,0.43,0.146), dirt, interp * fade);
float3 grassNorm = tex2D(StudsMap,uv).xyz;
float3 dirtNorm = float3(0.5,0.5,1);
float3 tn = lerp(grassNorm, dirtNorm, interp) - 0.5;
tn = CalcBevel(IN.EdgeDistances, tn, IN.View_Depth.w);
nn = mul(tn, normalMatrix);
float3 vn = normalize(IN.View_Depth.xyz);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
light.a = shadowSample(TEXTURE(ShadowMap), IN.PosLightSpace.xyz, light.a);
float3 diffuse;
float3 specular;
Shade(albedo, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
oColor0 = float4(diffuse + specular, IN.Color.w);
float fogAlpha = saturate((G(FogParams).z - length(IN.View_Depth.xyz)) * G(FogParams).w);
oColor0.xyz = lerp(G(FogColor), oColor0.rgb, fogAlpha);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 1
#define CFG_GLOSS_SCALE 256
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0.5
#define CFG_SPECULAR_LOD 0.17
#define CFG_GLOSS_LOD 18
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0.25
#define CFG_FAR_DIFFUSE_CUTOFF 0.6
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#define CFG_OPT_BLEND_COLOR
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,96 @@
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#include "default.hlsl"
#define SPEC_EXPON 25
#define KS .4
#define KR .275
#define NOISE_SCALE 7
#define SPREAD .3
#define GRASS_THRESHOLD .95
#define FADE_DIST 260
#define FADE_DIST_START 0
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float3 normal = normalize(IN.Normal);
float3x3 normalMatrix = {
IN.Tangent.xyz,
cross(normal, IN.Tangent.xyz),
normal
};
float fade = saturate(1 - (IN.View_Depth.w - FADE_DIST_START) / FADE_DIST);
float2 uv = IN.Uv.xy * .1;
float3 shiftPos = DisplaceCoord(IN.Pos.xyz);
float noiseval = tex3D(SpecularMap,shiftPos.xyz/NOISE_SCALE*0.1).x;
float noiseval2 = tex3D(SpecularMap,shiftPos.xyz/NOISE_SCALE*0.5).x * 0.7 + 0.5;
noiseval *= noiseval2;
noiseval = 0.3 + noiseval * 0.7;
float3 albedo = IN.Color.xyz + fade*(noiseval*.2);
float3 tn = tex2D(NormalMap,uv).xyz - .5;
float tNormSum = 0.85 + 0.15 * (tn.x + tn.y + tn.z); //do the thing!!!!!!!!!
tn = lerp(float3(0,0,.5), tn, 0.15 * fade);
albedo *= ((1-fade) + (fade*tNormSum));
tn = CalcBevel(IN.EdgeDistances, tn, IN.View_Depth.w);
float3 nn = mul(tn, normalMatrix);
//nn *= fade;
//KS *= fade; //ks is a constant and idk if this dumb shit is worth keeping anyways
float3 vn = normalize(IN.View_Depth.xyz);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
light.a = shadowSample(TEXTURE(ShadowMap), IN.PosLightSpace.xyz, light.a);
float3 diffuse;
float3 specular;
Shade(albedo, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
float3 enviroment = texCUBE(EnvironmentMap, reflect(-vn, nn)) * KR;
oColor0 = float4(diffuse + specular + enviroment, IN.Color.w);
float fogAlpha = saturate((G(FogParams).z - length(IN.View_Depth.xyz)) * G(FogParams).w);
oColor0.xyz = lerp(G(FogColor), oColor0.rgb, fogAlpha);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1.0
#define CFG_SPECULAR_SCALE 1.2
#define CFG_GLOSS_SCALE 256
#define CFG_REFLECTION_SCALE 0.3
#define CFG_NORMAL_SHADOW_SCALE 0
#define CFG_SPECULAR_LOD 1
#define CFG_GLOSS_LOD 190
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0.25
#define CFG_FAR_DIFFUSE_CUTOFF 0
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0.75
#define CFG_OPT_DIFFUSE_CONST
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,27 @@
#ifdef CLASSIC
#include "slate.hlsl"
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 1.0
#define CFG_GLOSS_SCALE 128
#define CFG_REFLECTION_SCALE 0.2
#define CFG_NORMAL_SHADOW_SCALE 0.1
#define CFG_SPECULAR_LOD 0.7
#define CFG_GLOSS_LOD 54
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0
#define CFG_FAR_DIFFUSE_CUTOFF 0
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#define CFG_OPT_NORMAL_CONST
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,100 @@
#define PIN_SURFACE
#include "default.hlsl"
#ifndef CFG_WANG_TILES
float4 sampleFar(TEXTURE_IN_2D(s), float2 uv, float fade, float cutoff)
{
#ifdef GLSLES
return tex2D(s, uv);
#else
if (cutoff == 0)
return tex2D(s, uv);
else
{
float cscale = 1 / (1 - cutoff);
return lerp(tex2D(s, uv * (CFG_FAR_TILING) ), tex2D(s, uv ), saturate0(fade * cscale - cutoff * cscale));
}
#endif
}
#endif
Surface surfaceShader(SurfaceInput IN, float2 fade2)
{
#ifdef CFG_WANG_TILES
float2 wangUv;
float4 wangUVDerivatives;
getWang(TEXTURE_WANG(NormalDetailMap), IN.Uv, CFG_TEXTURE_TILING, wangUv, wangUVDerivatives);
#endif
float2 uv = IN.Uv * (CFG_TEXTURE_TILING);
float fadeDiffuse = fade2.x;
float fade = fade2.y;
#ifdef CFG_OPT_DIFFUSE_CONST
float4 diffuse = 1;
#else
#ifdef CFG_WANG_TILES
float4 diffuse = sampleWang(TEXTURE(DiffuseMap), wangUv, wangUVDerivatives);
#else
float4 diffuse = sampleFar(TEXTURE(DiffuseMap), uv, fadeDiffuse, CFG_FAR_DIFFUSE_CUTOFF);
#endif
diffuse.rgba = diffuse.rgba * (CFG_DIFFUSE_SCALE);
#endif
#ifdef CFG_OPT_NORMAL_CONST
float3 normal = float3(0, 0, 1);
#else
#ifdef CFG_WANG_TILES
float3 normal = nmapUnpack(sampleWang(TEXTURE(NormalMap), wangUv, wangUVDerivatives));
#else
float3 normal = nmapUnpack(sampleFar(TEXTURE(NormalMap), uv, fade, CFG_FAR_NORMAL_CUTOFF));
#endif
#endif
#ifndef GLSLES
#ifndef CFG_WANG_TILES // normal detail unavailable when running wang tiles
float3 normalDetail = nmapUnpack(tex2D(NormalDetailMap, uv * (CFG_NORMAL_DETAIL_TILING)));
normal.xy += normalDetail.xy * (CFG_NORMAL_DETAIL_SCALE);
#endif
#endif
normal.xy *= fade;
float shadowFactor = 1 + normal.x * (CFG_NORMAL_SHADOW_SCALE);
#ifdef CFG_OPT_BLEND_COLOR
float3 albedo = lerp(float3(1, 1, 1), IN.Color.rgb, diffuse.a) * diffuse.rgb * shadowFactor;
#else
float3 albedo = IN.Color.rgb * diffuse.rgb * shadowFactor;
#endif
#ifndef GLSLES
float4 studs = tex2D(StudsMap, IN.UvStuds);
albedo *= studs.r * 2;
#endif
#ifdef CFG_WANG_TILES
float2 specular = sampleWang(TEXTURE(SpecularMap), wangUv, wangUVDerivatives).rg;
#else
float2 specular = sampleFar(TEXTURE(SpecularMap), uv, fade, CFG_FAR_SPECULAR_CUTOFF).rg;
#endif
// make sure glossiness is never 0 to avoid fp specials
float2 specbase = specular * float2(CFG_SPECULAR_SCALE, CFG_GLOSS_SCALE) + float2(0, 0.01);
float2 specfade = lerp(float2(CFG_SPECULAR_LOD, CFG_GLOSS_LOD), specbase, fade);
Surface surface = (Surface)0;
surface.albedo = albedo;
surface.normal = normal;
surface.specular = specfade.r;
surface.gloss = specfade.g;
surface.reflectance = specular.g * fade * (CFG_REFLECTION_SCALE);
return surface;
}

View File

@@ -0,0 +1,158 @@
#include "common.h"
struct Appdata
{
ATTR_INT4 Position : POSITION;
ATTR_INT3 Normal : NORMAL;
ATTR_INT4 Uv : TEXCOORD0;
#ifdef PIN_HQ
ATTR_INT4 EdgeDistances : TEXCOORD1;
ATTR_INT3 Tangent : TEXCOORD2;
#endif
};
struct VertexOutput
{
float4 HPosition : POSITION;
float4 UvHigh_EdgeDistance1 : TEXCOORD0;
float4 UvLow_EdgeDistance2 : TEXCOORD1;
float4 LightPosition_Fog : TEXCOORD2;
#ifdef PIN_HQ
float4 View_Depth : TEXCOORD3;
float4 Normal_Blend : TEXCOORD4;
float3 Tangent : TEXCOORD5;
#else
float4 Diffuse_Blend : COLOR0;
#endif
float3 PosLightSpace : TEXCOORD7;
};
WORLD_MATRIX(WorldMatrix);
VertexOutput MegaClusterVS(Appdata IN)
{
VertexOutput OUT = (VertexOutput)0;
// Decode vertex data
float3 Normal = (IN.Normal - 127.0) / 127.0;
float4 UV = IN.Uv / 2048.0;
// Transform position and normal to world space
// Note: world matrix does not contain rotation/scale for static geometry so we can avoid transforming normal
float3 posWorld = mul(WorldMatrix, IN.Position).xyz;
float3 normalWorld = Normal;
OUT.HPosition = mul(G(ViewProjection), float4(posWorld, 1));
float blend = OUT.HPosition.w / 200;
OUT.LightPosition_Fog = float4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)), (G(FogParams).z - OUT.HPosition.w) * G(FogParams).w);
OUT.UvHigh_EdgeDistance1.xy = UV.xy;
OUT.UvLow_EdgeDistance2.xy = UV.zw;
#ifdef PIN_HQ
OUT.View_Depth = float4(posWorld, OUT.HPosition.w * G(FadeDistance_GlowFactor).y);
float4 edgeDistances = IN.EdgeDistances*G(FadeDistance_GlowFactor).z + 0.5 * OUT.View_Depth.w;
OUT.UvHigh_EdgeDistance1.zw = edgeDistances.xy;
OUT.UvLow_EdgeDistance2.zw = edgeDistances.zw;
OUT.View_Depth.xyz = G(CameraPosition).xyz - posWorld;
OUT.Normal_Blend = float4(Normal, blend);
// decode tangent
OUT.Tangent = (IN.Tangent - 127.0) / 127.0;
#else
// IF LQ shading is performed in VS
float ndotl = dot(normalWorld, -G(Lamp0Dir));
float3 diffuse = saturate(ndotl) * G(Lamp0Color) + max(-ndotl, 0) * G(Lamp1Color);
OUT.Diffuse_Blend = float4(diffuse, blend);
#endif
OUT.PosLightSpace = shadowPrepareSample(posWorld);
return OUT;
}
TEX_DECLARE2D(DiffuseHighMap, 0);
TEX_DECLARE2D(DiffuseLowMap, 1);
TEX_DECLARE2D(NormalMap, 2);
TEX_DECLARE2D(SpecularMap, 3);
LGRID_SAMPLER(LightMap, 4);
TEX_DECLARE2D(LightMapLookup, 5);
TEX_DECLARE2D(ShadowMap, 6);
void MegaClusterPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float4 high = tex2D(DiffuseHighMap, IN.UvHigh_EdgeDistance1.xy);
float4 low = tex2D(DiffuseLowMap, IN.UvLow_EdgeDistance2.xy);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
float shadow = shadowSample(TEXTURE(ShadowMap), IN.PosLightSpace, light.a);
#ifdef PIN_HQ
float3 albedo = lerp(high.rgb, low.rgb, saturate1(IN.Normal_Blend.a));
// sample normal map and specular map
float4 normalMapSample = tex2D(NormalMap, IN.UvHigh_EdgeDistance1.xy);
float4 specularMapSample = tex2D(SpecularMap, IN.UvHigh_EdgeDistance1.xy);
// compute bitangent and world space normal
float3 bitangent = cross(IN.Normal_Blend.xyz, IN.Tangent.xyz);
#ifdef CLASSIC
float3 nmap = float3(0,0,.5);
#else
float3 nmap = nmapUnpack(normalMapSample);
#endif
float3 normal = normalize(nmap.x * IN.Tangent.xyz + nmap.y * bitangent + nmap.z * IN.Normal_Blend.xyz);
float ndotl = dot(normal, -G(Lamp0Dir));
float3 diffuseIntensity = saturate0(ndotl) * G(Lamp0Color) + max(-ndotl, 0) * G(Lamp1Color);
float specularIntensity = step(0, ndotl) * specularMapSample.r;
float specularPower = specularMapSample.g * 255 + 0.01;
// Compute diffuse and specular and combine them
float3 diffuse = (G(AmbientColor) + diffuseIntensity * shadow + light.rgb) * albedo.rgb;
float3 specular = G(Lamp0Color) * (specularIntensity * shadow * (float)(half)pow(saturate(dot(normal, normalize(-G(Lamp0Dir) + normalize(IN.View_Depth.xyz)))), specularPower));
oColor0.rgb = diffuse + specular;
// apply outlines
float outlineFade = saturate1(IN.View_Depth.w * G(OutlineBrightness_ShadowInfo).x + G(OutlineBrightness_ShadowInfo).y);
float2 minIntermediate = min(IN.UvHigh_EdgeDistance1.wz, IN.UvLow_EdgeDistance2.wz);
float minEdgesPlus = min(minIntermediate.x, minIntermediate.y) / IN.View_Depth.w;
oColor0.rgb *= saturate1(outlineFade * (1.5 - minEdgesPlus) + minEdgesPlus);
oColor0.a = 1;
#else
float3 albedo = lerp(high.rgb, low.rgb, saturate1(IN.Diffuse_Blend.a));
// Compute diffuse term
float3 diffuse = (G(AmbientColor) + IN.Diffuse_Blend.rgb * shadow + light.rgb) * albedo.rgb;
// Combine
oColor0.rgb = diffuse;
oColor0.a = 1;
#endif
float fogAlpha = saturate(IN.LightPosition_Fog.w);
oColor0.rgb = lerp(G(FogColor), oColor0.rgb, fogAlpha);
#ifdef CLASSIC
oColor0.rgb = IN.UvHigh_EdgeDistance1.xyy;
oColor0.rgb = G(OutlineBrightness_ShadowInfo).xxx;
#endif
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w*G(FadeDistance_GlowFactor).x, diffuse.rgb, 0, fogAlpha);
#endif
}

View File

@@ -0,0 +1,25 @@
#ifdef CLASSIC
#include "smoothplastic.hlsl"
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 2
#define CFG_GLOSS_SCALE 256
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0.3
#define CFG_SPECULAR_LOD 0.8
#define CFG_GLOSS_LOD 120
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0.25
#define CFG_FAR_DIFFUSE_CUTOFF 0
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0.75
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,3 @@
#define PIN_PLASTIC
#define PIN_NEON
#include "default.hlsl"

View File

@@ -0,0 +1,240 @@
#include "common.h"
TEX_DECLARE2D(tex, 0);
TEX_DECLARE2D(cstrip, 1);
TEX_DECLARE2D(astrip, 2);
uniform float4 throttleFactor; // .x = alpha cutoff, .y = alpha boost (clamp), .w - additive/alpha ratio for Crazy shaders
uniform float4 modulateColor;
uniform float4 zOffset;
struct VS_INPUT
{
float4 pos : POSITION;
ATTR_INT4 scaleRotLife : TEXCOORD0; // transform matrix
ATTR_INT2 disp : TEXCOORD1; // .xy = corner, either (0,0), (1,0), (0,1), or (1,1)
ATTR_INT2 cline: TEXCOORD2; // .x = color line [0...32767]
};
struct VS_OUTPUT
{
float4 pos : POSITION;
float3 uvFog : TEXCOORD0;
float2 colorLookup : TEXCOORD1;
};
float4 rotScale( float4 scaleRotLife )
{
float cr = cos( scaleRotLife.z );
float sr = sin( scaleRotLife.z );
float4 r;
r.x = cr * scaleRotLife.x;
r.y = -sr * scaleRotLife.x;
r.z = sr * scaleRotLife.y;
r.w = cr * scaleRotLife.y;
return r;
}
float4 mulq( float4 a, float4 b )
{
float3 i = cross( a.xyz, b.xyz ) + a.w * b.xyz + b.w * a.xyz;
float r = a.w * b.w - dot( a.xyz, b.xyz );
return float4( i, r );
}
float4 conj( float4 a ) { return float4( -a.xyz, a.w ); }
float4 rotate( float4 v, float4 q )
{
return mulq( mulq( q, v ), conj( q ) );
}
float4 axis_angle( float3 axis, float angle )
{
return float4( sin(angle/2) * axis, cos(angle/2) );
}
VS_OUTPUT vs( VS_INPUT input )
{
VS_OUTPUT o;
float4 pos = float4( input.pos.xyz, 1 );
float2 disp = input.disp.xy * 2 - 1; // -1..1
float4 scaleRotLifeFlt = (float4)input.scaleRotLife * float4( 1.0f/256.0f, 1.0f/256.0f, 2.0 * 3.1415926f / 32767.0f, 1.0f / 32767.0f );
scaleRotLifeFlt.xy += 127.0f;
float4 rs = rotScale( scaleRotLifeFlt );
pos += G(ViewRight) * dot( disp, rs.xy );
pos += G(ViewUp) * dot( disp, rs.zw );
float4 pos2 = pos + G(ViewDir)*zOffset.x; // Z-offset position in world space
o.pos = mul( G(ViewProjection), pos );
o.uvFog.xy = input.disp.xy;
o.uvFog.y = 1 - o.uvFog.y;
o.uvFog.z = (G(FogParams).z - o.pos.w) * G(FogParams).w;
o.colorLookup.x = 1 - max( 0, min(1, scaleRotLifeFlt.w ) );
o.colorLookup.y = (float)input.cline.x * (1.0 / 32767.0f);
pos2 = mul( G(ViewProjection), pos2 ); // Z-offset position in clip space
o.pos.z = pos2.z * o.pos.w/pos2.w; // Only need z
return o;
}
float4 psAdd( VS_OUTPUT input ) : COLOR0 // #0
{
float4 texcolor = tex2D( tex, input.uvFog.xy );
float4 vcolor = tex2D( cstrip, input.colorLookup.xy );
vcolor.a = tex2D( astrip, input.colorLookup.xy ).r;
float4 result;
result.rgb = (texcolor.rgb + vcolor.rgb) * modulateColor.rgb;
result.a = texcolor.a * vcolor.a;
result.rgb *= result.a;
result.rgb = lerp( 0.0f.xxx, result.rgb, saturate( input.uvFog.zzz ) );
return result;
}
float4 psModulate( VS_OUTPUT input ) : COLOR0 // #1
{
float4 texcolor = tex2D( tex, input.uvFog.xy );
float4 vcolor = tex2D( cstrip, input.colorLookup.xy ) * modulateColor;
vcolor.a = tex2D( astrip, input.colorLookup.xy ).r * modulateColor.a;
float4 result;
result.rgb = texcolor.rgb * vcolor.rgb;
result.a = texcolor.a * vcolor.a;
result.rgb = lerp( G(FogColor).rgb, result.rgb, saturate( input.uvFog.zzz ) );
return result;
}
// - this shader is crazy
// - used instead of additive particles to help see bright particles (e.g. fire) on top of extremely bright backgrounds
// - requires ONE | INVSRCALPHA blend mode, useless otherwise
// - does not use color strip texture
// - outputs a blend between additive blend and alpha blend in fragment alpha
// - ratio multiplier is in throttleFactor.w
float4 psCrazy( VS_OUTPUT input ) : COLOR0
{
float4 texcolor = tex2D( tex, input.uvFog.xy );
float4 vcolor = float4(1,0,0,0); //tex2D( cstrip, input.colorLookup.xy ); // not actually used
vcolor.a = tex2D( astrip, input.colorLookup.xy ).r;
float blendRatio = throttleFactor.w; // yeah yeah
float4 result;
result.rgb = (texcolor.rgb ) * modulateColor.rgb * vcolor.a * texcolor.a;
result.a = blendRatio * texcolor.a * vcolor.a;
result = lerp( 0.0f.xxxx, result, saturate( input.uvFog.zzzz ) );
return result;
}
float4 psCrazySparkles( VS_OUTPUT input ) : COLOR0
{
float4 texcolor = tex2D( tex, input.uvFog.xy );
float4 vcolor = tex2D( cstrip, input.colorLookup.xy );
vcolor.a = tex2D( astrip, input.colorLookup.xy ).r;
float blendRatio = throttleFactor.w;
float4 result;
if( texcolor.a < 0.5f )
{
result.rgb = vcolor.rgb * modulateColor.rgb * (2 * texcolor.a);
}
else
{
result.rgb = lerp( vcolor.rgb * modulateColor.rgb, texcolor.rgb, 2*texcolor.a-1 );
}
//vcolor.a *= modulateColor.a;
result.rgb *= vcolor.a;
result.a = blendRatio * texcolor.a * vcolor.a;
result = lerp( 0.0f.xxxx, result, saturate( input.uvFog.zzzz ) );
return result;
}
///////////////////////////////////////////////////////////////////////////////////
struct VS_INPUT2
{
float4 pos : POSITION;
ATTR_INT4 scaleRotLife : TEXCOORD0; // transform matrix
ATTR_INT2 disp : TEXCOORD1; // .xy = corner, either (0,0), (1,0), (0,1), or (1,1)
ATTR_INT2 cline: TEXCOORD2; // .x = color line [0...32767]
ATTR_INT4 color: TEXCOORD3; // .xyzw
};
struct VS_OUTPUT2
{
float4 pos : POSITION;
float3 uvFog : TEXCOORD0;
float4 color : TEXCOORD1;
};
VS_OUTPUT2 vsCustom( VS_INPUT2 input )
{
VS_OUTPUT2 o;
float4 pos = input.pos;
float2 disp = input.disp.xy * 2 - 1; // -1..1
float4 scaleRotLifeFlt = (float4)input.scaleRotLife * float4( 1.0/256.0f, 1.0/256.0f, 2.0 * 3.1415926f / 32767.0, 1.0 / 32767.0f );
scaleRotLifeFlt.xy += 127.0f;
float4 rs = rotScale( scaleRotLifeFlt );
pos += G(ViewRight) * dot( disp, rs.xy );
pos += G(ViewUp) * dot( disp, rs.zw );
float4 pos2 = pos + G(ViewDir)*zOffset.x; // Z-offset position in world space
o.pos = mul( G(ViewProjection), pos );
o.uvFog.xy = input.disp.xy;
o.uvFog.y = 1 - o.uvFog.y;
o.uvFog.z = (G(FogParams).z - o.pos.w) * G(FogParams).w;
o.color = input.color * (1/255.0f);
pos2 = mul( G(ViewProjection), pos2 ); // Z-offset position in clip space
o.pos.z = pos2.z * o.pos.w/pos2.w; // Only need z
return o;
}
float4 psCustom( VS_OUTPUT2 input ) : COLOR0 // #1
{
float4 texcolor = tex2D( tex, input.uvFog.xy );
float4 vcolor = input.color;
float blendRatio = throttleFactor.w; // yeah yeah
float4 result;
result.rgb = texcolor.rgb * vcolor.rgb * vcolor.a * texcolor.a;
result.a = blendRatio * texcolor.a * vcolor.a;
result = lerp( 0.0f.xxxx, result, saturate( input.uvFog.zzzz ) );
return result;
}

View File

@@ -0,0 +1,25 @@
#ifdef CLASSIC
#include "slate.hlsl"
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 2.5
#define CFG_GLOSS_SCALE 128
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0
#define CFG_SPECULAR_LOD 0.15
#define CFG_GLOSS_LOD 22
#define CFG_NORMAL_DETAIL_TILING 6
#define CFG_NORMAL_DETAIL_SCALE 1.5
#define CFG_FAR_TILING 0
#define CFG_FAR_DIFFUSE_CUTOFF 0
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,161 @@
#ifdef CLASSIC
#ifdef PIN_HQ
#define PIN_SURFACE
#define ALREADY_HAS_PS
#include "default.hlsl"
#define SPEC_EXPON 81 //81
#define KS .75
#define FADE_DIST 500
#define FADE_DIST_START 0
float3 CalcBevelDir(float4 edgeDistances)
{
float3 dir = float3(0, 0, 0);
float4 bevelMultiplier = edgeDistances <= BEVEL_WIDTH;
dir += bevelMultiplier.x * float3(1, 0, 0);
dir += bevelMultiplier.y * float3(-1, 0, 0);
dir += bevelMultiplier.z * float3(0, 1, 0);
dir += bevelMultiplier.w * float3(0, -1, 0);
return dir;
}
uniform float4 WaveParams; // .x = frequency .y = phase .z = height .w = lerp
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float normalStrength = .4;
float fade = saturate(normalStrength - (IN.View_Depth.w - FADE_DIST_START) / FADE_DIST);
float3 nn = normalize(IN.Normal);
float4 edgeDistances = IN.EdgeDistances;
float4 albedo = IN.Color;
float2 uv;
float wt = 1.0;
#ifndef PIN_MESH
uv = IN.UvStuds;
float3x3 normalMatrix = {
IN.Tangent.xyz,
cross(nn, IN.Tangent.xyz),
nn
};
//tn = tex2D(NormalMap, uv) - .5;//studs normal
float3 tn = float3(0,0,.5);
tn = lerp(float3(0, 0, .5), tn, fade);
tn = CalcBevel(edgeDistances, tn, IN.View_Depth.w);
nn = mul(tn, normalMatrix);
wt = 1.0 - abs(length(tn.xy));
float4 colorTex = tex2D(DiffuseMap, uv);
//albedo = lerp(albedo, colorTex.xyz, colorTex.w);//studs normal
//albedo += (colorTex.x * 2 - 1) * .07;//studs normal
#else
uv = IN.Uv;
float4 colorTex = tex2D(DiffuseMap, uv);
albedo *= colorTex;
#endif
float3 vn = normalize(IN.View_Depth.xyz);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
float3 diffuse;
float3 specular;
#ifdef CLASSIC_GOURAUD
float3 diffusePhong;
float3 specularPhong;
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffusePhong, specularPhong);
diffuse = lerp(diffusePhong, IN.Diffuse * albedo.rgb, wt);
specular = lerp(specularPhong, IN.Specular, wt);
#else
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
#endif
#ifndef PIN_MESH
diffuse = lerp(diffuse, colorTex.xyz, colorTex.w);
#endif
float3 result = diffuse + specular;
#ifdef PIN_REFLECTION
float3 reflection = texCUBE(EnvironmentMap, reflect(-vn, nn)).rgb;
result = lerp(result, reflection, IN.Reflection);
#endif
float fogAlpha = saturate((G(FogParams).z - length(IN.View_Depth.xyz)) * G(FogParams).w);
result = lerp(G(FogColor), result, fogAlpha);
oColor0 = float4(result, albedo.a);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define PIN_PLASTIC
#include "default.hlsl"
#endif
#else
#if defined(PIN_HQ)
#define PIN_SURFACE
#include "default.hlsl"
#define CFG_TEXTURE_TILING 1
#define CFG_BUMP_INTENSITY 0.5
#define CFG_SPECULAR 0.4
#define CFG_GLOSS 9
#define CFG_NORMAL_SHADOW_SCALE 0.1
Surface surfaceShader(SurfaceInput IN, float2 fade2)
{
float fade = fade2.y;
float4 studs = tex2D(DiffuseMap, IN.UvStuds);
float3 normal = nmapUnpack(tex2D(NormalMap, IN.UvStuds));
#ifdef GLSLES
float3 noise = float3(0, 0, 1);
#else
float3 noise = nmapUnpack(tex2D(NormalDetailMap, IN.Uv * (CFG_TEXTURE_TILING)));
#endif
float noiseScale = saturate0(IN.Color.a * 2 * (CFG_BUMP_INTENSITY) - 1 * (CFG_BUMP_INTENSITY));
#ifdef PIN_REFLECTION
noiseScale *= saturate(1 - 2 * IN.Reflectance);
#endif
normal.xy += noise.xy * noiseScale;
normal.xy *= fade;
Surface surface = (Surface)0;
surface.albedo = IN.Color.rgb * (studs.r * 2);
surface.normal = normal;
surface.specular = (CFG_SPECULAR);
surface.gloss = (CFG_GLOSS);
#ifdef PIN_REFLECTION
surface.reflectance = IN.Reflectance;
#endif
return surface;
}
#else
#define PIN_PLASTIC
#include "default.hlsl"
#endif
#endif

View File

@@ -0,0 +1,46 @@
#include "common.h"
struct Appdata
{
float4 Position : POSITION;
float2 Uv : TEXCOORD0;
float4 Color : COLOR0;
};
struct VertexOutput
{
float4 HPosition : POSITION;
float2 Uv : TEXCOORD0;
float4 Color : COLOR0;
};
VertexOutput ProfilerVS(Appdata IN)
{
VertexOutput OUT = (VertexOutput)0;
OUT.HPosition = mul(G(ViewProjection), IN.Position);
OUT.HPosition.y = -OUT.HPosition.y;
OUT.Uv = IN.Uv;
OUT.Color = IN.Color;
return OUT;
}
TEX_DECLARE2D(DiffuseMap, 0);
float4 ProfilerPS(VertexOutput IN): COLOR0
{
float4 c0 = tex2D(DiffuseMap, IN.Uv);
float4 c1 = tex2D(DiffuseMap, IN.Uv + float2(0, 1.f / 9.f));
return c0.a < 0.5 ? float4(0, 0, 0, c1.a) : c0 * IN.Color;
}
float4 ImGuiPS(VertexOutput IN): COLOR0
{
float4 texColor = tex2D(DiffuseMap, IN.Uv);
float4 finalColor = texColor * IN.Color;
return finalColor;
}

View File

@@ -0,0 +1,101 @@
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#include "default.hlsl"
#define SPEC_EXPON 70
#define KS .12
#define NOISE_SCALE float3(.02083, .0693, .2083)
#define SPREAD .3
#define RUST_THRESHOLD .8
#define CONTRAST float3(.1, .1, .1)
#define STUPID 0.125 * 1 //they do this stupid thing where different colors have assigned values for this coord val!!!!!
#define FADE_DIST 250 //133.33 fix!!!!!!!!!!
#define FADE_DIST_START 0
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float fade = saturate(1 - (IN.View_Depth.w - FADE_DIST_START) / FADE_DIST);
float3 nn = normalize(IN.Normal);
float3x3 normalMatrix = {
IN.Tangent.xyz,
cross(nn, IN.Tangent.xyz),
nn
};
float2 uv = IN.Uv.xy;
float3 shiftPos = DisplaceCoord(IN.Pos);
float noiseval = tex3D(SpecularMap,shiftPos.xyz*NOISE_SCALE.x).x * 0.5;
float noiseval2 = tex3D(SpecularMap,shiftPos.zyx*NOISE_SCALE.y).x * 0.3;
float noiseval3 = tex3D(SpecularMap,shiftPos.zyx*NOISE_SCALE.z).x * 0.2;
noiseval += noiseval2+noiseval3;
float3 metalColor = IN.Color.xyz * 1.3 + CONTRAST * (noiseval - .5);
float3 rustColor = tex2D(DiffuseMap, float2(STUPID, 1 - noiseval)).xyz;
float3 tn = tex2D(NormalMap,uv).xyz - .5;
float tnSum = 0.65 + 0.35 * (tn.x + tn.y + tn.z);
float interp = (noiseval - RUST_THRESHOLD + SPREAD) / 2 / SPREAD + .5;
interp = clamp(interp, 0, 1);
tn = lerp(tn, float3(0,0,.5), interp - .4);
float3 albedo = lerp(rustColor, metalColor,interp);
float3 albedo2 = albedo * tnSum;
albedo = lerp(albedo, albedo2, interp);
tn = lerp(tn, float3(0,0,.5), interp);
tn = CalcBevel(IN.EdgeDistances, tn, IN.View_Depth.w);
nn = mul(tn, normalMatrix);
float3 vn = normalize(IN.View_Depth.xyz);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
light.a = shadowSample(TEXTURE(ShadowMap), IN.PosLightSpace.xyz, light.a);
float3 diffuse;
float3 specular;
Shade(albedo, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
oColor0 = float4(diffuse + specular, IN.Color.w);
float fogAlpha = saturate((G(FogParams).z - length(IN.View_Depth.xyz)) * G(FogParams).w);
oColor0.xyz = lerp(G(FogColor), oColor0.rgb, fogAlpha);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 1
#define CFG_GLOSS_SCALE 256
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0.5
#define CFG_SPECULAR_LOD 0.35
#define CFG_GLOSS_LOD 103
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0.5
#define CFG_FAR_DIFFUSE_CUTOFF 0.6
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#define CFG_OPT_BLEND_COLOR
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,25 @@
#ifdef CLASSIC
#include "concrete.hlsl"
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 0.4
#define CFG_GLOSS_SCALE 32
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0
#define CFG_SPECULAR_LOD 0.07
#define CFG_GLOSS_LOD 6
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0
#define CFG_FAR_DIFFUSE_CUTOFF 0
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,369 @@
#include "common.h"
TEX_DECLARE2D(Texture, 0);
TEX_DECLARE2D(Mask, 1);
// .xy = gbuffer width/height, .zw = inverse gbuffer width/height
uniform float4 TextureSize;
uniform float4 Params1;
uniform float4 Params2;
#if defined(GLSL) || defined(DX11)
float4 convertPosition(float4 p, float scale)
{
return p;
}
#else
float4 convertPosition(float4 p, float scale)
{
// half-pixel offset
return p + float4(-TextureSize.z, TextureSize.w, 0, 0) * scale;
}
#endif
#ifndef GLSL
float2 convertUv(float4 p)
{
return p.xy * float2(0.5, -0.5) + 0.5;
}
#else
float2 convertUv(float4 p)
{
return p.xy * 0.5 + 0.5;
}
#endif
// simple pass through structure
struct VertexOutput
{
float4 p : POSITION;
float2 uv : TEXCOORD0;
};
// position and tex coord + 4 additional tex coords
struct VertexOutput_4uv
{
float4 p : POSITION;
float2 uv : TEXCOORD0;
float4 uv12 : TEXCOORD1;
float4 uv34 : TEXCOORD2;
};
// position and tex coord + 8 additional tex coords
struct VertexOutput_8uv
{
float4 p : POSITION;
float2 uv : TEXCOORD0;
float4 uv12 : TEXCOORD1;
float4 uv34 : TEXCOORD2;
float4 uv56 : TEXCOORD3;
float4 uv78 : TEXCOORD4;
};
VertexOutput passThrough_vs(float4 p: POSITION)
{
VertexOutput OUT;
OUT.p = convertPosition(p, 1);
OUT.uv = convertUv(p);
return OUT;
}
float4 passThrough_ps( VertexOutput IN ) : COLOR0
{
return tex2D(Texture, IN.uv);
}
float4 imageProcess_ps( VertexOutput IN ) : COLOR0
{
float3 color = tex2D(Texture, IN.uv).rgb;
float4 tintColor = float4(Params2.xyz,1);
//float4 tintColor = float4(18.0 / 255.0, 58.0 / 255.0, 80.0 / 255.0, 1);
float contrast = Params1.y;
float brightness = Params1.x;
float grayscaleLvl = Params1.z;
color = contrast*(color - 0.5) + 0.5 + brightness;
float grayscale = (color.r + color.g + color.g) / 3.0;
return lerp(float4(color.rgb,1), float4(grayscale.xxx,1), grayscaleLvl) * tintColor;
}
float4 gauss(float samples, float2 uv)
{
float2 step = Params1.xy;
float sigma = Params1.z;
float sigmaN1 = 1 / sqrt(2 * 3.1415926 * sigma * sigma);
float sigmaN2 = 1 / (2 * sigma * sigma);
// First sample is in the center and accounts for our pixel
float4 result = tex2D(Texture, uv) * sigmaN1;
float weight = sigmaN1;
// Every loop iteration computes impact of 4 pixels
// Each sample computes impact of 2 neighbor pixels, starting with the next one to the right
// Note that we sample exactly in between pixels to leverage bilinear filtering
for (int i = 0; i < samples; ++i)
{
float ix = 2 * i + 1.5;
float iw = 2 * exp(-ix * ix * sigmaN2) * sigmaN1;
result += (tex2D(Texture, uv + step * ix) + tex2D(Texture, uv - step * ix)) * iw;
weight += 2 * iw;
}
// Since the above is an approximation of the integral with step functions, normalization compensates for the error
return (result / weight);
}
float4 fxaa_ps(VertexOutput IN) : COLOR0
{
float2 uv = IN.uv;
float2 rcpFrame = TextureSize.zw;
// Luma conversion weights
const float3 luma = float3(0.299, 0.587, 0.114);
// Sample 3x3 neighborhood
float3 rgbM = tex2D(Texture, uv).rgb;
float3 rgbN = tex2D(Texture, uv + float2(0, -rcpFrame.y)).rgb;
float3 rgbS = tex2D(Texture, uv + float2(0, rcpFrame.y)).rgb;
float3 rgbE = tex2D(Texture, uv + float2(rcpFrame.x, 0)).rgb;
float3 rgbW = tex2D(Texture, uv + float2(-rcpFrame.x, 0)).rgb;
float3 rgbNW = tex2D(Texture, uv + float2(-rcpFrame.x, -rcpFrame.y)).rgb;
float3 rgbNE = tex2D(Texture, uv + float2(rcpFrame.x, -rcpFrame.y)).rgb;
float3 rgbSW = tex2D(Texture, uv + float2(-rcpFrame.x, rcpFrame.y)).rgb;
float3 rgbSE = tex2D(Texture, uv + float2(rcpFrame.x, rcpFrame.y)).rgb;
float lumaM = dot(rgbM, luma);
float lumaN = dot(rgbN, luma);
float lumaS = dot(rgbS, luma);
float lumaE = dot(rgbE, luma);
float lumaW = dot(rgbW, luma);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
// Find local contrast including corners
float lumaMin = min(lumaM, min(min(min(lumaN, lumaS), min(lumaE, lumaW)),
min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))));
float lumaMax = max(lumaM, max(max(max(lumaN, lumaS), max(lumaE, lumaW)),
max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))));
float range = lumaMax - lumaMin;
// Very low threshold - catch almost all edges
if (range < max(0.0156, lumaMax * 0.0625))
{
return float4(rgbM, 1.0);
}
// Determine edge orientation
float edgeVert = abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) +
abs((0.50 * lumaW) + (-1.0 * lumaM) + (0.50 * lumaE)) +
abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE));
float edgeHorz = abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) +
abs((0.50 * lumaN) + (-1.0 * lumaM) + (0.50 * lumaS)) +
abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE));
bool isHorizontal = (edgeHorz >= edgeVert);
// Select samples along edge
float luma1 = isHorizontal ? lumaS : lumaE;
float luma2 = isHorizontal ? lumaN : lumaW;
float gradient1 = luma1 - lumaM;
float gradient2 = luma2 - lumaM;
// Pick steepest gradient
bool is1Steepest = abs(gradient1) >= abs(gradient2);
float gradientScaled = 0.25 * max(abs(gradient1), abs(gradient2));
float lengthSign = is1Steepest ? -1.0 : 1.0;
if (!isHorizontal)
lengthSign *= -1.0;
// Setup for edge search
float2 posB = uv;
float2 offNP;
offNP.x = (!isHorizontal) ? rcpFrame.x : 0.0;
offNP.y = (isHorizontal) ? rcpFrame.y : 0.0;
if (!isHorizontal)
posB.x += lengthSign * 0.5 * rcpFrame.x;
else
posB.y += lengthSign * 0.5 * rcpFrame.y;
// Extended edge search - 12 iterations
float2 posN = posB - offNP;
float2 posP = posB + offNP;
float lumaEndN = dot(tex2D(Texture, posN).rgb, luma) - lumaM * 0.5;
float lumaEndP = dot(tex2D(Texture, posP).rgb, luma) - lumaM * 0.5;
bool doneN = abs(lumaEndN) >= gradientScaled;
bool doneP = abs(lumaEndP) >= gradientScaled;
// More iterations with finer steps for better accuracy
float stepSizes[12] = {1.0, 1.0, 1.5, 1.5, 2.0, 2.0, 4.0, 4.0, 8.0, 8.0, 16.0, 16.0};
for (int i = 0; i < 12; ++i)
{
if (doneN && doneP) break;
if (!doneN)
{
posN -= offNP * stepSizes[i];
lumaEndN = dot(tex2D(Texture, posN).rgb, luma) - lumaM * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
}
if (!doneP)
{
posP += offNP * stepSizes[i];
lumaEndP = dot(tex2D(Texture, posP).rgb, luma) - lumaM * 0.5;
doneP = abs(lumaEndP) >= gradientScaled;
}
}
// Calculate span and offset
float dstN = isHorizontal ? (uv.x - posN.x) : (uv.y - posN.y);
float dstP = isHorizontal ? (posP.x - uv.x) : (posP.y - uv.y);
bool directionN = dstN < dstP;
float dst = min(dstN, dstP);
float spanLength = (dstP + dstN);
float spanLengthRcp = 1.0 / spanLength;
float pixelOffset = dst * (-spanLengthRcp) + 0.5;
// Check if we're at a good span
bool goodSpanN = (lumaEndN < 0.0) != (lumaM < lumaMin);
bool goodSpanP = (lumaEndP < 0.0) != (lumaM < lumaMin);
bool goodSpan = directionN ? goodSpanN : goodSpanP;
if (!goodSpan)
pixelOffset = 0.0;
// sub-pixel antialiasing
float lumaAverage = (1.0/12.0) * (2.0 * (lumaN + lumaS + lumaE + lumaW) +
lumaNW + lumaNE + lumaSW + lumaSE);
float subPixelOffset1 = saturate(abs(lumaAverage - lumaM) / range);
subPixelOffset1 = (-2.0 * subPixelOffset1 + 3.0) * subPixelOffset1 * subPixelOffset1;
subPixelOffset1 = subPixelOffset1 * subPixelOffset1 * 0.85;
// Blend edge and subpixel offsets
float pixelOffsetFinal = max(pixelOffset, subPixelOffset1);
// Apply offset
float2 finalUv = uv;
if (!isHorizontal)
finalUv.x += pixelOffsetFinal * lengthSign * rcpFrame.x;
else
finalUv.y += pixelOffsetFinal * lengthSign * rcpFrame.y;
// Additional edge blending for remaining jaggies
float3 rgbFinal = tex2D(Texture, finalUv).rgb;
// If we're on a strong edge, do additional smart blending
if (range > 0.1)
{
float edgeBlend = saturate(range * 2.0 - 0.2);
float3 rgbBlur = (rgbN + rgbS + rgbE + rgbW) * 0.25;
rgbFinal = lerp(rgbFinal, rgbBlur, edgeBlend * 0.15);
}
return float4(rgbFinal, 1.0);
}
float4 blur3_ps(VertexOutput IN): COLOR0
{
return gauss(3, IN.uv);
}
float4 blur5_ps(VertexOutput IN): COLOR0
{
return gauss(5, IN.uv);
}
float4 blur7_ps(VertexOutput IN): COLOR0
{
return gauss(7, IN.uv);
}
float4 glowApply_ps( VertexOutput IN ) : COLOR0
{
float4 color = tex2D(Texture, IN.uv);
return float4(color.rgb * Params1.x, color.a);
}
// this is specific glow downsample
float4 downSample4x4Glow_ps( VertexOutput_4uv IN ) : COLOR0
{
float4 avgColor = tex2D( Texture, IN.uv12.xy );
avgColor += tex2D( Texture, IN.uv12.zw );
avgColor += tex2D( Texture, IN.uv34.xy );
avgColor += tex2D( Texture, IN.uv34.zw );
avgColor *= 0.25;
return float4(avgColor.rgb, 1) * (1-avgColor.a);
}
VertexOutput_4uv downsample4x4_vs(float4 p: POSITION)
{
float2 uv = convertUv(p);
VertexOutput_4uv OUT;
OUT.p = convertPosition(p, 1);
OUT.uv = uv;
float2 uvOffset = TextureSize.zw * 0.25f;
OUT.uv12.xy = uv + uvOffset * float2(-1, -1);
OUT.uv12.zw = uv + uvOffset * float2(+1, -1);
OUT.uv34.xy = uv + uvOffset * float2(-1, +1);
OUT.uv34.zw = uv + uvOffset * float2(+1, +1);
return OUT;
}
float4 ShadowBlurPS(VertexOutput IN): COLOR0
{
#ifdef GLSLES
int N = 1;
float sigma = 0.5;
#else
int N = 3;
float sigma = 1.5;
#endif
float2 step = Params1.xy;
float sigmaN1 = 1 / sqrt(2 * 3.1415926 * sigma * sigma);
float sigmaN2 = 1 / (2 * sigma * sigma);
float depth = 1;
float color = 0;
float weight = 0;
for (int i = -N; i <= N; ++i)
{
float ix = i;
float iw = exp(-ix * ix * sigmaN2) * sigmaN1;
float4 data = tex2D(Texture, IN.uv + step * ix);
depth = min(depth, data.x);
color += data.y * iw;
weight += iw;
}
float mask = tex2D(Mask, IN.uv).r;
// Since the above is an approximation of the integral with step functions, normalization compensates for the error
return float4(depth, color * mask * (1 / weight), 0, 0);
}

View File

@@ -0,0 +1,50 @@
#include "common.h"
struct Appdata
{
float4 Position : POSITION;
ATTR_INT4 Extra : COLOR1;
};
struct VertexOutput
{
float4 HPosition: POSITION;
float3 PosLightSpace: TEXCOORD0;
};
#ifdef PIN_SKINNED
WORLD_MATRIX_ARRAY(WorldMatrixArray, MAX_BONE_COUNT * 3);
#endif
VertexOutput ShadowVS(Appdata IN)
{
VertexOutput OUT = (VertexOutput)0;
// Transform position to world space
#ifdef PIN_SKINNED
int boneIndex = IN.Extra.r;
float4 worldRow0 = WorldMatrixArray[boneIndex * 3 + 0];
float4 worldRow1 = WorldMatrixArray[boneIndex * 3 + 1];
float4 worldRow2 = WorldMatrixArray[boneIndex * 3 + 2];
float3 posWorld = float3(dot(worldRow0, IN.Position), dot(worldRow1, IN.Position), dot(worldRow2, IN.Position));
#else
float3 posWorld = IN.Position.xyz;
#endif
OUT.HPosition = mul(G(ViewProjection), float4(posWorld, 1));
OUT.PosLightSpace = shadowPrepareSample(posWorld);
return OUT;
}
float4 ShadowPS(VertexOutput IN): COLOR0
{
float depth = shadowDepth(IN.PosLightSpace);
return float4(depth, 1, 0, 0);
}

View File

@@ -0,0 +1,53 @@
#include "common.h"
struct Appdata
{
float4 Position : POSITION;
float2 Uv : TEXCOORD0;
float4 Color : COLOR0;
};
struct VertexOutput
{
float4 HPosition : POSITION;
float PSize : PSIZE;
float2 Uv : TEXCOORD0;
float4 Color : COLOR0;
};
WORLD_MATRIX(WorldMatrix);
uniform float4 Color;
uniform float4 Color2;
VertexOutput SkyVS(Appdata IN)
{
VertexOutput OUT = (VertexOutput)0;
float4 wpos = mul(WorldMatrix, IN.Position);
OUT.HPosition = mul(G(ViewProjection), wpos);
#ifndef GLSLES
// snap to far plane to prevent scene-sky intersections
// small offset is needed to prevent 0/0 division in case w=0, which causes rasterization issues
// some mobile chips (hello, Vivante!) don't like it
OUT.HPosition.z = OUT.HPosition.w - 1.f / 16;
#endif
OUT.PSize = 2.0; // star size
OUT.Uv = IN.Uv;
OUT.Color = IN.Color * lerp(Color2,Color,wpos.y/1700);
//OUT.Color = IN.Color * Color;
return OUT;
}
TEX_DECLARE2D(DiffuseMap, 0);
float4 SkyPS(VertexOutput IN): COLOR0
{
return tex2D(DiffuseMap, IN.Uv) * IN.Color;
}

View File

@@ -0,0 +1,90 @@
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#include "default.hlsl"
#define SPEC_EXPON 40
#define KS .1
#define NOISE_SCALE 7
#define SPREAD .3
#define GRASS_THRESHOLD .95
#define FADE_DIST 290
#define FADE_DIST_START 0
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float3 normal = normalize(IN.Normal);
float3x3 normalMatrix = {
IN.Tangent.xyz,
cross(normal, IN.Tangent.xyz),
normal,
};
float fade = saturate(1 - (IN.View_Depth.w - FADE_DIST_START) / FADE_DIST);
float2 uv = IN.Uv.xy;
float3 shiftPos = IN.Pos.xyz;
float noiseval = tex3D(SpecularMap,shiftPos.xyz / NOISE_SCALE * .04).x;
float noiseval2 = tex3D(SpecularMap,shiftPos.xyz / NOISE_SCALE * .3).x + .2;
noiseval *= noiseval2;
float3 albedo = IN.Color.xyz + 0.8 * fade * (noiseval * 0.5 - 0.1);
float3 tn = tex2D(NormalMap,uv).xyz - .5;
float tNormSum = 0.9+0.4*(tn.x + tn.y + tn.z);
tn = lerp(tn, float3(0,0,.5), .9);
albedo *= ((1-fade) + (fade*tNormSum));
tn = CalcBevel(IN.EdgeDistances, tn, IN.View_Depth.w);
float3 nn = mul(tn, normalMatrix);
//nn *= fade;
//KS *= fade; //ks is a constant and idk if this dumb shit is worth keeping anyways
float3 vn = normalize(IN.View_Depth.xyz);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
light.a = shadowSample(TEXTURE(ShadowMap), IN.PosLightSpace.xyz, light.a);
float3 diffuse;
float3 specular;
Shade(albedo, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
oColor0 = float4(diffuse + specular, IN.Color.w);
float fogAlpha = saturate((G(FogParams).z - length(IN.View_Depth.xyz)) * G(FogParams).w);
oColor0.xyz = lerp(G(FogColor), oColor0.rgb, fogAlpha);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 0.9
#define CFG_GLOSS_SCALE 128
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0.5
#define CFG_SPECULAR_LOD 0.14
#define CFG_GLOSS_LOD 20
#define CFG_NORMAL_DETAIL_TILING 5
#define CFG_NORMAL_DETAIL_SCALE 1
#define CFG_FAR_TILING 0.25
#define CFG_FAR_DIFFUSE_CUTOFF 0.75
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,174 @@
#include "common.h"
struct Appdata
{
ATTR_INT4 Position : POSITION;
ATTR_INT4 Normal : NORMAL;
ATTR_INT4 Material0 : TEXCOORD0;
ATTR_INT4 Material1 : TEXCOORD1;
};
struct VertexOutput
{
float4 HPosition : POSITION;
float3 Weights: COLOR0;
float4 Uv0: TEXCOORD0;
float4 Uv1: TEXCOORD1;
float4 Uv2: TEXCOORD2;
float4 LightPosition_Fog : TEXCOORD3;
float3 PosLightSpace : TEXCOORD4;
#ifdef PIN_HQ
float3 Normal: TEXCOORD5;
float4 View_Depth: TEXCOORD6;
float3 Tangents: COLOR1;
#else
float3 Diffuse: COLOR1;
#endif
};
WORLD_MATRIX_ARRAY(WorldMatrixArray, 72);
uniform float4 LayerScale;
float4 getUV(float3 position, ATTR_INT material, ATTR_INT projection, float seed)
{
float3 u = WorldMatrixArray[1 + int(projection)].xyz;
float3 v = WorldMatrixArray[19 + int(projection)].xyz;
float4 m = WorldMatrixArray[37 + int(material)];
float2 uv = float2(dot(position, u), dot(position, v)) * m.x + m.y * float2(seed, floor(seed * 2.6651441f));
return float4(uv, m.zw);
}
VertexOutput TerrainVS(Appdata IN)
{
VertexOutput OUT = (VertexOutput)0;
float3 posWorld = IN.Position.xyz * WorldMatrixArray[0].w + WorldMatrixArray[0].xyz;
float3 normalWorld = IN.Normal.xyz * (1.0 / 127.0) - 1.0;
OUT.HPosition = mul(G(ViewProjection), float4(posWorld, 1));
OUT.LightPosition_Fog = float4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)), (G(FogParams).z - OUT.HPosition.w) * G(FogParams).w);
OUT.PosLightSpace = shadowPrepareSample(posWorld);
OUT.Uv0 = getUV(posWorld, IN.Material0.x, IN.Material1.x, IN.Normal.w);
OUT.Uv1 = getUV(posWorld, IN.Material0.y, IN.Material1.y, IN.Material0.w);
OUT.Uv2 = getUV(posWorld, IN.Material0.z, IN.Material1.z, IN.Material1.w);
#if defined(GLSLES) && !defined(GL3) // iPad2 workaround
OUT.Weights = abs(IN.Position.www - float3(0, 1, 2)) < 0.1;
#else
OUT.Weights = IN.Position.www == float3(0, 1, 2);
#endif
#ifdef PIN_HQ
OUT.Normal = normalWorld;
OUT.View_Depth = float4(G(CameraPosition) - posWorld, OUT.HPosition.w);
OUT.Tangents = float3(IN.Material1.xyz) > 7.5; // side vs top
#else
float ndotl = dot(normalWorld, -G(Lamp0Dir));
float3 diffuse = max(ndotl, 0) * G(Lamp0Color) + max(-ndotl, 0) * G(Lamp1Color);
OUT.Diffuse = diffuse;
#endif
return OUT;
}
TEX_DECLARE2D(AlbedoMap, 0);
TEX_DECLARE2D(NormalMap, 1);
TEX_DECLARE2D(SpecularMap, 2);
TEX_DECLARECUBE(EnvMap, 3);
LGRID_SAMPLER(LightMap, 4);
TEX_DECLARE2D(LightMapLookup, 5);
TEX_DECLARE2D(ShadowMap, 6);
float4 sampleMap(TEXTURE_IN_2D(s), float4 uv)
{
#ifdef PIN_HQ
float2 uvs = uv.xy * LayerScale.xy;
return tex2Dgrad(s, frac(uv.xy) * LayerScale.xy + uv.zw, ddx(uvs), ddy(uvs));
#else
return tex2D(s, frac(uv.xy) * LayerScale.xy + uv.zw);
#endif
}
float4 sampleBlend(TEXTURE_IN_2D(s), float4 uv0, float4 uv1, float4 uv2, float3 w)
{
return
sampleMap(TEXTURE(s), uv0) * w.x +
sampleMap(TEXTURE(s), uv1) * w.y +
sampleMap(TEXTURE(s), uv2) * w.z;
}
float3 sampleNormal(TEXTURE_IN_2D(s), float4 uv0, float4 uv1, float4 uv2, float3 w, float3 normal, float3 tsel)
{
return terrainNormal(sampleMap(TEXTURE(s), uv0), sampleMap(TEXTURE(s), uv1), sampleMap(TEXTURE(s), uv2), w, normal, tsel);
}
void TerrainPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
float shadow = shadowSample(TEXTURE(ShadowMap), IN.PosLightSpace, light.a);
float3 w = IN.Weights.xyz;
float4 albedo = sampleBlend(TEXTURE(AlbedoMap), IN.Uv0, IN.Uv1, IN.Uv2, w);
#ifdef PIN_HQ
float fade = saturate0(1 - IN.View_Depth.w * G(FadeDistance_GlowFactor).y);
#ifndef PIN_GBUFFER
float3 normal = IN.Normal;
#else
float3 normal = sampleNormal(TEXTURE(NormalMap), IN.Uv0, IN.Uv1, IN.Uv2, w, IN.Normal, IN.Tangents);
#endif
float4 params = sampleBlend(TEXTURE(SpecularMap), IN.Uv0, IN.Uv1, IN.Uv2, w);
float ndotl = dot(normal, -G(Lamp0Dir));
// Compute diffuse term
float3 diffuse = (G(AmbientColor) + (saturate(ndotl) * G(Lamp0Color) + max(-ndotl, 0) * G(Lamp1Color)) * shadow + light.rgb + params.b * 2) * albedo.rgb;
// Compute specular term
float specularIntensity = step(0, ndotl) * params.r * fade;
float specularPower = params.g * 128 + 0.01;
float3 specular = G(Lamp0Color) * (specularIntensity * shadow * (float)(half)pow(saturate(dot(normal, normalize(-G(Lamp0Dir) + normalize(IN.View_Depth.xyz)))), specularPower));
#else
// Compute diffuse term
float3 diffuse = (G(AmbientColor) + IN.Diffuse * shadow + light.rgb) * albedo.rgb;
// Compute specular term
float3 specular = 0;
#endif
// Combine
oColor0.rgb = diffuse + specular;
oColor0.a = 1;
float fogAlpha = saturate(IN.LightPosition_Fog.w);
oColor0.rgb = lerp(G(FogColor), oColor0.rgb, fogAlpha);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}

View File

@@ -0,0 +1,76 @@
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#include "default.hlsl"
#define SPEC_EXPON 81 //81
#define KS .75
#define FADE_DIST 500
#define FADE_DIST_START 0
float3 CalcBevelDir(float4 edgeDistances)
{
float3 dir = float3(0, 0, 0);
float4 bevelMultiplier = edgeDistances <= BEVEL_WIDTH;
dir += bevelMultiplier.x * float3(1, 0, 0);
dir += bevelMultiplier.y * float3(-1, 0, 0);
dir += bevelMultiplier.z * float3(0, 1, 0);
dir += bevelMultiplier.w * float3(0, -1, 0);
return dir;
}
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float normalStrength = .4;
float fade = saturate(normalStrength - (IN.View_Depth.w - FADE_DIST_START) / FADE_DIST);
float3 nn = normalize(IN.Normal);
float4 edgeDistances = IN.EdgeDistances;
float4 albedo = IN.Color;
// lets generate this matrix in the vertex shader and pass it in later
float3x3 normalMatrix = {
IN.Tangent.xyz,
cross(nn, IN.Tangent.xyz),
nn
};
float2 uv = IN.Uv;
float3 tn = float3(0,0,.5);
tn = lerp(float3(0, 0, .5), tn, fade);
tn = CalcBevel(edgeDistances, tn, IN.View_Depth.w);
nn = mul(tn, normalMatrix);
float3 vn = normalize(IN.View_Depth.xyz);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
float3 diffuse;
float3 specular;
Shade(albedo.rgb, nn, vn, KS, SPEC_EXPON, light, diffuse, specular);
float3 result = diffuse + specular;
#ifdef PIN_REFLECTION
float3 reflection = texCUBE(EnvironmentMap, reflect(-vn, nn)).rgb;
result = lerp(result, reflection, IN.Reflection);
#endif
float fogAlpha = saturate((G(FogParams).z - length(IN.View_Depth.xyz)) * G(FogParams).w);
result = lerp(G(FogColor), result, fogAlpha);
oColor0 = float4(result, albedo.a);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define PIN_PLASTIC
#include "default.hlsl"
#endif

View File

@@ -0,0 +1,310 @@
#include "common.h"
// Tunables
#define CFG_TEXTURE_TILING 0.2
#define CFG_TEXTURE_DETILING 0.1
#define CFG_SPECULAR 2
#define CFG_GLOSS 900
#define CFG_NORMAL_STRENGTH 0.25
#define CFG_REFRACTION_STRENGTH 0.05
#define CFG_FRESNEL_OFFSET 0.3
#define CFG_SSR_STEPS 8
#define CFG_SSR_START_DISTANCE 1
#define CFG_SSR_STEP_CLAMP 0.2
#define CFG_SSR_DEPTH_CUTOFF 10
// Shader code
struct Appdata
{
ATTR_INT4 Position : POSITION;
ATTR_INT4 Normal : NORMAL;
ATTR_INT4 Material0 : TEXCOORD0;
ATTR_INT4 Material1 : TEXCOORD1;
};
struct VertexOutput
{
float4 HPosition : POSITION;
float4 Weights_Wave: COLOR0;
float3 Tangents: COLOR1;
float2 Uv0: TEXCOORD0;
float2 Uv1: TEXCOORD1;
float2 Uv2: TEXCOORD2;
float4 LightPosition_Fog : TEXCOORD3;
float3 Normal: TEXCOORD4;
float4 View_Depth: TEXCOORD5;
#ifdef PIN_HQ
float4 PositionScreen: TEXCOORD6;
#endif
};
WORLD_MATRIX_ARRAY(WorldMatrixArray, 72);
uniform float4 WaveParams; // .x = frequency .y = phase .z = height .w = lerp
uniform float4 WaterColor; // deep water color
uniform float4 WaterParams; // .x = refraction depth scale, .y = refraction depth offset
float3 displacePosition(float3 position, float waveFactor)
{
float x = sin((position.z - position.x) * WaveParams.x - WaveParams.y);
float z = sin((position.z + position.x) * WaveParams.x + WaveParams.y);
float p = (x + z) * WaveParams.z;
float3 result = position;
result.y += p * waveFactor;
return result;
}
float4 clipToScreen(float4 pos)
{
#ifdef GLSL
pos.xy = pos.xy * 0.5 + 0.5 * pos.w;
#else
pos.xy = pos.xy * float2(0.5, -0.5) + 0.5 * pos.w;
#endif
return pos;
}
float2 getUV(float3 position, ATTR_INT projection, float seed)
{
float3 u = WorldMatrixArray[1 + int(projection)].xyz;
float3 v = WorldMatrixArray[19 + int(projection)].xyz;
float2 uv = float2(dot(position, u), dot(position, v)) * (0.25 * CFG_TEXTURE_TILING) + CFG_TEXTURE_DETILING * float2(seed, floor(seed * 2.6651441f));
return uv;
}
VertexOutput WaterVS(Appdata IN)
{
VertexOutput OUT = (VertexOutput)0;
float3 posWorld = IN.Position.xyz * WorldMatrixArray[0].w + WorldMatrixArray[0].xyz;
float3 normalWorld = IN.Normal.xyz * (1.0 / 127.0) - 1.0;
#if defined(GLSLES) && !defined(GL3) // iPad2 workaround
float3 weights = abs(IN.Position.www - float3(0, 1, 2)) < 0.1;
#else
float3 weights = IN.Position.www == float3(0, 1, 2);
#endif
float waveFactor = dot(weights, IN.Material0.xyz) * (1.0 / 255.0);
#ifdef PIN_HQ
float fade = saturate0(1 - dot(posWorld - G(CameraPosition), -G(ViewDir).xyz) * G(FadeDistance_GlowFactor).y);
posWorld = displacePosition(posWorld, waveFactor * fade);
#endif
OUT.HPosition = mul(G(ViewProjection), float4(posWorld, 1));
OUT.LightPosition_Fog = float4(lgridPrepareSample(lgridOffset(posWorld, normalWorld)), (G(FogParams).z - OUT.HPosition.w) * G(FogParams).w);
OUT.Uv0 = getUV(posWorld, IN.Material1.x, IN.Normal.w);
OUT.Uv1 = getUV(posWorld, IN.Material1.y, IN.Material0.w);
OUT.Uv2 = getUV(posWorld, IN.Material1.z, IN.Material1.w);
OUT.Weights_Wave.xyz = weights;
OUT.Weights_Wave.w = waveFactor;
OUT.Normal = normalWorld;
OUT.View_Depth = float4(G(CameraPosition) - posWorld, OUT.HPosition.w);
OUT.Tangents = float3(IN.Material1.xyz) > 7.5; // side vs top
#ifdef PIN_HQ
OUT.PositionScreen = clipToScreen(OUT.HPosition);
#endif
return OUT;
}
TEX_DECLARE2D(NormalMap1, 0);
TEX_DECLARE2D(NormalMap2, 1);
TEX_DECLARECUBE(EnvMap, 2);
LGRID_SAMPLER(LightMap, 3);
TEX_DECLARE2D(LightMapLookup, 4);
TEX_DECLARE2D(GBufferColor, 5);
TEX_DECLARE2D(GBufferDepth, 6);
float fresnel(float ndotv)
{
return saturate(0.78 - 2.5 * abs(ndotv)) + CFG_FRESNEL_OFFSET;
}
float4 sampleMix(float2 uv)
{
#ifdef PIN_HQ
return lerp(tex2D(NormalMap1, uv), tex2D(NormalMap2, uv), WaveParams.w);
#else
return tex2D(NormalMap1, uv);
#endif
}
float3 sampleNormal(float2 uv0, float2 uv1, float2 uv2, float3 w, float3 normal, float3 tsel)
{
return terrainNormal(sampleMix(uv0), sampleMix(uv1), sampleMix(uv2), w, normal, tsel);
}
float3 sampleNormalSimple(float2 uv0, float2 uv1, float2 uv2, float3 w)
{
float4 data = sampleMix(uv0) * w.x + sampleMix(uv1) * w.y + sampleMix(uv2) * w.z;
return nmapUnpack(data).xzy;
}
float unpackDepth(float2 uv)
{
float4 geomTex = tex2D(GBufferDepth, uv);
float d = geomTex.z * (1.0f/256.0f) + geomTex.w;
return d * GBUFFER_MAX_DEPTH;
}
float3 getRefractedColor(float4 cpos, float3 N, float3 waterColor)
{
float2 refruv0 = cpos.xy / cpos.w;
float2 refruv1 = refruv0 + N.xz * CFG_REFRACTION_STRENGTH;
float4 refr0 = tex2D(GBufferColor, refruv0);
refr0.w = unpackDepth(refruv0);
float4 refr1 = tex2D(GBufferColor, refruv1);
refr1.w = unpackDepth(refruv1);
float4 result = lerp(refr0, refr1, saturate(refr1.w - cpos.w));
// Estimate water absorption by a scaled depth difference
float depthfade = saturate((result.w - cpos.w) * WaterParams.x + WaterParams.y);
// Since GBuffer depth is clamped we tone the refraction down after half of the range for a smooth fadeout
float gbuffade = saturate(cpos.w * (2.f / GBUFFER_MAX_DEPTH) - 1);
float fade = saturate(depthfade + gbuffade);
return lerp(result.rgb, waterColor, fade);
}
float3 getReflectedColor(float4 cpos, float3 wpos, float3 R)
{
float3 result = 0;
float inside = 0;
float distance = CFG_SSR_START_DISTANCE;
float diff = 0;
float diffclamp = cpos.w * CFG_SSR_STEP_CLAMP;
float4 Pproj = cpos;
float4 Rproj = clipToScreen(mul(G(ViewProjection), float4(R, 0)));
#ifndef GLSL
[unroll]
#endif
for (int i = 0; i < CFG_SSR_STEPS; ++i)
{
distance += clamp(diff, -diffclamp, diffclamp);
float4 cposi = Pproj + Rproj * distance;
float2 uv = cposi.xy / cposi.w;
float depth = unpackDepth(uv);
diff = depth - cposi.w;
}
float4 cposi = Pproj + Rproj * distance;
float2 uv = cposi.xy / cposi.w;
// Ray hit has to be inside the screen bounds
float ufade = abs(uv.x - 0.5) < 0.5;
float vfade = abs(uv.y - 0.5) < 0.5;
// Fade reflections out with distance; use max(ray hit, original depth) to discard hits that are too far
// 4 - depth * 4 would give us fade out from 0.75 to 1; 3.9 makes sure reflections go to 0 slightly before GBUFFER_MAX_DEPTH
float wfade = saturate((4 - 0.1) - max(cpos.w, cposi.w) * (4.f / GBUFFER_MAX_DEPTH));
// Ray hit has to be reasonably close to where we started
float dfade = abs(diff) < CFG_SSR_DEPTH_CUTOFF;
// Avoid back-projection
float Vfade = Rproj.w > 0;
float fade = ufade * vfade * wfade * dfade * Vfade;
return lerp(texCUBE(EnvMap, R).rgb, tex2D(GBufferColor, uv).rgb, fade);
}
float4 WaterPS(VertexOutput IN): COLOR0
{
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
float shadow = light.a;
float3 w = IN.Weights_Wave.xyz;
// Use simplified normal reconstruction for LQ mobile (assumes flat water surface)
#if defined(GLSLES) && !defined(PIN_HQ)
float3 normal = sampleNormalSimple(IN.Uv0, IN.Uv1, IN.Uv2, w);
#else
float3 normal = sampleNormal(IN.Uv0, IN.Uv1, IN.Uv2, w, IN.Normal, IN.Tangents);
#endif
// Flatten the normal for Fresnel and for reflections to make them less chaotic
float3 flatNormal = lerp(IN.Normal, normal, CFG_NORMAL_STRENGTH);
float3 waterColor = WaterColor.rgb;
#ifdef PIN_HQ
float fade = saturate0(1 - IN.View_Depth.w * G(FadeDistance_GlowFactor).y);
float3 view = normalize(IN.View_Depth.xyz);
float fre = fresnel(dot(flatNormal, view)) * IN.Weights_Wave.w;
float3 position = G(CameraPosition) - IN.View_Depth.xyz;
#ifdef PIN_GBUFFER
float3 refr = getRefractedColor(IN.PositionScreen, normal, waterColor);
float3 refl = getReflectedColor(IN.PositionScreen, position, reflect(-view, flatNormal));
#else
float3 refr = waterColor;
float3 refl = texCUBE(EnvMap, reflect(-view, flatNormal)).rgb;
#endif
float specularIntensity = CFG_SPECULAR * fade;
float specularPower = CFG_GLOSS;
float3 specular = G(Lamp0Color) * (specularIntensity * shadow * (float)(half)pow(saturate(dot(normal, normalize(-G(Lamp0Dir) + view))), specularPower));
#else
float3 view = normalize(IN.View_Depth.xyz);
float fre = fresnel(dot(flatNormal, view));
float3 refr = waterColor;
float3 refl = texCUBE(EnvMap, reflect(-IN.View_Depth.xyz, flatNormal)).rgb;
float3 specular = 0;
#endif
// Combine
float4 result;
result.rgb = lerp(refr, refl, fre) * (G(AmbientColor).rgb + G(Lamp0Color).rgb * shadow + light.rgb) + specular;
result.a = 1;
float fogAlpha = saturate(IN.LightPosition_Fog.w);
result.rgb = lerp(G(FogColor), result.rgb, fogAlpha);
return result;
}

View File

@@ -0,0 +1,200 @@
#include "screenspace.hlsl"
// ao sampling
#define SSAO_NUM_PAIRS 8
#define SSAO_RADIUS 2
#define SSAO_MIN_PIXELS 10
#define SSAO_MAX_PIXELS 100
#define SSAO_MIP_OFFSET 2
// ao tuning
#define SSAO_OVERSHADOW 0.75
#define SSAO_ANGLELIMIT 0.1
#define SSAO_BOOST 1
// blur tuning
#define SSAO_BLUR_SAMPLES 3
#define SSAO_BLUR_STRENGTH 1.5
#define SSAO_BLUR_DEPTH_THRESHOLD 0.4
// composite tuning
#define SSAO_DEPTH_THRESHOLD_CENTER 0.02
#define SSAO_DEPTH_THRESHOLD_ESTIMATE 0.4
TEX_DECLARE2D(depthBuffer, 0);
TEX_DECLARE2D(randMap, 1);
TEX_DECLARE2D(map, 2);
TEX_DECLARE2D(geomMap, 3);
uniform float4 Params;
float4 SSAODepthDownPS(float4 pos: POSITION, float2 uv: TEXCOORD0) : COLOR0
{
float d0 = tex2D(geomMap, uv + TextureSize.zw * float2(-0.25, -0.25)).r;
float d1 = tex2D(geomMap, uv + TextureSize.zw * float2(+0.25, -0.25)).r;
float d2 = tex2D(geomMap, uv + TextureSize.zw * float2(-0.25, +0.25)).r;
float d3 = tex2D(geomMap, uv + TextureSize.zw * float2(+0.25, +0.25)).r;
return min(min(d0, d3), min(d1, d2));
}
float getSampleLength(float i)
{
return (i+1) / (SSAO_NUM_PAIRS+2);
}
float2 getSampleRotation(float i)
{
float pi = 3.1415926;
return float2(cos(i / SSAO_NUM_PAIRS * 2 * pi), sin (i / SSAO_NUM_PAIRS * 2 * pi));
}
float4 SSAOPS(float4 pos: POSITION, float2 uv: TEXCOORD0): COLOR0
{
float baseDepth = tex2Dlod(depthBuffer, float4(uv, 0, 0)).r;
float4 noiseTex = tex2D(randMap, frac(uv*TextureSize.xy /4))*2-1;
float2x2 rotation =
{
{ noiseTex.y, noiseTex.x },
{ -noiseTex.x, noiseTex.y }
};
const float sphereRadiusZB = SSAO_RADIUS / GBUFFER_MAX_DEPTH;
float2 radiusTex = clamp(sphereRadiusZB / baseDepth * Params.xy, SSAO_MIN_PIXELS * TextureSize.zw, SSAO_MAX_PIXELS * TextureSize.zw);
float lod = log2(getSampleLength(0) * length(radiusTex * TextureSize.xy)) - SSAO_MIP_OFFSET;
float result = 1; // center pixel
float weight = 2;
for (int i = 0; i < SSAO_NUM_PAIRS; i++)
{
const float offsetLength = getSampleLength(i);
const float2 offsetVector = getSampleRotation(i) * offsetLength;
const float segmentDiff = sphereRadiusZB * sqrt(1 - offsetLength*offsetLength);
const float angleLimit = offsetLength * SSAO_ANGLELIMIT;
float2 offset = mul(rotation, offsetVector) * radiusTex;
float2 offsetDepth;
offsetDepth.x = tex2Dlod(depthBuffer, float4(uv + offset, 0, lod)).r;
offsetDepth.y = tex2Dlod(depthBuffer, float4(uv - offset, 0, lod)).r;
float2 diff = offsetDepth - baseDepth.xx;
// 0 is the near surface of the sphere, 1 is the far surface, 0.5 is the middle
float2 normalizedDiff = diff * (1 / segmentDiff * 0.5) + 0.5;
// only add sample contribution if both samples are visible - if one is invisible we estimate the twin as 1-s so sum is 1
float sampleadd = saturate(min(normalizedDiff.x, normalizedDiff.y) + SSAO_OVERSHADOW);
result += (saturate(normalizedDiff.x + angleLimit) + saturate(normalizedDiff.y + angleLimit)) * sampleadd;
weight += 2 * sampleadd;
}
// rescale result from 0..0.5 to 0..1 and apply a power function
float finalocc = (baseDepth > 0.99) ? 1 : pow(saturate(result / weight * 2), SSAO_BOOST);
return float4(finalocc, baseDepth, 0, 1);
}
float2 ssaoBlur(float2 uv, float2 offset, TEXTURE_IN_2D(map))
{
float sigmaN = 1 / (2 * SSAO_BLUR_STRENGTH * SSAO_BLUR_STRENGTH);
float baseDepth = tex2D(map, uv).g;
const float sphereRadiusZB = SSAO_BLUR_DEPTH_THRESHOLD / GBUFFER_MAX_DEPTH;
float depthTolerance = clamp((baseDepth * 80) * sphereRadiusZB, 0.1 * sphereRadiusZB, 10 * sphereRadiusZB);
float result = 0;
float weight = 0;
for (int i = -SSAO_BLUR_SAMPLES; i <= SSAO_BLUR_SAMPLES; ++i)
{
const float ix = i;
const float iw = exp(-ix * ix * sigmaN);
float4 data = tex2D(map, uv + offset * ix);
float w = iw * (abs(data.g - baseDepth) < depthTolerance);
result += data.r * w;
weight += w;
}
return float2(result / weight, baseDepth);
}
float4 SSAOBlurXPS(float4 pos: POSITION, float2 uv : TEXCOORD0): COLOR0
{
float2 o = float2(TextureSize.z, 0);
float2 ssaoTerm = ssaoBlur(uv, o, TEXTURE(map));
return float4(ssaoTerm, 0, 1);
}
float4 SSAOBlurYPS(float4 pos: POSITION, float2 uv : TEXCOORD0): COLOR0
{
float2 o = float2(0, TextureSize.w);
float2 ssaoTerm = ssaoBlur(uv, o, TEXTURE(map));
return float4(ssaoTerm, 0, 1);
}
VertexOutput_4uv SSAOCompositVS(float4 p: POSITION)
{
float2 uv = convertUv(p);
VertexOutput_4uv OUT;
OUT.p = convertPosition(p, 1);
OUT.uv = uv;
float2 uvOffset = TextureSize.zw * 2;
OUT.uv12.xy = uv + float2(uvOffset.x, 0);
OUT.uv12.zw = uv - float2(uvOffset.x, 0);
OUT.uv34.xy = uv + float2(0, uvOffset.y);
OUT.uv34.zw = uv - float2(0, uvOffset.y);
return OUT;
}
float4 SSAOCompositPS(VertexOutput_4uv IN): COLOR0
{
float4 geom = tex2D(geomMap, IN.uv);
float4 mapC = tex2D(map, IN.uv);
float4 map0 = tex2D(map, IN.uv12.xy);
float4 map1 = tex2D(map, IN.uv12.zw);
float4 map2 = tex2D(map, IN.uv34.xy);
float4 map3 = tex2D(map, IN.uv34.zw);
float baseDepth = geom.r;
float ssaoC = mapC.r;
float depthC = mapC.g;
float4 ssaoEst = float4(map0.r, map1.r, map2.r, map3.r);
float4 depthEst = float4(map0.g, map1.g, map2.g, map3.g);
// can we trust the neighbors? 1 - yes, 0 - no
float4 checkEst = abs(depthEst - baseDepth) < SSAO_DEPTH_THRESHOLD_ESTIMATE / GBUFFER_MAX_DEPTH;
float checkEstSum = dot(checkEst, 1);
float ssaoTermEst = dot(ssaoEst, checkEst) / checkEstSum;
// the final decision: pick the estimate sample if there are good neighbors and base depth is not trustworthy
float ssaoTerm = abs(depthC - baseDepth) * checkEstSum > SSAO_DEPTH_THRESHOLD_CENTER / GBUFFER_MAX_DEPTH ? ssaoTermEst : ssaoC;
// AO reduction for high specular and diffuse values. Computed in gbufferPack in common.h
float slope = geom.g;
return float4((1 - slope) * ssaoTerm.xxx + slope, 1);
}

View File

@@ -0,0 +1,39 @@
#include "common.h"
struct Appdata
{
float4 Position : POSITION;
float2 Uv : TEXCOORD0;
};
struct VertexOutput
{
float4 HPosition : POSITION;
float2 Uv : TEXCOORD0;
};
VertexOutput TexCompVS(Appdata IN)
{
VertexOutput OUT = (VertexOutput)0;
OUT.HPosition = mul(G(ViewProjection), IN.Position);
OUT.Uv = IN.Uv;
return OUT;
}
TEX_DECLARE2D(DiffuseMap, 0);
uniform float4 Color;
float4 TexCompPS(VertexOutput IN): COLOR0
{
return tex2Dbias(DiffuseMap, float4(IN.Uv, 0, -10)) * Color;
}
float4 TexCompPMAPS(VertexOutput IN): COLOR0
{
float4 tex = tex2Dbias(DiffuseMap, float4(IN.Uv, 0, -10));
return float4(tex.rgb * tex.a * Color.rgb, tex.a * Color.a);
}

View File

@@ -0,0 +1,58 @@
#include "common.h"
struct Appdata
{
float4 Position : POSITION;
float2 Uv : TEXCOORD0;
float4 Color : COLOR0;
};
struct VertexOutput
{
float4 HPosition : POSITION;
float2 Uv : TEXCOORD0;
float4 Color : COLOR0;
#if defined(PIN_FOG)
float FogFactor : TEXCOORD1;
#endif
};
uniform float4 UIParams; // x = luminance sampling on/off, w = z offset
TEX_DECLARE2D(DiffuseMap, 0);
VertexOutput UIVS(Appdata IN)
{
VertexOutput OUT = (VertexOutput)0;
OUT.HPosition = mul(G(ViewProjection), IN.Position);
OUT.HPosition.z -= UIParams.w; // against z-fighting
OUT.Uv = IN.Uv;
OUT.Color = IN.Color;
#if defined(PIN_FOG)
OUT.FogFactor = (G(FogParams).z - OUT.HPosition.w) * G(FogParams).w;
#endif
return OUT;
}
float4 UIPS(VertexOutput IN): COLOR0
{
float4 base;
if (UIParams.x > 0.5)
base = float4(1, 1, 1,tex2D(DiffuseMap, IN.Uv).r);
else
base = tex2D(DiffuseMap, IN.Uv);
float4 result = IN.Color * base;
#if defined(PIN_FOG)
result.rgb = lerp(G(FogColor), result.rgb, saturate(IN.FogFactor));
#endif
return result;
}

View File

@@ -0,0 +1,213 @@
//
// Water shader.
// Big, fat and ugly.
//
// All (most) things considered, I have converged to this particular way of rendering water:
//
// Vertex waves
// No transparency. Solid color for deep water.
// Fresnel law, reflects environment.
// Phong speculars.
// Ripples via animated normal map. Adjustable intensity, speed and scale. Affect reflection and speculars.
#include "common.h"
WORLD_MATRIX(WorldMatrix);
uniform float4 nmAnimLerp; // ratio between normal map frames
uniform float4 waveParams; // .x = frequency .y = phase .z = height
uniform float4 WaterColor; // deep water color
#ifdef PIN_HQ
# define WATER_LOD 1
#else
# define WATER_LOD 2
#endif
#define LODBIAS (-1)
float fadeFactor( float3 wspos )
{
return saturate( -0.4f + 1.4f*length( G(CameraPosition) - wspos.xyz ) * G(FadeDistance_GlowFactor).y );
}
float wave( float4 wspos )
{
float x = sin( ( wspos.z - wspos.x - waveParams.y ) * waveParams.x );
float z = sin( ( wspos.z + wspos.x + waveParams.y ) * waveParams.x );
float p = (x + z) * waveParams.z;
return p - p * fadeFactor( wspos.xyz );
}
// perturbs the water mesh and vertex normals
void makeWaves( inout float4 wspos, inout float3 wsnrm )
{
#if WATER_LOD == 0
float gridSize = 4.0f;
float4 wspos1 = wspos;
float4 wspos2 = wspos;
wspos1.x += gridSize;
wspos2.z += gridSize;
wspos.y += wave(wspos) ;
wspos1.y += wave(wspos1);
wspos2.y += wave(wspos2);
wsnrm = normalize( cross( wspos2.xyz - wspos.xyz, wspos1.xyz - wspos.xyz ) );
#elif WATER_LOD == 1
wspos.y += wave( wspos );
#else /* do n0thing */
#endif
}
struct V2P
{
float4 pos : POSITION;
float4 tc0Fog : TEXCOORD0;
float4 wspos : TEXCOORD1;
float3 wsnrm : TEXCOORD2;
float3 light : TEXCOORD3;
float3 fade : TEXCOORD4;
};
V2P water_vs(
ATTR_INT4 pos : POSITION,
ATTR_INT3 nrm : NORMAL
)
{
V2P o;
// Decode vertex data
float3 normal = (nrm - 127.0) / 127.0;
normal = normalize(normal);
float4 wspos = mul( WorldMatrix, pos );
float3 wsnrm = normal;
wspos.y -= 2*waveParams.z;
makeWaves( /*INOUT*/ wspos, /*INOUT*/ wsnrm );
o.wspos = wspos;
o.wsnrm = wsnrm;
if( normal.y < 0.01f ) o.wsnrm = normal;
// box mapping
//float3x2 m = { wspos.xz, wspos.xy, wspos.yz };
//float2 tcselect = mul( abs( nrm.yzx ), m );
float2 tcselect;
float3 wspostc = float3( wspos.x, -wspos.y, wspos.z );
tcselect.x = dot( abs( normal.yxz ), wspostc.xzx );
tcselect.y = dot( abs( normal.yxz ), wspostc.zyy );
o.pos = mul( G(ViewProjection), wspos );
o.tc0Fog.xy = tcselect * .05f;
o.tc0Fog.z = saturate( (G(FogParams).z - o.pos.w) * G(FogParams).w );
o.tc0Fog.w = LODBIAS;
o.light = lgridPrepareSample(lgridOffset(wspos.xyz, wsnrm.xyz));
o.fade.x = fadeFactor( wspos.xyz );
o.fade.y = (1-o.fade.x) * saturate( dot( wsnrm, -G(Lamp0Dir) ) ) * 100;
o.fade.z = 1 - 0.9*saturate1( exp( -0.005 * length( G(CameraPosition) - wspos.xyz ) ) );
return o;
}
//////////////////////////////////////////////////////////////////////////////
TEX_DECLARE2D(NormalMap1, 0);
TEX_DECLARE2D(NormalMap2, 1);
TEX_DECLARECUBE(EnvMap, 2);
LGRID_SAMPLER(LightMap, 3);
TEX_DECLARE2D(LightMapLookup, 4);
float3 pixelNormal( float4 tc0 )
{
float4 nm1 = tex2Dbias( NormalMap1, tc0 );
#if WATER_LOD <= 1
float4 nm2 = tex2Dbias( NormalMap2, tc0 );
float4 nm3 = lerp( nm1, nm2, nmAnimLerp.xxxx );
#else
float4 nm3 = nm1;
#endif
return nmapUnpack( nm3 );
}
// Fresnel approximation. N1 and N2 are refractive indices.
// for above water, use n1 = 1, n2 = 1.3, for underwater use n1 = 1.3, n2 = 1
float fresnel( float3 N, float3 V, float n1, float n2, float p, float fade )
{
#if WATER_LOD == 0
float r0 = (n1-n2)/(n1+n2);
r0 *= r0;
return r0 + (1-r0) * pow( 1 - abs( dot( normalize(N), V ) ), p );
#else
return 0.1 + saturate( - 1.9 * abs( dot( N, V ) ) + 0.8); // HAXX!
//return 1 - 2 * abs( dot( N, V ) );
#endif
}
float4 envColor( float3 N, float3 V, float fade )
{
float3 dir = reflect( V, N );
return texCUBE(EnvMap, dir) * 0.91f;
}
float4 deepWaterColor(float4 light)
{
//float4 tint = 5*float4( 0.1f, 0.1f, 0.13f, 1);
float4 tint = 0.8f*float4( 118, 143, 153, 255 ) / 255;
return (light + texCUBEbias( EnvMap, float4( 0,1,0, 10.0f) )) * tint;
}
//////////////////////////////////////////
//////////////////////////////////////////
float4 water_ps( V2P v ) : COLOR0
{
float4 WaterColorTest = 0.5 * float4( 26, 169, 185, 0 ) / 255;
float4 FogColorTest = 0.8 * float4( 35, 107, 130, 0 ) / 255;
float3 N2 = v.wsnrm;
float3 N1 = pixelNormal( v.tc0Fog ).xzy;
float3 N3 = 0.5*(N2 + N1);
N3 = lerp( N3, N2, v.fade.z );
float3 L = /*normalize*/(-G(Lamp0Dir).xyz);
float3 E = normalize( G(CameraPosition) - v.wspos.xyz );
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), v.light.xyz);
float fre = fresnel( N3, E, 1.0f, 1.3f, 5, v.fade.x );
float3 diffuse = deepWaterColor(light).rgb;
float3 env = envColor( N3, -E, v.fade.x ).rgb;
float3 R = reflect( -L, N1 );
#if WATER_LOD <= 1
float specular = pow( saturate0( dot( R, E ) ), 1600 ) * L.y * 100; // baseline
# ifndef GLSLES
specular = 0.65 * saturate1( specular * saturate0( light.a - 0.4f ) );
# endif
#else
float specular = 0;
#endif
float3 result = lerp( diffuse, env, fre ) + specular.xxx;
result = lerp( G(FogColor).rgb, result, v.tc0Fog.z );
return float4( result, 1 );
}

View File

@@ -0,0 +1,100 @@
#ifdef CLASSIC
#define PIN_SURFACE
#define ALREADY_HAS_PS
#include "default.hlsl"
#define SPEC_EXPON 4
#define KS .1
#define WoodContrast float3(0.1, 0.1, 0.1)
#define Ks1 0.32
#define Ks2 0.16
#define RingScale 4
#define AmpScale 1
#define LightRingEnd 0.4
#define DarkRingStart 0.8
#define DarkRingEnd 0.83
#define NormMapScale 0.6
#define NoiseScale 64
#define MixedColorRatio 0.315
#define AAFreqMultiplier 12
void DefaultPS(VertexOutput IN,
#ifdef PIN_GBUFFER
out float4 oColor1: COLOR1,
#endif
out float4 oColor0: COLOR0)
{
float3 nn = normalize(IN.Normal);
float3x3 normalMatrix = {
IN.Tangent.xyz,
cross(nn, IN.Tangent.xyz),
nn
};
float4 WoodPos = float4(IN.Pos.xyz, lerp(0, .92, abs(dot(float3(1,0,0), nn))));
float2 NormalUV = IN.Uv.xy * NormMapScale * 3;
float singularityAttenuation = WoodPos.w;
float noiseval = tex3D(SpecularMap, WoodPos.xyz / NoiseScale).x;
float3 tn = tex2D(NormalMap, NormalUV).xyz - .5;
tn = lerp(tn, float3(0, 0, .5), singularityAttenuation);
float4 edgeDistances = IN.EdgeDistances;
tn = CalcBevel(edgeDistances, tn, IN.View_Depth.w);
nn = mul(tn, normalMatrix);
float signalfreq = length(float4(ddx(WoodPos.y), ddx(WoodPos.z), ddy(WoodPos.y), ddy(WoodPos.z))); // seems to be angle based thing
float aa_attn = saturate(signalfreq*AAFreqMultiplier - 1.0f);
float3 Pwood = WoodPos.xyz + (AmpScale * noiseval);
float r = RingScale * length(Pwood.yz);
r = r + tex3D(SpecularMap,r.xxx/32.0).x;
r = r - floor(r); // stepping in the rings in formed through this here
r = smoothstep(LightRingEnd, DarkRingStart, r) - smoothstep(DarkRingEnd,1.0,r);
// apply anti-aliasing
r = lerp(r, MixedColorRatio, aa_attn);
float3 albedo = IN.Color.xyz + WoodContrast * (MixedColorRatio - r);
float Ks = lerp(Ks1,Ks2,r);
float3 vn = normalize(IN.View_Depth.xyz);
float4 light = lgridSample(TEXTURE(LightMap), TEXTURE(LightMapLookup), IN.LightPosition_Fog.xyz);
light.a = shadowSample(TEXTURE(ShadowMap), IN.PosLightSpace.xyz, light.a);
float3 diffuse;
float3 specular;
Shade(albedo, nn, vn, Ks, SPEC_EXPON, light, diffuse, specular);
oColor0 = float4(diffuse + specular, IN.Color.w);
float fogAlpha = saturate((G(FogParams).z - length(IN.View_Depth.xyz)) * G(FogParams).w);
oColor0.xyz = lerp(G(FogColor), oColor0.rgb, fogAlpha);
#ifdef PIN_GBUFFER
oColor1 = gbufferPack(IN.View_Depth.w, diffuse.rgb, specular.rgb, fogAlpha);
#endif
}
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 2
#define CFG_GLOSS_SCALE 256
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0.3
#define CFG_SPECULAR_LOD 0.25
#define CFG_GLOSS_LOD 32
#define CFG_NORMAL_DETAIL_TILING 7
#define CFG_NORMAL_DETAIL_SCALE 0.6
#define CFG_FAR_TILING 0
#define CFG_FAR_DIFFUSE_CUTOFF 0
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#include "material.hlsl"
#endif

View File

@@ -0,0 +1,27 @@
#ifdef CLASSIC
#include "wood.hlsl"
#else
#define CFG_TEXTURE_TILING 1
#define CFG_DIFFUSE_SCALE 1
#define CFG_SPECULAR_SCALE 2
#define CFG_GLOSS_SCALE 256
#define CFG_REFLECTION_SCALE 0
#define CFG_NORMAL_SHADOW_SCALE 0.3
#define CFG_SPECULAR_LOD 0.28
#define CFG_GLOSS_LOD 53
#define CFG_NORMAL_DETAIL_TILING 0
#define CFG_NORMAL_DETAIL_SCALE 0
#define CFG_FAR_TILING 0
#define CFG_FAR_DIFFUSE_CUTOFF 0
#define CFG_FAR_NORMAL_CUTOFF 0
#define CFG_FAR_SPECULAR_CUTOFF 0
#define CFG_OPT_BLEND_COLOR
#include "material.hlsl"
#endif