|
@@ -46,8 +46,12 @@
|
|
|
precision highp float;
|
|
|
|
|
|
uniform vec2 resolution;
|
|
|
- uniform vec3 cameraPos;
|
|
|
- uniform vec3 cameraDir;
|
|
|
+
|
|
|
+ uniform mat4 viewMatrix;
|
|
|
+ uniform vec3 cameraPosition;
|
|
|
+
|
|
|
+ uniform mat4 cameraWorldMatrix;
|
|
|
+ uniform mat4 cameraProjectionMatrixInverse;
|
|
|
|
|
|
const float EPS = 0.01;
|
|
|
const float OFFSET = EPS * 100.0;
|
|
@@ -198,33 +202,32 @@
|
|
|
void main(void) {
|
|
|
|
|
|
// fragment position
|
|
|
- vec2 p = ( gl_FragCoord.xy * 2.0 - resolution ) / min( resolution.x, resolution.y );
|
|
|
+ vec2 screenPos = ( gl_FragCoord.xy * 2.0 - resolution ) / min( resolution.x, resolution.y );
|
|
|
+
|
|
|
+ // convert ray direction from screen coordinate to world coordinate
|
|
|
+ vec3 ray = (cameraWorldMatrix * cameraProjectionMatrixInverse * vec4( screenPos.xy, 1.0, 1.0 )).xyz;
|
|
|
+ ray = normalize( ray );
|
|
|
|
|
|
- // camera and ray
|
|
|
- vec3 cPos = cameraPos;
|
|
|
- vec3 cDir = cameraDir;
|
|
|
- vec3 cSide = normalize( cross( cDir, vec3( 0.0, 1.0 ,0.0 ) ) );
|
|
|
- vec3 cUp = normalize( cross( cSide, cDir ) );
|
|
|
- float targetDepth = 1.3;
|
|
|
- vec3 ray = normalize( cSide * p.x + cUp * p.y + cDir * targetDepth );
|
|
|
+ // camera position
|
|
|
+ vec3 cPos = cameraPosition;
|
|
|
|
|
|
vec3 color = vec3( 0.0 );
|
|
|
- vec3 q, normal;
|
|
|
+ vec3 p, normal;
|
|
|
bool hit;
|
|
|
float alpha = 1.0;
|
|
|
|
|
|
for ( int i = 0; i < 3; i++ ) {
|
|
|
|
|
|
- color += alpha * getRayColor( cPos, ray, q, normal, hit );
|
|
|
+ color += alpha * getRayColor( cPos, ray, p, normal, hit );
|
|
|
alpha *= 0.3;
|
|
|
ray = normalize( reflect( ray, normal ) );
|
|
|
- cPos = q + normal * OFFSET;
|
|
|
+ cPos = p + normal * OFFSET;
|
|
|
|
|
|
if ( !hit ) break;
|
|
|
|
|
|
}
|
|
|
|
|
|
- gl_FragColor = vec4(color, 1.0);
|
|
|
+ gl_FragColor = vec4( color, 1.0 );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -250,7 +253,7 @@
|
|
|
|
|
|
<script>
|
|
|
|
|
|
- var camera, dummyCamera, scene, controls, renderer;
|
|
|
+ var camera, scene, controls, renderer;
|
|
|
var geometry, material, mesh;
|
|
|
var mouse = new THREE.Vector2( 0.5, 0.5 );
|
|
|
var canvas;
|
|
@@ -261,7 +264,7 @@
|
|
|
var config = {
|
|
|
saveImage: function() {
|
|
|
|
|
|
- renderer.render( scene, dummyCamera );
|
|
|
+ renderer.render( scene, camera );
|
|
|
window.open( canvas.toDataURL() );
|
|
|
|
|
|
},
|
|
@@ -274,40 +277,42 @@
|
|
|
|
|
|
function init() {
|
|
|
|
|
|
+ renderer = new THREE.WebGLRenderer();
|
|
|
+ renderer.setPixelRatio( window.devicePixelRatio );
|
|
|
+ renderer.setSize( 512, 512 );
|
|
|
+
|
|
|
+ canvas = renderer.domElement;
|
|
|
+ canvas.addEventListener( 'mousemove', onMouseMove );
|
|
|
+ window.addEventListener( 'resize', onWindowResize );
|
|
|
+ document.body.appendChild( canvas );
|
|
|
+
|
|
|
+ // Scene
|
|
|
scene = new THREE.Scene();
|
|
|
- camera = new THREE.Camera();
|
|
|
- dummyCamera = new THREE.Camera();
|
|
|
+ camera = new THREE.PerspectiveCamera( 60, canvas.width / canvas.height, 1, 2000 );
|
|
|
camera.lookAt( new THREE.Vector3( 0.0, -0.3, 1.0 ) );
|
|
|
|
|
|
geometry = new THREE.PlaneBufferGeometry( 2.0, 2.0 );
|
|
|
material = new THREE.RawShaderMaterial( {
|
|
|
uniforms: {
|
|
|
resolution: { value: new THREE.Vector2( 512, 512 ) },
|
|
|
- cameraPos: { value: camera.getWorldPosition() },
|
|
|
- cameraDir: { value: camera.getWorldDirection() }
|
|
|
+ cameraWorldMatrix: { value: camera.matrixWorld },
|
|
|
+ cameraProjectionMatrixInverse: { value: new THREE.Matrix4().getInverse( camera.projectionMatrix ) }
|
|
|
},
|
|
|
vertexShader: document.getElementById( 'vertex_shader' ).textContent,
|
|
|
fragmentShader: document.getElementById( 'fragment_shader' ).textContent
|
|
|
} );
|
|
|
mesh = new THREE.Mesh( geometry, material );
|
|
|
+ mesh.frustumCulled = false;
|
|
|
scene.add( mesh );
|
|
|
|
|
|
- renderer = new THREE.WebGLRenderer();
|
|
|
- renderer.setPixelRatio( window.devicePixelRatio );
|
|
|
- renderer.setSize( 512, 512 );
|
|
|
-
|
|
|
- canvas = renderer.domElement;
|
|
|
- canvas.addEventListener( 'mousemove', onMouseMove );
|
|
|
- window.addEventListener( 'resize', onWindowResize );
|
|
|
- document.body.appendChild( canvas );
|
|
|
-
|
|
|
+ // Controls
|
|
|
controls = new THREE.FlyControls( camera, canvas );
|
|
|
-
|
|
|
controls.autoForward = true;
|
|
|
controls.dragToLook = false;
|
|
|
controls.rollSpeed = Math.PI / 12;
|
|
|
controls.movementSpeed = 0.5;
|
|
|
|
|
|
+ // GUI
|
|
|
var gui = new dat.GUI();
|
|
|
gui.add( config, 'saveImage' ).name( 'Save Image' );
|
|
|
gui.add( config, 'freeCamera' ).name( 'Free Camera' );
|
|
@@ -348,9 +353,11 @@
|
|
|
if ( camera.position.y < 0 ) camera.position.y = 0;
|
|
|
|
|
|
material.uniforms.resolution.value = new THREE.Vector2( canvas.width, canvas.height );
|
|
|
- material.uniforms.cameraPos.value = camera.getWorldPosition();
|
|
|
- material.uniforms.cameraDir.value = camera.getWorldDirection();
|
|
|
- renderer.render( scene, dummyCamera );
|
|
|
+
|
|
|
+ material.uniforms.cameraWorldMatrix.value = camera.matrixWorld;
|
|
|
+ material.uniforms.cameraProjectionMatrixInverse.value = new THREE.Matrix4().getInverse( camera.projectionMatrix );
|
|
|
+
|
|
|
+ renderer.render( scene, camera );
|
|
|
|
|
|
stats.end();
|
|
|
requestAnimationFrame( render );
|