Shader Graph 闪闪的翡翠效果

首先需要两个自定义节点

1.三角形平铺定制节点 

 

如果是老版本shader graph 直接创建脚本继承 CodeFunctionNode

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.ShaderGraph;
using System.Reflection;

[Title("Distance", "Triangle")]
public class TriangleNode : CodeFunctionNode
{
    public TriangleNode()
    {
        name = "Triangle";
    }

    protected override MethodInfo GetFunctionToConvert()
    {
        return GetType().GetMethod("TriangleNode_Function",
            BindingFlags.Static | BindingFlags.NonPublic);
    }
    public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
    {
        registry.ProvideFunction("fmod", s => s.Append(@"
float fmod(float a, float b)
{
    return a - floor(a / b) * b;
}
        "));

        base.GenerateNodeFunction(registry, graphContext, generationMode);
    }
    static string TriangleNode_Function(
        [Slot(0, Binding.MeshUV0)] Vector2 UV,
        [Slot(1, Binding.None, 4f, 0f, 0f, 0f)] Vector1 Scale,
        [Slot(10, Binding.None)] out Vector1 Triangle, // 三角形
        [Slot(11, Binding.None)] out Vector2 TrianglePosition // 三角形
    )
    {
        TrianglePosition = Vector2.zero;
        return @"{
  #define N Scale
  float2 p = UV;
  p.x *= 0.86602; // sqrt(3)/2倍
  float isTwo = fmod(floor(p.y * N), 2.0); // 偶数列
  float isOne = 1.0 - isTwo; // 奇数列
  // 将xy坐标0~1的正方形以瓷砖形式排列多个
  p = p * N;
  p.x += isTwo * 0.5; // 偶数列数乘以0.5
  float2 p_index = floor(p); // 正方形编号
  float2 p_rect = frac(p);
  p = p_rect; // 正方形内部的坐标
  float xSign = sign(p.x - 0.5); // 瓷砖的右侧为+1.0,左侧为-1.0
  p.x = abs(0.5 - p.x); // 以x=0.5为轴左右对称
  float isInTriangle = step(p.x * 2.0 + p.y, 1.0); // 三角形の内部にある場合は1.0
  float isOutTriangle = 1.0 - isInTriangle; //在三角形内部时为1.0
  // 中央三角形
  float w1 = max( p.x * 2.0 + p.y, 1.0 - p.y * 1.5 ); 
  
  // 右上角(左上角)的三角形
  p = float2(0.5, 1.0) - p;
  float w2 = max(p.x * 2.0 + p.y, 1.0 - p.y * 1.5 );
  // 三角形渐变
  Triangle = lerp(1.0 - w2, 1.0 - w1, isInTriangle) / 0.6;
  
  // 三角形位置
  float2 triangleIndex = p_index + float2(
     isOutTriangle * xSign / 2.0 // 左上部分是-0.5,右上部分是+0.5
    + isOne / 2.0, // 基数列的三角形水平偏移0.5,+0.5
  );
  
  // 三角形坐标
  TrianglePosition = triangleIndex / N;
        }";
    }
}

 新版本无法继承CodeFunctionNode ,需要在shader里创建一个Custom Function Node

上面代码改成hlsl就行了,或者简单的直接用string body

2.范围扭曲节点

 

using UnityEngine;
using UnityEditor.ShaderGraph;
using System.Reflection;


[Title("Custom", "Domain Warping")]
public class DomainWarpingNode : CodeFunctionNode
{
    public DomainWarpingNode()
    {
        name = "Domain Warping";
    }

    protected override MethodInfo GetFunctionToConvert()
    {
        return GetType().GetMethod("DomainWarpingNode_Function",
            BindingFlags.Static | BindingFlags.NonPublic);
    }


    public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
    {
        registry.ProvideFunction("random", s => s.Append(@"
            float random(float2 st) {
                return frac(sin(dot(st.xy,
                                    float2(12.9898,78.233)))*
                            43758.5453123);
            }
        "));
        registry.ProvideFunction("noise", s => s.Append(@"
            float noise (float2 st) {
                float2 i = floor(st);
                float2 f = frac(st);
                // Four corners in 2D of a tile
                float a = random(i);
                float b = random(i + float2(1.0, 0.0));
                float c = random(i + float2(0.0, 1.0));
                float d = random(i + float2(1.0, 1.0));
                float2 u = f * f * (3.0 - 2.0 * f);
                return lerp(a, b, u.x) +
                        (c - a)* u.y * (1.0 - u.x) +
                        (d - b) * u.x * u.y;
            }
        "));
        registry.ProvideFunction("fbm", s => s.Append(@"
            #define OCTAVES 6
            float fbm (float2 st) {
                // Initial values
                float value = 0.0;
                float amplitude = .5;
                float frequency = 0.;
                // Loop of octaves
                for (int i = 0; i < OCTAVES; i++) {
                    value += amplitude * noise(st);
                    st *= 2.;
                    amplitude *= .5;
                }
                return value;
            }
        "));

        registry.ProvideFunction("pattern_1", s => s.Append(@"
            float pattern_1 (float2 p) {
                return fbm(p);
            }
        "));

        registry.ProvideFunction("pattern_2", s => s.Append(@"
            float pattern_2 (float2 p) {
                float2 q = float2( 
                                fbm( p + float2(0.0,0.0) ),
                                fbm( p + float2(5.2,1.3) ) 
                                );
                return fbm( p + 4.0*q );
            }
        "));

        registry.ProvideFunction("pattern_3", s => s.Append(@"
            float pattern_3 (float2 p) {
                // first domain warping
                float2 q = float2( 
                                fbm( p + float2(0.0,0.0) ),
                                fbm( p + float2(5.2,1.3) ) 
                                );
                            
                // second domain warping
                float2 r = float2( 
                                fbm( p + 4.0*q + float2(1.7,9.2) ),
                                fbm( p + 4.0*q + float2(8.3,2.8) ) 
                                );
                return fbm( p + 4.0*r );
            }
        "));

        registry.ProvideFunction("pattern", s => s.Append(@"
            float pattern (float2 p, float4 scale_1, float scale_2, float4 add_1, float4 add_2) {
                // first domain warping
                float2 q = float2( 
                                fbm( p + scale_1.x * add_1.xy ),
                                fbm( p + scale_1.y * add_1.zw ) 
                                );
                            
                // second domain warping
                float2 r = float2( 
                                fbm( p + scale_1.z * q + add_2.xy ),
                                fbm( p + scale_1.w * q + add_2.zw ) 
                                );
                return fbm( p + scale_2 * r );
            }
        "));

        base.GenerateNodeFunction(registry, graphContext, generationMode);
    }

    static string DomainWarpingNode_Function(
        [Slot(0, Binding.MeshUV0)] Vector2 UV,
        [Slot(1, Binding.None, 0f, 0f, 5.2f, 1.3f)] Vector4 Fbm_AddFactor_1,
        [Slot(2, Binding.None, 1.7f, 9.2f, 8.3f, 2.8f)] Vector4 Fbm_AddFactor_2,
        [Slot(3, Binding.None, 1f, 1f, 4f, 4f)] Vector4 Fbm_ScaleFactor_1,
        [Slot(4, Binding.None, 4f, 0f, 0f, 0f)] Vector1 Fbm_ScaleFactor_2,
        [Slot(5, Binding.None)] out Vector1 Pattern
    )
    {
        return @"{  
                Pattern = pattern(UV, Fbm_ScaleFactor_1, Fbm_ScaleFactor_2, Fbm_AddFactor_1, Fbm_AddFactor_2);
             }";
    }
}

 新版本同样,改成hlsl

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值