How to use JavaScript to render a diamond more realistic

I tried for a long time but failed to render a diamond model as real.
Here is the model I used
huatou.gltf (1.3 MB)
Here are the results I hope to achieve
demo
I think I need your help. Can someone provide some suggestions or demos? Thank you very much

There was a topic about this last year: How to make diamond looks real?

1 Like

Thank you for reply.I have seen the content here before, but it still hasn’t achieved the desired effect

The code is open source, look for mesh refraction material GitHub - pmndrs/drei: 🥉 useful helpers for react-three-fiber

1 Like

Thank you for reply.These demos are implemented on the basis of React, what I need is a demo that is only implemented on JavaScript

The shader is glsl, it is unrelated to react or even threejs. In vanilla nothing is easily reusable, but you can pull out the source, adapt it to your purposes.

Btw, there is a vanilla project GitHub - N8python/diamonds but the drei source is more up to date and contains multiple bug fixes, it is most likely easier to port because the shader exists in isolation.

you can tried it with glsl.
1.make axies

    vec2 uv = fragCoord/iResolution.xy;
    
    uv = (uv - .5) * 2.;

    uv.x *= iResolution.x / iResolution.y;
  1. draw 2d y axies
void main()
  {
    vec2 uv = gl_FragCoord/u_resolution.xy;
    vec2 uv2 = gl_FragCoord/u_resolution.xy;
    
    uv = (uv - .5) * 2.;

    uv.x *= u_resolution.x / u_resolution.y;
    vec3 col = vec3( 0. );
    
    float p = 0.;

    float py = uv.y;
    
    if( py < -.3 ){
        py = -1.;
    }
    
    py = abs( py ) - 1.;
    py = abs( py );
    
    p = abs( uv.x ) - .5 * py;
    
    p = step( p, 0. );
    
    col += p;
    gl_FragColor = vec4(col,1.0);
}

then you will got a

at last draw close path shape eg. triangle, rectangle or fivestar etc and calculated with y axies at 2 step

we used rectangle for eg.

float map(vec3 p)
{
    
    float d = 5.;
    
    p.xz *= rotation( iTime );
    
    float py = p.y;

    
    if( py < -.3 ){
        py = -1.;
    }
    
    py = abs( py ) - 1.;
    py = abs( py );
    
    // max( abs( p.x ) - .3, abs( p.z ) - .3 ) was 
    d = max( max( abs( p.x ) - .3 * py, abs( p.z ) - .3 * py ), abs( p.y ) - 1. );
    
  
    return d;
}

the model show

we can map some pictures or effect, rendered a diamond use glsl veryeasy
in the result


mat2 rotation(float a) {
    float s = sin(a), c = cos(a);
    return mat2(c, s, -s, c);
}

float map(vec3 p)
{
    float d = 5.;
    
    p.xz *= rotation( time );
    
    float py = p.y;

    if( py < -.3 ){
        py = -1.;
    }
    
    py = abs( py ) - 1.;
    py = abs( py );
    
    d = max( max( abs( p.x ) - .3 * py, abs( p.z ) - .3 * py ), abs( p.y ) - 1. );    
    return d;
}

// https://iquilezles.org/articles/normalsSDF
vec3 calcNormal( in vec3 pos) {
    vec2 e = vec2(1.0, -1.0) * 0.5773;
    const float eps = 0.0005;
    return normalize(e.xyy * map(pos + e.xyy * eps) +
        e.yyx * map(pos + e.yyx * eps) +
        e.yxy * map(pos + e.yxy * eps) +
        e.xxx * map(pos + e.xxx * eps));
}

vec3 raymarching( vec3 ro, vec3 rd ){
    
    float t = 0.,
          dist = 0.;
          
    vec3 pos = vec3( 0. );
    
    for( int i = 0; i < 64; i++ ){
        
        pos = ro + rd * t;
        dist = map( pos );
        
        if( t > 1e3 ){
            break ;
        }
        
        t += dist;
    }
    
    
    if( dist < 1e-3 ){
    
        vec3 nor = calcNormal(pos);
        
        float dif = clamp(dot(nor, vec3(.4, 1., -.5)), 0.0, 1.0);

        float amb = dot(nor, vec3(0.0, 1.0, 0.0));

        nor.xz *= rotation( iTime );
        rd.xz *= rotation( iTime * .1 );

        vec3 reflection = reflect(rd, nor);
        
        vec3 tex = textureCube( cubemaps, reflection ).rgb;

        return vec3(.1) * amb + vec3(.5) * dif + vec3(.3) + tex;
        
    }
        
    return vec3( 0. );
}

void main( )
{
    vec2 uv = gl_FragCoord/u_resolution.xy;
    
    uv = (uv - .5) * 2.;

    uv.x *= u_resolution.x / u_resolution.y;

    vec3 col = vec3( 0. );
    
    vec3 ro = vec3( 0., 0., -2. );
    vec3 rd = vec3( uv, 1. );
    
    col = raymarching( ro, rd );

    gl_FragColor = vec4(col,1.0);
}

output result

1 Like

Thank you for reply.I am trying to overcome this problem

Thank you for reply.I will try this method