Unity3D Shader实现贴图切换效果
程序员文章站
2022-10-15 14:29:50
本文实例为大家分享了shader实现基于世界坐标的贴图置换效果。
效果如下:
设置面板如下:
可在面板上设置切换方向,与切换对象,及其切换速度。
shade...
本文实例为大家分享了shader实现基于世界坐标的贴图置换效果。
效果如下:
设置面板如下:
可在面板上设置切换方向,与切换对象,及其切换速度。
shader实现如下:
shader "xm/effect/swaptexture" { properties { _color ("color", color) = (1,1,1,1) _maintex ("albedo (rgb)", 2d) = "white" {} _targettex ("target tex", 2d) = "white" {}//目标贴图 [keywordenum(up, down, left, right, forward, back)] _mode ("mode", int) = 0//切换方向 _swapblend ("blend", range(0,1)) = 0//0-1混合值 _swapmin("min value", float) = 0//最小世界坐标 _swapmax("max value", float) = 0//最大世界坐标 _glossiness ("smoothness", range(0,1)) = 0.5 _metallic ("metallic", range(0,1)) = 0.0 } subshader { tags { "rendertype"="opaque" } lod 200 cgprogram // physically based standard lighting model, and enable shadows on all light types #pragma surface surf standard fullforwardshadows vertex:vert // use shader model 3.0 target, to get nicer looking lighting #pragma target 3.0 sampler2d _maintex; sampler2d _targettex; struct input { float2 uv_maintex; float3 worldpos; }; half _mode; half _swapblend; float _swapmin; float _swapmax; half _glossiness; half _metallic; fixed4 _color; void vert (inout appdata_full v, out input o) { unity_initialize_output(input,o); } void surf (input in, inout surfaceoutputstandard o) { half usetarget = 0; float targetvalue = 0; switch(_mode)//模式选择 { case 0://up targetvalue = (_swapmax - _swapmin) * _swapblend + _swapmin; usetarget = in.worldpos.y > targetvalue?0:1; break; case 1://down targetvalue = (_swapmax - _swapmin) * (1 - _swapblend) + _swapmin; usetarget = in.worldpos.y < targetvalue?0:1; break; case 2://left targetvalue = (_swapmax - _swapmin) * (1 - _swapblend) + _swapmin; usetarget = in.worldpos.x < targetvalue?0:1; break; case 3://right targetvalue = (_swapmax - _swapmin) * _swapblend + _swapmin; usetarget = in.worldpos.x > targetvalue?0:1; break; case 4://forward targetvalue = (_swapmax - _swapmin) * _swapblend + _swapmin; usetarget = in.worldpos.z > targetvalue?0:1; break; case 5://back targetvalue = (_swapmax - _swapmin) * (1 - _swapblend) + _swapmin; usetarget = in.worldpos.z < targetvalue?0:1; break; } // albedo comes from a texture tinted by color fixed4 c; if(usetarget == 1) { c = tex2d (_targettex, in.uv_maintex); } else { c = tex2d (_maintex, in.uv_maintex); } c *= _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" }
配合使用的脚本如下:
using system; using system.collections; using unityengine; namespace xm.effect { public class swaptexture : monobehaviour { public enum swapdirection { up, down, left, right, forward, back } public shader _shader;//"xm/effect/swaptexture” shader public swapdirection _swapdir;//切换方向 public renderer _target;//目标对象 [range(0, 1)] public float _speed;//速度 private material _matold; private material _matnew; public void swap(texture tex, action<bool> oncomplete) { if (_matold != null) { stopallcoroutines(); if (null != oncomplete) { oncomplete(false); } _target.material = _matold; } _matold = _target.material; _matnew = new material(_shader); _matnew.settexture("_maintex", _target.material.gettexture("_maintex")); _matnew.settexture("_targettex", tex); _matnew.setint("_mode", (int)_swapdir); _matnew.setfloat("_swapblend", 0); startcoroutine("_startchange", oncomplete); } private ienumerator _startchange(action<bool> oncomplete) { float deltaval = 0; _target.material = _matnew; vector3 vtmin; vector3 vtmax; float minval = 0; float maxval = 0; while (deltaval != 1) { vtmin = _target.bounds.min; vtmax = _target.bounds.max; switch (_swapdir) { case swapdirection.up: case swapdirection.down: minval = vtmin.y; maxval = vtmax.y; break; case swapdirection.left: case swapdirection.right: minval = vtmin.x; maxval = vtmax.x; break; case swapdirection.forward: case swapdirection.back: minval = vtmin.z; maxval = vtmax.z; break; } minval -= 0.01f; maxval += 0.01f; _matnew.setfloat("_swapmin", minval); _matnew.setfloat("_swapmax", maxval); deltaval = mathf.clamp01(deltaval + _speed * time.deltatime); _matnew.setfloat("_swapblend", deltaval); yield return null; } _matold.settexture("_maintex", _matnew.gettexture("_targettex")); _target.material = _matold; _matnew = null; _matold = null; if (null != oncomplete) { oncomplete(true); } } public void ondrawgizmos() { if (_target != null) { gizmos.drawwirecube(_target.bounds.center, _target.bounds.size); gizmos.drawwiresphere(_target.bounds.min, 0.1f); gizmos.drawwiresphere(_target.bounds.max, 0.1f); } } //test public texture testtex; private void ongui() { if (guilayout.button("swaptexture")) { swap(testtex, (t) => { debug.log("swap>" + t); }); } } // } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: 适合女性保养的食物有哪些