纯GLSL分步实现电影般画面的湖光山色<Step1>: 艳阳蓝天(WebGL实现)

在实时渲染领域,呈现一个绚丽的画面除了艺术美术的功力之外,还需要大部分的技术支持: 数理几何原理和渲染技术。

GLSL(OpenGL的Shader语言,用于对GPU渲染过程实现编程控制)就是这些技艺和呈现之间的桥梁。

一个稍微复杂的画面,用纯GLSL实现,除了要熟悉这个语法以及对应的GPU功能之外还需要熟悉数理原理和一些技巧,所以包含的内容比较多。

湖光山色是一个富有诗意的画面,在ShaderToy上看到大神的一个作品: Shader - Shadertoy BETA, 画面很美

现在,就分若干步骤,一步一步分解开来,由简入繁,单独拆解几个重要的技术点,以实现对大神技艺的临摹和分享

因为是重写,加了自己的想法,代码和画面效果都和原来有出入。

Step1,艳阳和蓝天。效果如下:

Demo: Rendering & Art

GLSL源码:

// Write by Vily.
precision highp float;
// u_param.xy: (stageWidth,stageHeight), u_param.z>1.0: mouse_down,u_param.z<1.0: mouse_up
uniform vec4 u_param;
// u_mouse.x: mouse x offset from mouseDown position x,
// u_mouse.y: mouse y offset from mouseDown position y,
// u_mouse.z: mouse x accumulation from mouseDown position x,
// u_mouse.w: mouse y accumulation from mouseDown position y
uniform vec4 u_mouse;

mat2 rotY(const in float a) {
	return mat2(cos(a),sin(a),-sin(a),cos(a));	
}
// light direction
vec3 lightDirection = normalize(vec3( 0.3,0.7, 0.6));
// create the sky and a sun
vec3 createSkyAndSun( const in vec3 ray ) {
	float sunDensity = clamp( dot(lightDirection, ray), 0.0, 1.0 );
	// sky color
	vec3 color = vec3(0.2,0.4,0.6) - ray.y*0.3*vec3(0.1,0.5,1.0) + 0.13;
	// sun and sun's halo
	color += vec3(0.8,.7,0.2)*pow( sunDensity, 16.0 ) * 0.4 + vec3(1.0,.7,0.2)*pow( sunDensity, 32.0 ) * 0.6;
	color *= 0.95;
	return color;
}
// create a matrix33 of camera space to world space
mat3 viewMatrix3(vec3 eye, vec3 center, vec3 up) {
    vec3 f = normalize(center - eye);
    vec3 s = normalize(cross(f, up));
    vec3 u = cross(s, f);
    return mat3(s, u, -f);
}
void main()
{
    vec2 q = gl_FragCoord.xy / u_param.xy;
    q = -1.0 + 2.0*q;
    q.x *= u_param.x/ u_param.y;
	//
    float inTime = u_param.z * 2.0;
	vec3 lookAtCenter = vec3(0.0, 0.0, 0.0);
	vec3 eye = vec3(0.0, 3.5,3.0);
	//
	//if(u_param.z > 1.0) inTime += 0.1 * u_mouse.x;
	inTime += 0.1 * u_mouse.z;
	//
	vec3 ray = normalize(vec3(q.x,q.y,2.5));
	eye.xz *= rotY( mod(inTime * 0.03, 6.2831852) );
    ray = viewMatrix3(eye, lookAtCenter, vec3(0.0,1.0,0.0)) * ray;
	//
	vec3 col = createSkyAndSun( ray );
	//
    gl_FragColor = vec4( col * vec3(1.0,1.0,1.4), 1.0 );
}

在以上源码上,已有相应的注释。

这个GLSL,我所需Geometry的只是由两个三角形构成的矩形,这个矩形铺满整个视口。不需要纹理。需要的输入参数由uniform指定。以上代码中 uniform vec4 u_param,存放了四个值,x,y对应的是视口对应的额屏幕设备宽和高,z是一个由0开始每一帧累加0.1的float值, 暂时w没用到,值为0.0

以上Demo中所用的引擎是我自己的渲染系统, 比较完整,支持webgl1和webgl2, 如果有需要可以直接在浏览器的资源中下载得到。而且这部分代码是按c++原来的方式写的,所以归类很清晰。

下一篇:纯GLSL分步实现电影般画面的湖光山色<Step2>: 艳阳蓝天和碧水(WebGL实现)_含影的博客-CSDN博客

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值