layout: post
title: “中级Shader教程17 海洋渲染”
date: 2018-04-23 16:09:03
author: Jiepeng Tan
categories:

  • shader tutorial
    tags: shader_tutorial theory shader
    img_path: /assets/img/blog/ShaderTutorial2D/Snow
    mathjax: true

Shader 视频教程

  • shader基础教程(超多案例)

1.前置知识链接

1.Noise和FBM请参考这篇文章中给出的链接
2.ranymarching 框架

2.海浪型状的构造

1.基本形状构造

1.基本周期函数
2.扩散方向
3.Noise扰动

2.性能分析

1.还是和地形渲染一样,我们这里采用多种分辨率的地形函数
2.性能关键
.基本周期函数
.Nolise函数的实现

3.实现

0.基本框架

1.基本raymarching
#define Waves(pos,NUM)\float2 uv = pos.xz;\....//不同的实现float2 TerrainL(float3 pos){ Waves(pos,5.);
}
float2 TerrainM(float3 pos){Waves(pos,9.);
}
float2 TerrainH(float3 pos){Waves(pos,24.);
} float RaycastTerrain(float3 ro, float3 rd) { _MRCRO_RAY_CAST(ro,rd,10000.,TerrainL);
}
float3 NormalTerrian( in float3 pos, float rz ){_MACRO_CALC_NORMAL(pos,rz,TerrainH);
}float SoftShadow(in float3 ro, in float3 rd,float tmax){    _MACRO_SOFT_SHADOW(ro,rd,tmax,TerrainM);
}  
2.水渲染

海水渲染需要考虑的有diffuse,specular,reflect,refract,fresnel这集中不同的效应

//基本渲染
float3 RenderSea(float3 pos, float3 rd,float rz, float3 nor, float3 lightDir) {  float fresnel = clamp(1.0 - dot(nor,-rd), 0.0, 1.0);fresnel = pow(fresnel,3.0) * 0.65;float3 reflected = Sky(pos,reflect(rd,nor),lightDir);    float3 diff = pow(dot(nor,lightDir) * 0.4 + 0.6,3.);float3 refracted = _SeaBaseColor + diff * _SeaWaterColor * 0.12;float3 col = lerp(refracted,reflected,fresnel);float spec=  pow(max(dot(reflect(rd,nor),lightDir),0.0),60.) * 3.;col += float3(spec,spec,spec);return col;
}
3.海天的处理

在海水和天空之间过渡

float4 ProcessRayMarch(float2 uv,float3 ro,float3 rd,inout float sceneDep,float4 sceneCol){ float rz = RaycastTerrain(ro,rd).x; float3 pos = ro + rd *rz;float3 nor = NormalTerrian(pos,rz);// colorfloat3 skyCol = Sky(pos,rd,_LightDir);float3 seaCol = RenderSea(pos,rd,rz,nor,_LightDir);//让海水和天空的过渡平和点float3 col = lerp(skyCol,seaCol,pow(smoothstep(0.0,-0.05,rd.y),0.3));col = pow( col, float3(0.4545,0.4545,0.4545) );sceneCol.xyz = col;return sceneCol;
}

这里介绍两种方式来够着波浪:
1.使用多个发射点(圆形)发射不同频率,振幅的波来合成最终效果
2.使用多个放射方向(直线)发射不同频率,振幅的波来合成最终效果

1.圆形波
#define Waves(pos,NUM)\float2 uv = pos.xz;\float w = 0.0,sw = 0.0;\float iter = 0.0, ww = 1.0;\uv += ftime * 0.5;\// 类FBM 波合成for(int i=0;i<NUM;i++){\w += ww * Wave(uv * 0.06 , float2(sin(iter), cos(iter)) * 10.0, 2.0 + iter * 0.08, 2.0 + iter * 3.0);\sw += ww;\ww = lerp(ww, 0.0115, 0.4);\iter += 2.39996;\}\return float2(pos.y- w / sw*_SeaWaveHeight,1.);\float Wave(float2 uv, float2 emitter, float speed, float phase){ //uv += Noise(uv);// 是否使用noise 来扭曲采样点float dst = distance(uv, emitter);//圆形扩散 极坐标return pow((0.5 + 0.5 * sin(dst * phase - ftime * speed)), 5.0);
}

两个sin波叠加的效果

多个sin波叠加的效果

最终效果

1.方向波
#define Waves(pos,_LOOP_NUM)\float2 uv = pos.xz;\//float2x2(0.8,0.6,-0.6,0.8) * 2.0float2x2 octave_m = float2x2(1.6,1.2,-1.2,1.6);\float freq = _SeaFreq;\float amp = _SeaWaveHeight;\float choppy = _SeaChoppy;\uv.x *= 0.75;\float d, h = 0.0;   \//类FBM效果  for(int i = 0; i < _LOOP_NUM; i++) {        \//让波浪相交d = Wave((uv+SEA_TIME)*freq,choppy);\d += Wave((uv-SEA_TIME)*freq,choppy);\h += d * amp;  \uv = mul(octave_m,uv); freq *= 1.9; amp *= 0.22;\choppy = lerp(choppy,1.0,0.2);\}\return float2(pos.y - h,1.0);// sea
float Wave(float2 uv, float choppy) {uv += Noise(uv);   // 是否使用noise 来扭曲采样点float2 wv = 1.0-abs(sin(uv));//让波尖锐float2 swv = abs(cos(uv));   //方型wv = lerp(wv,swv,wv);return pow(1.0-pow(wv.x * wv.y,0.65),choppy);
}

两个方向波的效果

多个方向波的效果

2.随机化

float Wave(float2 uv, float choppy) {uv += Noise(uv);   // 是否使用noise 来扭曲采样点...
}

添加Noise来增加波浪的随机行为

最终效果

  • 本教程配套blog

  • 本教程配套项目源码

  • 教程中抽取的RayMarching框架

中级Shader教程17 海洋渲染相关推荐

  1. 中级Shader教程26 三种Caustic实现方式

    layout: post title: "中级Shader教程26 三种Caustic实现方式" date: 2018-04-26 16:09:03 author: Jiepeng ...

  2. 中级Shader教程10 shader建模工具--SDF

    layout: post title: "中级Shader教程10 shader建模工具–SDF " date: 2018-04-23 16:09:03 author: Jiepe ...

  3. 中级Shader教程06 2D火焰粒子

    layout: post title: "中级Shader教程06 2D火焰粒子" date: 2018-03-27 16:09:03 author: Jiepeng Tan ca ...

  4. 中级Shader教程00 总纲

    FishMan Shader Tutorial Shader 视频教程 shader基础教程(超多案例) 0.说在前面 帧同步ECS 框架教程 帧同步ECS 框架源码 本教程配套blog 本教程配套项 ...

  5. 【C4D教程】Octane渲染大师班

    [C4D教程]Octane渲染大师班 本套教程共9大章 4小时20分 高清1920X1080 mp4 视频 英语+机译中文字幕 大小 17.8G 信息. 云桥网络 平台获取教程 学习使用Cinema ...

  6. 微信小程序教学第二章(含视频):小程序中级实战教程之预备篇 - 提取util公用方法 |基于最新版1.0开发者工具

    iKcamp官网:http://www.ikcamp.com 访问官网更快阅读全部免费分享课程:<iKcamp出品|全网最新|微信小程序|基于最新版1.0开发者工具之初中级培训教程分享>. ...

  7. Shader教程系列XNA

     Shader教程系列 XNA Shader编程教程1-环境光照 原文地址:http://digierr.spaces.live.com/blog/cns!2B7007E9EC2AE37B!424 ...

  8. STM32 电机教程 17 - 基于ST MotorControl Workbench的电机调试

    前言 磁场定向控制又称矢量控制(FOC), 本质上为控制定子电流的幅度和相位,使之产生的磁场和转子的磁场正交,以产生最大的扭矩. PMSM的磁场定向控制框图如下图所示: 上一讲详细介绍了磁场定向控制的 ...

  9. STM32 进阶教程 17 - ADC注入通道

    前言 STM32 的ADC的一个强大功能是支持触发注入功能,在103中每个ADC模块支持4个注入通道,每个注入通道具有独立的结果突存器,注入通道具有较规划通道更高的优先级,在实际工程应用中,注入通道更 ...

  10. STM32 基础系列教程 17 – CRC

    前言 学习stm32 循环冗余校验(CRC)计算单元接口使用,学会stm32f103 CRC应用与编程,关于CRC的基础知识请各位自行百度,STM32有些芯片的CRC多项式可自由设定,有些则是固定值0 ...

最新文章

  1. TTL电平、CMOS电平、RS232电平的区别
  2. 60秒,我们可以干什么?
  3. 别总埋汰写代码,停下总结一下吧
  4. Windows注册表修改实例完全手册(下)
  5. suoi46 最大和和 (线段树)
  6. Hacking Team Flash 0day漏洞学习笔记
  7. 最简单的SpringMVC + Maven配置
  8. 化工计算机软件基础考试题,化工原理模拟试题(一)及答案.doc
  9. 如何进行动态的SQL环境搭建?
  10. 解决Linux下使用sqlplus不能使用上下键,退格键
  11. Java调用发微博API_编写调用新浪微博API的Java程序来发送微博
  12. Windows10 Hero默认壁纸(11色)
  13. 向量索引算法HNSW和NSG的比较
  14. arcpy投影(二)——基准面变换概念及参数、空间参考对象获取、变换关系获取方法梳理与解析(Spatial Reference、ListTransformations)
  15. python OpenCV与NAOqi库在机器人点球比赛中的应用
  16. 如何合并多个PDF文件?这几个小妙招快来码住吧
  17. 连接高匿代理接口调用并测试是否可用
  18. 孤独的人在孤独的地方...
  19. Python整体缩进和整体去掉缩进
  20. OM | 电子商务平台中的合约选择:批发合约or代理合约?

热门文章

  1. Word分栏在排版中的应用
  2. 谱尼测试凭借现代化的测试平台
  3. DNA分子结构3D模型
  4. apache启动失败原因
  5. DELPHI常用的VCL类简介
  6. 浏览器安全检查5秒解决方案
  7. 2008年度江苏地税纳税百强企业名单
  8. Eighth Week(补充完整)
  9. 公有云、私有云、私有化_私有云与公共云的评估
  10. 【原创】基于Springboot、WebSocket的一对一聊天室