矮草坪渲染尝试

本来说写unity里的,由于three测试方便,先试试three

在这里插入图片描述
这个图片是目标效果
可以看见草很矮,很密集,如果用instance来绘制的话,遭不住的
忽然发现这个效果很像绒毛效果
于是找了博客康康
https://zhuanlan.zhihu.com/p/256445252
大概就是叠alpha,性能比instance好多了,虽然效果其实比不得instance,他这个实际来说丢失了每一根草的渲染能力,只能调叠层的色彩和整体调色,可能要和一根一根的草混用吧

在这里插入图片描述

这是在three构建demo的代码

			const geometry = new THREE.PlaneGeometry(20, 20);//new THREE.ConeGeometry( 10, 30, 20, 20 );
			geometry.rotateX(Math.PI * 0.5);
			// const material = new THREE.MeshPhongMaterial( { color: 0xffffff, wireframe: true } );
			const material = new THREE.ShaderMaterial({
    
    
				uniforms: {
    
    
					id: {
    
     value: 1 },
					iTime: {
    
     value: 0 },
				},
				vertexShader: `
					uniform float id;
					varying vec2 vUv;
					varying vec3 vColor;
					varying vec3 vNormal;
					varying vec3 pos;
					void main() {
						vUv = uv;
						vColor = vec3(1.0, 0.0, 0.0);
						pos = position.xyz;
						vNormal = normal;
						pos+=normal*0.1*id;
						gl_Position = projectionMatrix * modelViewMatrix * vec4(pos.xyz,1.0);
					}
					`,
				fragmentShader: `
				uniform float id;
				uniform float iTime;
					varying vec3 vColor;
					varying vec3 vNormal;
					varying vec3 pos;
					varying vec2 vUv;
					float random (in vec2 st) {
    return fract(sin(dot(st.xy,
                         vec2(12.9898,78.233)))
                 * 43758.5453123);
}

// 2D Noise based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
float noise (in vec2 st) {
    vec2 i = floor(st);
    vec2 f = fract(st);

    // Four corners in 2D of a tile
    float a = random(i);
    float b = random(i + vec2(1.0, 0.0));
    float c = random(i + vec2(0.0, 1.0));
    float d = random(i + vec2(1.0, 1.0));

    // Smooth Interpolation

    // Cubic Hermine Curve.  Same as SmoothStep()
    vec2 u = f*f*(3.0-2.0*f);
    // u = smoothstep(0.,1.,f);

    // Mix 4 coorners percentages
    return mix(a, b, u.x) +
				(c - a)* u.y * (1.0 - u.x) +
				(d - b) * u.x * u.y;
	}
						vec4 permute(vec4 x) {
	return mod((34.0 * x + 1.0) * x, 289.0);
	}

	// Cellular noise, returning F1 and F2 in a vec2.
	// Speeded up by using 2x2 search window instead of 3x3,
	// at the expense of some strong pattern artifacts.
	// F2 is often wrong and has sharp discontinuities.
	// If you need a smooth F2, use the slower 3x3 version.
	// F1 is sometimes wrong, too, but OK for most purposes.
	vec2 cellular2x2(vec2 P) {
		#define K 0.142857142857 // 1/7
		#define K2 0.0714285714285 // K/2
		#define jitter 0.8 // jitter 1.0 makes F1 wrong more often
		vec2 Pi = mod(floor(P), 289.0);
		vec2 Pf = fract(P);
		vec4 Pfx = Pf.x + vec4(-0.5, -1.5, -0.5, -1.5);
		vec4 Pfy = Pf.y + vec4(-0.5, -0.5, -1.5, -1.5);
		vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0));
		p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0));
		vec4 ox = mod(p, 7.0)*K+K2;
		vec4 oy = mod(floor(p*K),7.0)*K+K2;
		vec4 dx = Pfx + jitter*ox;
		vec4 dy = Pfy + jitter*oy;
		vec4 d = dx * dx + dy * dy; // d11, d12, d21 and d22, squared
		// Sort out the two smallest distances
	#if 0
		// Cheat and pick only F1
		d.xy = min(d.xy, d.zw);
		d.x = min(d.x, d.y);
		return d.xx; // F1 duplicated, F2 not computed
	#else
		// Do it right and find both F1 and F2
		d.xy = (d.x < d.y) ? d.xy : d.yx; // Swap if smaller
		d.xz = (d.x < d.z) ? d.xz : d.zx;
		d.xw = (d.x < d.w) ? d.xw : d.wx;
		d.y = min(d.y, d.z);
		d.y = min(d.y, d.w);
		return sqrt(d.xy);
	#endif
	}
					void main(){
						float test2 = (noise(vUv*30.0)*0.5+0.5)*0.5;
						vec2 F = cellular2x2((vUv + 0.0* test2 * 0.0025*(1.0 - id)* sin(test2*0.1*iTime) )*2000.);


						float test = noise(vUv*15.0);
						vec3 yellow = vec3(0.4,0.9,0.0)*0.85;
						vec3 green = vec3(0.2,1.0,0.0)*0.85;

						float n = 1.0-1.5*F.x;
						
							//gl_FragColor += vec4(0.1, 0.5 + (1.0 - id)*0.25, 0.0, n * id);
							gl_FragColor += vec4(mix(green,yellow,  test)*0.5+(1.0 - id)*0.5, n * id );
							// if(gl_FragColor.a<0.21)discard; else {gl_FragColor.a=1.0;
							// }
							//  gl_FragColor += vec4(n,n,n, n * id*0.5);
						
						
					}
					`,
				transparent: true,
				side: 2
			})
			let arr = [];
			const COUNT = 30;
			for (let i = 0; i < COUNT; i++) {
    
    
				let geo = geometry.clone();
				const materialClone = material.clone();
				materialClone.uniforms.id.value = 1.0 - (i / COUNT);
				arr.push(materialClone);
				const mesh = new THREE.Mesh(geo, materialClone);
				scene.add(mesh);
			}

猜你喜欢

转载自blog.csdn.net/qq_35158695/article/details/141857346