Skip to content

Instantly share code, notes, and snippets.

@nathanpc
Created June 6, 2022 12:28
Show Gist options
  • Save nathanpc/eb0f36612871f7d2415ee7d7c1b0efe7 to your computer and use it in GitHub Desktop.
Save nathanpc/eb0f36612871f7d2415ee7d7c1b0efe7 to your computer and use it in GitHub Desktop.
Transform Textures in Unity
// 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"
}
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