Initial Commit

This commit is contained in:
Toomas Tamm
2020-11-28 16:54:41 +02:00
parent 97292ee26e
commit ea967135f2
4217 changed files with 2945663 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fd2e51a1201e9294f89c28dd4a5de2de
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ece97ec1882fb054ebace17485b43dad
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
#pragma kernel Converter
struct grassCell {
uint grassElementIndexes[512];//map to grass elements
};
StructuredBuffer<grassCell> grassCellBuffer;
StructuredBuffer<uint> grassCellIndexBuffer;
AppendStructuredBuffer<uint> outGrassBuffer;
[numthreads(8,8,8)]
void Converter (uint callIndex : SV_GroupIndex, uint3 groupID : SV_GroupID) {
uint realIndex = groupID.x + groupID.y + groupID.z;
uint cellIndex = grassCellIndexBuffer[realIndex];
grassCell cell = grassCellBuffer[ cellIndex ];
int elementIndex = callIndex;//Correct
uint objIndex = cell.grassElementIndexes[elementIndex];
if(objIndex != 0) outGrassBuffer.Append(objIndex);
}
//So the error seems to have been the usement of the wrong ID... but there must have been something else as well

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1fd24d1f469889243b1b12e2b668be27
ComputeShaderImporter:
externalObjects: {}
currentAPIMask: 4
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,146 @@
#pragma kernel CSCullIndividual
#pragma kernel CSCullCell
struct GrassElement {
float3 position;
float rotation;
float size;
float colorBlend;//0-1
};
struct grassCell {
uint grassElementIndexes[512];//map to grass elements
};
//struct grassOcclusionCell {
// uint grassCellIndex;
// uint visibleCellIndexes[2048];//Map to occlusion cells
// };
//General
uint grassCount;
float2 distanceBounts;//Start, end
Texture2D<float4> ditherTex;
int ditherTexSizeX;
float ditherSize;
//Input
StructuredBuffer<GrassElement> grassBuffer;
//Frustrum culling
float3 cameraPos;
float4x3 cameraFrustumNormals;
//settings
int doOcclusion;
//Cells
uint grassCellCount;
uint grassCellSize;
StructuredBuffer<grassCell> grassCellBuffer;
//Occlusion culling
//StructuredBuffer<grassOcclusionCell> grassOcclusionBuffer;
//Output
AppendStructuredBuffer<uint> outGrassBuffer;
AppendStructuredBuffer<uint> outCellIndexBuffer;
bool Is3DDither (float dist, float2 pos) {
float distAmount = 1 - (dist-distanceBounts.x)/(distanceBounts.y-distanceBounts.x);//0-1
float2 relativePos = pos/ditherSize;
float2 positivePos = float2(relativePos.x*sign(relativePos.x),relativePos.y*sign(relativePos.y));
float2 repeatingPos = float2(fmod(positivePos.x,ditherTexSizeX),fmod(positivePos.y,ditherTexSizeX));
float dit = ditherTex[repeatingPos].x;
return distAmount - dit > 0;
}
[numthreads(16,16,4)]
void CSCullIndividual (uint index : SV_GroupIndex, uint3 group : SV_GroupID) {//This only does frustrum culling
//1. get index
uint realIndex = index + 1024 * group.x;//id.x + id.y group.x + id.z group.x * group.y
//2. index valid?
if(realIndex < grassCount) {
GrassElement data = grassBuffer[realIndex];
float3 pos = data.position;
float3 posFromCamera = pos - cameraPos;
float scale = data.size;
//3. frustrum culling
if( (dot(cameraFrustumNormals[0], posFromCamera) > -scale) &&
(dot(cameraFrustumNormals[1], posFromCamera) > -scale) &&
(dot(cameraFrustumNormals[2], posFromCamera) > -scale) &&
(dot(cameraFrustumNormals[3], posFromCamera) > -scale) ){
//3D dither culling (includes dist culling)
float dist = length(posFromCamera);
if(Is3DDither(dist,pos.xz)) {
outGrassBuffer.Append(realIndex);
}
}
}
}
[numthreads(8,8,1)]
void CSCullCell (uint index : SV_GroupIndex, uint3 group : SV_GroupID) {//This does frustrum and occlusion culling on cells
//1. get index
uint realIndex = index + 8*8*group.x;
//2. index valid?
if(realIndex < grassCellCount) {
//outGrassBuffer.Append(realIndex);
//outCellIndexBuffer.Append(realIndex);
grassCell cell = grassCellBuffer[realIndex];
//for(int i=0;i<512;i++) {
// int k = cell.grassElementIndexes[i];
// if(k != 0)outGrassBuffer.Append(k);
// }
//Doing frustrum check with ranodom element from cell
float3 pos = grassBuffer[cell.grassElementIndexes[0]].position;
float3 posFromCamera = pos - cameraPos;
float scale = grassCellSize;
//3. frustrum culling
if( (dot(cameraFrustumNormals[0], posFromCamera) > -scale) &&
(dot(cameraFrustumNormals[1], posFromCamera) > -scale) &&
(dot(cameraFrustumNormals[2], posFromCamera) > -scale) &&
(dot(cameraFrustumNormals[3], posFromCamera) > -scale) ){
if(length(posFromCamera) <= distanceBounts.y) {//Dist check
if(doOcclusion == 1) {
//TODO see if this chunk is visible from current chunk
//TODO if yes then append chunk grass indexes
}
else {
outCellIndexBuffer.Append(realIndex);
}
}
}
}
}
//group -> thread
//SV_GroupThreadID = current threads num.xyz
//SV_GroupIndex = num.x * num.y * num.z;
//SV_GroupID = current gorup indices
/* This works for some reason
[numthreads(8,8,8)]
void Converter (uint callIndex : SV_GroupIndex, uint3 groupID : SV_GroupID) {
uint realIndex = groupID.x + groupID.y + groupID.z;
uint cellIndex = grassCellIndexBuffer[realIndex];
grassCell cell = grassCellBuffer[ cellIndex ];
int elementIndex = callIndex;//Correct
uint objIndex = cell.grassElementIndexes[elementIndex];
if(objIndex != 0) outGrassBuffer.Append(objIndex);
}
*/

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7ceab07ca6d762d41baf41ab2a390c25
ComputeShaderImporter:
externalObjects: {}
currentAPIMask: 4
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4c66346fab7980a4f929c61d7510c130
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7cb3135d9c7fc794e907765b9aef86f8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,54 @@
#pragma kernel ConvertTrianglesToDotsKernel
struct TriangleInput {
float3 p1;
float3 p2;
float3 p3;
};
StructuredBuffer<TriangleInput> triangles;
RWStructuredBuffer<float3> positionOutputs;
float maxDotAmount = 0.225;
float seed = 1.32523252;
int pointCountPerTriangle = 10;
float pointsPerUnit = 1;
float rand(float3 co){
return (frac(sin(dot(co ,float3(12.9898,78.233,45.5432))) * 43758.5453));
}
float triangleArea (float3 a, float3 b, float3 c) {
//for simplicitys sake ignoring the y dimension and finding area of 2D triangle
return (a.x*(b.z-c.z) + b.x*(c.z-a.z) + c.x*(a.z-b.z))/2.0;
}
float3 randomPointOnTriangle (float3 a, float3 b, float3 c, float index) {
float r1 = rand(index*b*seed);
float r0 = r1 + rand(index*c*seed) * (1-r1);//bigger
return float3(r1 * a.x + (r0-r1)*b.x + (1-r0)*c.x,
r1 * a.y + (r0-r1)*b.y + (1-r0)*c.y,
r1 * a.z + (r0-r1)*b.z + (1-r0)*c.z
);
}
[numthreads(16,1,1)]
void ConvertTrianglesToDotsKernel (uint3 id : SV_DispatchThreadID)
{
TriangleInput tri = triangles[id.x];
int startIndex = id.x*pointCountPerTriangle;
//based on triangle size get point amount
float points = min(triangleArea(tri.p1,tri.p2,tri.p3)*pointsPerUnit,pointCountPerTriangle);
for (int i = 0; i < pointCountPerTriangle; ++i) {
if(i < points) {
positionOutputs[startIndex + i] = randomPointOnTriangle(tri.p1,tri.p2,tri.p3, saturate((float)i/(float)points) );//tri.p1 * saturate(1 - (float)i/(float)points) + tri.p2 * saturate((float)i/(float)points);
}
else {
positionOutputs[startIndex + i] = float3(0,0,0);
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0b019a8b66e1a35458a71c2297608a26
ComputeShaderImporter:
externalObjects: {}
currentAPIMask: 4
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9f51fb5d6fd8a2940b27ac89529b4f07
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a490d5ae78d2b40408e40c7a94adc9f6
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2e128af5fc364d04cbe70030007a473e
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6cd2d0a79ec5af7428b2aaf3f2062554
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "DBV_GrassData", menuName = "Delta/Kristo/Grass_Data")]
public class GrassPositionScriptableObject : ScriptableObject {
[HideInInspector]
public List<Vector3> points = new List<Vector3>();
public struct cell {
public int[] arrayOfPointIndexes;
}
public struct occlusionCell {
public int cellIndex;
public int[] arrayOfVisibleOcclusionCellIndexes;
}
[HideInInspector]
public List<cell> cells = new List<cell>();
[HideInInspector]
public List<occlusionCell> occlusionCells = new List<occlusionCell>();
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1bbb7ddcdfb501845bff224521ebbcca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,594 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GrassLoader : MonoBehaviour {
public static GrassLoader instance;
void Awake () {
instance = this;
}
[Header("Requiered variables")]
public Mesh grassMesh;
public Mesh boxMesh;
public Material instancedGrassMaterial;
public Material instancedConsumeGrassMaterial;
public GrassPositionScriptableObject grassStorage;
public ComputeShader cullShader;
public ComputeShader convertArrayShader;
[Header("Tilemap (Occlusion culling)")]
public Vector3 bottomLeftCorner;
public float cellSideLengh = 1f;
public float totalLength = 100f;
[Header("3D culling")]
public Vector2 distanceBounds;
public Texture2D ditherTexture;
public float ditherSize;
[Header("Manual controls")]
public bool update;
public bool updateData;
public bool bakeCells;
public bool bakeOcclusion;
[Header("Testing")]
public bool debugTilemap1;
public bool debugTilemap2;
public bool debugTilemap3;
public bool debugTilemap4;
public bool showTilemap;
[Space]
public bool doCells;
public bool doCulling;
public bool doOcclusionCulling;
//[Header("Testing")]
//public bool update = false;
//data types
struct grassElement {
public Vector3 position;
public float rotation;
public float size;
public float colorBlend;//0-1
public grassElement (Vector3 position, float rotation, float size, float colorBlend) {
this.position = position;
this.rotation = rotation;
this.size = size;
this.colorBlend = colorBlend;
}
//Total size of is 4*3 + 3*4 = 24
}
struct grassCell {
public uint[] grassElementIndexes;//map to grass elements
public grassCell (uint[] grassElementIndexes) {
this.grassElementIndexes = grassElementIndexes;
}
public grassCell(grassCell x) {
grassElementIndexes = new uint[x.grassElementIndexes.Length];
for(int i = 0;i < x.grassElementIndexes.Length;i++){
grassElementIndexes[i] = x.grassElementIndexes[i] * 1;
}
}
//Total size = 4*length = must be calculated
}
struct grassOcclusionCell {
public uint grassCellIndex;
public uint[] visibleCellIndexes;//Map to occlusion cells
public grassOcclusionCell (uint grassCellIndex, uint[] visibleCellIndexes) {
this.grassCellIndex = grassCellIndex;
this.visibleCellIndexes = visibleCellIndexes;
}
//Total size = 4 + 4*length = must be calculated
}
//buffers
uint[] arguments = new uint[5] {0,0,0,0,0};
//main
ComputeBuffer grassBuffer;
ComputeBuffer argumentsBuffer;
ComputeBuffer allArgumentsBuffer;
//culling
ComputeBuffer workBuffer;//Append/Consume buffer for grass elements
ComputeBuffer grassCellBuffer;
ComputeBuffer cellWorkBuffer;
ComputeBuffer convertSizeBuffer;
public bool isOn = true;
int elementCount = 0;
int cellCount = 0;
bool startupDone;
grassElement[] grassElements;
Camera cam;
public void BakeCells () {
if(grassElements == null) UpdateMainBuffers();
bakeCells = false;
//Maps points into cells
// 0. Create tilemap
var tilemap = new Dictionary<int,List<int>>();
int cellsCount = Mathf.CeilToInt(totalLength/cellSideLengh);
for(int x = 0;x < cellsCount;x++) for(int y = 0;y < cellsCount;y++) tilemap.Add(x + y*cellsCount,new List<int>());
// 1. Set grassObjects into tiles
for(int i = 0;i < elementCount;i++) tilemap[GetTileIndex(grassElements[i].position)].Add(i);
//Debug
if(debugTilemap1) for(int x = 0;x < cellsCount;x++){
for(int y = 0;y < cellsCount;y++){
var pos = bottomLeftCorner + (x * Vector3.forward + y * Vector3.right)*cellSideLengh + Vector3.one * cellSideLengh/2f;
int i = GetTileIndex(pos);
if(tilemap.ContainsKey(i)) foreach(var k in tilemap[i]) Debug.DrawLine(grassElements[k].position + Vector3.right* 0.2f, pos,Color.green,100f);
}
}
// 2. Cull empty tiles
var removables = new Queue<int>();
foreach(var x in tilemap) if(x.Value.Count == 0) removables.Enqueue(x.Key);
foreach(var x in removables) tilemap.Remove(x);
//Debug
if(debugTilemap2) for(int x = 0;x < cellsCount;x++){
for(int y = 0;y < cellsCount;y++){
var pos = bottomLeftCorner + (x * Vector3.forward + y * Vector3.right)*cellSideLengh + Vector3.one * cellSideLengh/2f + Vector3.up;
int i = GetTileIndex(pos);
if(tilemap.ContainsKey(i)) foreach(var k in tilemap[i]) {Debug.DrawLine(grassElements[k].position + Vector3.right* 0.2f, pos,Color.magenta,100f); Debug.DrawRay(pos, Vector3.up,Color.magenta,100f);}
}
}
// 3. Get cell average grass count - not needed anymore
//float total = 0; float count = 0;
//foreach(var x in tilemap) { total += x.Value.Count; count++; }
//int mean = (int)(total/count);
//TODO 4. Convert tiles into cells of 512 elements (512 bc byte limit is 2048 and 1 index = 4 bytes so 512*4 = 2048)
var cells = new List<grassCell>();
var cellIdTilemap = new Dictionary<int,List<int>>();
foreach(var x in tilemap) {
//foreach entry convert indexes into how many cells are needed
var tileCellIDs = new List<int>();
var cellGrassIndexes = x.Value;
int leftToProcess = cellGrassIndexes.Count;
while(leftToProcess > 0) {
//Create new cell
var grassIndexArray = new uint[512];
for(int i = 0;i < grassIndexArray.Length;i++) {
if(cellGrassIndexes.Count > 0) {
grassIndexArray[i] = (uint)(cellGrassIndexes[0]);
cellGrassIndexes.RemoveAt(0);
leftToProcess--;
}
else grassIndexArray[i] = 0;
}
cells.Add( new grassCell(grassIndexArray) );
//Remember id
tileCellIDs.Add(cells.Count-1);
}
//Save cell ids so they can be used in occlusion culling
cellIdTilemap.Add(x.Key,tileCellIDs);
}
//Debug, foreach cell show which cells they map to by each cells connections
if(debugTilemap3) for(int x = 0;x < cellsCount;x++){
for(int y = 0;y < cellsCount;y++){
var pos = bottomLeftCorner + (x * Vector3.forward + y * Vector3.right)*cellSideLengh + Vector3.one * cellSideLengh/2f + Vector3.up * 2f;
int i = GetTileIndex(pos);
if(cellIdTilemap.ContainsKey(i)) {
//foreach cell get center
foreach(var cellIndex in cellIdTilemap[i]) {
var cell = cells[cellIndex];
Vector3 center = Vector3.zero;
float count = 0;
foreach(var grassIndex in cell.grassElementIndexes) {
if(grassIndex > 0) {center += grassElements[grassIndex].position; count++; Debug.DrawLine(grassElements[grassIndex].position, pos,Color.white,100f);}
}
Debug.DrawLine(center / count, pos,Color.blue,100f);
}
}
}
}
// 5. Convert cells into array (bc array in a struct is not bittable...)
cellCount = cells.Count;
var convertedArray = new uint[cellCount * 512];
for(int i = 0;i < cellCount;i++){
var c = cells[i];
for(int j = 0;j < 512;j++) { convertedArray[j + i * 512] = c.grassElementIndexes[j]; if(debugTilemap4) Debug.DrawRay(grassElements[c.grassElementIndexes[j]].position, Vector3.up,Color.magenta,100f); }
}
//Wipe old buffers
if(grassCellBuffer != null) grassCellBuffer.Release();
if(cellWorkBuffer != null) cellWorkBuffer.Release();
if(convertSizeBuffer != null) convertSizeBuffer.Release();
//Create new buffers
grassCellBuffer = new ComputeBuffer(cellCount, 2048);
cellWorkBuffer = new ComputeBuffer(cellCount, 4, ComputeBufferType.Append);
convertSizeBuffer = new ComputeBuffer(1, 12, ComputeBufferType.IndirectArguments);
//Upload data
grassCellBuffer.SetData(convertedArray);
cellWorkBuffer.SetCounterValue(0);
convertSizeBuffer.SetData(new uint[]{1,1,1});
//Send buffers to shaders
cullShader.SetBuffer(1, "grassBuffer", grassBuffer);
cullShader.SetBuffer(1, "grassCellBuffer", grassCellBuffer);
cullShader.SetBuffer(1, "outCellIndexBuffer", cellWorkBuffer);
//cullShader.SetBuffer(1, "outGrassBuffer", workBuffer);
convertArrayShader.SetBuffer(0, "grassCellBuffer", grassCellBuffer);
convertArrayShader.SetBuffer(0, "outGrassBuffer", workBuffer);
convertArrayShader.SetBuffer(0, "grassCellIndexBuffer", cellWorkBuffer);
//Set buffer values
cullShader.SetInt("grassCellCount", cellCount);
cullShader.SetInt("grassCellSize", Mathf.CeilToInt(cellSideLengh));
cullShader.SetVector("distanceBounts", distanceBounds);
cullShader.SetTexture(0, "ditherTex", ditherTexture);
cullShader.SetTexture(1, "ditherTex", ditherTexture);
cullShader.SetFloat("ditherTexSizeX", ditherTexture.width);
cullShader.SetFloat("ditherSize", ditherSize);
Debug.Log("GRASS: Created " + cellCount.ToString() + " cells");
}
public void BakeOcclusionCells () {
/*
bakeOcclusion = false;
//Creates occlusion cells
//OCCLUSION GENERATION (from created cell structs)
// 1. Create target low and full objects
var grassCollider = new GameObject();
grassCollider.transform.name = "TEMP_GRASS_COLLIDER";
grassCollider.AddComponent(typeof(BoxCollider));
var gMeshFilter = grassCollider.AddComponent(typeof(MeshFilter)) as MeshFilter;
var gMeshRenderer = grassCollider.AddComponent(typeof(MeshRenderer)) as MeshRenderer;
gMeshFilter.mesh = boxMesh;
grassCollider.transform.localScale = new Vector3(cellSideLengh,0.5f,cellSideLengh);
var fallableCollider = new GameObject();
fallableCollider.transform.name = "TEMP_FALLABLE_COLLIDER";
fallableCollider.AddComponent(typeof(BoxCollider));
var fMeshFilter = fallableCollider.AddComponent(typeof(MeshFilter)) as MeshFilter;
var fMeshRenderer = fallableCollider.AddComponent(typeof(MeshRenderer)) as MeshRenderer;
fMeshFilter.mesh = boxMesh;
fallableCollider.transform.localScale = new Vector3(cellSideLengh,20f,cellSideLengh);
// 2. Foreach cell try to see each other cell, if not already marked visible
//Create full tilemap of all possible places where camera might be
var fullTilemap = new HashSet<int>();
for(int x = 0;x < cellCount;x++){
for(int y = 0;y < cellCount;y++){
var pos = bottomLeftCorner + (x * Vector3.forward + y * Vector3.right)*cellSideLengh;
if(Physics.Raycast(pos + Vector3.up*100f, -Vector3.up, Mathf.Infinity)) fullTilemap.Add(GetTileIndex(pos));
}
}
var occlusionCells = new Dictionary<int,List<int>>();
foreach(var x in tilemap) occlusionCells.Add(x.Key,new List<int>());
foreach(var x in fullTilemap) if(!occlusionCells.ContainsKey(x)) occlusionCells.Add(x,new List<int>());
void PositionColliderAtPostion (Vector3 pos, Transform collider) {
RaycastHit hit;
if(Physics.Raycast(pos + Vector3.up*100f, -Vector3.up, out hit, Mathf.Infinity)) {
collider.position = new Vector3(pos.x,hit.point.y + collider.localScale.y/2f,pos.z);
}
else collider.position = new Vector3(pos.x,0,pos.z);
}
bool DoRaycastTest (Vector3 from, Vector3 to, string targetName) {
//Will shoot rays 1. from the bottom of from, then from middle and then from top, if hit then returns true, else false
bool ShootRays (Vector3 pos) {
RaycastHit hit;
for(int i = 0;i < 5;i++){
var start = pos + new Vector3(Random.Range(0,1f),Random.Range(0,.5f),Random.Range(0,1f));
var target = to + new Vector3(Random.Range(0,1f),Random.Range(0,.5f),Random.Range(0,1f));
if( Physics.Raycast(start, target-start, out hit, Mathf.Infinity) ) if(hit.transform.name == targetName) return true;
}
return false;
}
if(ShootRays(from)) return true;
if(ShootRays(from + Vector3.up * 2f)) return true;
if(ShootRays(from + Vector3.up * 4f)) return true;
return false;
}
void TestVisibilityBetweenCells (int i, int j) {
//0. see if already done
var oI = occlusionCells[i];
var oJ = occlusionCells[j];
if(!oI.Contains(j)) {
//1. Get both positions
var posI = bottomLeftCorner + (i % cellCount) * Vector3.forward * cellSideLengh + Mathf.FloorToInt(i/cellCount) * Vector3.right * cellSideLengh;
var posJ = bottomLeftCorner + (j % cellCount) * Vector3.forward * cellSideLengh + Mathf.FloorToInt(j/cellCount) * Vector3.right * cellSideLengh;
//2. Try visibility form i -> j
PositionColliderAtPostion(posJ, grassCollider.transform);
if(DoRaycastTest(posI, posJ, "TEMP_GRASS_COLLIDER")) {
//3. If possible then register both as possible
oI.Add(j);
oJ.Add(i);
}
}
}
int k = 0;
float t = fullTilemap.Count * tilemap.Count;
foreach(var x in fullTilemap) foreach(var y in tilemap) if(x != y.Key) {TestVisibilityBetweenCells(x,y.Key); k++; if(k%30000==0) {yield return 0;Debug.Log((k/t).ToString() + "% done");} } //Do all possible tests
Destroy(grassCollider);
Destroy(fallableCollider);
//Debug show connections
//TODO 3. Get cell average seeable length.
//TODO 4. Convert all cells into structs, if more seeables then create more structs per cell
//TODO Give cell and occulsion data to cullShader
//1. Create walkable area
//2. Foreach cell in walkable area find all grass cells that it sees
//3. Save data to storage
*/
}
public void Setup () {
cam = Camera.main;
//arguments buffer
argumentsBuffer = new ComputeBuffer(1, arguments.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
allArgumentsBuffer = new ComputeBuffer(1, arguments.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
//Main buffer
UpdateMainBuffers();
//Cells
BakeCells();
//Occlusion
//BakeOcclusionCells();
}
void DebugWorkBufferCount () {
var tempBuffer = new ComputeBuffer(1, sizeof(uint), ComputeBufferType.IndirectArguments);
uint[] x = new uint[1];
ComputeBuffer.CopyCount(workBuffer,tempBuffer,0);
tempBuffer.GetData(x);
var s = "";
foreach(var k in x) s += " " + k.ToString();
Debug.Log(s);
tempBuffer.Release();
}
void DebugWorkCellBufferCount () {
var tempBuffer = new ComputeBuffer(1, sizeof(uint), ComputeBufferType.IndirectArguments);
uint[] x = new uint[1];
ComputeBuffer.CopyCount(cellWorkBuffer,tempBuffer,0);
tempBuffer.GetData(x);
var s = "";
foreach(var k in x) s += " " + k.ToString();
Debug.Log(s);
tempBuffer.Release();
}
public void Run () {
if(!startupDone) return;//Wait for startup do complete
//0. manual update
if(update) UpdateMainBuffers();
if(bakeCells) BakeCells();
//1. UpdateCullBuffer
if(doCulling) UpdateCullBuffer();
//Draw
if(isOn) Graphics.DrawMeshInstancedIndirect(grassMesh, 0, doCulling?instancedConsumeGrassMaterial:instancedGrassMaterial, new Bounds(Vector3.zero, new Vector3(1000.0f, 1000.0f, 1000.0f)), doCulling?argumentsBuffer:allArgumentsBuffer);
//Testing
if(showTilemap) {
int cellsCount = Mathf.CeilToInt(totalLength/cellSideLengh);
for(int x = 0;x < cellsCount;x++){
for(int y = 0;y < cellsCount;y++){
var pos = bottomLeftCorner + (x * Vector3.forward + y * Vector3.right)*cellSideLengh;
Debug.DrawRay(pos, Vector3.up * 5f,Color.blue);
}
}
}
}
void UpdateCullBuffer () {
//1. Update frustrum culling information
var cam = Camera.main;
var mat = cam.projectionMatrix * cam.worldToCameraMatrix;
var normals = new Vector3[4];
var normalsMatrix = new float[12];
Vector3 temp;
//left
temp.x = mat.m30 + mat.m00;
temp.y = mat.m31 + mat.m01;
temp.z = mat.m32 + mat.m02;
normals[0] = temp;
//right
temp.x = mat.m30 - mat.m00;
temp.y = mat.m31 - mat.m01;
temp.z = mat.m32 - mat.m02;
normals[1] = temp;
//bottom
temp.x = mat.m30 + mat.m10;
temp.y = mat.m31 + mat.m11;
temp.z = mat.m32 + mat.m12;
normals[2] = temp;
//top
temp.x = mat.m30 - mat.m10;
temp.y = mat.m31 - mat.m11;
temp.z = mat.m32 - mat.m12;
normals[3] = temp;
for (int i = 0; i < 4; i++){
//Debug.DrawRay(camera.transform.position, _planes[i].normal * 10f, Color.yellow);
normalsMatrix[i + 0] = normals[i].x;
normalsMatrix[i + 4] = normals[i].y;
normalsMatrix[i + 8] = normals[i].z;
}
cullShader.SetFloats("cameraPos", cam.transform.position.x, cam.transform.position.y, cam.transform.position.z);
cullShader.SetInt("doOcclusion",doOcclusionCulling?1:0);
cullShader.SetFloats("cameraFrustumNormals", normalsMatrix);
//Reset
if(cellWorkBuffer != null) cellWorkBuffer.SetCounterValue(0);
workBuffer.SetCounterValue(0);
//2. Dispatch culler
if(doCells && cellCount > 0 && cellWorkBuffer != null) {
//1. Get cell indexes
int batchCount = Mathf.CeilToInt(cellCount/64f);
cullShader.Dispatch(1,batchCount,1,1);
//2. Get object indexes
//convertSizeBuffer.SetData(new uint[] {1,1,1});
ComputeBuffer.CopyCount(cellWorkBuffer,convertSizeBuffer,0);
convertArrayShader.DispatchIndirect(0,convertSizeBuffer);
}
else {
int batchCount = Mathf.CeilToInt(elementCount/1024f);
cullShader.Dispatch(0,batchCount,1,1);
}
//3. Copy work count -> arguments
ComputeBuffer.CopyCount(workBuffer,argumentsBuffer,4);
}
int GetTileIndex (Vector3 pos) {
int cellsCount = Mathf.CeilToInt(totalLength/cellSideLengh);
//1. relative pos
var p = pos - bottomLeftCorner;
//2. safety
if(p.x < 0 || p.x > totalLength || p.z < 0 || p.z > totalLength) return 0;
//3. get index
return Mathf.CeilToInt(p.x/cellSideLengh) + cellsCount * Mathf.CeilToInt(p.z/cellSideLengh);
}
void UpdateMainBuffers () {
startupDone = false;
update = false;
//Debug.Log("Updating main");
elementCount = grassStorage.points.Count;
//Reset buffers
if(workBuffer != null) workBuffer.Release();
if(grassBuffer != null) grassBuffer.Release();
grassBuffer = new ComputeBuffer(elementCount, 24);
workBuffer = new ComputeBuffer(elementCount, 4, ComputeBufferType.Append);
workBuffer.SetCounterValue(0);//effectivly this clears the buffer
//Create grass elements from data
grassElements = new grassElement[elementCount];
for(int i = 0;i < elementCount;i++){
grassElements[i] = new grassElement(
grassStorage.points[i],
Random.Range(0f,360f),
Random.Range(0.9f,1f),
Random.Range(0,1f)
);
//Debug.DrawRay(grassStorage.points[i] + Vector3.right* 0.2f, Vector3.up * 10f,Color.yellow,100f);
}
Debug.Log("GRASS: Working with a total of " + grassElements.Length.ToString() + " grass objects");
//Save data to buffer
grassBuffer.SetData(grassElements);
distanceBounds = new Vector2(Mathf.Min(distanceBounds.y, distanceBounds.x),Mathf.Max(distanceBounds.y, distanceBounds.x)) ;
//Set buffers
cullShader.SetInt("grassCount", elementCount);
cullShader.SetFloat("maxDistance", distanceBounds.y);
cullShader.SetBuffer(0, "grassBuffer", grassBuffer);
cullShader.SetBuffer(0, "outGrassBuffer", workBuffer);
instancedConsumeGrassMaterial.SetBuffer("grassBuffer", grassBuffer);
instancedConsumeGrassMaterial.SetBuffer("inGrassBuffer", workBuffer);
instancedGrassMaterial.SetBuffer("grassBuffer", grassBuffer);
instancedGrassMaterial.SetFloat("fadeStartDist", distanceBounds.x - cellSideLengh);
instancedGrassMaterial.SetFloat("fadeEndDist", distanceBounds.y - cellSideLengh);
//Set arguments
arguments[0] = (grassMesh != null) ? (uint)grassMesh.GetIndexCount(0) : 0;
arguments[1] = (uint)elementCount;
argumentsBuffer.SetData(arguments);
allArgumentsBuffer.SetData(arguments);
if(doCulling) UpdateCullBuffer();
startupDone = true;
}
void OnDisable() {
if(grassBuffer != null) grassBuffer.Release(); grassBuffer = null;
if(argumentsBuffer != null) argumentsBuffer.Release(); argumentsBuffer = null;
if(allArgumentsBuffer != null) allArgumentsBuffer.Release(); allArgumentsBuffer = null;
if(workBuffer != null) workBuffer.Release(); workBuffer = null;
if(grassCellBuffer != null) grassCellBuffer.Release(); grassCellBuffer = null;
if(cellWorkBuffer != null) cellWorkBuffer.Release(); cellWorkBuffer = null;
if(convertSizeBuffer != null) convertSizeBuffer.Release(); convertSizeBuffer = null;
}
void Start () {
Setup();
}
void Update () {
Run();
}
}
/*
TODOS
1. Occlusion
- Switch to quads instead of traingles for grass
- Try shape that is more similar to cutout
- Add Wind
- Second billboard shader
- Billboard switch range
- Standard cull two outputs
- Cell cull two outputs
- Cell cull second converter
- Free camera
- Cell optimizations
- Distance dither cull? (optional)
2. Fallable particles (Rain, snow)
- Plan
2.1 Rain drop splashes
3. Volumetric fog with moving 3D noise and godrays?
4. Rain puddles, shininess
*/

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ecba1f8646b67e34bb6e21651aedb9b0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 10474e839531b834d943ec7230f72af3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,96 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: GrassConsumeInstancedMaterial
m_Shader: {fileID: 4800000, guid: d423e3e229bf71743b583d87c24d1a0f, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DitherTex:
m_Texture: {fileID: 2800000, guid: 4acb113475018874bbbc58f460e0f640, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 527cea5a6b017984894d91563b2bdefb, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _WindTex:
m_Texture: {fileID: 2800000, guid: 5e187697202a0ca4f80836a911eb0633, type: 3}
m_Scale: {x: 100, y: 100}
m_Offset: {x: 55345, y: 35235236}
m_Floats:
- _AlphaCutoff: 0.666
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.206
- _GlossyReflections: 1
- _Height: 1
- _Metallic: 0.392
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _Size: 0.25
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _WindAmount: 3.34
- _WindSize: 0.01
- _WindSpeed: 0.05
- _ZWrite: 1
- fadeEndDist: 100
- fadeStartDist: 90
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _ColorA: {r: 0.078097194, g: 0.6132076, b: 0.09535255, a: 1}
- _ColorB: {r: 0.17318603, g: 0.3679245, b: 0.03297436, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _windOffset: {r: -0.5, g: 0, b: 0, a: 0}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8b643e93bd7e02d41b00c7333021a78a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: GrassGround
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords: _NORMALMAP _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 2800000, guid: bc20a819849c6fd42b95aa9e2913ea40, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 20, y: 20}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 1b00fbcbdd1b477489caa310eeeb9ce3, type: 3}
m_Scale: {x: 20, y: 20}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 2800000, guid: a71a28c7c2debb640a3fbb8037a1a556, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 2800000, guid: 0066ce0e7c2e06f489981174b1d9f975, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 0
- _Glossiness: 0.6
- _GlossyReflections: 1
- _Metallic: 1
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.0135
- _SmoothnessTextureChannel: 1
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0, g: 0.41509432, b: 0.022040365, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 44f124f3f0705a742929361bf31ef6db
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: GrassInstancedMaterial
m_Shader: {fileID: 4800000, guid: 02f353f6dc231064c9224e1bde0fd751, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 527cea5a6b017984894d91563b2bdefb, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AlphaCutoff: 0.666
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 1
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _Size: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _ColorA: {r: 0.49910027, g: 0.6698113, b: 0.38229796, a: 1}
- _ColorB: {r: 0.3647059, g: 0.47450984, b: 0.19607845, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 891c69aeb607f0c49b71b7000efa4ceb
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,95 @@
fileFormatVersion: 2
guid: 4b7270406110eb348824f607a798034a
ModelImporter:
serializedVersion: 28
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 1
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVPackMargin: 4
useFileScale: 1
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,103 @@
fileFormatVersion: 2
guid: 527cea5a6b017984894d91563b2bdefb
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 10
mipmaps:
mipMapMode: 1
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.1
mipMapFadeDistanceStart: 0
mipMapFadeDistanceEnd: 2
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 2
aniso: 16
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 512
resizeAlgorithm: 0
textureFormat: 4
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 512
resizeAlgorithm: 0
textureFormat: 4
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,95 @@
fileFormatVersion: 2
guid: 37a17204eeb420948a913b69143253af
ModelImporter:
serializedVersion: 28
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 0
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVPackMargin: 4
useFileScale: 1
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,95 @@
fileFormatVersion: 2
guid: d6c88ec8475424a43829ad6ffc6245a6
ModelImporter:
serializedVersion: 28
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 1
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVPackMargin: 4
useFileScale: 1
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 837be2f6219051c479b1f6bd722b4a04
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
Shader "DBV/Kristo/FastGrass2.0"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Texture", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
[Space]
_AlphaCutoff ("Alpha cutoff", Range(0,1)) = 0.05
[Space]
_WindTexture ("Wind texture", 2D) = "white" {}
_WindSpeed ("Wind direction", Vector) = (1,1,1,1)
_HeightStart ("Height start", Float) = 0.05
_WindStrength ("Wind strength", Float) = 1
_WindTimeSpeed ("Wind speed", Float) = 1
}
SubShader
{
Tags { "RenderType"="Transparent" }
LOD 200
Cull Off
ZWrite Off
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard vertex:vert noshadowmask nodynlightmap nodirlightmap nolightmap noshadow
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex,_WindTexture;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
float _AlphaCutoff, _HeightStart, _WindStrength, _WindTimeSpeed;
float4 _WindSpeed;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void vert (inout appdata_full v) {
// get vertex world position
float4 worldPos = mul(v.vertex, unity_ObjectToWorld);
float2 samplePos = worldPos.xz;
samplePos += _Time.x * _WindSpeed.xz;
float windAmount = tex2Dlod(_WindTexture, float4(samplePos, 0, 0));
float heightAmount = v.vertex.z > _HeightStart;//v.vertex.y - _HeightStart;
v.vertex.y += sin(_WindTimeSpeed*windAmount)*_WindStrength * heightAmount;
v.vertex.x += cos(_WindTimeSpeed*windAmount)*_WindStrength * heightAmount;
}
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
clip(c.a-_AlphaCutoff);
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: db7b361255b6374438781f932dd1e8e0
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,334 @@
// Used Unitys "Standard geometry shader example" as a base to get unitys standard lighting and stuff w/ a custom geometry stage since surface shaders dont allow this
//and when writing from the ground up lighting has to be done by hand
// https://github.com/keijiro/StandardGeometryShader
#include "UnityCG.cginc"
#include "UnityGBuffer.cginc"
#include "UnityStandardUtils.cginc"
// Cube map shadow caster; Used to render point light shadows on platforms
// that lacks depth cube map support.
#if defined(SHADOWS_CUBE) && !defined(SHADOWS_CUBE_IN_DEPTH_TEX)
#define PASS_CUBE_SHADOWCASTER
#endif
// Shader uniforms
half4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
half _Glossiness;
half _Metallic;
sampler2D _BumpMap;
float _BumpScale;
sampler2D _OcclusionMap;
float _OcclusionStrength;
float _LocalTime;
// Vertex input attributes
struct Attributes {
float4 position : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 texcoord : TEXCOORD;
};
// Fragment varyings
struct Varyings {
float4 position : SV_POSITION;
#if defined(PASS_CUBE_SHADOWCASTER)
// Cube map shadow caster pass
float3 shadow : TEXCOORD0;
#elif defined(UNITY_PASS_SHADOWCASTER)
// Default shadow caster pass
#else
// GBuffer construction pass
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
float4 tspace0 : TEXCOORD1;
float4 tspace1 : TEXCOORD2;
float4 tspace2 : TEXCOORD3;
half3 ambient : TEXCOORD4;
#endif
};
//
// Vertex stage
//
Attributes Vertex(Attributes input) {
// Only do object space to world space transform.
input.position = mul(unity_ObjectToWorld, input.position);
input.normal = UnityObjectToWorldNormal(input.normal);
input.tangent.xyz = UnityObjectToWorldDir(input.tangent.xyz);
input.texcoord = TRANSFORM_TEX(input.texcoord, _MainTex);
return input;
}
//
// Geometry stage
//
Varyings VertexOutput(float3 wpos, half3 wnrm, half4 wtan, float2 uv) {
Varyings o;
#if defined(PASS_CUBE_SHADOWCASTER)
// Cube map shadow caster pass: Transfer the shadow vector.
o.position = UnityWorldToClipPos(float4(wpos, 1));
o.shadow = wpos - _LightPositionRange.xyz;
#elif defined(UNITY_PASS_SHADOWCASTER)
// Default shadow caster pass: Apply the shadow bias.
float scos = dot(wnrm, normalize(UnityWorldSpaceLightDir(wpos)));
wpos -= wnrm * unity_LightShadowBias.z * sqrt(1 - scos * scos);
o.position = UnityApplyLinearShadowBias(UnityWorldToClipPos(float4(wpos, 1)));
#else
// GBuffer construction pass
half3 bi = cross(wnrm, wtan) * wtan.w * unity_WorldTransformParams.w;
o.position = UnityWorldToClipPos(float4(wpos, 1));
o.normal = wnrm;
o.texcoord = uv;
o.tspace0 = float4(wtan.x, bi.x, wnrm.x, wpos.x);
o.tspace1 = float4(wtan.y, bi.y, wnrm.y, wpos.y);
o.tspace2 = float4(wtan.z, bi.z, wnrm.z, wpos.z);
o.ambient = ShadeSHPerVertex(wnrm, 0);
#endif
return o;
}
float3 ConstructNormal(float3 v1, float3 v2, float3 v3) {
return normalize(cross(v2 - v1, v3 - v1));
}
float rand(float3 co){
return frac(sin(dot(co.xyz, float3(12.9898, 78.233, 53.539))) * 43758.5453);
}
float3x3 AngleAxis3x3(float angle, float3 axis){
float c, s;
sincos(angle, s, c);
float t = 1 - c;
float x = axis.x;
float y = axis.y;
float z = axis.z;
return float3x3(
t * x * x + c, t * x * y - s * z, t * x * z + s * y,
t * x * y + s * z, t * y * y + c, t * y * z - s * x,
t * x * z - s * y, t * y * z + s * x, t * z * z + c
);
}
float _BladeHeight, _BladeHeightRandom, _BladeWidth, _BladeWidthRandom, _BendRotationRandom;
int _Test;
[instance(5)]
[maxvertexcount(42)]
void Geometry( triangle Attributes input[3], uint pid : SV_PrimitiveID, inout TriangleStream<Varyings> outStream, uint InstanceID : SV_GSInstanceID) {
//Vertex inputs;
//
//float2 uv0 = input[0].texcoord;
//float2 uv1 = input[1].texcoord;
//float2 uv2 = input[2].texcoord;
float3 pos = input[0].position;
float3 vNormal = input[0].normal;
float4 vTangent = input[0].tangent;
float3 vBinormal = cross (vNormal,vTangent)*vTangent.w;
float height = (rand(pos.zyx) * 2 - 1) * _BladeHeightRandom + _BladeHeight;
float width = (rand(pos.xzy) * 2 - 1) * _BladeWidthRandom + _BladeWidth;
float3x3 tangentToLocal = float3x3(
vTangent.x, vBinormal.x, vNormal.x,
vTangent.y, vBinormal.y, vNormal.y,
vTangent.z, vBinormal.z, vNormal.z
);
//TODO add geometry instancing
//TODO create nodes based on world pos
//TODO find out if need to remember geometry instancing index to create mor tris
//TODO keep track of how many verts used
//Add node
//float3 wn = ConstructNormal(wp3, wp4, wp5);
//outStream.Append(VertexOutput(pos + mul(transformationMatrix, float3( width, 0, 0 )),half3(0,1,0),float4(1,1,0,0), float2(1.25,0) ));
//outStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(-width, 0, 0 )),half3(0,1,0),float4(1,1,0,0), float2(-0.25,0) ));
//outStream.Append(VertexOutput(pos + mul(transformationMatrix, float3( 0 , 0, height)),half3(0,1,0),float4(1,1,0,0), float2(0.5,1.5) ));
//outStream.RestartStrip();
//outStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(0, width, 0 )),half3(0,1,0),float4(1,1,0,0), float2(1.25,0) ));
//outStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(0, -width, 0 )),half3(0,1,0),float4(1,1,0,0), float2(-0.25,0) ));
//outStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(0, 0 , height)),half3(0,1,0),float4(1,1,0,0), float2(0.5,1.5) ));
//outStream.RestartStrip();
//Do triangle
float3 wp0 = input[0].position.xyz;
float3 wp1 = input[1].position.xyz;
float3 wp2 = input[2].position.xyz;
//1. Order points
float3 p1 = max(wp0,max(wp1,wp2));
float3 p2;
float3 p3 = min(wp0,min(wp1,wp2));
if (all(p1 >= wp0) && all(p3 <= wp0)) {p2 = wp0;}
else if(all(p1 >= wp1) && all(p3 <= wp1)) {p2 = wp1;}
else if(all(p1 >= wp2) && all(p3 <= wp2)) {p2 = wp2;}
//2. Get directions
float3 vec1 = p3-p1;
float3 vec2 = p2-p1;
float3 vec3 = p3-p2;
float dir1Len = length(vec1);
float dir2Len = length(vec2);
float dir3Len = length(vec3);
float3 dir1 = vec1 / dir1Len;
float3 dir2 = vec2 / dir2Len;
float3 dir3 = vec3 / dir3Len;
//3. Define values
float unit = 0.5;
float3 step1 = dir1 * unit;
float3 step2 = dir2 * unit * abs(vec2.x/vec1.x);
float3 step3 = dir3 * unit;
float3 current1 = p1;
float3 current2 = p1;
//4. loop
int unitsToX = abs(floor(vec1.x/unit));
for (int i = 0; i < unitsToX; ++i) {
current1 += step1;
current2 += step2;
int unitsToZ = abs(floor((current1.z-current2.z)/unit));
//1. create start and ends
float3 current = floor(current1);
for (int j = 0; j < unitsToZ; ++j) {//loop and create nodes
float3x3 facingRotationMatrix = AngleAxis3x3(rand(pos) * UNITY_TWO_PI, float3(0, 0, 1));
float3x3 bendRotationMatrix = AngleAxis3x3(rand(pos.zzx) * _BendRotationRandom * UNITY_PI * 0.5, float3(-1, 0, 0));
float3x3 transformationMatrix = mul(mul(tangentToLocal, facingRotationMatrix),bendRotationMatrix);
float k = i+j+1;
//-Creat node- START
outStream.Append(VertexOutput(current + mul(transformationMatrix, float3( width, 0, 0 )),half3(0,1,0),float4(1,1,0,0), float2(1.25,0) ));
outStream.Append(VertexOutput(current + mul(transformationMatrix, float3(-width, 0, 0 )),half3(0,1,0),float4(1,1,0,0), float2(-0.25,0) ));
outStream.Append(VertexOutput(current + mul(transformationMatrix, float3( 0 , 0, height*k)),half3(0,1,0),float4(1,1,0,0), float2(0.5,1.5) ));
outStream.RestartStrip();
outStream.Append(VertexOutput(current + mul(transformationMatrix, float3(0, width, 0 )),half3(0,1,0),float4(1,1,0,0), float2(1.25,0) ));
outStream.Append(VertexOutput(current + mul(transformationMatrix, float3(0, -width, 0 )),half3(0,1,0),float4(1,1,0,0), float2(-0.25,0) ));
outStream.Append(VertexOutput(current + mul(transformationMatrix, float3(0, 0 , height*k)),half3(0,1,0),float4(1,1,0,0), float2(0.5,1.5) ));
outStream.RestartStrip();
//-Create node- END
current.z += unit;
}
}
// Extrusion amount
//float ext = saturate(0.4 - cos(_LocalTime * UNITY_PI * 2) * 0.41);
//ext *= 1 + 0.3 * sin(pid * 832.37843 + _LocalTime * 88.76);
//
//// Extrusion points
//float3 offs = ConstructNormal(wp0, wp1, wp2) * ext;
//float3 wp3 = wp0 + offs;
//float3 wp4 = wp1 + offs;
//float3 wp5 = wp2 + offs;
//
//// Cap triangle
//float3 wn = ConstructNormal(wp3, wp4, wp5);
//float np = saturate(ext * 10);
//float3 wn0 = lerp(input[0].normal, wn, np);
//float3 wn1 = lerp(input[1].normal, wn, np);
//float3 wn2 = lerp(input[2].normal, wn, np);
//outStream.Append(VertexOutput(wp3, wn0, input[0].tangent, uv0));
//outStream.Append(VertexOutput(wp4, wn1, input[1].tangent, uv1));
//outStream.Append(VertexOutput(wp5, wn2, input[2].tangent, uv2));
//outStream.RestartStrip();
//
//// Side faces
//float4 wt = float4(normalize(wp3 - wp0), 1); // world space tangent
//wn = ConstructNormal(wp3, wp0, wp4);
//outStream.Append(VertexOutput(wp3, wn, wt, uv0));
//outStream.Append(VertexOutput(wp0, wn, wt, uv0));
//outStream.Append(VertexOutput(wp4, wn, wt, uv1));
//outStream.Append(VertexOutput(wp1, wn, wt, uv1));
//outStream.RestartStrip();
//
//wn = ConstructNormal(wp4, wp1, wp5);
//outStream.Append(VertexOutput(wp4, wn, wt, uv1));
//outStream.Append(VertexOutput(wp1, wn, wt, uv1));
//outStream.Append(VertexOutput(wp5, wn, wt, uv2));
//outStream.Append(VertexOutput(wp2, wn, wt, uv2));
//outStream.RestartStrip();
//
//wn = ConstructNormal(wp5, wp2, wp3);
//outStream.Append(VertexOutput(wp5, wn, wt, uv2));
//outStream.Append(VertexOutput(wp2, wn, wt, uv2));
//outStream.Append(VertexOutput(wp3, wn, wt, uv0));
//outStream.Append(VertexOutput(wp0, wn, wt, uv0));
//outStream.RestartStrip();
}
//
// Fragment phase
//
#if defined(PASS_CUBE_SHADOWCASTER)
// Cube map shadow caster pass
half4 Fragment(Varyings input) : SV_Target {
float depth = length(input.shadow) + unity_LightShadowBias.x;
return UnityEncodeCubeShadowDepth(depth * _LightPositionRange.w);
}
#elif defined(UNITY_PASS_SHADOWCASTER)
// Default shadow caster pass
half4 Fragment() : SV_Target { return 0; }
#else
float _AlphaCutoff;
// GBuffer construction pass
void Fragment( Varyings input, out half4 outGBuffer0 : SV_Target0, out half4 outGBuffer1 : SV_Target1, out half4 outGBuffer2 : SV_Target2, out half4 outEmission : SV_Target3) {
// Sample textures
float4 sample = tex2D(_MainTex, input.texcoord);
if(sample.a <= _AlphaCutoff) clip(-1);
half3 albedo = sample.rgb * _Color.rgb;
half4 normal = tex2D(_BumpMap, input.texcoord);
normal.xyz = UnpackScaleNormal(normal, _BumpScale);
half occ = tex2D(_OcclusionMap, input.texcoord).g;
occ = LerpOneTo(occ, _OcclusionStrength);
// PBS workflow conversion (metallic -> specular)
half3 c_diff, c_spec;
half refl10;
c_diff = DiffuseAndSpecularFromMetallic(
albedo, _Metallic, // input
c_spec, refl10 // output
);
// Tangent space conversion (tangent space normal -> world space normal)
float3 wn = normalize(float3( dot(input.tspace0.xyz, normal), dot(input.tspace1.xyz, normal), dot(input.tspace2.xyz, normal) ));
// Update the GBuffer.
UnityStandardData data;
data.diffuseColor = c_diff;
data.occlusion = occ;
data.specularColor = c_spec;
data.smoothness = _Glossiness;
data.normalWorld = wn;
UnityStandardDataToGbuffer(data, outGBuffer0, outGBuffer1, outGBuffer2);
// Calculate ambient lighting and output to the emission buffer.
float3 wp = float3(input.tspace0.w, input.tspace1.w, input.tspace2.w);
half3 sh = ShadeSHPerPixel(data.normalWorld, input.ambient, wp);
outEmission = half4(sh * c_diff, 1) * occ;
}
#endif

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 1828c58b5b8ba824296cee46b4d55d78
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,86 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: GrassMaterial
m_Shader: {fileID: 4800000, guid: db7b361255b6374438781f932dd1e8e0, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 1
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 527cea5a6b017984894d91563b2bdefb, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _WindTexture:
m_Texture: {fileID: 2800000, guid: 5e187697202a0ca4f80836a911eb0633, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AlphaCutoff: 0.948
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 1
- _GlossyReflections: 1
- _HeightStart: 0.86
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _WindStrength: 0.5
- _WindTimeSpeed: 0.02
- _ZWrite: 1
m_Colors:
- _Color: {r: 0.8343865, g: 0.8584906, b: 0.75725347, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _WindSpeed: {r: 100, g: 100, b: 1, a: 1}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7703a0bcaa149214693ccf4e5154e464
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,110 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: GrassShader
m_Shader: {fileID: 4800000, guid: 83a3afa28b3f4da48981ac72df1bc398, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 527cea5a6b017984894d91563b2bdefb, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AlphaCutoff: 0.297
- _BendRotationRandom: 0
- _BladeHeight: 1.87
- _BladeHeightRandom: 0.2
- _BladeWidth: 0.6
- _BladeWidthRandom: 0.2
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailBumpScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0
- _GlossyReflections: 1
- _LocalTime: 0
- _Metallic: 0.917
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _ParallaxStrength: 0
- _Smoothness: 0.1
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _TessellationEdgeLength: 32.5
- _TessellationUniform: 17.7
- _Test: 6.63
- _UVSec: 0
- _WindQuality: 0
- _WireframeSmoothing: 1
- _WireframeThickness: 0
- _ZWrite: 1
m_Colors:
- _BottomCol: {r: 0, g: 0, b: 0, a: 1}
- _Color: {r: 0.8808059, g: 1, b: 0.514151, a: 1}
- _Emission: {r: 0, g: 0, b: 0, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _HueVariation: {r: 1, g: 0.5, b: 0, a: 0.1}
- _TopCol: {r: 0, g: 0.990566, b: 0.1815736, a: 1}
- _WireframeColor: {r: 0, g: 0, b: 0, a: 1}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3ab8ff7b784eb34449b2a9c40a0df1d3
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,79 @@
// Standard geometry shader example
// https://github.com/keijiro/StandardGeometryShader
Shader "DBV/Kristo/GrassShader"
{
Properties
{
_Color("Color", Color) = (1, 1, 1, 1)
_MainTex("Albedo", 2D) = "white" {}
[Space]
_Glossiness("Smoothness", Range(0, 1)) = 0.5
[Gamma] _Metallic("Metallic", Range(0, 1)) = 0
[Space]
_BumpMap("Normal Map", 2D) = "bump" {}
_BumpScale("Scale", Float) = 1
[Space]
_OcclusionMap("Occlusion Map", 2D) = "white" {}
_OcclusionStrength("Strength", Range(0, 1)) = 1
[Space]
_LocalTime("Animation Time", Float) = 0.0
[Space]
_BendRotationRandom("Bend Rotation Random", Range(0, 1)) = 0.2
[Space]
_BladeWidth("Blade Width", Float) = 0.05
_BladeWidthRandom("Blade Width Random", Float) = 0.02
_BladeHeight("Blade Height", Float) = 0.5
_BladeHeightRandom("Blade Height Random", Float) = 0.3
[Space]
_AlphaCutoff ("Alpha cutoff", Range(0,1)) = 0.05
_Test ("_Test", Range(0,10)) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
// This shader only implements the deferred rendering pass (GBuffer
// construction) and the shadow caster pass, so that it doesn't
// support forward rendering.
Pass
{
Tags { "LightMode"="Deferred" }
Cull Off
CGPROGRAM
#pragma target 5.0
#pragma vertex Vertex
#pragma geometry Geometry
#pragma fragment Fragment
#pragma multi_compile_prepassfinal noshadowmask nodynlightmap nodirlightmap nolightmap
#include "GrassGeometry.cginc"
ENDCG
}
//Pass
//{
// Tags { "LightMode"="ShadowCaster" }
// Cull Off
// CGPROGRAM
// #pragma target 5.0
// #pragma vertex Vertex
// #pragma geometry Geometry
// #pragma fragment Fragment
// #pragma multi_compile_shadowcaster noshadowmask nodynlightmap nodirlightmap nolightmap
// #define UNITY_PASS_SHADOWCASTER
// #include "GrassGeometry.cginc"
// ENDCG
//}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 83a3afa28b3f4da48981ac72df1bc398
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,138 @@
Shader "Unlit/GrassShaderLearn"
{
Properties {
_MainTex ("Texture", 2D) = "white" {}
_Color ("Color", COlor) = (1,1,1,1)
_BottomCol ("Bottom", COlor) = (1,1,1,1)
_TopCol ("Top", COlor) = (1,1,1,1)
_BendRotationRandom("Bend Rotation Random", Range(0, 1)) = 0.2
_BladeWidth("Blade Width", Float) = 0.05
_BladeWidthRandom("Blade Width Random", Float) = 0.02
_BladeHeight("Blade Height", Float) = 0.5
_BladeHeightRandom("Blade Height Random", Float) = 0.3
_TessellationUniform("Tessellation Uniform", Range(1, 64)) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma geometry geo
//#pragma hull hull
//#pragma domain domain
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
//#include "Shaders/CustomTessellation.cginc"
struct appdata
{
float2 uv : TEXCOORD0;
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
};
struct v2f
{
float2 uv : TEXCOORD0;
//UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
};
struct geometryOutput {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
geometryOutput VertexOutput(float3 pos, float2 uv){
geometryOutput o;
o.pos = UnityObjectToClipPos(pos);
o.uv = uv;
return o;
}
float rand(float3 co){
return frac(sin(dot(co.xyz, float3(12.9898, 78.233, 53.539))) * 43758.5453);
}
float3x3 AngleAxis3x3(float angle, float3 axis){
float c, s;
sincos(angle, s, c);
float t = 1 - c;
float x = axis.x;
float y = axis.y;
float z = axis.z;
return float3x3(
t * x * x + c, t * x * y - s * z, t * x * z + s * y,
t * x * y + s * z, t * y * y + c, t * y * z - s * x,
t * x * z - s * y, t * y * z + s * x, t * z * z + c
);
}
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color, _BottomCol, _TopCol;
float _BendRotationRandom;
float _BladeHeight;
float _BladeHeightRandom;
float _BladeWidth;
float _BladeWidthRandom;
v2f vert (appdata v) {
v2f o;
o.vertex = v.vertex;//UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.normal = v.normal;
o.tangent = v.tangent;
//UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
[maxvertexcount(3)]
void geo(triangle v2f IN[3] : SV_POSITION, inout TriangleStream<geometryOutput> triStream) {
float3 pos = IN[0].vertex;
float3 vNormal = IN[0].normal;
float4 vTangent = IN[0].tangent;
float3 vBinormal = cross (vNormal,vTangent)*vTangent.w;
float height = (rand(pos.zyx) * 2 - 1) * _BladeHeightRandom + _BladeHeight;
float width = (rand(pos.xzy) * 2 - 1) * _BladeWidthRandom + _BladeWidth;
float3x3 tangentToLocal = float3x3(
vTangent.x, vBinormal.x, vNormal.x,
vTangent.y, vBinormal.y, vNormal.y,
vTangent.z, vBinormal.z, vNormal.z
);
float3x3 facingRotationMatrix = AngleAxis3x3(rand(pos) * UNITY_TWO_PI, float3(0, 0, 1));
float3x3 bendRotationMatrix = AngleAxis3x3(rand(pos.zzx) * _BendRotationRandom * UNITY_PI * 0.5, float3(-1, 0, 0));
float3x3 transformationMatrix = mul(mul(tangentToLocal, facingRotationMatrix),bendRotationMatrix);
triStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(width, 0, 0 )), float2(0 ,0) ));
triStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(-width, 0, 0)), float2(1 ,0) ));
triStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(height, 0, 1 )), float2(0.5,1) ));
}
fixed4 frag (geometryOutput i) : SV_Target {
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv) * _Color;
// apply fog
//UNITY_APPLY_FOG(i.fogCoord, col);
return lerp(_BottomCol, _TopCol, i.uv.y) * _Color;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 115182574462e9e45a2a9fa02a849aa2
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,124 @@
Shader "DBV/Kristo/InstancedGrassShader"
{
Properties {
_MainTex("Albedo (RGB)", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
[Space]
_ColorA("Color A", Color) = (1,1,1,1)
_ColorB("Color B", Color) = (1,1,1,1)
[Space]
_AlphaCutoff ("Alpha cutoff", Range(0,1)) = 0.05
}
SubShader
{
Tags { "RenderType"="Instanced" }
LOD 200
Cull Off
CGPROGRAM
#pragma surface surf Standard vertex:vert //addshadow
#pragma multi_compile_instancing
#pragma instancing_options procedural:setup
#pragma target 4.5
sampler2D _MainTex;
struct Input{
float2 uv_MainTex;
};
struct GrassElement {
float3 position;
float rotation;
float size;
float colorBlend;//0-1
};
//Note
//StructuredBuffers are good when there are loads of data that needs to be read at different places by different threads
//Constant buffers are good when there isent too much data and threads read the same data
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
StructuredBuffer<GrassElement> grassBuffer;
#endif
//https://forum.unity.com/threads/rotating-mesh-in-vertex-shader.501709/
float3x3 YRotationMatrix(float degrees) {
float alpha = degrees * UNITY_PI / 180.0;
float sina, cosa;
sincos(alpha, sina, cosa);
return float3x3(
cosa, 0, -sina,
0, 1, 0,
sina, 0, cosa);
}
//USAGE: pos.xyz = mul(YRotationMatrix(degrees),pos.xyz);
void rotate2D(inout float2 v, float r) {
float s, c;
sincos(r, s, c);
v = float2(v.x * c - v.y * s, v.x * s + v.y * c);
}
half _Glossiness;
half _Metallic;
fixed4 _ColorA, _ColorB;
float _AlphaCutoff;
void setup () {
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
GrassElement data = grassBuffer[unity_InstanceID];
//Scale the mesh
unity_ObjectToWorld._11_21_31_41 = float4(data.size, 0, 0, 0);
unity_ObjectToWorld._12_22_32_42 = float4(0, data.size, 0, 0);
unity_ObjectToWorld._13_23_33_43 = float4(0, 0, data.size, 0);
//position the mesh
unity_ObjectToWorld._14_24_34_44 = float4(data.position.xyz, 1);
//No idea what this does
unity_WorldToObject = unity_ObjectToWorld;
unity_WorldToObject._14_24_34 *= -1;
unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
#endif
}
void vert (inout appdata_full v) {
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
GrassElement data = grassBuffer[unity_InstanceID];
//Rotate
v.vertex.xyz = mul(YRotationMatrix(data.rotation),v.vertex);
#endif
}
void surf (Input IN, inout SurfaceOutputStandard o) {
//Clip the grass
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
clip(c.a - _AlphaCutoff);
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
GrassElement data = grassBuffer[unity_InstanceID];
float blend = data.colorBlend;
fixed4 col = blend * _ColorA + (1-blend) * _ColorB;
#else
fixed4 col = _ColorA;
#endif
// Albedo comes from a texture tinted by color
c = c * col;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 1743210f01f7ba843bb566086818c652
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,58 @@
Shader "Unlit/NewUnlitShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: dd51a02f82d912148a47f1383511f846
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: NormalMat
m_Shader: {fileID: 4800000, guid: d81e5fd7a7a2c874d821bd6d5adfc5cd, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.225
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _FadeDistance: 10
- _FadeSmooth: 1
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _BackFaceColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _FadeColor: {r: 1, g: 1, b: 1, a: 1}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9363e008b0ee6e2458f8fcacdad04a8b
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
Shader "Unlit/NormalShader"
{
Properties
{
_Cutoff ("Threshold", Range(0,1)) = 0.5
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float3 normalWorld : TEXCOORD1;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
float _Cutoff;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.normalWorld = normalize( mul( float4( v.normal, 0.0 ), unity_WorldToObject ).xyz );
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
clip( dot(i.normalWorld, float3(0,1,0)) - _Cutoff );
// apply fog bc why not
UNITY_APPLY_FOG(i.fogCoord, col);
return half4(0,1,0,1);
}
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: d81e5fd7a7a2c874d821bd6d5adfc5cd
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,175 @@
Shader "Hidden/OcclusionReplacementShader"
{
SubShader {
Tags {
"RenderType"="Opaque"
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
};
struct v2f {
float4 vertex : SV_POSITION;
};
v2f vert (appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target {
return half4(0,0,0,1);
}
ENDCG
}
}
SubShader {
Tags {
"RenderType"="CullHighlightOne"
}
ZWrite Off
Cull Off
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _CameraDepthTexture;
sampler2D _MainTex;
float4 _MainTex_ST;
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float4 screenPos : TEXCOORD1;
float2 depth : TEXCOORD2;
float dist : TEXCOORD3;
};
v2f vert (appdata v) {
v2f o;
o.vertex = mul(UNITY_MATRIX_MV, v.vertex);
//o.depth = o.vertex.z;
o.vertex = mul(UNITY_MATRIX_P, o.vertex);
//UNITY_TRANSFER_DEPTH(o.depth);
//o.screenPos = ComputeScreenPos(o.vertex);
o.dist = distance(_WorldSpaceCameraPos, mul(unity_ObjectToWorld, v.vertex) );
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
half4 frag (v2f i) : COLOR {
//float depth = saturate(-0.005f * i.depth);//(i.depth) / _ProjectionParams.z;
float depth = i.dist/_ProjectionParams.z;//SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos)).r;
//depth = Linear01Depth(depth);
//depth = Linear01Depth(depth)* _ProjectionParams.z;
return half4(1-depth,0,depth,1-depth);
//UNITY_OUTPUT_DEPTH(i.depth);
}
ENDCG
}
}
/*
SubShader {
Tags {
"RenderType"="CullHighlightTwo"
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _CameraDepthTexture;
sampler2D _MainTex;
float4 _MainTex_ST;
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target {
float depth = tex2D(_CameraDepthTexture,i.uv).r;
depth = Linear01Depth(depth)* _ProjectionParams.z;
return half4(0,1,0,depth);
}
ENDCG
}
}
SubShader {
Tags {
"RenderType"="CullHighlightThree"
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _CameraDepthTexture;
sampler2D _MainTex;
float4 _MainTex_ST;
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target {
float depth = tex2D(_CameraDepthTexture,i.uv).r;
depth = Linear01Depth(depth)* _ProjectionParams.z;
return half4(0,0,1,depth);
}
ENDCG
}
}
*/
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0de689ec91fac7540954eb71df6af20b
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
Shader "DBV/Kristo/OcclusionStandardShader"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags {
"RenderType"="CullHighlightOne"
}
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 6a1b07d3a30e63845b1f8510cafda92b
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &7082488895860155134
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6057719699220877549}
- component: {fileID: 2975279872206531291}
- component: {fileID: 8824478207646799394}
m_Layer: 0
m_Name: SingleGrass
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 22
m_IsActive: 1
--- !u!4 &6057719699220877549
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7082488895860155134}
m_LocalRotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071067}
m_LocalPosition: {x: 71.13544, y: 34.075233, z: 26.2224}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &2975279872206531291
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7082488895860155134}
m_Mesh: {fileID: -5495902117074765545, guid: 37a17204eeb420948a913b69143253af, type: 3}
--- !u!23 &8824478207646799394
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7082488895860155134}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 7703a0bcaa149214693ccf4e5154e464, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0dba6d7333783064f957dab4a9660a05
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2a23a82050951cf40a7e12d22566dc1a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4de32985296057e45bdf6a6d33d53d19
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,185 @@
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
Shader "DBV/Kristo/InstancedConsumeGrassShader"
{
Properties {
_MainTex("Main tex", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
[Space]
_ColorA("Color A", Color) = (1,1,1,1)
_ColorB("Color B", Color) = (1,1,1,1)
[Space]
_Size("Size",float) = 1
_Height("Height",float) = 1
[Space]
_WindTex("Wind tex", 2D) = "grey" {}
_WindAmount("Wind strength", float) = 1
_WindSize("Wind size", float) = 1
_WindSpeed("Wind speed", float) = 1
[Space]
_AlphaCutoff ("Alpha cutoff", Range(0,1)) = 0.05
_DitherTex ("Dither tex.", 2D) = "white" {}
fadeStartDist ("Fade start",float) = 1
fadeEndDist ("Fade end",float) = 1
}
SubShader
{
Tags { "RenderType"="Instanced" }
LOD 200
Cull Off
//ZWrite Off
CGPROGRAM
#pragma surface surf BlinnPhong vertex:vert noshadowmask nodynlightmap nodirlightmap nolightmap noshadow
#pragma multi_compile_instancing
#pragma instancing_options procedural:setup
#pragma target 4.5
sampler2D _MainTex, _DitherTex, _WindTex;
fixed4 _DitherTex_TexelSize, _WindTex_TexelSize;
struct Input{
float2 uv_MainTex;
float4 screenPos;
float3 worldPos;
};
struct GrassElement {
float3 position;
float rotation;
float size;
float colorBlend;//0-1
};
struct custom_appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
float4 texcoord2 : TEXCOORD2;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
//Note
//StructuredBuffers are good when there are loads of data that needs to be read at different places by different threads
//Constant buffers are good when there isent too much data and threads read the same dat
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
StructuredBuffer<GrassElement> grassBuffer;
StructuredBuffer<uint> inGrassBuffer;//ConsumeStructuredBuffer<uint> inGrassBuffer;
#endif
//https://forum.unity.com/threads/rotating-mesh-in-vertex-shader.501709/
float3x3 YRotationMatrix(float degrees) {
float alpha = degrees * UNITY_PI / 180.0;
float sina, cosa;
sincos(alpha, sina, cosa);
return float3x3(
cosa, 0, -sina,
0, 1, 0,
sina, 0, cosa);
}
//USAGE: pos.xyz = mul(YRotationMatrix(degrees),pos.xyz);
//void rotate2D(inout float2 v, float r) {
// float s, c;
// sincos(r, s, c);
// v = float2(v.x * c - v.y * s, v.x * s + v.y * c);
// }
half _Glossiness;
half _Metallic;
fixed4 _ColorA, _ColorB;
float _AlphaCutoff, _Size, _Height;
float fadeStartDist, fadeEndDist, _WindAmount, _WindSize, _WindSpeed;
//float3 pos;
float colorBlend;
float rotationInDegrees;
void setup () {
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
uint index = inGrassBuffer[unity_InstanceID];//inGrassBuffer.Consume();//Consume buffer is not working at all for some reason
GrassElement data = grassBuffer[index];//unity_InstanceID
//save data
float3 pos = data.position.xyz;
colorBlend = data.colorBlend;
rotationInDegrees = data.rotation;
//Scale the mesh
float size = _Size * data.size;
unity_ObjectToWorld._11_21_31_41 = float4(size, 0, 0, 0);
unity_ObjectToWorld._12_22_32_42 = float4(0, size*_Height, 0, 0);
unity_ObjectToWorld._13_23_33_43 = float4(0, 0, size, 0);
//position the mesh
unity_ObjectToWorld._14_24_34_44 = float4(pos, 1);
//No idea what this does but it must be important
unity_WorldToObject = unity_ObjectToWorld;
unity_WorldToObject._14_24_34 *= -1;
unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
#else
//pos = float3(0,2,0);
colorBlend = 0.5;
rotationInDegrees = 45;
#endif
}
void vert (inout custom_appdata v) {
//Rotate
v.vertex.xyz = mul(YRotationMatrix(rotationInDegrees),v.vertex);
//Do wind
float vertexHeight = v.vertex.y;
float3 worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
float2 windCoord = (worldPos.xz)*_WindSize + (_Time.yy)*_WindSpeed;
float3 wind = (tex2Dlod(_WindTex,float4(windCoord.xy,0,0)*2 - 1 )).xyz * _WindAmount;//tex2D(_WindTex, windCoord).rgb * vertexHeight;
v.vertex.xyz += float3(wind.x-0.5,0,wind.z) * vertexHeight;
}
void surf (Input IN, inout SurfaceOutput o) {
//Get color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
//Do cutout
clip(c.a - _AlphaCutoff);
//Do dithering
float2 screenPos = IN.screenPos.xy / IN.screenPos.w;
float2 ditherCoord = screenPos * _ScreenParams.xy * _DitherTex_TexelSize.xy;
float ditherAmount = tex2D(_DitherTex, ditherCoord).r;
float distToCamera = distance(IN.worldPos, _WorldSpaceCameraPos);
if(distToCamera > fadeStartDist) {
float ditherRange = 1 - saturate((distToCamera-fadeStartDist)/(fadeEndDist-fadeStartDist));
clip(ditherRange - ditherAmount);
}
//Do blending
fixed4 col = colorBlend * _ColorA + (1-colorBlend) * _ColorB;
// Albedo comes from a texture tinted by color
c = c * col;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
//o.Metallic = _Metallic;
//o.Smoothness = _Glossiness;
//o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: d423e3e229bf71743b583d87c24d1a0f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,141 @@
Shader "DBV/Kristo/InstancedGrassShader"
{
Properties {
_MainTex("Albedo (RGB)", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
[Space]
_ColorA("Color A", Color) = (1,1,1,1)
_ColorB("Color B", Color) = (1,1,1,1)
[Space]
_Size("Size",float) = 1
[Space]
_AlphaCutoff ("Alpha cutoff", Range(0,1)) = 0.05
}
SubShader
{
Tags { "RenderType"="Instanced" }
LOD 200
Cull Off
CGPROGRAM
#pragma surface surf Standard vertex:vert //addshadow
#pragma multi_compile_instancing
#pragma instancing_options procedural:setup lodfade
#pragma target 4.5
sampler2D _MainTex;
struct Input{
float2 uv_MainTex;
};
struct GrassElement {
float3 position;
float rotation;
float size;
float colorBlend;//0-1
};
struct custom_appdata {
float4 vertex : POSITION;
//float4 tangent : TANGENT;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
float4 texcoord2 : TEXCOORD2;
//float4 texcoord3 : TEXCOORD3;
//fixed4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
//Note
//StructuredBuffers are good when there are loads of data that needs to be read at different places by different threads
//Constant buffers are good when there isent too much data and threads read the same data
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
StructuredBuffer<GrassElement> grassBuffer;
#endif
//https://forum.unity.com/threads/rotating-mesh-in-vertex-shader.501709/
float3x3 YRotationMatrix(float degrees) {
float alpha = degrees * UNITY_PI / 180.0;
float sina, cosa;
sincos(alpha, sina, cosa);
return float3x3(
cosa, 0, -sina,
0, 1, 0,
sina, 0, cosa);
}
//USAGE: pos.xyz = mul(YRotationMatrix(degrees),pos.xyz);
void rotate2D(inout float2 v, float r) {
float s, c;
sincos(r, s, c);
v = float2(v.x * c - v.y * s, v.x * s + v.y * c);
}
half _Glossiness;
half _Metallic;
fixed4 _ColorA, _ColorB;
float _AlphaCutoff, _Size;
void setup () {
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
GrassElement data = grassBuffer[unity_InstanceID];
//Scale the mesh
float size = _Size * data.size;
unity_ObjectToWorld._11_21_31_41 = float4(size, 0, 0, 0);
unity_ObjectToWorld._12_22_32_42 = float4(0, size, 0, 0);
unity_ObjectToWorld._13_23_33_43 = float4(0, 0, size, 0);
//position the mesh
unity_ObjectToWorld._14_24_34_44 = float4(data.position.xyz, 1);
//No idea what this does
unity_WorldToObject = unity_ObjectToWorld;
unity_WorldToObject._14_24_34 *= -1;
unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
#endif
}
void vert (inout custom_appdata v) {
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
GrassElement data = grassBuffer[unity_InstanceID];
//Rotate
v.vertex.xyz = mul(YRotationMatrix(data.rotation),v.vertex);
#endif
}
void surf (Input IN, inout SurfaceOutputStandard o) {
//Clip the grass
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
clip(c.a - _AlphaCutoff);
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
GrassElement data = grassBuffer[unity_InstanceID];
float blend = data.colorBlend;
fixed4 col = blend * _ColorA + (1-blend) * _ColorB;
#else
fixed4 col = _ColorA;
#endif
// Albedo comes from a texture tinted by color
c = c * col;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 02f353f6dc231064c9224e1bde0fd751
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,103 @@
fileFormatVersion: 2
guid: 5e187697202a0ca4f80836a911eb0633
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 10
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 0
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
How to bake grass?
1. Make a grass layouy mesh (see Grass_Model for example)
- Grass maker will use each of the models triangles to place grass on top of
2. Give Grass_Baker the referencte to gameobject with the correct model
3. Press "Generate" on Grass_Baker
Future improvements:
1. Cull nonvisible grass blades
2. Convert farther grassblades to billboards

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c0db162189b453f41830d9b83ef83959
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: