Add LOD 3
This commit is contained in:
parent
f5de2988d0
commit
dce3637ad6
31
Assets/Materials/Grass LOD 3.mat
Normal file
31
Assets/Materials/Grass LOD 3.mat
Normal file
@ -0,0 +1,31 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Grass LOD 3
|
||||
m_Shader: {fileID: 4800000, guid: eebe2969663fc40449d6052c661a6c2e, type: 3}
|
||||
m_Parent: {fileID: 2100000, guid: 1cd7df4d77cf1ae40ad59a15c2769be9, type: 2}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords:
|
||||
- _LOD_LOD_3
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs: []
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _LOD: 3
|
||||
m_Colors: []
|
||||
m_BuildTextureStacks: []
|
||||
8
Assets/Materials/Grass LOD 3.mat.meta
Normal file
8
Assets/Materials/Grass LOD 3.mat.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b747ca32ff9b8ee408e794d093cbdd54
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -33,4 +33,5 @@ Material:
|
||||
- _Color0: {r: 0.5882353, g: 1, b: 0.5882353, a: 1}
|
||||
- _Color1: {r: 1, g: 0.8209069, b: 0.495283, a: 1}
|
||||
- _Color2: {r: 1, g: 0.49831352, b: 0.21226418, a: 1}
|
||||
- _Color3: {r: 0.7075472, g: 0.15018693, b: 0.15018693, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -4,6 +4,7 @@ using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(GrassField))]
|
||||
public class GrassFieldEditor : Editor {
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
public override void OnInspectorGUI() {
|
||||
base.OnInspectorGUI();
|
||||
|
||||
@ -14,5 +15,9 @@ public class GrassFieldEditor : Editor {
|
||||
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Update LODs")) {
|
||||
((GrassField) target).UpdateLODsAndMaterials();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,6 +84,33 @@ public class GrassChunk : MonoBehaviour {
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private Material _materialLOD3;
|
||||
public Material MaterialLOD3 {
|
||||
get { return _materialLOD3; }
|
||||
set {
|
||||
_materialLOD3 = value;
|
||||
UpdateLODAssets();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private Mesh _meshLOD3;
|
||||
public Mesh MeshLOD3 {
|
||||
get { return _meshLOD3; }
|
||||
set {
|
||||
_meshLOD3 = value;
|
||||
UpdateLODAssets();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private bool _enableShadowsLOD3;
|
||||
public bool EnableShadowsLOD3 {
|
||||
get { return _enableShadowsLOD3; }
|
||||
set {
|
||||
_enableShadowsLOD3 = value;
|
||||
UpdateLODAssets();
|
||||
}
|
||||
}
|
||||
|
||||
private int _lod;
|
||||
public int LOD {
|
||||
get { return _lod; }
|
||||
@ -134,6 +161,14 @@ public class GrassChunk : MonoBehaviour {
|
||||
MeshRenderer.shadowCastingMode = EnableShadowsLOD2 ? ShadowCastingMode.On : ShadowCastingMode.Off;
|
||||
MeshFilter.sharedMesh = _meshLOD2;
|
||||
break;
|
||||
case 3:
|
||||
MeshRenderer.sharedMaterial = _materialLOD3;
|
||||
MeshRenderer.shadowCastingMode = EnableShadowsLOD3 ? ShadowCastingMode.On : ShadowCastingMode.Off;
|
||||
MeshFilter.sharedMesh = _meshLOD3;
|
||||
break;
|
||||
default:
|
||||
Debug.LogError("ehm?");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ using UnityEngine;
|
||||
|
||||
public class GrassField : MonoBehaviour {
|
||||
public int size = 100;
|
||||
public int numChunks = 10;
|
||||
public int numChunks = 20;
|
||||
public int bladesPerMeter = 100;
|
||||
public GrassChunk chunkPrefab;
|
||||
public bool ignoreHeightForLOD = true;
|
||||
@ -18,10 +18,15 @@ public class GrassField : MonoBehaviour {
|
||||
[Range(0f, 1f)] public float densityLOD1 = 0.5f;
|
||||
public bool enableShadowsLOD1 = true;
|
||||
[Header("LOD 2")]
|
||||
public float distanceLOD2 = 5f + (100f / 10f) * SQRT_2 + 3f;
|
||||
public float distanceLOD2 = 15f;
|
||||
public Material grassMaterialLOD2;
|
||||
[Range(0f, 1f)] public float densityLOD2 = 0.2f;
|
||||
[Range(0f, 1f)] public float densityLOD2 = 0.25f;
|
||||
public bool enableShadowsLOD2 = false;
|
||||
[Header("LOD 3")]
|
||||
public float distanceLOD3 = 25f;
|
||||
public Material grassMaterialLOD3;
|
||||
[Range(0f, 1f)] public float densityLOD3 = 0.125f;
|
||||
public bool enableShadowsLOD3 = false;
|
||||
|
||||
private const float SQRT_2 = 1.4142135623730f;
|
||||
private static readonly int pId_WorldSpaceCameraPosEditor = Shader.PropertyToID("_WorldSpaceCameraPosEditor");
|
||||
@ -31,19 +36,24 @@ public class GrassField : MonoBehaviour {
|
||||
// serialize it, because the chunks are generated offline and used during runtime
|
||||
[SerializeField, HideInInspector] private GrassChunk[] _chunks;
|
||||
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
public void GenerateGrassField() {
|
||||
Debug.Log("Generating grass field... ");
|
||||
var bladesLOD0 = GrassMeshGeneration.GenerateBladesRandom(
|
||||
size, size * size * (int)(bladesPerMeter * densityLOD0)
|
||||
);
|
||||
// var bladesLOD1 = GenerateBladesRandom(size, size * size * (int)(bladesPerMeter * densityLOD1));
|
||||
// var bladesLOD2 = GenerateBladesRandom(size, size * size * (int)(bladesPerMeter * densityLOD2));
|
||||
var bladesLOD1 = GrassMeshGeneration.GenerateBladesReduced(bladesLOD0, densityLOD1);
|
||||
var bladesLOD2 = GrassMeshGeneration.GenerateBladesReduced(bladesLOD1, densityLOD2 / densityLOD1);
|
||||
CreateChunks(bladesLOD0, bladesLOD1, bladesLOD2);
|
||||
var bladesLOD3 = GrassMeshGeneration.GenerateBladesReduced(bladesLOD2, densityLOD3 / densityLOD2);
|
||||
CreateChunks(bladesLOD0, bladesLOD1, bladesLOD2, bladesLOD3);
|
||||
|
||||
Debug.Log("Generating grass field done");
|
||||
var camPosWorld = Camera.main ? Camera.main.transform.position : Vector3.zero;
|
||||
UpdateLODs(camPosWorld);
|
||||
UpdateMaterials(camPosWorld);
|
||||
}
|
||||
|
||||
public void UpdateLODsAndMaterials() {
|
||||
var camPosWorld = Camera.main ? Camera.main.transform.position : Vector3.zero;
|
||||
UpdateMaterials(camPosWorld);
|
||||
UpdateLODs(camPosWorld);
|
||||
}
|
||||
|
||||
private void OnEnable() {
|
||||
@ -52,6 +62,10 @@ public class GrassField : MonoBehaviour {
|
||||
if (distanceLOD2 < minDistLOD2) {
|
||||
Debug.LogWarning("It is recommended that minDistLOD2 is greater than " + minDistLOD2 + ".");
|
||||
}
|
||||
var minDistLOD3 = distanceLOD2 + chunkSize * SQRT_2;
|
||||
if (distanceLOD3 < minDistLOD3) {
|
||||
Debug.LogWarning("It is recommended that minDistLOD3 is greater than " + minDistLOD3 + ".");
|
||||
}
|
||||
|
||||
if (_chunks.Length != numChunks * numChunks) {
|
||||
Debug.LogError(this.name + ": Existing chunks does not match numChunks.");
|
||||
@ -60,21 +74,16 @@ public class GrassField : MonoBehaviour {
|
||||
}
|
||||
|
||||
private void OnDisable() {
|
||||
var camPosWorld = Camera.main ? Camera.main.transform.position : Vector3.zero;
|
||||
UpdateMaterials(camPosWorld);
|
||||
UpdateLODs(camPosWorld);
|
||||
UpdateLODsAndMaterials();
|
||||
}
|
||||
|
||||
private void OnValidate() {
|
||||
var camPosWorld = Camera.main ? Camera.main.transform.position : Vector3.zero;
|
||||
UpdateMaterials(camPosWorld);
|
||||
}
|
||||
|
||||
private void Update() {
|
||||
private void FixedUpdate() {
|
||||
var cam = Camera.main;
|
||||
if (!cam) return;
|
||||
var camPosWorld = cam.transform.position;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// update LOD distances and camera position
|
||||
UpdateMaterials(camPosWorld);
|
||||
#endif
|
||||
|
||||
@ -105,7 +114,10 @@ public class GrassField : MonoBehaviour {
|
||||
var localCamPos = camPos - chunkPos; // cam position relative to chunk
|
||||
|
||||
var sqrCamDist = bounds.SqrDistance(localCamPos);
|
||||
if (sqrCamDist > distanceLOD2 * distanceLOD2) {
|
||||
if (sqrCamDist > distanceLOD3 * distanceLOD3) {
|
||||
_chunks[x + y * numChunks].LOD = 3;
|
||||
}
|
||||
else if (sqrCamDist > distanceLOD2 * distanceLOD2) {
|
||||
_chunks[x + y * numChunks].LOD = 2;
|
||||
}
|
||||
else if (sqrCamDist > distanceLOD1 * distanceLOD1) {
|
||||
@ -128,10 +140,10 @@ public class GrassField : MonoBehaviour {
|
||||
GridRange range;
|
||||
|
||||
var maxCamMove = 3f; // assume that the camera did not move further than this distance
|
||||
var fromXWorld = camPos.x - distanceLOD2 - maxCamMove;
|
||||
var toXWorld = camPos.x + distanceLOD2 + maxCamMove;
|
||||
var fromZWorld = camPos.z - distanceLOD2 - maxCamMove;
|
||||
var toZWorld = camPos.z + distanceLOD2 + maxCamMove;
|
||||
var fromXWorld = camPos.x - distanceLOD3 - maxCamMove;
|
||||
var toXWorld = camPos.x + distanceLOD3 + maxCamMove;
|
||||
var fromZWorld = camPos.z - distanceLOD3 - maxCamMove;
|
||||
var toZWorld = camPos.z + distanceLOD3 + maxCamMove;
|
||||
|
||||
range.fromX = Math.Max( 0, (int) (fromXWorld / chunkSize) );
|
||||
range.toX = Math.Max( 0, (int) (toXWorld / chunkSize) );
|
||||
@ -153,8 +165,11 @@ public class GrassField : MonoBehaviour {
|
||||
var transition0To = distanceLOD1;
|
||||
var transition1From = transition0To + chunkDiagonalLength;
|
||||
var transition1To = distanceLOD2;
|
||||
var transition2From = transition1To + chunkDiagonalLength;
|
||||
var transition2To = distanceLOD3;
|
||||
grassMaterialLOD0.SetVector(pId_TransitionRange, new Vector2(transition0From, transition0To));
|
||||
grassMaterialLOD1.SetVector(pId_TransitionRange, new Vector2(transition1From, transition1To));
|
||||
grassMaterialLOD2.SetVector(pId_TransitionRange, new Vector2(transition2From, transition2To));
|
||||
#if UNITY_EDITOR
|
||||
if (ignoreHeightForLOD) {
|
||||
camPosWorld.y = 0;
|
||||
@ -162,10 +177,13 @@ public class GrassField : MonoBehaviour {
|
||||
grassMaterialLOD0.SetVector(pId_WorldSpaceCameraPosEditor, camPosWorld);
|
||||
grassMaterialLOD1.SetVector(pId_WorldSpaceCameraPosEditor, camPosWorld);
|
||||
grassMaterialLOD2.SetVector(pId_WorldSpaceCameraPosEditor, camPosWorld);
|
||||
grassMaterialLOD3.SetVector(pId_WorldSpaceCameraPosEditor, camPosWorld);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void CreateChunks(BladeData[] bladesLOD0, BladeData[] bladesLOD1, BladeData[] bladesLOD2) {
|
||||
private void CreateChunks(
|
||||
BladeData[] bladesLOD0, BladeData[] bladesLOD1, BladeData[] bladesLOD2, BladeData[] bladesLOD3
|
||||
) {
|
||||
GameObject chunksContainer;
|
||||
// If a child called "Chunks" exists, destroy it -> children are also destroyed
|
||||
var chunksTransform = gameObject.transform.Find("Chunks");
|
||||
@ -191,6 +209,7 @@ public class GrassField : MonoBehaviour {
|
||||
var meshLOD0 = GenerateChunkMesh(chunkPos, chunkBounds, bladesLOD0, "grass_chunk_" + x + "_" + y + "_lod0");
|
||||
var meshLOD1 = GenerateChunkMesh(chunkPos, chunkBounds, bladesLOD1, "grass_chunk_" + x + "_" + y + "_lod1");
|
||||
var meshLOD2 = GenerateChunkMesh(chunkPos, chunkBounds, bladesLOD2, "grass_chunk_" + x + "_" + y + "_lod2");
|
||||
var meshLOD3 = GenerateChunkMesh(chunkPos, chunkBounds, bladesLOD3, "grass_chunk_" + x + "_" + y + "_lod3");
|
||||
|
||||
var chunk = Instantiate(chunkPrefab, chunksContainer.transform);
|
||||
chunk.name = "Chunk [" + x + ", " + y +"]";
|
||||
@ -199,19 +218,18 @@ public class GrassField : MonoBehaviour {
|
||||
chunk.MaterialLOD0 = grassMaterialLOD0;
|
||||
chunk.MaterialLOD1 = grassMaterialLOD1;
|
||||
chunk.MaterialLOD2 = grassMaterialLOD2;
|
||||
chunk.MaterialLOD3 = grassMaterialLOD3;
|
||||
chunk.MeshLOD0 = meshLOD0;
|
||||
chunk.MeshLOD1 = meshLOD1;
|
||||
chunk.MeshLOD2 = meshLOD2;
|
||||
chunk.MeshLOD3 = meshLOD3;
|
||||
chunk.EnableShadowsLOD0 = enableShadowsLOD0;
|
||||
chunk.EnableShadowsLOD1 = enableShadowsLOD1;
|
||||
chunk.EnableShadowsLOD2 = enableShadowsLOD2;
|
||||
chunk.EnableShadowsLOD3 = enableShadowsLOD3;
|
||||
|
||||
_chunks[x + y * numChunks] = chunk;
|
||||
}
|
||||
|
||||
var camPosWorld = Camera.main ? Camera.main.transform.position : Vector3.zero;
|
||||
UpdateLODs(camPosWorld);
|
||||
UpdateMaterials(camPosWorld);
|
||||
}
|
||||
|
||||
private Mesh GenerateChunkMesh(Vector3 chunkPos, Bounds chunkBounds, BladeData[] blades, string meshName) {
|
||||
@ -257,6 +275,7 @@ public class GrassField : MonoBehaviour {
|
||||
var chunkSize = ((float)size) / numChunks;
|
||||
var tPos = transform.position;
|
||||
|
||||
// grid
|
||||
for (int i = 0; i < numChunks + 1; i++) {
|
||||
Gizmos.color = new Color(0f, 0.3f, 1f, 1f);
|
||||
Gizmos.DrawLine(
|
||||
@ -282,10 +301,13 @@ public class GrassField : MonoBehaviour {
|
||||
Gizmos.color = new Color(0f, 0.3f, 1f, 1f);
|
||||
Gizmos.DrawWireSphere(center, distanceLOD1);
|
||||
Gizmos.DrawWireSphere(center, distanceLOD2);
|
||||
Gizmos.DrawWireSphere(center, distanceLOD3);
|
||||
|
||||
Gizmos.color = new Color(1.0f, 1.0f, 0.0f, 1f);
|
||||
var minDistLOD2 = distanceLOD1 + chunkSize * SQRT_2;
|
||||
var minDistLOD3 = distanceLOD2 + chunkSize * SQRT_2;
|
||||
Gizmos.DrawWireSphere(center, minDistLOD2);
|
||||
Gizmos.DrawWireSphere(center, minDistLOD3);
|
||||
|
||||
Gizmos.matrix = oldMatrix;
|
||||
}
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
Shader "Grass/GrassBlade" {
|
||||
Properties {
|
||||
[KeywordEnum(LOD 0, LOD 1, LOD 2)] _LOD("Level of Detail", int) = 0
|
||||
[KeywordEnum(LOD 0, LOD 1, LOD 2, LOD 3)] _LOD("Level of Detail", int) = 0
|
||||
|
||||
_BladeWidth("Blade Width", Range(0.003, .1)) = 0.01
|
||||
_BendStrength("Bend Strength", Range(0, 1)) = 1
|
||||
_Color0("Color LOD 0", Color) = (0.3, 1.0, 0.3, 1.0)
|
||||
_Color1("Color LOD 1", Color) = (1.0, 0.7, 0.3, 1.0)
|
||||
_Color2("Color LOD 2", Color) = (1.0, 0.3, 0.1, 1.0)
|
||||
_Color3("Color LOD 3", Color) = (0.8, 0.0, 0.0, 1.0)
|
||||
}
|
||||
SubShader {
|
||||
LOD 100
|
||||
@ -22,7 +23,7 @@
|
||||
|
||||
#pragma multi_compile _ SHADOWS_SCREEN
|
||||
// shader_feature is very similar to multi_compile. Use multi_compile for keywords that are set from code.
|
||||
#pragma shader_feature _LOD_LOD_0 _LOD_LOD_1 _LOD_LOD_2
|
||||
#pragma shader_feature _LOD_LOD_0 _LOD_LOD_1 _LOD_LOD_2 _LOD_LOD_3
|
||||
#pragma shader_feature UNITY_EDITOR
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
@ -49,7 +50,7 @@
|
||||
#pragma fragment frag
|
||||
#pragma geometry geom
|
||||
|
||||
#pragma shader_feature _LOD_LOD_0 _LOD_LOD_1 _LOD_LOD_2
|
||||
#pragma shader_feature _LOD_LOD_0 _LOD_LOD_1 _LOD_LOD_2 _LOD_LOD_3
|
||||
#pragma shader_feature UNITY_EDITOR
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Material Properties
|
||||
float _BladeWidth, _BendStrength;
|
||||
float4 _Color0, _Color1, _Color2;
|
||||
float4 _Color0, _Color1, _Color2, _Color3;
|
||||
|
||||
float2 _TransitionRange;
|
||||
|
||||
@ -22,7 +22,7 @@ struct g2f {
|
||||
#ifdef IS_IN_BASE_PASS
|
||||
float2 uv : TEXCOORD0; // bottom left 0.0 top right 1.1 (values converge - 0 and 1 meet at the tip)
|
||||
SHADOW_COORDS(1) // put shadows data into TEXCOORD1
|
||||
float3 worldPos : TEXCOORD2;
|
||||
float transitionInterpolator : TEXCOORD2;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -46,6 +46,8 @@ float getCameraDistance(float3 pos) {
|
||||
#elif _LOD_LOD_1
|
||||
[MaxVertexCount(4 + ( 5 - 1 ) * 2)]
|
||||
#elif _LOD_LOD_2
|
||||
[MaxVertexCount(4 + ( 2 - 1 ) * 2)]
|
||||
#elif _LOD_LOD_3
|
||||
[MaxVertexCount(4)]
|
||||
#endif
|
||||
void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
||||
@ -60,6 +62,8 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
||||
const float3 basePosWS = mul(unity_ObjectToWorld, float4(basePos.xyz, 1.0)).xyz;
|
||||
|
||||
const float cameraDistance = getCameraDistance(basePosWS);
|
||||
|
||||
float interpolator = invLerp(_TransitionRange.x, _TransitionRange.y, cameraDistance);
|
||||
|
||||
// randomly cull grass blades
|
||||
// float randoVal = N21(basePos);
|
||||
@ -86,27 +90,30 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
||||
#elif _LOD_LOD_1
|
||||
int numSegments = 5;
|
||||
#elif _LOD_LOD_2
|
||||
int numSegments = 2;
|
||||
#elif _LOD_LOD_3
|
||||
int numSegments = 1;
|
||||
#endif
|
||||
for (int i = 0; i < numSegments; i++) {
|
||||
const float lowerThickness = 0.8;
|
||||
|
||||
#if _LOD_LOD_2
|
||||
#if _LOD_LOD_3
|
||||
{
|
||||
const float segmentWidth = halfWidth * pow(sin(lowerThickness * 3.141), .8);
|
||||
const float3 widthOffset = getWidthOffset(segmentWidth, tipPosBladeSpace.xz) * max(1, cameraDistance / 8);
|
||||
float3 segmentCenterBase = basePos;
|
||||
float3 segmentCenterTip = basePos + tipPosBladeSpace;
|
||||
const float3 vertLeftBase = segmentCenterBase + widthOffset;
|
||||
const float3 vertRightBase = segmentCenterBase - widthOffset;
|
||||
const float3 vertLeftTip = segmentCenterTip + widthOffset * 0.4;
|
||||
const float3 vertRightTip = segmentCenterTip - widthOffset * 0.4;
|
||||
const float3 vertLeftBase = segmentCenterBase + widthOffset * 2.0;
|
||||
const float3 vertRightBase = segmentCenterBase - widthOffset * 2.0;
|
||||
const float3 vertLeftTip = segmentCenterTip + widthOffset * 0.5;
|
||||
const float3 vertRightTip = segmentCenterTip - widthOffset * 0.5;
|
||||
|
||||
o.pos = UnityObjectToClipPos(vertLeftBase);
|
||||
#ifdef IS_IN_BASE_PASS
|
||||
|
||||
o.uv = float2(0, 0);
|
||||
TRANSFER_SHADOW(o)
|
||||
o.worldPos = mul(unity_ObjectToWorld, float4(basePos, 1.0));
|
||||
o.transitionInterpolator = interpolator;
|
||||
#endif
|
||||
triStream.Append(o);
|
||||
|
||||
@ -114,7 +121,7 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
||||
#ifdef IS_IN_BASE_PASS
|
||||
o.uv = float2(1, 0);
|
||||
TRANSFER_SHADOW(o)
|
||||
o.worldPos = mul(unity_ObjectToWorld, float4(basePos, 1.0));
|
||||
o.transitionInterpolator = interpolator;
|
||||
#endif
|
||||
triStream.Append(o);
|
||||
|
||||
@ -122,7 +129,7 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
||||
#ifdef IS_IN_BASE_PASS
|
||||
o.uv = float2(0, 1);
|
||||
TRANSFER_SHADOW(o)
|
||||
o.worldPos = mul(unity_ObjectToWorld, float4(basePos, 1.0));
|
||||
o.transitionInterpolator = interpolator;
|
||||
#endif
|
||||
triStream.Append(o);
|
||||
|
||||
@ -130,7 +137,7 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
||||
#ifdef IS_IN_BASE_PASS
|
||||
o.uv = float2(1, 1);
|
||||
TRANSFER_SHADOW(o)
|
||||
o.worldPos = mul(unity_ObjectToWorld, float4(basePos, 1.0));
|
||||
o.transitionInterpolator = interpolator;
|
||||
#endif
|
||||
triStream.Append(o);
|
||||
}
|
||||
@ -174,7 +181,7 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
||||
#ifdef IS_IN_BASE_PASS
|
||||
o.uv = float2(0, segmentHeightNormalized);
|
||||
TRANSFER_SHADOW(o)
|
||||
o.worldPos = mul(unity_ObjectToWorld, float4(basePos, 1.0));
|
||||
o.transitionInterpolator = interpolator;
|
||||
#endif
|
||||
triStream.Append(o);
|
||||
|
||||
@ -182,7 +189,7 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
||||
#ifdef IS_IN_BASE_PASS
|
||||
o.uv = float2(1, segmentHeightNormalized);
|
||||
TRANSFER_SHADOW(o)
|
||||
o.worldPos = mul(unity_ObjectToWorld, float4(basePos, 1.0));
|
||||
o.transitionInterpolator = interpolator;
|
||||
#endif
|
||||
triStream.Append(o);
|
||||
|
||||
@ -193,7 +200,7 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
||||
#ifdef IS_IN_BASE_PASS
|
||||
o.uv = float2(.5, 1);
|
||||
TRANSFER_SHADOW(o)
|
||||
o.worldPos = mul(unity_ObjectToWorld, float4(basePos, 1.0));
|
||||
o.transitionInterpolator = interpolator;
|
||||
#endif
|
||||
triStream.Append(o);
|
||||
}
|
||||
@ -208,19 +215,20 @@ float4 frag(g2f i) : SV_Target{
|
||||
float3 light = float3(i.uv.yyy);
|
||||
light *= max(.35, shadow);
|
||||
#if _LOD_LOD_2
|
||||
light *= 0.75;
|
||||
light *= 0.75; // fake shadow
|
||||
#elif _LOD_LOD_3
|
||||
light *= 0.6; // fake shadow
|
||||
#endif
|
||||
|
||||
const float camDist = getCameraDistance(i.worldPos);
|
||||
float interpolator = invLerp(_TransitionRange.x, _TransitionRange.y, camDist);
|
||||
|
||||
float3 albedo;
|
||||
#if _LOD_LOD_0
|
||||
albedo = lerp(_Color0.xyz, _Color1.xyz, interpolator);
|
||||
albedo = lerp(_Color0.xyz, _Color1.xyz, i.transitionInterpolator);
|
||||
#elif _LOD_LOD_1
|
||||
albedo = lerp(_Color1.xyz, _Color2.xyz, interpolator);
|
||||
albedo = lerp(_Color1.xyz, _Color2.xyz, i.transitionInterpolator);
|
||||
#elif _LOD_LOD_2
|
||||
albedo = _Color2.xyz;
|
||||
albedo = lerp(_Color2.xyz, _Color3.xyz, i.transitionInterpolator);
|
||||
#elif _LOD_LOD_3
|
||||
albedo = _Color3.xyz;
|
||||
#endif
|
||||
// albedo = _Color0.xyz;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user