Created
June 6, 2022 12:28
-
-
Save nathanpc/eb0f36612871f7d2415ee7d7c1b0efe7 to your computer and use it in GitHub Desktop.
Transform Textures in Unity
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// TextureTransformation.shader | |
// A simple shader that allows us to transition between two textures from a script. | |
// | |
// Author: Nathan Campos <[email protected]> | |
Shader "Custom/TextureTransformation" { | |
Properties { | |
_Color ("Color", Color) = (1,1,1,1) | |
_MainTex ("Original Texture", 2D) = "white" {} | |
_TransTex("Transformed Texture", 2D) = "gray" {} | |
_Glossiness ("Smoothness", Range(0,1)) = 0.0 | |
_Metallic ("Metallic", Range(0,1)) = 0.0 | |
_Transformation("Transformation", Range(0,1)) = 0.0 | |
} | |
SubShader { | |
// Make sure we can do transparency. | |
Tags { "RenderType" = "Transparent" "Queue" = "Transparent" } | |
LOD 300 | |
Blend SrcAlpha OneMinusSrcAlpha // Use blend for alpha values. | |
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 | |
struct Input { | |
float2 uv_MainTex; | |
float2 uv_TransTex; | |
}; | |
// Turn our properties into variables. | |
sampler2D _MainTex; | |
sampler2D _TransTex; | |
half _Glossiness; | |
half _Metallic; | |
fixed4 _Color; | |
half _Transformation; | |
// 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) | |
// Calculate the surface properties. | |
void surf (Input IN, inout SurfaceOutputStandard o) { | |
// Get textures. | |
fixed4 colMain = tex2D (_MainTex, IN.uv_MainTex) * _Color; | |
fixed4 colTrans = tex2D(_TransTex, IN.uv_TransTex) * _Color; | |
// Calculate how much each texture will weigh in the transformation. | |
o.Albedo = (colMain.rgb * (1 - _Transformation)) + (colTrans.rgb * _Transformation); | |
// Apply all the other "standard" effects. | |
o.Metallic = _Metallic; | |
o.Smoothness = _Glossiness; | |
o.Alpha = _Color.a; | |
} | |
ENDCG | |
} | |
FallBack "Diffuse" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
/// <summary> | |
/// Transforms a <see cref="GameObject"/> when the fog touches it using our | |
/// custom shader. | |
/// </summary> | |
[RequireComponent(typeof(Renderer))] | |
public class TransformShader : MonoBehaviour, ITransformation { | |
public GameObject fog; | |
public float transformationAmount = 0.0f; | |
private Renderer objectRenderer; | |
private float insideDistance = 33.0f; | |
// Start is called before the first frame update | |
void Start() { | |
objectRenderer = gameObject.GetComponent<Renderer>(); | |
} | |
// Update is called once per frame | |
void Update() { | |
// Do nothing if we've already transformed. | |
if (transformationAmount == 1.0f) | |
return; | |
// Check if we are inside the fog. | |
if (InsideFog()) | |
StartTransformation(); | |
// Apply transformation to the shader. | |
objectRenderer.material.SetFloat("_Transformation", transformationAmount); | |
} | |
public void StartTransformation() { | |
transformationAmount = 1; | |
} | |
/// <summary> | |
/// Check if our <see cref="GameObject"/> is inside the fog. | |
/// </summary> | |
/// <returns>True if we are inside the fog.</returns> | |
private bool InsideFog() { | |
// Check if the distance from the fog is less than its radius. | |
return Vector3.Distance(transform.position, fog.transform.position) < insideDistance; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment