首页 > 编程语言 >Unity+Houdini+SP+SD 程序化风格化石头

Unity+Houdini+SP+SD 程序化风格化石头

时间:2024-03-09 17:22:33浏览次数:26  
标签:psInput sampler surfaceData SP 形状 风格化 Unity result half

Houdini程序化模型

  • 整体思路:先生成一个基础模型,再基于该模型进行cutoff、控制拐角,随后转换为低模,最后uv映射、物体的像素密度、贴图大小

基础模型

  • 基础形状采用Box,再使用Point Jitter改变形状,最后添加normal为后续的cutoff做铺垫
  • 大致形状如下

基础形状

  • 基于point个数使用for loop循环进行cutoff,因为cut后可以看到物体内部,所以需要polyfill
  • 重点在于cutoff,核心是随机化
  • 大致效果如下

进一步修改模型形状

  • 接下来是进一步修改物体形状,resolution对point和point之间进行插值增加新的point,fuse融合重复的point,polybevel沿边缘和拐角生成倒角
  • 大致效果如下

生成低模

  • 将之前的属性转换为VDB,再转换为polygon,最后使用polyreduce减面

Game Asset

  • 对模型进行uv映射,然后控制模型的纹素密度,及纹理贴图大小,最后使用Normal基于face进行平滑

SP烘培石头贴图

  • 为了加快产生,可以使用SP来制作烘培贴图,主要思路是使用noise纹理+blur+控制整体颜色+打灯
  • 具体思路可以参考这个视频how to make anime rocks

SD制作风格化草贴图

  • 最终效果如下
  • 整体思路:先制作长草和花的形状,再使用tile sampler添加随机性来覆盖整个面,最后添加颜色
    • 基础形状
    • 花的形状
    • 颜色:颜色也是基于之前创建的形状mask,可以在网上下载一些好康的草笔刷来丰富

Unity

  • shader的重点在于石头如何和青苔、雪之类的纹理进行混合,这里用到了高度混合,具体参考的这个项目

  • 实现

    • 管线设定:石头这玩意用不透明的即可

    • 法线混合

      half3 baseNormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_NormalTex, sampler_NormalTex, uv), _NormalScale * 0.5h);
      half3 topNormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_TopNormalTex, sampler_TopNormalTex, topUV), _TopNormalScale * 0.5h);
      surfaceData.normalTS = WhiteOutBlendNormal(baseNormalTS, topNormalTS);
      
    • 世界空间下物体顶部的映射。这部分是最重要的

      half TopMask(half3 baseNormalTSUnNor)
      {
          half result = abs(saturate(baseNormalTSUnNor.y) + _TopOffset);
          result = pow(result, _TopContrast);
          result *= _TopIntensity;
          result = saturate(result);
      
          return result;
      }
      half TopHeight(float3 positionWS)
      {
          half result = RemapFloat(positionWS.y, -100, 1, 0, 1);
          return saturate(result);
      }
      half TopWorldMapping(half3 baseNormalTSUnNor, float positionWS)
      {
          half result = 0.h;
          result = TopMask(baseNormalTSUnNor) * TopHeight(positionWS);
          return result;
      }
      
      // 将normal从切线空间转换至世界空间
      psInput.tangentWS = SafeNormalize(psInput.tangentWS);
      psInput.bitTangentWS = SafeNormalize(psInput.bitTangentWS);
      psInput.normalWS = SafeNormalize(psInput.normalWS);
      half3x3 TBN = half3x3(psInput.tangentWS, psInput.bitTangentWS, psInput.normalWS);
      lightData.normalWS = SafeNormalize(TransformTangentToWorld(surfaceData.normalTS, TBN));
      // 计算顶部mask
      half finalTopMask = TopWorldMapping(lightData.normalWS, lightData.positionWS);
      
    • 计算Albedo:使用finalTopMasklerp

      half4 albedo = GetSurfaceAlbedo(_AlbedoTex, sampler_AlbedoTex, uv, _AlbedoTint);
      half4 topAlbedo = GetSurfaceAlbedo(_TopAlbedoTex, sampler_TopAlbedoTex, topUV, _TopAlbedoTint);
      surfaceData.albedo = lerp(albedo.rgb, topAlbedo, finalTopMask);
      surfaceData.opacity = 1.h;
      
    • 计算AO

      half4 MOS = SAMPLE_TEXTURE2D(_MetallicR_OcclusionG_SmoothnessA_Tex, sampler_MetallicR_OcclusionG_SmoothnessA_Tex, uv);
      surfaceData.occlusion = lerp(1.h, MOS.g, _BaseAOIntensity);
      half baseAO = surfaceData.occlusion;
      surfaceData.occlusion = lerp(baseAO, lerp(baseAO, 1.h, 0.8h), finalTopMask);
      
    • 计算Smoothness

      surfaceData.smoothness = 1 - MOS.b;
      half baseSmoothness = surfaceData.smoothness + RemapFloat(_BaseSmoothnessOffset, 0.h, 1.h, -1.h, 1.h);
      half topSmoothness = 1.h - topMOS.b + RemapFloat(_TopSmoothnessOffset, 0.h, 1.h, -1.h, 1.h);
      surfaceData.smoothness = lerp(baseSmoothness, topSmoothness, finalTopMask);
      
  • 效果

Reference

Procedural Stylized Rock - Sidefx Houdini

ANGRY MESH

标签:psInput,sampler,surfaceData,SP,形状,风格化,Unity,result,half
From: https://www.cnblogs.com/chenglixue/p/18062998

相关文章

  • Unity URP Houdini 风格化云
    目录前言RenderType不透明度自发光ParallaxOcclusionMapping动画reference前言云的实现一般有三种思路:Volume体积云、billboard公告牌、Particle粒子,对于风格化来说体渲染的实现过于真实(但光遇的风格化云貌似是使用体渲染实现的,后面有空会考虑尝试还原还原),而Particle消耗太......
  • SpringCloud入门
    微服务架构的出现单体应用之殇无法快速迭代代码合并冲突,沟通成本大幅提高回归用例庞杂,无法快速迭代无法快速恢复某版本小需求有bug需要回退整个版本的功能,且需要再走一遍冗长的发布流程微服务架构优势微服务架构是在SOA(Service-OrientedArchitecture,面向服务的架......
  • spdlog 源码解析
    spdlog是开源、高性能、跨平台,支持header-only/compiled的C++日志库。本文主要目的是对spdlogv1.13.0的源码进行分析(编译运行环境为6.5.0-18-generic#18~22.04.1-Ubuntu),以探讨spdlog如何构建高性能、可扩展的日志框架的。github链接gabime/spdlog:FastC++loggingli......
  • springboot注册
    查询用户,判断用户名是否被占用。1.没有被占用,则注册2.被占用,则显示用户名已被占用!service:UserServiceimportcom.example.pojo.User;publicinterfaceUserService{//根据用户名查询用户UserfindByUserName(Stringusername);}mapper:UserMapper@Map......
  • 痞子衡嵌入式:不清i.MXRTxxx里FLEXSPI_MCR0寄存器保留位会造成IP CMD读写异常
    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是不清i.MXRTxxx里FLEXSPI_MCR0寄存器保留位会造成IPCMD读写异常。痞子衡曾经写过一篇文章《改动i.MXRT1xxx里IOMUXC_GPR寄存器保留位可能会造成系统异常》,这篇文章提出了一个观点,即对于MCU外设寄存器应......
  • spring - mvc -2
    springmvc1.@Required注解的作用是什么@Required注解用在setter方法上,它表明具有该注解的bean属性必须在配置时填充。否则,Spring容器将抛出BeanInitializationException异常。此外,@Required与@Autowired不同——因为它仅限于setter,而@Autowired则不然。@Autowired也可用于......
  • spring - mvc - @Valid
    自定义验证创建自定义验证器需要推出我们自己的注释并在我们的模型中使用它来强制执行验证规则。因此,让我们创建自定义验证器来检查电话号码。电话号码必须是至少8位数字,但不超过11位数字。1.新注释让我们创建一个新的@interface来定义我们的注释:@Documented@Constrain......
  • springboot项目构建docker镜像
    springboot项目构建docker镜像springboot项目构建成docker镜像的两种方式手动方式:将springboot项目打成一个jar包,将jar包上次到服务器的指定目录下(具备docker环境),然后在同一目录下编写Dockerfile文件,通过dockerbuild命令构建镜像,之后把镜像发布到远程仓库中。半自动方式:......
  • VMware vSphere 7 Update 3p 下载 (安全更新)
    VMwarevSphere7Update3p下载(安全更新)vCenterServer&ESXi,Dell,HPE,Cisco,LENOVO,FUJITSU,NEC,Inspur,HitachiCustomImage请访问原文链接:https://sysin.org/blog/vmware-vsphere-7-u3/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org服务器虚拟......
  • SpringCloud Gateway实战
    SpringCloudGateway目录SpringCloudGateway认识SpringCloudGatewaySpringCloudGateway和Zuul最核心的区别SpringCloudGateway工作模型图及解读SpringCloudGateway三大核心概念Route、Predicate、FilterSpringCloudGateway过滤器全局过滤器和局部过滤器SpringCloudGatew......