feat/fix: misc shader changes (fix normals, lighting, uv)
This commit is contained in:
@@ -7,24 +7,24 @@ import grassVert from './shaders/grass.vert';
|
|||||||
import grassFrag from './shaders/grass.frag';
|
import grassFrag from './shaders/grass.frag';
|
||||||
|
|
||||||
interface GrassProps {
|
interface GrassProps {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
size: number;
|
size: number;
|
||||||
count: number;
|
count: number;
|
||||||
grassSize: number;
|
grassSize: number;
|
||||||
scale: number;
|
scale: number;
|
||||||
hillScale: number;
|
hillScale: number;
|
||||||
hillHeight: number;
|
hillHeight: number;
|
||||||
detailScale: number;
|
detailScale: number;
|
||||||
detailHeight: number;
|
detailHeight: number;
|
||||||
noise2D: (x: number, y: number) => number;
|
noise2D: (x: number, y: number) => number;
|
||||||
grassLOD: number;
|
grassLOD: number;
|
||||||
dryColor: string;
|
dryColor: string;
|
||||||
lushColor: string;
|
lushColor: string;
|
||||||
grassBlades?: number;
|
grassBlades?: number;
|
||||||
grassSegments?: number;
|
grassSegments?: number;
|
||||||
grassLODStart?: number;
|
grassLODStart?: number;
|
||||||
grassLODExponent?: number;
|
grassLODExponent?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Grass({
|
export default function Grass({
|
||||||
@@ -222,62 +222,61 @@ export default function Grass({
|
|||||||
shader.uniforms.uTime = { value: 0 };
|
shader.uniforms.uTime = { value: 0 };
|
||||||
|
|
||||||
shader.vertexShader = `
|
shader.vertexShader = `
|
||||||
uniform float uTime;
|
uniform float uTime;
|
||||||
varying vec2 vGrassUv;
|
varying vec2 vGrassUv;
|
||||||
|
varying vec3 vWorldPos;
|
||||||
float hash(vec2 p) {
|
|
||||||
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
float hash(vec2 p) {
|
||||||
}
|
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
||||||
|
}
|
||||||
float noise(vec2 p) {
|
|
||||||
vec2 i = floor(p);
|
float noise(vec2 p) {
|
||||||
vec2 f = fract(p);
|
vec2 i = floor(p);
|
||||||
f = f * f * (3.0 - 2.0 * f);
|
vec2 f = fract(p);
|
||||||
|
f = f * f * (3.0 - 2.0 * f);
|
||||||
float a = hash(i);
|
float a = hash(i);
|
||||||
float b = hash(i + vec2(1.0, 0.0));
|
float b = hash(i + vec2(1.0, 0.0));
|
||||||
float c = hash(i + vec2(0.0, 1.0));
|
float c = hash(i + vec2(0.0, 1.0));
|
||||||
float d = hash(i + vec2(1.0, 1.0));
|
float d = hash(i + vec2(1.0, 1.0));
|
||||||
|
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
||||||
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
}
|
||||||
}
|
|
||||||
|
float fbm(vec2 p) {
|
||||||
float fbm(vec2 p) {
|
float value = 0.0;
|
||||||
float value = 0.0;
|
float amplitude = 0.5;
|
||||||
float amplitude = 0.5;
|
float frequency = 1.0;
|
||||||
float frequency = 1.0;
|
for(int i = 0; i < 4; i++) {
|
||||||
|
value += amplitude * noise(p * frequency);
|
||||||
for(int i = 0; i < 4; i++) {
|
frequency *= 2.0;
|
||||||
value += amplitude * noise(p * frequency);
|
amplitude *= 0.5;
|
||||||
frequency *= 2.0;
|
}
|
||||||
amplitude *= 0.5;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
${shader.vertexShader}
|
||||||
}
|
`;
|
||||||
|
|
||||||
${shader.vertexShader}
|
|
||||||
`;
|
|
||||||
shader.vertexShader = shader.vertexShader.replace(
|
shader.vertexShader = shader.vertexShader.replace(
|
||||||
'#include <begin_vertex>',
|
'#include <begin_vertex>',
|
||||||
`
|
`
|
||||||
#include <begin_vertex>
|
#include <begin_vertex>
|
||||||
vGrassUv = uv;
|
${grassVert}
|
||||||
${grassVert}
|
`
|
||||||
`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
shader.fragmentShader = `
|
shader.fragmentShader = `
|
||||||
uniform float uTime;
|
uniform float uTime;
|
||||||
varying vec2 vGrassUv;
|
varying vec2 vGrassUv;
|
||||||
${shader.fragmentShader}
|
varying vec3 vWorldPos;
|
||||||
`;
|
${shader.fragmentShader}
|
||||||
|
`;
|
||||||
|
|
||||||
shader.fragmentShader = shader.fragmentShader.replace(
|
shader.fragmentShader = shader.fragmentShader.replace(
|
||||||
'#include <color_fragment>',
|
'#include <color_fragment>',
|
||||||
`
|
`
|
||||||
#include <color_fragment>
|
#include <color_fragment>
|
||||||
${grassFrag}
|
${grassFrag}
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
if (materialRef.current) {
|
if (materialRef.current) {
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
float ao = smoothstep(0.0, 0.7, vGrassUv.y);
|
float ao = smoothstep(0.0, 0.8, vGrassUv.y);
|
||||||
ao = mix(0.05, 1.0, ao);
|
ao = mix(0.15, 1.0, ao);
|
||||||
|
|
||||||
vec3 rootColor = diffuseColor.rgb * 0.4;
|
|
||||||
vec3 tipColor = diffuseColor.rgb * 1.5;
|
|
||||||
|
|
||||||
|
vec3 rootColor = diffuseColor.rgb * 0.35;
|
||||||
|
vec3 tipColor = diffuseColor.rgb * 1.3;
|
||||||
vec3 grassColor = mix(rootColor, tipColor, vGrassUv.y);
|
vec3 grassColor = mix(rootColor, tipColor, vGrassUv.y);
|
||||||
grassColor *= ao;
|
|
||||||
|
|
||||||
float translucency = pow(vGrassUv.y, 2.0) * 0.5;
|
vec3 viewDir = normalize(cameraPosition - vWorldPos);
|
||||||
grassColor += diffuseColor.rgb * translucency;
|
vec3 lightDir = normalize(vec3(15.0, 25.0, 15.0));
|
||||||
|
|
||||||
diffuseColor.rgb = grassColor;
|
float backLighting = max(0.0, dot(viewDir, -lightDir));
|
||||||
|
backLighting = pow(backLighting, 3.0) * smoothstep(0.2, 1.0, vGrassUv.y);
|
||||||
|
|
||||||
|
vec3 sssColor = vec3(0.4, 0.8, 0.3) * diffuseColor.rgb;
|
||||||
|
grassColor += sssColor * backLighting * 1.5;
|
||||||
|
|
||||||
|
diffuseColor.rgb = grassColor * ao;
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
vGrassUv = uv;
|
||||||
|
|
||||||
vec4 worldPos = modelMatrix * instanceMatrix * vec4(0.0, 0.0, 0.0, 1.0);
|
vec4 worldPos = modelMatrix * instanceMatrix * vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
float gx = worldPos.x;
|
float gx = worldPos.x;
|
||||||
float gz = worldPos.z;
|
float gz = worldPos.z;
|
||||||
@@ -8,7 +10,6 @@ float windSpeed = 1.5;
|
|||||||
float windTime = uTime * windSpeed;
|
float windTime = uTime * windSpeed;
|
||||||
vec2 windSamplePos = (worldPos.xz * 0.05) - (mainWindDir * windTime * 0.2);
|
vec2 windSamplePos = (worldPos.xz * 0.05) - (mainWindDir * windTime * 0.2);
|
||||||
|
|
||||||
|
|
||||||
float windBase = fbm(windSamplePos * 0.8) * 0.4 + 0.2;
|
float windBase = fbm(windSamplePos * 0.8) * 0.4 + 0.2;
|
||||||
float gustNoise = fbm(windSamplePos * 0.4);
|
float gustNoise = fbm(windSamplePos * 0.4);
|
||||||
float gust = pow(gustNoise, 3.0) * 1.8;
|
float gust = pow(gustNoise, 3.0) * 1.8;
|
||||||
@@ -35,4 +36,7 @@ transformed.z += curveAmount * curveDir.y * 0.5;
|
|||||||
float swayAmount = (totalWind + spring) * uv.y * uv.y;
|
float swayAmount = (totalWind + spring) * uv.y * uv.y;
|
||||||
transformed.x += swayAmount * windDir.x;
|
transformed.x += swayAmount * windDir.x;
|
||||||
transformed.z += swayAmount * windDir.y;
|
transformed.z += swayAmount * windDir.y;
|
||||||
transformed.y -= abs(swayAmount) * 0.2;
|
transformed.y -= abs(swayAmount) * 0.2;
|
||||||
|
|
||||||
|
objectNormal = vec3(0.0, 1.0, 0.0);
|
||||||
|
vWorldPos = (modelMatrix * instanceMatrix * vec4(transformed, 1.0)).xyz;
|
||||||
Reference in New Issue
Block a user